Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

"use strict";
const TEST_STORE_FILE_NAME = "test-profile.json";
const { CREDIT_CARD_SCHEMA_VERSION } = ChromeUtils.importESModule(
);
// NOTE: a guide to reading these test-cases:
// parent: What the local record looked like the last time we wrote the
// record to the Sync server.
// local: What the local record looks like now. IOW, the differences between
// 'parent' and 'local' are changes recently made which we wish to sync.
// remote: An incoming record we need to apply (ie, a record that was possibly
// changed on a remote device)
//
// To further help understanding this, a few of the testcases are annotated.
const ADDRESS_RECONCILE_TESTCASES = [
{
description: "Local change",
parent: {
// So when we last wrote the record to the server, it had these values.
guid: "2bbd2d8fbc6b",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
local: [
{
// The current local record - by comparing against parent we can see that
// only the name has changed locally.
name: "Skip",
"street-address": "32 Vassar Street",
},
],
remote: {
// This is the incoming record. It has the same values as "parent", so
// we can deduce the record hasn't actually been changed remotely so we
// can safely ignore the incoming record and write our local changes.
guid: "2bbd2d8fbc6b",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
reconciled: {
guid: "2bbd2d8fbc6b",
name: "Skip",
"street-address": "32 Vassar Street",
},
},
{
description: "Remote change",
parent: {
guid: "e3680e9f890d",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
local: [
{
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
],
remote: {
guid: "e3680e9f890d",
version: 1,
name: "Skip",
"street-address": "32 Vassar Street",
},
reconciled: {
guid: "e3680e9f890d",
name: "Skip",
"street-address": "32 Vassar Street",
},
},
{
description: "New local field",
parent: {
guid: "0cba738b1be0",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
local: [
{
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
},
],
remote: {
guid: "0cba738b1be0",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
reconciled: {
guid: "0cba738b1be0",
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
},
},
{
description: "New remote field",
parent: {
guid: "be3ef97f8285",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
local: [
{
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
],
remote: {
guid: "be3ef97f8285",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
},
reconciled: {
guid: "be3ef97f8285",
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
},
},
{
description: "Deleted field locally",
parent: {
guid: "9627322248ec",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
},
local: [
{
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
],
remote: {
guid: "9627322248ec",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
},
reconciled: {
guid: "9627322248ec",
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
},
{
description: "Deleted field remotely",
parent: {
guid: "7d7509f3eeb2",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
},
local: [
{
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
},
],
remote: {
guid: "7d7509f3eeb2",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
reconciled: {
guid: "7d7509f3eeb2",
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
},
{
description: "Local and remote changes to unrelated fields",
parent: {
// The last time we wrote this to the server, country was NZ.
guid: "e087a06dfc57",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "NZ",
// We also had an unknown field we round-tripped
foo: "bar",
},
local: [
{
// The current local record - so locally we've changed name to Skip.
name: "Skip",
"street-address": "32 Vassar Street",
country: "NZ",
},
],
remote: {
// Remotely, we've changed the country to AU.
guid: "e087a06dfc57",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "AU",
// This is a new unknown field that should send instead!
"unknown-1": "an unknown field from another client",
},
reconciled: {
guid: "e087a06dfc57",
name: "Skip",
"street-address": "32 Vassar Street",
country: "AU",
// This is a new unknown field that should send instead!
"unknown-1": "an unknown field from another client",
},
},
{
description: "Multiple local changes",
parent: {
guid: "340a078c596f",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
country: "US",
},
local: [
{
name: "Skip",
"street-address": "32 Vassar Street",
country: "US",
},
{
name: "Skip",
"street-address": "32 Vassar Street",
organization: "Mozilla",
country: "US",
},
],
remote: {
guid: "340a078c596f",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
country: "AU",
},
reconciled: {
guid: "340a078c596f",
name: "Skip",
"street-address": "32 Vassar Street",
organization: "Mozilla",
country: "AU",
},
},
{
// Local and remote diverged from the shared parent, but the values are the
// same, so we shouldn't fork.
description: "Same change to local and remote",
parent: {
guid: "0b3a72a1bea2",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
// unknown fields we previously roundtripped
foo: "bar",
},
local: [
{
name: "Skip",
"street-address": "32 Vassar Street",
},
],
remote: {
guid: "0b3a72a1bea2",
version: 1,
name: "Skip",
"street-address": "32 Vassar Street",
// New unknown field that should be the new round trip
"unknown-1": "an unknown field from another client",
},
reconciled: {
guid: "0b3a72a1bea2",
name: "Skip",
"street-address": "32 Vassar Street",
},
},
{
description: "Conflicting changes to single field",
parent: {
// This is what we last wrote to the sync server.
guid: "62068784d089",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
"unknown-1": "an unknown field from another client",
},
local: [
{
// The current version of the local record - the name has changed locally.
name: "Skip",
"street-address": "32 Vassar Street",
},
],
remote: {
// An incoming record has a different name than any of the above!
guid: "62068784d089",
version: 1,
name: "Kip",
"street-address": "32 Vassar Street",
"unknown-1": "an unknown field from another client",
},
forked: {
// So we've forked the local record to a new GUID (and the next sync is
// going to write this as a new record)
name: "Skip",
"street-address": "32 Vassar Street",
"unknown-1": "an unknown field from another client",
},
reconciled: {
// And we've updated the local version of the record to be the remote version.
guid: "62068784d089",
name: "Kip",
"street-address": "32 Vassar Street",
"unknown-1": "an unknown field from another client",
},
},
{
description: "Conflicting changes to multiple fields",
parent: {
guid: "244dbb692e94",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "NZ",
},
local: [
{
name: "Skip",
"street-address": "32 Vassar Street",
country: "AU",
},
],
remote: {
guid: "244dbb692e94",
version: 1,
name: "Kip",
"street-address": "32 Vassar Street",
country: "CA",
},
forked: {
name: "Skip",
"street-address": "32 Vassar Street",
country: "AU",
},
reconciled: {
guid: "244dbb692e94",
name: "Kip",
"street-address": "32 Vassar Street",
country: "CA",
},
},
{
description: "Field deleted locally, changed remotely",
parent: {
guid: "6fc45e03d19a",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "AU",
},
local: [
{
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
],
remote: {
guid: "6fc45e03d19a",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "NZ",
},
forked: {
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
reconciled: {
guid: "6fc45e03d19a",
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "NZ",
},
},
{
description: "Field changed locally, deleted remotely",
parent: {
guid: "fff9fa27fa18",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "AU",
},
local: [
{
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "NZ",
},
],
remote: {
guid: "fff9fa27fa18",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
forked: {
name: "Mark Hammond",
"street-address": "32 Vassar Street",
country: "NZ",
},
reconciled: {
guid: "fff9fa27fa18",
name: "Mark Hammond",
"street-address": "32 Vassar Street",
},
},
{
// Created, last modified should be synced; last used and times used should
// be local. Remote created time older than local, remote modified time
// newer than local.
description:
"Created, last modified time reconciliation without local changes",
parent: {
guid: "5113f329c42f",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
timeCreated: 1234,
timeLastModified: 5678,
timeLastUsed: 5678,
timesUsed: 6,
},
local: [],
remote: {
guid: "5113f329c42f",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
timeCreated: 1200,
timeLastModified: 5700,
timeLastUsed: 5700,
timesUsed: 3,
},
reconciled: {
guid: "5113f329c42f",
name: "Mark Hammond",
"street-address": "32 Vassar Street",
timeCreated: 1200,
timeLastModified: 5700,
timeLastUsed: 5678,
timesUsed: 6,
},
},
{
// Local changes, remote created time newer than local, remote modified time
// older than local.
description:
"Created, last modified time reconciliation with local changes",
parent: {
guid: "791e5608b80a",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
timeCreated: 1234,
timeLastModified: 5678,
timeLastUsed: 5678,
timesUsed: 6,
},
local: [
{
name: "Skip",
"street-address": "32 Vassar Street",
},
],
remote: {
guid: "791e5608b80a",
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
timeCreated: 1300,
timeLastModified: 5000,
timeLastUsed: 5000,
timesUsed: 3,
},
reconciled: {
guid: "791e5608b80a",
name: "Skip",
"street-address": "32 Vassar Street",
timeCreated: 1234,
timeLastUsed: 5678,
timesUsed: 6,
},
},
];
const CREDIT_CARD_RECONCILE_TESTCASES = [
{
description: "Local change",
parent: {
// So when we last wrote the record to the server, it had these values.
guid: "2bbd2d8fbc6b",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"unknown-1": "an unknown field from another client",
},
local: [
{
// The current local record - by comparing against parent we can see that
// only the cc-number has changed locally.
"cc-name": "John Doe",
"cc-number": "4929001587121045",
},
],
remote: {
// This is the incoming record. It has the same values as "parent", so
// we can deduce the record hasn't actually been changed remotely so we
// can safely ignore the incoming record and write our local changes.
guid: "2bbd2d8fbc6b",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"unknown-2": "a newer unknown field",
},
reconciled: {
guid: "2bbd2d8fbc6b",
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"unknown-2": "a newer unknown field",
},
},
{
description: "Remote change",
parent: {
guid: "e3680e9f890d",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"unknown-1": "unknown field",
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
],
remote: {
guid: "e3680e9f890d",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"unknown-1": "unknown field",
},
reconciled: {
guid: "e3680e9f890d",
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"unknown-1": "unknown field",
},
},
{
description: "New local field",
parent: {
guid: "0cba738b1be0",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
],
remote: {
guid: "0cba738b1be0",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
reconciled: {
guid: "0cba738b1be0",
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
},
{
description: "New remote field",
parent: {
guid: "be3ef97f8285",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
],
remote: {
guid: "be3ef97f8285",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
reconciled: {
guid: "be3ef97f8285",
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
},
{
description: "Deleted field locally",
parent: {
guid: "9627322248ec",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
],
remote: {
guid: "9627322248ec",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
reconciled: {
guid: "9627322248ec",
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
},
{
description: "Deleted field remotely",
parent: {
guid: "7d7509f3eeb2",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
],
remote: {
guid: "7d7509f3eeb2",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
reconciled: {
guid: "7d7509f3eeb2",
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
},
{
description: "Local and remote changes to unrelated fields",
parent: {
// The last time we wrote this to the server, "cc-exp-month" was 12.
guid: "e087a06dfc57",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
"unknown-1": "unknown field",
},
local: [
{
// The current local record - so locally we've changed "cc-number".
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"cc-exp-month": 12,
},
],
remote: {
// Remotely, we've changed "cc-exp-month" to 1.
guid: "e087a06dfc57",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 1,
"unknown-2": "a newer unknown field",
},
reconciled: {
guid: "e087a06dfc57",
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"cc-exp-month": 1,
"unknown-2": "a newer unknown field",
},
},
{
description: "Multiple local changes",
parent: {
guid: "340a078c596f",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"unknown-1": "unknown field",
},
local: [
{
"cc-name": "Skip",
"cc-number": "4111111111111111",
},
{
"cc-name": "Skip",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
],
remote: {
guid: "340a078c596f",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-year": 2000,
"unknown-1": "unknown field",
},
reconciled: {
guid: "340a078c596f",
"cc-name": "Skip",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
"cc-exp-year": 2000,
"unknown-1": "unknown field",
},
},
{
// Local and remote diverged from the shared parent, but the values are the
// same, so we shouldn't fork.
description: "Same change to local and remote",
parent: {
guid: "0b3a72a1bea2",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4929001587121045",
},
],
remote: {
guid: "0b3a72a1bea2",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4929001587121045",
},
reconciled: {
guid: "0b3a72a1bea2",
"cc-name": "John Doe",
"cc-number": "4929001587121045",
},
},
{
description: "Conflicting changes to single field",
parent: {
// This is what we last wrote to the sync server.
guid: "62068784d089",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"unknown-1": "unknown field",
},
local: [
{
// The current version of the local record - the cc-number has changed locally.
"cc-name": "John Doe",
"cc-number": "5103059495477870",
},
],
remote: {
// An incoming record has a different cc-number than any of the above!
guid: "62068784d089",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"unknown-1": "unknown field",
},
forked: {
// So we've forked the local record to a new GUID (and the next sync is
// going to write this as a new record)
"cc-name": "John Doe",
"cc-number": "5103059495477870",
"unknown-1": "unknown field",
},
reconciled: {
// And we've updated the local version of the record to be the remote version.
guid: "62068784d089",
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"unknown-1": "unknown field",
},
},
{
description: "Conflicting changes to multiple fields",
parent: {
guid: "244dbb692e94",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
local: [
{
"cc-name": "John Doe",
"cc-number": "5103059495477870",
"cc-exp-month": 1,
},
],
remote: {
guid: "244dbb692e94",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"cc-exp-month": 3,
},
forked: {
"cc-name": "John Doe",
"cc-number": "5103059495477870",
"cc-exp-month": 1,
},
reconciled: {
guid: "244dbb692e94",
"cc-name": "John Doe",
"cc-number": "4929001587121045",
"cc-exp-month": 3,
},
},
{
description: "Field deleted locally, changed remotely",
parent: {
guid: "6fc45e03d19a",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
],
remote: {
guid: "6fc45e03d19a",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 3,
},
forked: {
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
reconciled: {
guid: "6fc45e03d19a",
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 3,
},
},
{
description: "Field changed locally, deleted remotely",
parent: {
guid: "fff9fa27fa18",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 12,
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 3,
},
],
remote: {
guid: "fff9fa27fa18",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
forked: {
"cc-name": "John Doe",
"cc-number": "4111111111111111",
"cc-exp-month": 3,
},
reconciled: {
guid: "fff9fa27fa18",
"cc-name": "John Doe",
"cc-number": "4111111111111111",
},
},
{
// Created, last modified should be synced; last used and times used should
// be local. Remote created time older than local, remote modified time
// newer than local.
description:
"Created, last modified time reconciliation without local changes",
parent: {
guid: "5113f329c42f",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1234,
timeLastModified: 5678,
timeLastUsed: 5678,
timesUsed: 6,
},
local: [],
remote: {
guid: "5113f329c42f",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1200,
timeLastModified: 5700,
timeLastUsed: 5700,
timesUsed: 3,
},
reconciled: {
guid: "5113f329c42f",
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1200,
timeLastModified: 5700,
timeLastUsed: 5678,
timesUsed: 6,
},
},
{
// Local changes, remote created time newer than local, remote modified time
// older than local.
description:
"Created, last modified time reconciliation with local changes",
parent: {
guid: "791e5608b80a",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1234,
timeLastModified: 5678,
timeLastUsed: 5678,
timesUsed: 6,
},
local: [
{
"cc-name": "John Doe",
"cc-number": "4929001587121045",
},
],
remote: {
guid: "791e5608b80a",
version: CREDIT_CARD_SCHEMA_VERSION,
"cc-name": "John Doe",
"cc-number": "4111111111111111",
timeCreated: 1300,
timeLastModified: 5000,
timeLastUsed: 5000,
timesUsed: 3,
},
reconciled: {
guid: "791e5608b80a",
"cc-name": "John Doe",
"cc-number": "4929001587121045",
timeCreated: 1234,
timeLastUsed: 5678,
timesUsed: 6,
},
},
];
add_task(async function test_reconcile_unknown_version() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME);
// Cross-version reconciliation isn't supported yet. See bug 1377204.
await Assert.rejects(
profileStorage.addresses.reconcile({
guid: "31d83d2725ec",
version: 3,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
}),
/Got unknown record version/
);
});
add_task(async function test_reconcile_idempotent() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME);
let guid = "de1ba7b094fe";
await profileStorage.addresses.add(
{
guid,
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
// an unknown field from a previous sync
foo: "bar",
},
{ sourceSync: true }
);
await profileStorage.addresses.update(guid, {
name: "Skip",
"street-address": "32 Vassar Street",
organization: "Mozilla",
});
let remote = {
guid,
version: 1,
name: "Mark Hammond",
"street-address": "32 Vassar Street",
tel: "123456",
"unknown-1": "an unknown field from another client",
};
{
let { forkedGUID } = await profileStorage.addresses.reconcile(remote);
let updatedRecord = await profileStorage.addresses.get(guid, {
rawData: true,
});
ok(!forkedGUID, "First merge should not fork record");
ok(
objectMatches(updatedRecord, {
guid: "de1ba7b094fe",
name: "Skip",
"street-address": "32 Vassar Street",
organization: "Mozilla",
tel: "123456",
"unknown-1": "an unknown field from another client",
}),
"First merge should merge local and remote changes"
);
}
{
let { forkedGUID } = await profileStorage.addresses.reconcile(remote);
let updatedRecord = await profileStorage.addresses.get(guid, {
rawData: true,
});
ok(!forkedGUID, "Second merge should not fork record");
ok(
objectMatches(updatedRecord, {
guid: "de1ba7b094fe",
name: "Skip",
"street-address": "32 Vassar Street",
organization: "Mozilla",
tel: "123456",
"unknown-1": "an unknown field from another client",
}),
"Second merge should not change record"
);
}
});
add_task(async function test_reconcile_three_way_merge() {
let TESTCASES = {
addresses: ADDRESS_RECONCILE_TESTCASES,
creditCards: CREDIT_CARD_RECONCILE_TESTCASES,
};
for (let collectionName in TESTCASES) {
info(`Start to test reconcile on ${collectionName}`);
let profileStorage = await initProfileStorage(
TEST_STORE_FILE_NAME,
null,
collectionName
);
for (let test of TESTCASES[collectionName]) {
info(test.description);
await profileStorage[collectionName].add(test.parent, {
sourceSync: true,
});
for (let updatedRecord of test.local) {
await profileStorage[collectionName].update(
test.parent.guid,
updatedRecord
);
}
let localRecord = await profileStorage[collectionName].get(
test.parent.guid,
{
rawData: true,
}
);
let onReconciled = TestUtils.topicObserved(
"formautofill-storage-changed",
(subject, data) =>
data == "reconcile" &&
subject.wrappedJSObject.collectionName == collectionName
);
let { forkedGUID } = await profileStorage[collectionName].reconcile(
test.remote
);
await onReconciled;
let reconciledRecord = await profileStorage[collectionName].get(
test.parent.guid,
{
rawData: true,
}
);
if (forkedGUID) {
let forkedRecord = await profileStorage[collectionName].get(
forkedGUID,
{
rawData: true,
}
);
notEqual(forkedRecord.guid, reconciledRecord.guid);
equal(forkedRecord.timeLastModified, localRecord.timeLastModified);
ok(
objectMatches(forkedRecord, test.forked),
`${test.description} should fork record`
);
} else {
ok(!test.forked, `${test.description} should not fork record`);
}
ok(objectMatches(reconciledRecord, test.reconciled));
}
}
});