summaryrefslogtreecommitdiffstats
path: root/services/sync/tests/unit/test_fxa_migration.js
diff options
context:
space:
mode:
Diffstat (limited to 'services/sync/tests/unit/test_fxa_migration.js')
-rw-r--r--services/sync/tests/unit/test_fxa_migration.js279
1 files changed, 0 insertions, 279 deletions
diff --git a/services/sync/tests/unit/test_fxa_migration.js b/services/sync/tests/unit/test_fxa_migration.js
deleted file mode 100644
index 7c65d5996..000000000
--- a/services/sync/tests/unit/test_fxa_migration.js
+++ /dev/null
@@ -1,279 +0,0 @@
-// Test the FxAMigration module
-Cu.import("resource://services-sync/FxaMigrator.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/FxAccounts.jsm");
-Cu.import("resource://gre/modules/FxAccountsCommon.js");
-Cu.import("resource://services-sync/browserid_identity.js");
-
-// Set our username pref early so sync initializes with the legacy provider.
-Services.prefs.setCharPref("services.sync.username", "foo");
-// And ensure all debug messages end up being printed.
-Services.prefs.setCharPref("services.sync.log.appender.dump", "Debug");
-
-// Now import sync
-Cu.import("resource://services-sync/service.js");
-Cu.import("resource://services-sync/record.js");
-Cu.import("resource://services-sync/util.js");
-
-// And reset the username.
-Services.prefs.clearUserPref("services.sync.username");
-
-Cu.import("resource://testing-common/services/sync/utils.js");
-Cu.import("resource://testing-common/services/common/logging.js");
-Cu.import("resource://testing-common/services/sync/rotaryengine.js");
-
-const FXA_USERNAME = "someone@somewhere";
-
-// Utilities
-function promiseOneObserver(topic) {
- return new Promise((resolve, reject) => {
- let observer = function(subject, topic, data) {
- Services.obs.removeObserver(observer, topic);
- resolve({ subject: subject, data: data });
- }
- Services.obs.addObserver(observer, topic, false);
- });
-}
-
-function promiseStopServer(server) {
- return new Promise((resolve, reject) => {
- server.stop(resolve);
- });
-}
-
-
-// Helpers
-function configureLegacySync() {
- let engine = new RotaryEngine(Service);
- engine.enabled = true;
- Svc.Prefs.set("registerEngines", engine.name);
- Svc.Prefs.set("log.logger.engine.rotary", "Trace");
-
- let contents = {
- meta: {global: {engines: {rotary: {version: engine.version,
- syncID: engine.syncID}}}},
- crypto: {},
- rotary: {}
- };
-
- const USER = "foo";
- const PASSPHRASE = "abcdeabcdeabcdeabcdeabcdea";
-
- setBasicCredentials(USER, "password", PASSPHRASE);
-
- let onRequest = function(request, response) {
- // ideally we'd only do this while a legacy user is configured, but WTH.
- response.setHeader("x-weave-alert", JSON.stringify({code: "soft-eol"}));
- }
- let server = new SyncServer({onRequest: onRequest});
- server.registerUser(USER, "password");
- server.createContents(USER, contents);
- server.start();
-
- Service.serverURL = server.baseURI;
- Service.clusterURL = server.baseURI;
- Service.identity.username = USER;
- Service._updateCachedURLs();
-
- Service.engineManager._engines[engine.name] = engine;
-
- return [engine, server];
-}
-
-function configureFxa() {
- Services.prefs.setCharPref("identity.fxaccounts.auth.uri", "http://localhost");
-}
-
-add_task(function *testMigration() {
- configureFxa();
-
- // when we do a .startOver we want the new provider.
- let oldValue = Services.prefs.getBoolPref("services.sync-testing.startOverKeepIdentity");
- Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", false);
-
- // disable the addons engine - this engine choice is arbitrary, but we
- // want to check it remains disabled after migration.
- Services.prefs.setBoolPref("services.sync.engine.addons", false);
-
- do_register_cleanup(() => {
- Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", oldValue)
- Services.prefs.setBoolPref("services.sync.engine.addons", true);
- });
-
- // No sync user - that should report no user-action necessary.
- Assert.deepEqual((yield fxaMigrator._queueCurrentUserState()), null,
- "no user state when complete");
-
- // Arrange for a legacy sync user and manually bump the migrator
- let [engine, server] = configureLegacySync();
-
- // Check our disabling of the "addons" engine worked, and for good measure,
- // that the "passwords" engine is enabled.
- Assert.ok(!Service.engineManager.get("addons").enabled, "addons is disabled");
- Assert.ok(Service.engineManager.get("passwords").enabled, "passwords is enabled");
-
- // monkey-patch the migration sentinel code so we know it was called.
- let haveStartedSentinel = false;
- let origSetFxAMigrationSentinel = Service.setFxAMigrationSentinel;
- let promiseSentinelWritten = new Promise((resolve, reject) => {
- Service.setFxAMigrationSentinel = function(arg) {
- haveStartedSentinel = true;
- return origSetFxAMigrationSentinel.call(Service, arg).then(result => {
- Service.setFxAMigrationSentinel = origSetFxAMigrationSentinel;
- resolve(result);
- return result;
- });
- }
- });
-
- // We are now configured for legacy sync, but we aren't in an EOL state yet,
- // so should still be not waiting for a user.
- Assert.deepEqual((yield fxaMigrator._queueCurrentUserState()), null,
- "no user state before server EOL");
-
- // Start a sync - this will cause an EOL notification which the migrator's
- // observer will notice.
- let promise = promiseOneObserver("fxa-migration:state-changed");
- _("Starting sync");
- Service.sync();
- _("Finished sync");
-
- // We should have seen the observer, so be waiting for an FxA user.
- Assert.equal((yield promise).data, fxaMigrator.STATE_USER_FXA, "now waiting for FxA.")
-
- // Re-calling our user-state promise should also reflect the same state.
- Assert.equal((yield fxaMigrator._queueCurrentUserState()),
- fxaMigrator.STATE_USER_FXA,
- "still waiting for FxA.");
-
- // arrange for an unverified FxA user.
- let config = makeIdentityConfig({username: FXA_USERNAME});
- let fxa = new FxAccounts({});
- config.fxaccount.user.email = config.username;
- delete config.fxaccount.user.verified;
- // *sob* - shouldn't need this boilerplate
- fxa.internal.currentAccountState.getCertificate = function(data, keyPair, mustBeValidUntil) {
- this.cert = {
- validUntil: fxa.internal.now() + CERT_LIFETIME,
- cert: "certificate",
- };
- return Promise.resolve(this.cert.cert);
- };
-
- // As soon as we set the FxA user the observers should fire and magically
- // transition.
- promise = promiseOneObserver("fxa-migration:state-changed");
- fxAccounts.setSignedInUser(config.fxaccount.user);
-
- let observerInfo = yield promise;
- Assert.equal(observerInfo.data,
- fxaMigrator.STATE_USER_FXA_VERIFIED,
- "now waiting for verification");
- Assert.ok(observerInfo.subject instanceof Ci.nsISupportsString,
- "email was passed to observer");
- Assert.equal(observerInfo.subject.data,
- FXA_USERNAME,
- "email passed to observer is correct");
-
- // should have seen the user set, so state should automatically update.
- Assert.equal((yield fxaMigrator._queueCurrentUserState()),
- fxaMigrator.STATE_USER_FXA_VERIFIED,
- "now waiting for verification");
-
- // Before we verify the user, fire off a sync that calls us back during
- // the sync and before it completes - this way we can ensure we do the right
- // thing in terms of blocking sync and waiting for it to complete.
-
- let wasWaiting = false;
- // This is a PITA as sync is pseudo-blocking.
- engine._syncFinish = function () {
- // We aren't in a generator here, so use a helper to block on promises.
- function getState() {
- let cb = Async.makeSpinningCallback();
- fxaMigrator._queueCurrentUserState().then(state => cb(null, state));
- return cb.wait();
- }
- // should still be waiting for verification.
- Assert.equal(getState(), fxaMigrator.STATE_USER_FXA_VERIFIED,
- "still waiting for verification");
-
- // arrange for the user to be verified. The fxAccount's mock story is
- // broken, so go behind its back.
- config.fxaccount.user.verified = true;
- fxAccounts.setSignedInUser(config.fxaccount.user);
- Services.obs.notifyObservers(null, ONVERIFIED_NOTIFICATION, null);
-
- // spinningly wait for the migrator to catch up - sync is running so
- // we should be in a 'null' user-state as there is no user-action
- // necessary.
- let cb = Async.makeSpinningCallback();
- promiseOneObserver("fxa-migration:state-changed").then(({ data: state }) => cb(null, state));
- Assert.equal(cb.wait(), null, "no user action necessary while sync completes.");
-
- // We must not have started writing the sentinel yet.
- Assert.ok(!haveStartedSentinel, "haven't written a sentinel yet");
-
- // sync should be blocked from continuing
- Assert.ok(Service.scheduler.isBlocked, "sync is blocked.")
-
- wasWaiting = true;
- throw ex;
- };
-
- _("Starting sync");
- Service.sync();
- _("Finished sync");
-
- // mock sync so we can ensure the final sync is scheduled with the FxA user.
- // (letting a "normal" sync complete is a PITA without mocking huge amounts
- // of FxA infra)
- let promiseFinalSync = new Promise((resolve, reject) => {
- let oldSync = Service.sync;
- Service.sync = function() {
- Service.sync = oldSync;
- resolve();
- }
- });
-
- Assert.ok(wasWaiting, "everything was good while sync was running.")
-
- // The migration is now going to run to completion.
- // sync should still be "blocked"
- Assert.ok(Service.scheduler.isBlocked, "sync is blocked.");
-
- // We should see the migration sentinel written and it should return true.
- Assert.ok((yield promiseSentinelWritten), "wrote the sentinel");
-
- // And we should see a new sync start
- yield promiseFinalSync;
-
- // and we should be configured for FxA
- let WeaveService = Cc["@mozilla.org/weave/service;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
- Assert.ok(WeaveService.fxAccountsEnabled, "FxA is enabled");
- Assert.ok(Service.identity instanceof BrowserIDManager,
- "sync is configured with the browserid_identity provider.");
- Assert.equal(Service.identity.username, config.username, "correct user configured")
- Assert.ok(!Service.scheduler.isBlocked, "sync is not blocked.")
- // and the user state should remain null.
- Assert.deepEqual((yield fxaMigrator._queueCurrentUserState()),
- null,
- "still no user action necessary");
- // and our engines should be in the same enabled/disabled state as before.
- Assert.ok(!Service.engineManager.get("addons").enabled, "addons is still disabled");
- Assert.ok(Service.engineManager.get("passwords").enabled, "passwords is still enabled");
-
- // aaaand, we are done - clean up.
- yield promiseStopServer(server);
-});
-
-
-function run_test() {
- initTestLogging();
- do_register_cleanup(() => {
- fxaMigrator.finalize();
- Svc.Prefs.resetBranch("");
- });
- run_next_test();
-}