Files
UXP-Fixed/services/sync/tests/unit/test_bookmark_validator.js
T
2018-02-02 04:16:08 -05:00

348 lines
10 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Components.utils.import("resource://services-sync/bookmark_validator.js");
Components.utils.import("resource://services-sync/util.js");
function inspectServerRecords(data) {
return new BookmarkValidator().inspectServerRecords(data);
}
add_test(function test_isr_rootOnServer() {
let c = inspectServerRecords([{
id: 'places',
type: 'folder',
children: [],
}]);
ok(c.problemData.rootOnServer);
run_next_test();
});
add_test(function test_isr_empty() {
let c = inspectServerRecords([]);
ok(!c.problemData.rootOnServer);
notEqual(c.root, null);
run_next_test();
});
add_test(function test_isr_cycles() {
let c = inspectServerRecords([
{id: 'C', type: 'folder', children: ['A', 'B'], parentid: 'places'},
{id: 'A', type: 'folder', children: ['B'], parentid: 'B'},
{id: 'B', type: 'folder', children: ['A'], parentid: 'A'},
]).problemData;
equal(c.cycles.length, 1);
ok(c.cycles[0].indexOf('A') >= 0);
ok(c.cycles[0].indexOf('B') >= 0);
run_next_test();
});
add_test(function test_isr_orphansMultiParents() {
let c = inspectServerRecords([
{ id: 'A', type: 'bookmark', parentid: 'D' },
{ id: 'B', type: 'folder', parentid: 'places', children: ['A']},
{ id: 'C', type: 'folder', parentid: 'places', children: ['A']},
]).problemData;
deepEqual(c.orphans, [{ id: "A", parent: "D" }]);
equal(c.multipleParents.length, 1)
ok(c.multipleParents[0].parents.indexOf('B') >= 0);
ok(c.multipleParents[0].parents.indexOf('C') >= 0);
run_next_test();
});
add_test(function test_isr_orphansMultiParents2() {
let c = inspectServerRecords([
{ id: 'A', type: 'bookmark', parentid: 'D' },
{ id: 'B', type: 'folder', parentid: 'places', children: ['A']},
]).problemData;
equal(c.orphans.length, 1);
equal(c.orphans[0].id, 'A');
equal(c.multipleParents.length, 0);
run_next_test();
});
add_test(function test_isr_deletedParents() {
let c = inspectServerRecords([
{ id: 'A', type: 'bookmark', parentid: 'B' },
{ id: 'B', type: 'folder', parentid: 'places', children: ['A']},
{ id: 'B', type: 'item', deleted: true},
]).problemData;
deepEqual(c.deletedParents, ['A'])
run_next_test();
});
add_test(function test_isr_badChildren() {
let c = inspectServerRecords([
{ id: 'A', type: 'bookmark', parentid: 'places', children: ['B', 'C'] },
{ id: 'C', type: 'bookmark', parentid: 'A' }
]).problemData;
deepEqual(c.childrenOnNonFolder, ['A'])
deepEqual(c.missingChildren, [{parent: 'A', child: 'B'}]);
deepEqual(c.parentNotFolder, ['C']);
run_next_test();
});
add_test(function test_isr_parentChildMismatches() {
let c = inspectServerRecords([
{ id: 'A', type: 'folder', parentid: 'places', children: [] },
{ id: 'B', type: 'bookmark', parentid: 'A' }
]).problemData;
deepEqual(c.parentChildMismatches, [{parent: 'A', child: 'B'}]);
run_next_test();
});
add_test(function test_isr_duplicatesAndMissingIDs() {
let c = inspectServerRecords([
{id: 'A', type: 'folder', parentid: 'places', children: []},
{id: 'A', type: 'folder', parentid: 'places', children: []},
{type: 'folder', parentid: 'places', children: []}
]).problemData;
equal(c.missingIDs, 1);
deepEqual(c.duplicates, ['A']);
run_next_test();
});
add_test(function test_isr_duplicateChildren() {
let c = inspectServerRecords([
{id: 'A', type: 'folder', parentid: 'places', children: ['B', 'B']},
{id: 'B', type: 'bookmark', parentid: 'A'},
]).problemData;
deepEqual(c.duplicateChildren, ['A']);
run_next_test();
});
// Each compareServerWithClient test mutates these, so we can't just keep them
// global
function getDummyServerAndClient() {
let server = [
{
id: 'menu',
parentid: 'places',
type: 'folder',
parentName: '',
title: 'foo',
children: ['bbbbbbbbbbbb', 'cccccccccccc']
},
{
id: 'bbbbbbbbbbbb',
type: 'bookmark',
parentid: 'menu',
parentName: 'foo',
title: 'bar',
bmkUri: 'http://baz.com'
},
{
id: 'cccccccccccc',
parentid: 'menu',
parentName: 'foo',
title: '',
type: 'query',
bmkUri: 'place:type=6&sort=14&maxResults=10'
}
];
let client = {
"guid": "root________",
"title": "",
"id": 1,
"type": "text/x-moz-place-container",
"children": [
{
"guid": "menu________",
"title": "foo",
"id": 1000,
"type": "text/x-moz-place-container",
"children": [
{
"guid": "bbbbbbbbbbbb",
"title": "bar",
"id": 1001,
"type": "text/x-moz-place",
"uri": "http://baz.com"
},
{
"guid": "cccccccccccc",
"title": "",
"id": 1002,
"annos": [{
"name": "Places/SmartBookmark",
"flags": 0,
"expires": 4,
"value": "RecentTags"
}],
"type": "text/x-moz-place",
"uri": "place:type=6&sort=14&maxResults=10"
}
]
}
]
};
return {server, client};
}
add_test(function test_cswc_valid() {
let {server, client} = getDummyServerAndClient();
let c = new BookmarkValidator().compareServerWithClient(server, client).problemData;
equal(c.clientMissing.length, 0);
equal(c.serverMissing.length, 0);
equal(c.differences.length, 0);
run_next_test();
});
add_test(function test_cswc_serverMissing() {
let {server, client} = getDummyServerAndClient();
// remove c
server.pop();
server[0].children.pop();
let c = new BookmarkValidator().compareServerWithClient(server, client).problemData;
deepEqual(c.serverMissing, ['cccccccccccc']);
equal(c.clientMissing.length, 0);
deepEqual(c.structuralDifferences, [{id: 'menu', differences: ['childGUIDs']}]);
run_next_test();
});
add_test(function test_cswc_clientMissing() {
let {server, client} = getDummyServerAndClient();
client.children[0].children.pop();
let c = new BookmarkValidator().compareServerWithClient(server, client).problemData;
deepEqual(c.clientMissing, ['cccccccccccc']);
equal(c.serverMissing.length, 0);
deepEqual(c.structuralDifferences, [{id: 'menu', differences: ['childGUIDs']}]);
run_next_test();
});
add_test(function test_cswc_differences() {
{
let {server, client} = getDummyServerAndClient();
client.children[0].children[0].title = 'asdf';
let c = new BookmarkValidator().compareServerWithClient(server, client).problemData;
equal(c.clientMissing.length, 0);
equal(c.serverMissing.length, 0);
deepEqual(c.differences, [{id: 'bbbbbbbbbbbb', differences: ['title']}]);
}
{
let {server, client} = getDummyServerAndClient();
server[2].type = 'bookmark';
let c = new BookmarkValidator().compareServerWithClient(server, client).problemData;
equal(c.clientMissing.length, 0);
equal(c.serverMissing.length, 0);
deepEqual(c.differences, [{id: 'cccccccccccc', differences: ['type']}]);
}
run_next_test();
});
add_test(function test_cswc_serverUnexpected() {
let {server, client} = getDummyServerAndClient();
client.children.push({
"guid": "dddddddddddd",
"title": "",
"id": 2000,
"annos": [{
"name": "places/excludeFromBackup",
"flags": 0,
"expires": 4,
"value": 1
}, {
"name": "PlacesOrganizer/OrganizerFolder",
"flags": 0,
"expires": 4,
"value": 7
}],
"type": "text/x-moz-place-container",
"children": [{
"guid": "eeeeeeeeeeee",
"title": "History",
"annos": [{
"name": "places/excludeFromBackup",
"flags": 0,
"expires": 4,
"value": 1
}, {
"name": "PlacesOrganizer/OrganizerQuery",
"flags": 0,
"expires": 4,
"value": "History"
}],
"type": "text/x-moz-place",
"uri": "place:type=3&sort=4"
}]
});
server.push({
id: 'dddddddddddd',
parentid: 'places',
parentName: '',
title: '',
type: 'folder',
children: ['eeeeeeeeeeee']
}, {
id: 'eeeeeeeeeeee',
parentid: 'dddddddddddd',
parentName: '',
title: 'History',
type: 'query',
bmkUri: 'place:type=3&sort=4'
});
let c = new BookmarkValidator().compareServerWithClient(server, client).problemData;
equal(c.clientMissing.length, 0);
equal(c.serverMissing.length, 0);
equal(c.serverUnexpected.length, 2);
deepEqual(c.serverUnexpected, ["dddddddddddd", "eeeeeeeeeeee"]);
run_next_test();
});
function validationPing(server, client, duration) {
return wait_for_ping(function() {
// fake this entirely
Svc.Obs.notify("weave:service:sync:start");
Svc.Obs.notify("weave:engine:sync:start", null, "bookmarks");
Svc.Obs.notify("weave:engine:sync:finish", null, "bookmarks");
let validator = new BookmarkValidator();
let data = {
// We fake duration and version just so that we can verify they're passed through.
duration,
version: validator.version,
recordCount: server.length,
problems: validator.compareServerWithClient(server, client).problemData,
};
Svc.Obs.notify("weave:engine:validate:finish", data, "bookmarks");
Svc.Obs.notify("weave:service:sync:finish");
}, true); // Allow "failing" pings, since having validation info indicates failure.
}
add_task(function *test_telemetry_integration() {
let {server, client} = getDummyServerAndClient();
// remove "c"
server.pop();
server[0].children.pop();
const duration = 50;
let ping = yield validationPing(server, client, duration);
ok(ping.engines);
let bme = ping.engines.find(e => e.name === "bookmarks");
ok(bme);
ok(bme.validation);
ok(bme.validation.problems)
equal(bme.validation.checked, server.length);
equal(bme.validation.took, duration);
bme.validation.problems.sort((a, b) => String.localeCompare(a.name, b.name));
equal(bme.validation.version, new BookmarkValidator().version);
deepEqual(bme.validation.problems, [
{ name: "badClientRoots", count: 3 },
{ name: "sdiff:childGUIDs", count: 1 },
{ name: "serverMissing", count: 1 },
{ name: "structuralDifferences", count: 1 },
]);
});
function run_test() {
run_next_test();
}