summaryrefslogtreecommitdiffstats
path: root/services/sync/tests/unit/test_tab_engine.js
diff options
context:
space:
mode:
Diffstat (limited to 'services/sync/tests/unit/test_tab_engine.js')
-rw-r--r--services/sync/tests/unit/test_tab_engine.js141
1 files changed, 141 insertions, 0 deletions
diff --git a/services/sync/tests/unit/test_tab_engine.js b/services/sync/tests/unit/test_tab_engine.js
new file mode 100644
index 000000000..049250230
--- /dev/null
+++ b/services/sync/tests/unit/test_tab_engine.js
@@ -0,0 +1,141 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+Cu.import("resource://services-sync/constants.js");
+Cu.import("resource://services-sync/engines/tabs.js");
+Cu.import("resource://services-sync/record.js");
+Cu.import("resource://services-sync/service.js");
+Cu.import("resource://services-sync/util.js");
+Cu.import("resource://testing-common/services/sync/utils.js");
+
+function getMocks() {
+ let engine = new TabEngine(Service);
+ let store = engine._store;
+ store.getTabState = mockGetTabState;
+ store.shouldSkipWindow = mockShouldSkipWindow;
+ return [engine, store];
+}
+
+function run_test() {
+ run_next_test();
+}
+
+add_test(function test_getOpenURLs() {
+ _("Test getOpenURLs.");
+ let [engine, store] = getMocks();
+
+ let superLongURL = "http://" + (new Array(MAX_UPLOAD_BYTES).join("w")) + ".com/";
+ let urls = ["http://bar.com", "http://foo.com", "http://foobar.com", superLongURL];
+ function fourURLs() {
+ return urls.pop();
+ }
+ store.getWindowEnumerator = mockGetWindowEnumerator.bind(this, fourURLs, 1, 4);
+
+ let matches;
+
+ _(" test matching works (true)");
+ let openurlsset = engine.getOpenURLs();
+ matches = openurlsset.has("http://foo.com");
+ ok(matches);
+
+ _(" test matching works (false)");
+ matches = openurlsset.has("http://barfoo.com");
+ ok(!matches);
+
+ _(" test matching works (too long)");
+ matches = openurlsset.has(superLongURL);
+ ok(!matches);
+
+ run_next_test();
+});
+
+add_test(function test_tab_engine_skips_incoming_local_record() {
+ _("Ensure incoming records that match local client ID are never applied.");
+ let [engine, store] = getMocks();
+ let localID = engine.service.clientsEngine.localID;
+ let apply = store.applyIncoming;
+ let applied = [];
+
+ store.applyIncoming = function (record) {
+ notEqual(record.id, localID, "Only apply tab records from remote clients");
+ applied.push(record);
+ apply.call(store, record);
+ }
+
+ let collection = new ServerCollection();
+
+ _("Creating remote tab record with local client ID");
+ let localRecord = encryptPayload({id: localID, clientName: "local"});
+ collection.insert(localID, localRecord);
+
+ _("Creating remote tab record with a different client ID");
+ let remoteID = "different";
+ let remoteRecord = encryptPayload({id: remoteID, clientName: "not local"});
+ collection.insert(remoteID, remoteRecord);
+
+ _("Setting up Sync server");
+ let server = sync_httpd_setup({
+ "/1.1/foo/storage/tabs": collection.handler()
+ });
+
+ let syncTesting = new SyncTestingInfrastructure(server);
+ Service.identity.username = "foo";
+
+ let meta_global = Service.recordManager.set(engine.metaURL,
+ new WBORecord(engine.metaURL));
+ meta_global.payload.engines = {tabs: {version: engine.version,
+ syncID: engine.syncID}};
+
+ generateNewKeys(Service.collectionKeys);
+
+ let syncFinish = engine._syncFinish;
+ engine._syncFinish = function () {
+ equal(applied.length, 1, "Remote client record was applied");
+ equal(applied[0].id, remoteID, "Remote client ID matches");
+
+ syncFinish.call(engine);
+ run_next_test();
+ }
+
+ _("Start sync");
+ engine._sync();
+});
+
+add_test(function test_reconcile() {
+ let [engine, store] = getMocks();
+
+ _("Setup engine for reconciling");
+ engine._syncStartup();
+
+ _("Create an incoming remote record");
+ let remoteRecord = {id: "remote id",
+ cleartext: "stuff and things!",
+ modified: 1000};
+
+ ok(engine._reconcile(remoteRecord), "Apply a recently modified remote record");
+
+ remoteRecord.modified = 0;
+ ok(engine._reconcile(remoteRecord), "Apply a remote record modified long ago");
+
+ // Remote tab records are never tracked locally, so the only
+ // time they're skipped is when they're marked as deleted.
+ remoteRecord.deleted = true;
+ ok(!engine._reconcile(remoteRecord), "Skip a deleted remote record");
+
+ _("Create an incoming local record");
+ // The locally tracked tab record always takes precedence over its
+ // remote counterparts.
+ let localRecord = {id: engine.service.clientsEngine.localID,
+ cleartext: "this should always be skipped",
+ modified: 2000};
+
+ ok(!engine._reconcile(localRecord), "Skip incoming local if recently modified");
+
+ localRecord.modified = 0;
+ ok(!engine._reconcile(localRecord), "Skip incoming local if modified long ago");
+
+ localRecord.deleted = true;
+ ok(!engine._reconcile(localRecord), "Skip incoming local if deleted");
+
+ run_next_test();
+});