michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: Cu.import("resource://gre/modules/Log.jsm"); michael@0: Cu.import("resource://services-sync/stages/enginesync.js"); michael@0: Cu.import("resource://services-sync/util.js"); michael@0: Cu.import("resource://services-sync/engines/passwords.js"); michael@0: Cu.import("resource://services-sync/service.js"); michael@0: Cu.import("resource://testing-common/services/sync/utils.js"); michael@0: michael@0: function run_test() { michael@0: initTestLogging("Trace"); michael@0: run_next_test(); michael@0: } michael@0: michael@0: add_test(function test_simple() { michael@0: ensureLegacyIdentityManager(); michael@0: // Stub fxAccountsEnabled michael@0: let xpcs = Cc["@mozilla.org/weave/service;1"] michael@0: .getService(Components.interfaces.nsISupports) michael@0: .wrappedJSObject; michael@0: let fxaEnabledGetter = xpcs.__lookupGetter__("fxAccountsEnabled"); michael@0: xpcs.__defineGetter__("fxAccountsEnabled", () => true); michael@0: michael@0: // Stub mpEnabled. michael@0: let mpEnabledF = Utils.mpEnabled; michael@0: let mpEnabled = false; michael@0: Utils.mpEnabled = function() mpEnabled; michael@0: michael@0: let manager = Service.engineManager; michael@0: michael@0: Service.engineManager.register(PasswordEngine); michael@0: let engine = Service.engineManager.get("passwords"); michael@0: let wipeCount = 0; michael@0: let engineWipeServerF = engine.wipeServer; michael@0: engine.wipeServer = function() { michael@0: ++wipeCount; michael@0: } michael@0: michael@0: // A server for the metadata. michael@0: let server = new SyncServer(); michael@0: let johndoe = server.registerUser("johndoe", "password"); michael@0: johndoe.createContents({ michael@0: meta: {global: {engines: {passwords: {version: engine.version, michael@0: syncID: engine.syncID}}}}, michael@0: crypto: {}, michael@0: clients: {} michael@0: }); michael@0: server.start(); michael@0: setBasicCredentials("johndoe", "password", "abcdeabcdeabcdeabcdeabcdea"); michael@0: Service.serverURL = server.baseURI; michael@0: Service.clusterURL = server.baseURI; michael@0: michael@0: let engineSync = new EngineSynchronizer(Service); michael@0: engineSync._log.level = Log.Level.Trace; michael@0: michael@0: function assertEnabled(expected, message) { michael@0: Assert.strictEqual(engine.enabled, expected, message); michael@0: // The preference *must* reflect the actual state. michael@0: Assert.strictEqual(Svc.Prefs.get("engine." + engine.prefName), expected, michael@0: message + " (pref should match enabled state)"); michael@0: } michael@0: michael@0: try { michael@0: assertEnabled(true, "password engine should be enabled by default") michael@0: let engineMeta = Service.recordManager.get(engine.metaURL); michael@0: // This engine should be in the meta/global michael@0: Assert.notStrictEqual(engineMeta.payload.engines[engine.name], undefined, michael@0: "The engine should appear in the metadata"); michael@0: Assert.ok(!engineMeta.changed, "the metadata for the password engine hasn't changed"); michael@0: michael@0: // (pretend to) enable a master-password michael@0: mpEnabled = true; michael@0: // The password engine should be locally disabled... michael@0: assertEnabled(false, "if mp is locked the engine should be disabled"); michael@0: // ...but not declined. michael@0: Assert.ok(!manager.isDeclined("passwords"), "password engine is not declined"); michael@0: // Next time a sync would happen, we call _updateEnabledEngines(), which michael@0: // would remove the engine from the metadata - call that now. michael@0: engineSync._updateEnabledEngines(); michael@0: // The global meta should no longer list the engine. michael@0: engineMeta = Service.recordManager.get(engine.metaURL); michael@0: Assert.strictEqual(engineMeta.payload.engines[engine.name], undefined, michael@0: "The engine should have vanished"); michael@0: // And we should have wiped the server data. michael@0: Assert.strictEqual(wipeCount, 1, "wipeServer should have been called"); michael@0: michael@0: // Now simulate an incoming meta/global indicating the engine should be michael@0: // enabled. We should fail to actually enable it - the pref should remain michael@0: // false and we wipe the server for anything another device might have michael@0: // stored. michael@0: let meta = { michael@0: payload: { michael@0: engines: { michael@0: "passwords": {"version":1,"syncID":"yfBi2v7PpFO2"}, michael@0: }, michael@0: }, michael@0: }; michael@0: engineSync._updateEnabledFromMeta(meta, 3, manager); michael@0: Assert.strictEqual(wipeCount, 2, "wipeServer should have been called"); michael@0: Assert.ok(!manager.isDeclined("passwords"), "password engine is not declined"); michael@0: assertEnabled(false, "engine still not enabled locally"); michael@0: michael@0: // Let's turn the MP off - but *not* re-enable it locally. michael@0: mpEnabled = false; michael@0: // Just disabling the MP isn't enough to force it back to enabled. michael@0: assertEnabled(false, "engine still not enabled locally"); michael@0: // Another incoming metadata record with the engine enabled should cause michael@0: // it to be enabled locally. michael@0: meta = { michael@0: payload: { michael@0: engines: { michael@0: "passwords": 1, michael@0: }, michael@0: }, michael@0: }; michael@0: engineSync._updateEnabledFromMeta(meta, 3, manager); michael@0: Assert.strictEqual(wipeCount, 2, "wipeServer should *not* have been called again"); michael@0: Assert.ok(!manager.isDeclined("passwords"), "password engine is not declined"); michael@0: // It should be enabled locally. michael@0: assertEnabled(true, "engine now enabled locally"); michael@0: // Next time a sync starts it should magically re-appear in our meta/global michael@0: engine._syncStartup(); michael@0: //engineSync._updateEnabledEngines(); michael@0: engineMeta = Service.recordManager.get(engine.metaURL); michael@0: Assert.equal(engineMeta.payload.engines[engine.name].version, engine.version, michael@0: "The engine should re-appear in the metadata"); michael@0: } finally { michael@0: // restore the damage we did above... michael@0: engine.wipeServer = engineWipeServerF; michael@0: engine._store.wipe(); michael@0: // Un-stub mpEnabled and fxAccountsEnabled michael@0: Utils.mpEnabled = mpEnabledF; michael@0: xpcs.__defineGetter__("fxAccountsEnabled", fxaEnabledGetter); michael@0: server.stop(run_next_test); michael@0: } michael@0: });