Wed, 31 Dec 2014 07:22:50 +0100
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://gre/modules/Log.jsm"); |
michael@0 | 5 | Cu.import("resource://services-sync/stages/enginesync.js"); |
michael@0 | 6 | Cu.import("resource://services-sync/util.js"); |
michael@0 | 7 | Cu.import("resource://services-sync/engines/passwords.js"); |
michael@0 | 8 | Cu.import("resource://services-sync/service.js"); |
michael@0 | 9 | Cu.import("resource://testing-common/services/sync/utils.js"); |
michael@0 | 10 | |
michael@0 | 11 | function run_test() { |
michael@0 | 12 | initTestLogging("Trace"); |
michael@0 | 13 | run_next_test(); |
michael@0 | 14 | } |
michael@0 | 15 | |
michael@0 | 16 | add_test(function test_simple() { |
michael@0 | 17 | ensureLegacyIdentityManager(); |
michael@0 | 18 | // Stub fxAccountsEnabled |
michael@0 | 19 | let xpcs = Cc["@mozilla.org/weave/service;1"] |
michael@0 | 20 | .getService(Components.interfaces.nsISupports) |
michael@0 | 21 | .wrappedJSObject; |
michael@0 | 22 | let fxaEnabledGetter = xpcs.__lookupGetter__("fxAccountsEnabled"); |
michael@0 | 23 | xpcs.__defineGetter__("fxAccountsEnabled", () => true); |
michael@0 | 24 | |
michael@0 | 25 | // Stub mpEnabled. |
michael@0 | 26 | let mpEnabledF = Utils.mpEnabled; |
michael@0 | 27 | let mpEnabled = false; |
michael@0 | 28 | Utils.mpEnabled = function() mpEnabled; |
michael@0 | 29 | |
michael@0 | 30 | let manager = Service.engineManager; |
michael@0 | 31 | |
michael@0 | 32 | Service.engineManager.register(PasswordEngine); |
michael@0 | 33 | let engine = Service.engineManager.get("passwords"); |
michael@0 | 34 | let wipeCount = 0; |
michael@0 | 35 | let engineWipeServerF = engine.wipeServer; |
michael@0 | 36 | engine.wipeServer = function() { |
michael@0 | 37 | ++wipeCount; |
michael@0 | 38 | } |
michael@0 | 39 | |
michael@0 | 40 | // A server for the metadata. |
michael@0 | 41 | let server = new SyncServer(); |
michael@0 | 42 | let johndoe = server.registerUser("johndoe", "password"); |
michael@0 | 43 | johndoe.createContents({ |
michael@0 | 44 | meta: {global: {engines: {passwords: {version: engine.version, |
michael@0 | 45 | syncID: engine.syncID}}}}, |
michael@0 | 46 | crypto: {}, |
michael@0 | 47 | clients: {} |
michael@0 | 48 | }); |
michael@0 | 49 | server.start(); |
michael@0 | 50 | setBasicCredentials("johndoe", "password", "abcdeabcdeabcdeabcdeabcdea"); |
michael@0 | 51 | Service.serverURL = server.baseURI; |
michael@0 | 52 | Service.clusterURL = server.baseURI; |
michael@0 | 53 | |
michael@0 | 54 | let engineSync = new EngineSynchronizer(Service); |
michael@0 | 55 | engineSync._log.level = Log.Level.Trace; |
michael@0 | 56 | |
michael@0 | 57 | function assertEnabled(expected, message) { |
michael@0 | 58 | Assert.strictEqual(engine.enabled, expected, message); |
michael@0 | 59 | // The preference *must* reflect the actual state. |
michael@0 | 60 | Assert.strictEqual(Svc.Prefs.get("engine." + engine.prefName), expected, |
michael@0 | 61 | message + " (pref should match enabled state)"); |
michael@0 | 62 | } |
michael@0 | 63 | |
michael@0 | 64 | try { |
michael@0 | 65 | assertEnabled(true, "password engine should be enabled by default") |
michael@0 | 66 | let engineMeta = Service.recordManager.get(engine.metaURL); |
michael@0 | 67 | // This engine should be in the meta/global |
michael@0 | 68 | Assert.notStrictEqual(engineMeta.payload.engines[engine.name], undefined, |
michael@0 | 69 | "The engine should appear in the metadata"); |
michael@0 | 70 | Assert.ok(!engineMeta.changed, "the metadata for the password engine hasn't changed"); |
michael@0 | 71 | |
michael@0 | 72 | // (pretend to) enable a master-password |
michael@0 | 73 | mpEnabled = true; |
michael@0 | 74 | // The password engine should be locally disabled... |
michael@0 | 75 | assertEnabled(false, "if mp is locked the engine should be disabled"); |
michael@0 | 76 | // ...but not declined. |
michael@0 | 77 | Assert.ok(!manager.isDeclined("passwords"), "password engine is not declined"); |
michael@0 | 78 | // Next time a sync would happen, we call _updateEnabledEngines(), which |
michael@0 | 79 | // would remove the engine from the metadata - call that now. |
michael@0 | 80 | engineSync._updateEnabledEngines(); |
michael@0 | 81 | // The global meta should no longer list the engine. |
michael@0 | 82 | engineMeta = Service.recordManager.get(engine.metaURL); |
michael@0 | 83 | Assert.strictEqual(engineMeta.payload.engines[engine.name], undefined, |
michael@0 | 84 | "The engine should have vanished"); |
michael@0 | 85 | // And we should have wiped the server data. |
michael@0 | 86 | Assert.strictEqual(wipeCount, 1, "wipeServer should have been called"); |
michael@0 | 87 | |
michael@0 | 88 | // Now simulate an incoming meta/global indicating the engine should be |
michael@0 | 89 | // enabled. We should fail to actually enable it - the pref should remain |
michael@0 | 90 | // false and we wipe the server for anything another device might have |
michael@0 | 91 | // stored. |
michael@0 | 92 | let meta = { |
michael@0 | 93 | payload: { |
michael@0 | 94 | engines: { |
michael@0 | 95 | "passwords": {"version":1,"syncID":"yfBi2v7PpFO2"}, |
michael@0 | 96 | }, |
michael@0 | 97 | }, |
michael@0 | 98 | }; |
michael@0 | 99 | engineSync._updateEnabledFromMeta(meta, 3, manager); |
michael@0 | 100 | Assert.strictEqual(wipeCount, 2, "wipeServer should have been called"); |
michael@0 | 101 | Assert.ok(!manager.isDeclined("passwords"), "password engine is not declined"); |
michael@0 | 102 | assertEnabled(false, "engine still not enabled locally"); |
michael@0 | 103 | |
michael@0 | 104 | // Let's turn the MP off - but *not* re-enable it locally. |
michael@0 | 105 | mpEnabled = false; |
michael@0 | 106 | // Just disabling the MP isn't enough to force it back to enabled. |
michael@0 | 107 | assertEnabled(false, "engine still not enabled locally"); |
michael@0 | 108 | // Another incoming metadata record with the engine enabled should cause |
michael@0 | 109 | // it to be enabled locally. |
michael@0 | 110 | meta = { |
michael@0 | 111 | payload: { |
michael@0 | 112 | engines: { |
michael@0 | 113 | "passwords": 1, |
michael@0 | 114 | }, |
michael@0 | 115 | }, |
michael@0 | 116 | }; |
michael@0 | 117 | engineSync._updateEnabledFromMeta(meta, 3, manager); |
michael@0 | 118 | Assert.strictEqual(wipeCount, 2, "wipeServer should *not* have been called again"); |
michael@0 | 119 | Assert.ok(!manager.isDeclined("passwords"), "password engine is not declined"); |
michael@0 | 120 | // It should be enabled locally. |
michael@0 | 121 | assertEnabled(true, "engine now enabled locally"); |
michael@0 | 122 | // Next time a sync starts it should magically re-appear in our meta/global |
michael@0 | 123 | engine._syncStartup(); |
michael@0 | 124 | //engineSync._updateEnabledEngines(); |
michael@0 | 125 | engineMeta = Service.recordManager.get(engine.metaURL); |
michael@0 | 126 | Assert.equal(engineMeta.payload.engines[engine.name].version, engine.version, |
michael@0 | 127 | "The engine should re-appear in the metadata"); |
michael@0 | 128 | } finally { |
michael@0 | 129 | // restore the damage we did above... |
michael@0 | 130 | engine.wipeServer = engineWipeServerF; |
michael@0 | 131 | engine._store.wipe(); |
michael@0 | 132 | // Un-stub mpEnabled and fxAccountsEnabled |
michael@0 | 133 | Utils.mpEnabled = mpEnabledF; |
michael@0 | 134 | xpcs.__defineGetter__("fxAccountsEnabled", fxaEnabledGetter); |
michael@0 | 135 | server.stop(run_next_test); |
michael@0 | 136 | } |
michael@0 | 137 | }); |