services/sync/tests/unit/test_clients_engine.js

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 Cu.import("resource://services-sync/constants.js");
michael@0 5 Cu.import("resource://services-sync/engines.js");
michael@0 6 Cu.import("resource://services-sync/engines/clients.js");
michael@0 7 Cu.import("resource://services-sync/record.js");
michael@0 8 Cu.import("resource://services-sync/service.js");
michael@0 9 Cu.import("resource://services-sync/util.js");
michael@0 10 Cu.import("resource://testing-common/services/sync/utils.js");
michael@0 11
michael@0 12 const MORE_THAN_CLIENTS_TTL_REFRESH = 691200; // 8 days
michael@0 13 const LESS_THAN_CLIENTS_TTL_REFRESH = 86400; // 1 day
michael@0 14
michael@0 15 let engine = Service.clientsEngine;
michael@0 16
michael@0 17 /**
michael@0 18 * Unpack the record with this ID, and verify that it has the same version that
michael@0 19 * we should be putting into records.
michael@0 20 */
michael@0 21 function check_record_version(user, id) {
michael@0 22 let payload = JSON.parse(user.collection("clients").wbo(id).payload);
michael@0 23
michael@0 24 let rec = new CryptoWrapper();
michael@0 25 rec.id = id;
michael@0 26 rec.collection = "clients";
michael@0 27 rec.ciphertext = payload.ciphertext;
michael@0 28 rec.hmac = payload.hmac;
michael@0 29 rec.IV = payload.IV;
michael@0 30
michael@0 31 let cleartext = rec.decrypt(Service.collectionKeys.keyForCollection("clients"));
michael@0 32
michael@0 33 _("Payload is " + JSON.stringify(cleartext));
michael@0 34 do_check_eq(Services.appinfo.version, cleartext.version);
michael@0 35 do_check_eq(2, cleartext.protocols.length);
michael@0 36 do_check_eq("1.1", cleartext.protocols[0]);
michael@0 37 do_check_eq("1.5", cleartext.protocols[1]);
michael@0 38 }
michael@0 39
michael@0 40 add_test(function test_bad_hmac() {
michael@0 41 _("Ensure that Clients engine deletes corrupt records.");
michael@0 42 let contents = {
michael@0 43 meta: {global: {engines: {clients: {version: engine.version,
michael@0 44 syncID: engine.syncID}}}},
michael@0 45 clients: {},
michael@0 46 crypto: {}
michael@0 47 };
michael@0 48 let deletedCollections = [];
michael@0 49 let deletedItems = [];
michael@0 50 let callback = {
michael@0 51 __proto__: SyncServerCallback,
michael@0 52 onItemDeleted: function (username, coll, wboID) {
michael@0 53 deletedItems.push(coll + "/" + wboID);
michael@0 54 },
michael@0 55 onCollectionDeleted: function (username, coll) {
michael@0 56 deletedCollections.push(coll);
michael@0 57 }
michael@0 58 }
michael@0 59 let server = serverForUsers({"foo": "password"}, contents, callback);
michael@0 60 let user = server.user("foo");
michael@0 61
michael@0 62 function check_clients_count(expectedCount) {
michael@0 63 let stack = Components.stack.caller;
michael@0 64 let coll = user.collection("clients");
michael@0 65
michael@0 66 // Treat a non-existent collection as empty.
michael@0 67 do_check_eq(expectedCount, coll ? coll.count() : 0, stack);
michael@0 68 }
michael@0 69
michael@0 70 function check_client_deleted(id) {
michael@0 71 let coll = user.collection("clients");
michael@0 72 let wbo = coll.wbo(id);
michael@0 73 return !wbo || !wbo.payload;
michael@0 74 }
michael@0 75
michael@0 76 function uploadNewKeys() {
michael@0 77 generateNewKeys(Service.collectionKeys);
michael@0 78 let serverKeys = Service.collectionKeys.asWBO("crypto", "keys");
michael@0 79 serverKeys.encrypt(Service.identity.syncKeyBundle);
michael@0 80 do_check_true(serverKeys.upload(Service.resource(Service.cryptoKeysURL)).success);
michael@0 81 }
michael@0 82
michael@0 83 try {
michael@0 84 ensureLegacyIdentityManager();
michael@0 85 let passphrase = "abcdeabcdeabcdeabcdeabcdea";
michael@0 86 Service.serverURL = server.baseURI;
michael@0 87 Service.login("foo", "ilovejane", passphrase);
michael@0 88
michael@0 89 generateNewKeys(Service.collectionKeys);
michael@0 90
michael@0 91 _("First sync, client record is uploaded");
michael@0 92 do_check_eq(engine.lastRecordUpload, 0);
michael@0 93 check_clients_count(0);
michael@0 94 engine._sync();
michael@0 95 check_clients_count(1);
michael@0 96 do_check_true(engine.lastRecordUpload > 0);
michael@0 97
michael@0 98 // Our uploaded record has a version.
michael@0 99 check_record_version(user, engine.localID);
michael@0 100
michael@0 101 // Initial setup can wipe the server, so clean up.
michael@0 102 deletedCollections = [];
michael@0 103 deletedItems = [];
michael@0 104
michael@0 105 _("Change our keys and our client ID, reupload keys.");
michael@0 106 let oldLocalID = engine.localID; // Preserve to test for deletion!
michael@0 107 engine.localID = Utils.makeGUID();
michael@0 108 engine.resetClient();
michael@0 109 generateNewKeys(Service.collectionKeys);
michael@0 110 let serverKeys = Service.collectionKeys.asWBO("crypto", "keys");
michael@0 111 serverKeys.encrypt(Service.identity.syncKeyBundle);
michael@0 112 do_check_true(serverKeys.upload(Service.resource(Service.cryptoKeysURL)).success);
michael@0 113
michael@0 114 _("Sync.");
michael@0 115 engine._sync();
michael@0 116
michael@0 117 _("Old record " + oldLocalID + " was deleted, new one uploaded.");
michael@0 118 check_clients_count(1);
michael@0 119 check_client_deleted(oldLocalID);
michael@0 120
michael@0 121 _("Now change our keys but don't upload them. " +
michael@0 122 "That means we get an HMAC error but redownload keys.");
michael@0 123 Service.lastHMACEvent = 0;
michael@0 124 engine.localID = Utils.makeGUID();
michael@0 125 engine.resetClient();
michael@0 126 generateNewKeys(Service.collectionKeys);
michael@0 127 deletedCollections = [];
michael@0 128 deletedItems = [];
michael@0 129 check_clients_count(1);
michael@0 130 engine._sync();
michael@0 131
michael@0 132 _("Old record was not deleted, new one uploaded.");
michael@0 133 do_check_eq(deletedCollections.length, 0);
michael@0 134 do_check_eq(deletedItems.length, 0);
michael@0 135 check_clients_count(2);
michael@0 136
michael@0 137 _("Now try the scenario where our keys are wrong *and* there's a bad record.");
michael@0 138 // Clean up and start fresh.
michael@0 139 user.collection("clients")._wbos = {};
michael@0 140 Service.lastHMACEvent = 0;
michael@0 141 engine.localID = Utils.makeGUID();
michael@0 142 engine.resetClient();
michael@0 143 deletedCollections = [];
michael@0 144 deletedItems = [];
michael@0 145 check_clients_count(0);
michael@0 146
michael@0 147 uploadNewKeys();
michael@0 148
michael@0 149 // Sync once to upload a record.
michael@0 150 engine._sync();
michael@0 151 check_clients_count(1);
michael@0 152
michael@0 153 // Generate and upload new keys, so the old client record is wrong.
michael@0 154 uploadNewKeys();
michael@0 155
michael@0 156 // Create a new client record and new keys. Now our keys are wrong, as well
michael@0 157 // as the object on the server. We'll download the new keys and also delete
michael@0 158 // the bad client record.
michael@0 159 oldLocalID = engine.localID; // Preserve to test for deletion!
michael@0 160 engine.localID = Utils.makeGUID();
michael@0 161 engine.resetClient();
michael@0 162 generateNewKeys(Service.collectionKeys);
michael@0 163 let oldKey = Service.collectionKeys.keyForCollection();
michael@0 164
michael@0 165 do_check_eq(deletedCollections.length, 0);
michael@0 166 do_check_eq(deletedItems.length, 0);
michael@0 167 engine._sync();
michael@0 168 do_check_eq(deletedItems.length, 1);
michael@0 169 check_client_deleted(oldLocalID);
michael@0 170 check_clients_count(1);
michael@0 171 let newKey = Service.collectionKeys.keyForCollection();
michael@0 172 do_check_false(oldKey.equals(newKey));
michael@0 173
michael@0 174 } finally {
michael@0 175 Svc.Prefs.resetBranch("");
michael@0 176 Service.recordManager.clearCache();
michael@0 177 server.stop(run_next_test);
michael@0 178 }
michael@0 179 });
michael@0 180
michael@0 181 add_test(function test_properties() {
michael@0 182 _("Test lastRecordUpload property");
michael@0 183 try {
michael@0 184 do_check_eq(Svc.Prefs.get("clients.lastRecordUpload"), undefined);
michael@0 185 do_check_eq(engine.lastRecordUpload, 0);
michael@0 186
michael@0 187 let now = Date.now();
michael@0 188 engine.lastRecordUpload = now / 1000;
michael@0 189 do_check_eq(engine.lastRecordUpload, Math.floor(now / 1000));
michael@0 190 } finally {
michael@0 191 Svc.Prefs.resetBranch("");
michael@0 192 run_next_test();
michael@0 193 }
michael@0 194 });
michael@0 195
michael@0 196 add_test(function test_sync() {
michael@0 197 _("Ensure that Clients engine uploads a new client record once a week.");
michael@0 198
michael@0 199 let contents = {
michael@0 200 meta: {global: {engines: {clients: {version: engine.version,
michael@0 201 syncID: engine.syncID}}}},
michael@0 202 clients: {},
michael@0 203 crypto: {}
michael@0 204 };
michael@0 205 let server = serverForUsers({"foo": "password"}, contents);
michael@0 206 let user = server.user("foo");
michael@0 207
michael@0 208 new SyncTestingInfrastructure(server.server);
michael@0 209 generateNewKeys(Service.collectionKeys);
michael@0 210
michael@0 211 function clientWBO() {
michael@0 212 return user.collection("clients").wbo(engine.localID);
michael@0 213 }
michael@0 214
michael@0 215 try {
michael@0 216
michael@0 217 _("First sync. Client record is uploaded.");
michael@0 218 do_check_eq(clientWBO(), undefined);
michael@0 219 do_check_eq(engine.lastRecordUpload, 0);
michael@0 220 engine._sync();
michael@0 221 do_check_true(!!clientWBO().payload);
michael@0 222 do_check_true(engine.lastRecordUpload > 0);
michael@0 223
michael@0 224 _("Let's time travel more than a week back, new record should've been uploaded.");
michael@0 225 engine.lastRecordUpload -= MORE_THAN_CLIENTS_TTL_REFRESH;
michael@0 226 let lastweek = engine.lastRecordUpload;
michael@0 227 clientWBO().payload = undefined;
michael@0 228 engine._sync();
michael@0 229 do_check_true(!!clientWBO().payload);
michael@0 230 do_check_true(engine.lastRecordUpload > lastweek);
michael@0 231
michael@0 232 _("Remove client record.");
michael@0 233 engine.removeClientData();
michael@0 234 do_check_eq(clientWBO().payload, undefined);
michael@0 235
michael@0 236 _("Time travel one day back, no record uploaded.");
michael@0 237 engine.lastRecordUpload -= LESS_THAN_CLIENTS_TTL_REFRESH;
michael@0 238 let yesterday = engine.lastRecordUpload;
michael@0 239 engine._sync();
michael@0 240 do_check_eq(clientWBO().payload, undefined);
michael@0 241 do_check_eq(engine.lastRecordUpload, yesterday);
michael@0 242
michael@0 243 } finally {
michael@0 244 Svc.Prefs.resetBranch("");
michael@0 245 Service.recordManager.clearCache();
michael@0 246 server.stop(run_next_test);
michael@0 247 }
michael@0 248 });
michael@0 249
michael@0 250 add_test(function test_client_name_change() {
michael@0 251 _("Ensure client name change incurs a client record update.");
michael@0 252
michael@0 253 let tracker = engine._tracker;
michael@0 254
michael@0 255 let localID = engine.localID;
michael@0 256 let initialName = engine.localName;
michael@0 257
michael@0 258 Svc.Obs.notify("weave:engine:start-tracking");
michael@0 259 _("initial name: " + initialName);
michael@0 260
michael@0 261 // Tracker already has data, so clear it.
michael@0 262 tracker.clearChangedIDs();
michael@0 263
michael@0 264 let initialScore = tracker.score;
michael@0 265
michael@0 266 do_check_eq(Object.keys(tracker.changedIDs).length, 0);
michael@0 267
michael@0 268 Svc.Prefs.set("client.name", "new name");
michael@0 269
michael@0 270 _("new name: " + engine.localName);
michael@0 271 do_check_neq(initialName, engine.localName);
michael@0 272 do_check_eq(Object.keys(tracker.changedIDs).length, 1);
michael@0 273 do_check_true(engine.localID in tracker.changedIDs);
michael@0 274 do_check_true(tracker.score > initialScore);
michael@0 275 do_check_true(tracker.score >= SCORE_INCREMENT_XLARGE);
michael@0 276
michael@0 277 Svc.Obs.notify("weave:engine:stop-tracking");
michael@0 278
michael@0 279 run_next_test();
michael@0 280 });
michael@0 281
michael@0 282 add_test(function test_send_command() {
michael@0 283 _("Verifies _sendCommandToClient puts commands in the outbound queue.");
michael@0 284
michael@0 285 let store = engine._store;
michael@0 286 let tracker = engine._tracker;
michael@0 287 let remoteId = Utils.makeGUID();
michael@0 288 let rec = new ClientsRec("clients", remoteId);
michael@0 289
michael@0 290 store.create(rec);
michael@0 291 let remoteRecord = store.createRecord(remoteId, "clients");
michael@0 292
michael@0 293 let action = "testCommand";
michael@0 294 let args = ["foo", "bar"];
michael@0 295
michael@0 296 engine._sendCommandToClient(action, args, remoteId);
michael@0 297
michael@0 298 let newRecord = store._remoteClients[remoteId];
michael@0 299 do_check_neq(newRecord, undefined);
michael@0 300 do_check_eq(newRecord.commands.length, 1);
michael@0 301
michael@0 302 let command = newRecord.commands[0];
michael@0 303 do_check_eq(command.command, action);
michael@0 304 do_check_eq(command.args.length, 2);
michael@0 305 do_check_eq(command.args, args);
michael@0 306
michael@0 307 do_check_neq(tracker.changedIDs[remoteId], undefined);
michael@0 308
michael@0 309 run_next_test();
michael@0 310 });
michael@0 311
michael@0 312 add_test(function test_command_validation() {
michael@0 313 _("Verifies that command validation works properly.");
michael@0 314
michael@0 315 let store = engine._store;
michael@0 316
michael@0 317 let testCommands = [
michael@0 318 ["resetAll", [], true ],
michael@0 319 ["resetAll", ["foo"], false],
michael@0 320 ["resetEngine", ["tabs"], true ],
michael@0 321 ["resetEngine", [], false],
michael@0 322 ["wipeAll", [], true ],
michael@0 323 ["wipeAll", ["foo"], false],
michael@0 324 ["wipeEngine", ["tabs"], true ],
michael@0 325 ["wipeEngine", [], false],
michael@0 326 ["logout", [], true ],
michael@0 327 ["logout", ["foo"], false],
michael@0 328 ["__UNKNOWN__", [], false]
michael@0 329 ];
michael@0 330
michael@0 331 for each (let [action, args, expectedResult] in testCommands) {
michael@0 332 let remoteId = Utils.makeGUID();
michael@0 333 let rec = new ClientsRec("clients", remoteId);
michael@0 334
michael@0 335 store.create(rec);
michael@0 336 store.createRecord(remoteId, "clients");
michael@0 337
michael@0 338 engine.sendCommand(action, args, remoteId);
michael@0 339
michael@0 340 let newRecord = store._remoteClients[remoteId];
michael@0 341 do_check_neq(newRecord, undefined);
michael@0 342
michael@0 343 if (expectedResult) {
michael@0 344 _("Ensuring command is sent: " + action);
michael@0 345 do_check_eq(newRecord.commands.length, 1);
michael@0 346
michael@0 347 let command = newRecord.commands[0];
michael@0 348 do_check_eq(command.command, action);
michael@0 349 do_check_eq(command.args, args);
michael@0 350
michael@0 351 do_check_neq(engine._tracker, undefined);
michael@0 352 do_check_neq(engine._tracker.changedIDs[remoteId], undefined);
michael@0 353 } else {
michael@0 354 _("Ensuring command is scrubbed: " + action);
michael@0 355 do_check_eq(newRecord.commands, undefined);
michael@0 356
michael@0 357 if (store._tracker) {
michael@0 358 do_check_eq(engine._tracker[remoteId], undefined);
michael@0 359 }
michael@0 360 }
michael@0 361
michael@0 362 }
michael@0 363 run_next_test();
michael@0 364 });
michael@0 365
michael@0 366 add_test(function test_command_duplication() {
michael@0 367 _("Ensures duplicate commands are detected and not added");
michael@0 368
michael@0 369 let store = engine._store;
michael@0 370 let remoteId = Utils.makeGUID();
michael@0 371 let rec = new ClientsRec("clients", remoteId);
michael@0 372 store.create(rec);
michael@0 373 store.createRecord(remoteId, "clients");
michael@0 374
michael@0 375 let action = "resetAll";
michael@0 376 let args = [];
michael@0 377
michael@0 378 engine.sendCommand(action, args, remoteId);
michael@0 379 engine.sendCommand(action, args, remoteId);
michael@0 380
michael@0 381 let newRecord = store._remoteClients[remoteId];
michael@0 382 do_check_eq(newRecord.commands.length, 1);
michael@0 383
michael@0 384 _("Check variant args length");
michael@0 385 newRecord.commands = [];
michael@0 386
michael@0 387 action = "resetEngine";
michael@0 388 engine.sendCommand(action, [{ x: "foo" }], remoteId);
michael@0 389 engine.sendCommand(action, [{ x: "bar" }], remoteId);
michael@0 390
michael@0 391 _("Make sure we spot a real dupe argument.");
michael@0 392 engine.sendCommand(action, [{ x: "bar" }], remoteId);
michael@0 393
michael@0 394 do_check_eq(newRecord.commands.length, 2);
michael@0 395
michael@0 396 run_next_test();
michael@0 397 });
michael@0 398
michael@0 399 add_test(function test_command_invalid_client() {
michael@0 400 _("Ensures invalid client IDs are caught");
michael@0 401
michael@0 402 let id = Utils.makeGUID();
michael@0 403 let error;
michael@0 404
michael@0 405 try {
michael@0 406 engine.sendCommand("wipeAll", [], id);
michael@0 407 } catch (ex) {
michael@0 408 error = ex;
michael@0 409 }
michael@0 410
michael@0 411 do_check_eq(error.message.indexOf("Unknown remote client ID: "), 0);
michael@0 412
michael@0 413 run_next_test();
michael@0 414 });
michael@0 415
michael@0 416 add_test(function test_process_incoming_commands() {
michael@0 417 _("Ensures local commands are executed");
michael@0 418
michael@0 419 engine.localCommands = [{ command: "logout", args: [] }];
michael@0 420
michael@0 421 let ev = "weave:service:logout:finish";
michael@0 422
michael@0 423 var handler = function() {
michael@0 424 Svc.Obs.remove(ev, handler);
michael@0 425 run_next_test();
michael@0 426 };
michael@0 427
michael@0 428 Svc.Obs.add(ev, handler);
michael@0 429
michael@0 430 // logout command causes processIncomingCommands to return explicit false.
michael@0 431 do_check_false(engine.processIncomingCommands());
michael@0 432 });
michael@0 433
michael@0 434 add_test(function test_command_sync() {
michael@0 435 _("Ensure that commands are synced across clients.");
michael@0 436
michael@0 437 engine._store.wipe();
michael@0 438 generateNewKeys(Service.collectionKeys);
michael@0 439
michael@0 440 let contents = {
michael@0 441 meta: {global: {engines: {clients: {version: engine.version,
michael@0 442 syncID: engine.syncID}}}},
michael@0 443 clients: {},
michael@0 444 crypto: {}
michael@0 445 };
michael@0 446 let server = serverForUsers({"foo": "password"}, contents);
michael@0 447 new SyncTestingInfrastructure(server.server);
michael@0 448
michael@0 449 let user = server.user("foo");
michael@0 450 let remoteId = Utils.makeGUID();
michael@0 451
michael@0 452 function clientWBO(id) {
michael@0 453 return user.collection("clients").wbo(id);
michael@0 454 }
michael@0 455
michael@0 456 _("Create remote client record");
michael@0 457 let rec = new ClientsRec("clients", remoteId);
michael@0 458 engine._store.create(rec);
michael@0 459 let remoteRecord = engine._store.createRecord(remoteId, "clients");
michael@0 460 engine.sendCommand("wipeAll", []);
michael@0 461
michael@0 462 let clientRecord = engine._store._remoteClients[remoteId];
michael@0 463 do_check_neq(clientRecord, undefined);
michael@0 464 do_check_eq(clientRecord.commands.length, 1);
michael@0 465
michael@0 466 try {
michael@0 467 _("Syncing.");
michael@0 468 engine._sync();
michael@0 469 _("Checking record was uploaded.");
michael@0 470 do_check_neq(clientWBO(engine.localID).payload, undefined);
michael@0 471 do_check_true(engine.lastRecordUpload > 0);
michael@0 472
michael@0 473 do_check_neq(clientWBO(remoteId).payload, undefined);
michael@0 474
michael@0 475 Svc.Prefs.set("client.GUID", remoteId);
michael@0 476 engine._resetClient();
michael@0 477 do_check_eq(engine.localID, remoteId);
michael@0 478 _("Performing sync on resetted client.");
michael@0 479 engine._sync();
michael@0 480 do_check_neq(engine.localCommands, undefined);
michael@0 481 do_check_eq(engine.localCommands.length, 1);
michael@0 482
michael@0 483 let command = engine.localCommands[0];
michael@0 484 do_check_eq(command.command, "wipeAll");
michael@0 485 do_check_eq(command.args.length, 0);
michael@0 486
michael@0 487 } finally {
michael@0 488 Svc.Prefs.resetBranch("");
michael@0 489 Service.recordManager.clearCache();
michael@0 490 server.stop(run_next_test);
michael@0 491 }
michael@0 492 });
michael@0 493
michael@0 494 add_test(function test_send_uri_to_client_for_display() {
michael@0 495 _("Ensure sendURIToClientForDisplay() sends command properly.");
michael@0 496
michael@0 497 let tracker = engine._tracker;
michael@0 498 let store = engine._store;
michael@0 499
michael@0 500 let remoteId = Utils.makeGUID();
michael@0 501 let rec = new ClientsRec("clients", remoteId);
michael@0 502 rec.name = "remote";
michael@0 503 store.create(rec);
michael@0 504 let remoteRecord = store.createRecord(remoteId, "clients");
michael@0 505
michael@0 506 tracker.clearChangedIDs();
michael@0 507 let initialScore = tracker.score;
michael@0 508
michael@0 509 let uri = "http://www.mozilla.org/";
michael@0 510 let title = "Title of the Page";
michael@0 511 engine.sendURIToClientForDisplay(uri, remoteId, title);
michael@0 512
michael@0 513 let newRecord = store._remoteClients[remoteId];
michael@0 514
michael@0 515 do_check_neq(newRecord, undefined);
michael@0 516 do_check_eq(newRecord.commands.length, 1);
michael@0 517
michael@0 518 let command = newRecord.commands[0];
michael@0 519 do_check_eq(command.command, "displayURI");
michael@0 520 do_check_eq(command.args.length, 3);
michael@0 521 do_check_eq(command.args[0], uri);
michael@0 522 do_check_eq(command.args[1], engine.localID);
michael@0 523 do_check_eq(command.args[2], title);
michael@0 524
michael@0 525 do_check_true(tracker.score > initialScore);
michael@0 526 do_check_true(tracker.score - initialScore >= SCORE_INCREMENT_XLARGE);
michael@0 527
michael@0 528 _("Ensure unknown client IDs result in exception.");
michael@0 529 let unknownId = Utils.makeGUID();
michael@0 530 let error;
michael@0 531
michael@0 532 try {
michael@0 533 engine.sendURIToClientForDisplay(uri, unknownId);
michael@0 534 } catch (ex) {
michael@0 535 error = ex;
michael@0 536 }
michael@0 537
michael@0 538 do_check_eq(error.message.indexOf("Unknown remote client ID: "), 0);
michael@0 539
michael@0 540 run_next_test();
michael@0 541 });
michael@0 542
michael@0 543 add_test(function test_receive_display_uri() {
michael@0 544 _("Ensure processing of received 'displayURI' commands works.");
michael@0 545
michael@0 546 // We don't set up WBOs and perform syncing because other tests verify
michael@0 547 // the command API works as advertised. This saves us a little work.
michael@0 548
michael@0 549 let uri = "http://www.mozilla.org/";
michael@0 550 let remoteId = Utils.makeGUID();
michael@0 551 let title = "Page Title!";
michael@0 552
michael@0 553 let command = {
michael@0 554 command: "displayURI",
michael@0 555 args: [uri, remoteId, title],
michael@0 556 };
michael@0 557
michael@0 558 engine.localCommands = [command];
michael@0 559
michael@0 560 // Received 'displayURI' command should result in the topic defined below
michael@0 561 // being called.
michael@0 562 let ev = "weave:engine:clients:display-uri";
michael@0 563
michael@0 564 let handler = function(subject, data) {
michael@0 565 Svc.Obs.remove(ev, handler);
michael@0 566
michael@0 567 do_check_eq(subject.uri, uri);
michael@0 568 do_check_eq(subject.client, remoteId);
michael@0 569 do_check_eq(subject.title, title);
michael@0 570 do_check_eq(data, null);
michael@0 571
michael@0 572 run_next_test();
michael@0 573 };
michael@0 574
michael@0 575 Svc.Obs.add(ev, handler);
michael@0 576
michael@0 577 do_check_true(engine.processIncomingCommands());
michael@0 578 });
michael@0 579
michael@0 580 function run_test() {
michael@0 581 initTestLogging("Trace");
michael@0 582 Log.repository.getLogger("Sync.Engine.Clients").level = Log.Level.Trace;
michael@0 583 run_next_test();
michael@0 584 }

mercurial