summaryrefslogtreecommitdiffstats
path: root/services/sync/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'services/sync/tests/unit')
-rw-r--r--services/sync/tests/unit/test_browserid_identity.js682
-rw-r--r--services/sync/tests/unit/test_errorhandler.js4
-rw-r--r--services/sync/tests/unit/test_fxa_node_reassignment.js321
-rw-r--r--services/sync/tests/unit/test_fxa_service_cluster.js68
-rw-r--r--services/sync/tests/unit/test_fxa_startOver.js63
-rw-r--r--services/sync/tests/unit/test_load_modules.js1
-rw-r--r--services/sync/tests/unit/xpcshell.ini6
7 files changed, 0 insertions, 1145 deletions
diff --git a/services/sync/tests/unit/test_browserid_identity.js b/services/sync/tests/unit/test_browserid_identity.js
deleted file mode 100644
index f3cde9f8f..000000000
--- a/services/sync/tests/unit/test_browserid_identity.js
+++ /dev/null
@@ -1,682 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Cu.import("resource://gre/modules/FxAccounts.jsm");
-Cu.import("resource://services-sync/browserid_identity.js");
-Cu.import("resource://services-sync/rest.js");
-Cu.import("resource://services-sync/util.js");
-Cu.import("resource://services-common/utils.js");
-Cu.import("resource://services-crypto/utils.js");
-Cu.import("resource://testing-common/services/sync/utils.js");
-Cu.import("resource://testing-common/services/sync/fxa_utils.js");
-Cu.import("resource://services-common/hawkclient.js");
-Cu.import("resource://gre/modules/FxAccounts.jsm");
-Cu.import("resource://gre/modules/FxAccountsClient.jsm");
-Cu.import("resource://gre/modules/FxAccountsCommon.js");
-Cu.import("resource://services-sync/service.js");
-Cu.import("resource://services-sync/status.js");
-Cu.import("resource://services-sync/constants.js");
-
-const SECOND_MS = 1000;
-const MINUTE_MS = SECOND_MS * 60;
-const HOUR_MS = MINUTE_MS * 60;
-
-let identityConfig = makeIdentityConfig();
-let browseridManager = new BrowserIDManager();
-configureFxAccountIdentity(browseridManager, identityConfig);
-
-/**
- * Mock client clock and skew vs server in FxAccounts signed-in user module and
- * API client. browserid_identity.js queries these values to construct HAWK
- * headers. We will use this to test clock skew compensation in these headers
- * below.
- */
-let MockFxAccountsClient = function() {
- FxAccountsClient.apply(this);
-};
-MockFxAccountsClient.prototype = {
- __proto__: FxAccountsClient.prototype
-};
-
-function MockFxAccounts() {
- let fxa = new FxAccounts({
- _now_is: Date.now(),
-
- now: function () {
- return this._now_is;
- },
-
- fxAccountsClient: new MockFxAccountsClient()
- });
- fxa.internal.currentAccountState.getCertificate = function(data, keyPair, mustBeValidUntil) {
- this.cert = {
- validUntil: fxa.internal.now() + CERT_LIFETIME,
- cert: "certificate",
- };
- return Promise.resolve(this.cert.cert);
- };
- return fxa;
-}
-
-function run_test() {
- initTestLogging("Trace");
- Log.repository.getLogger("Sync.Identity").level = Log.Level.Trace;
- Log.repository.getLogger("Sync.BrowserIDManager").level = Log.Level.Trace;
- run_next_test();
-};
-
-add_test(function test_initial_state() {
- _("Verify initial state");
- do_check_false(!!browseridManager._token);
- do_check_false(browseridManager.hasValidToken());
- run_next_test();
- }
-);
-
-add_task(function test_initialializeWithCurrentIdentity() {
- _("Verify start after initializeWithCurrentIdentity");
- browseridManager.initializeWithCurrentIdentity();
- yield browseridManager.whenReadyToAuthenticate.promise;
- do_check_true(!!browseridManager._token);
- do_check_true(browseridManager.hasValidToken());
- do_check_eq(browseridManager.account, identityConfig.fxaccount.user.email);
- }
-);
-
-add_task(function test_initialializeWithNoKeys() {
- _("Verify start after initializeWithCurrentIdentity without kA, kB or keyFetchToken");
- let identityConfig = makeIdentityConfig();
- delete identityConfig.fxaccount.user.kA;
- delete identityConfig.fxaccount.user.kB;
- // there's no keyFetchToken by default, so the initialize should fail.
- configureFxAccountIdentity(browseridManager, identityConfig);
-
- yield browseridManager.initializeWithCurrentIdentity();
- yield browseridManager.whenReadyToAuthenticate.promise;
- do_check_eq(Status.login, LOGIN_SUCCEEDED, "login succeeded even without keys");
- do_check_false(browseridManager._canFetchKeys(), "_canFetchKeys reflects lack of keys");
- do_check_eq(browseridManager._token, null, "we don't have a token");
-});
-
-add_test(function test_getResourceAuthenticator() {
- _("BrowserIDManager supplies a Resource Authenticator callback which returns a Hawk header.");
- configureFxAccountIdentity(browseridManager);
- let authenticator = browseridManager.getResourceAuthenticator();
- do_check_true(!!authenticator);
- let req = {uri: CommonUtils.makeURI(
- "https://example.net/somewhere/over/the/rainbow"),
- method: 'GET'};
- let output = authenticator(req, 'GET');
- do_check_true('headers' in output);
- do_check_true('authorization' in output.headers);
- do_check_true(output.headers.authorization.startsWith('Hawk'));
- _("Expected internal state after successful call.");
- do_check_eq(browseridManager._token.uid, identityConfig.fxaccount.token.uid);
- run_next_test();
- }
-);
-
-add_test(function test_getRESTRequestAuthenticator() {
- _("BrowserIDManager supplies a REST Request Authenticator callback which sets a Hawk header on a request object.");
- let request = new SyncStorageRequest(
- "https://example.net/somewhere/over/the/rainbow");
- let authenticator = browseridManager.getRESTRequestAuthenticator();
- do_check_true(!!authenticator);
- let output = authenticator(request, 'GET');
- do_check_eq(request.uri, output.uri);
- do_check_true(output._headers.authorization.startsWith('Hawk'));
- do_check_true(output._headers.authorization.includes('nonce'));
- do_check_true(browseridManager.hasValidToken());
- run_next_test();
- }
-);
-
-add_test(function test_resourceAuthenticatorSkew() {
- _("BrowserIDManager Resource Authenticator compensates for clock skew in Hawk header.");
-
- // Clock is skewed 12 hours into the future
- // We pick a date in the past so we don't risk concealing bugs in code that
- // uses new Date() instead of our given date.
- let now = new Date("Fri Apr 09 2004 00:00:00 GMT-0700").valueOf() + 12 * HOUR_MS;
- let browseridManager = new BrowserIDManager();
- let hawkClient = new HawkClient("https://example.net/v1", "/foo");
-
- // mock fxa hawk client skew
- hawkClient.now = function() {
- dump("mocked client now: " + now + '\n');
- return now;
- }
- // Imagine there's already been one fxa request and the hawk client has
- // already detected skew vs the fxa auth server.
- let localtimeOffsetMsec = -1 * 12 * HOUR_MS;
- hawkClient._localtimeOffsetMsec = localtimeOffsetMsec;
-
- let fxaClient = new MockFxAccountsClient();
- fxaClient.hawk = hawkClient;
-
- // Sanity check
- do_check_eq(hawkClient.now(), now);
- do_check_eq(hawkClient.localtimeOffsetMsec, localtimeOffsetMsec);
-
- // Properly picked up by the client
- do_check_eq(fxaClient.now(), now);
- do_check_eq(fxaClient.localtimeOffsetMsec, localtimeOffsetMsec);
-
- let fxa = new MockFxAccounts();
- fxa.internal._now_is = now;
- fxa.internal.fxAccountsClient = fxaClient;
-
- // Picked up by the signed-in user module
- do_check_eq(fxa.internal.now(), now);
- do_check_eq(fxa.internal.localtimeOffsetMsec, localtimeOffsetMsec);
-
- do_check_eq(fxa.now(), now);
- do_check_eq(fxa.localtimeOffsetMsec, localtimeOffsetMsec);
-
- // Mocks within mocks...
- configureFxAccountIdentity(browseridManager, identityConfig);
-
- // Ensure the new FxAccounts mock has a signed-in user.
- fxa.internal.currentAccountState.signedInUser = browseridManager._fxaService.internal.currentAccountState.signedInUser;
-
- browseridManager._fxaService = fxa;
-
- do_check_eq(browseridManager._fxaService.internal.now(), now);
- do_check_eq(browseridManager._fxaService.internal.localtimeOffsetMsec,
- localtimeOffsetMsec);
-
- do_check_eq(browseridManager._fxaService.now(), now);
- do_check_eq(browseridManager._fxaService.localtimeOffsetMsec,
- localtimeOffsetMsec);
-
- let request = new SyncStorageRequest("https://example.net/i/like/pie/");
- let authenticator = browseridManager.getResourceAuthenticator();
- let output = authenticator(request, 'GET');
- dump("output" + JSON.stringify(output));
- let authHeader = output.headers.authorization;
- do_check_true(authHeader.startsWith('Hawk'));
-
- // Skew correction is applied in the header and we're within the two-minute
- // window.
- do_check_eq(getTimestamp(authHeader), now - 12 * HOUR_MS);
- do_check_true(
- (getTimestampDelta(authHeader, now) - 12 * HOUR_MS) < 2 * MINUTE_MS);
-
- run_next_test();
-});
-
-add_test(function test_RESTResourceAuthenticatorSkew() {
- _("BrowserIDManager REST Resource Authenticator compensates for clock skew in Hawk header.");
-
- // Clock is skewed 12 hours into the future from our arbitary date
- let now = new Date("Fri Apr 09 2004 00:00:00 GMT-0700").valueOf() + 12 * HOUR_MS;
- let browseridManager = new BrowserIDManager();
- let hawkClient = new HawkClient("https://example.net/v1", "/foo");
-
- // mock fxa hawk client skew
- hawkClient.now = function() {
- return now;
- }
- // Imagine there's already been one fxa request and the hawk client has
- // already detected skew vs the fxa auth server.
- hawkClient._localtimeOffsetMsec = -1 * 12 * HOUR_MS;
-
- let fxaClient = new MockFxAccountsClient();
- fxaClient.hawk = hawkClient;
- let fxa = new MockFxAccounts();
- fxa.internal._now_is = now;
- fxa.internal.fxAccountsClient = fxaClient;
-
- configureFxAccountIdentity(browseridManager, identityConfig);
-
- // Ensure the new FxAccounts mock has a signed-in user.
- fxa.internal.currentAccountState.signedInUser = browseridManager._fxaService.internal.currentAccountState.signedInUser;
-
- browseridManager._fxaService = fxa;
-
- do_check_eq(browseridManager._fxaService.internal.now(), now);
-
- let request = new SyncStorageRequest("https://example.net/i/like/pie/");
- let authenticator = browseridManager.getResourceAuthenticator();
- let output = authenticator(request, 'GET');
- dump("output" + JSON.stringify(output));
- let authHeader = output.headers.authorization;
- do_check_true(authHeader.startsWith('Hawk'));
-
- // Skew correction is applied in the header and we're within the two-minute
- // window.
- do_check_eq(getTimestamp(authHeader), now - 12 * HOUR_MS);
- do_check_true(
- (getTimestampDelta(authHeader, now) - 12 * HOUR_MS) < 2 * MINUTE_MS);
-
- run_next_test();
-});
-
-add_task(function test_ensureLoggedIn() {
- configureFxAccountIdentity(browseridManager);
- yield browseridManager.initializeWithCurrentIdentity();
- yield browseridManager.whenReadyToAuthenticate.promise;
- Assert.equal(Status.login, LOGIN_SUCCEEDED, "original initialize worked");
- yield browseridManager.ensureLoggedIn();
- Assert.equal(Status.login, LOGIN_SUCCEEDED, "original ensureLoggedIn worked");
- Assert.ok(browseridManager._shouldHaveSyncKeyBundle,
- "_shouldHaveSyncKeyBundle should always be true after ensureLogin completes.");
-
- // arrange for no logged in user.
- let fxa = browseridManager._fxaService
- let signedInUser = fxa.internal.currentAccountState.signedInUser;
- fxa.internal.currentAccountState.signedInUser = null;
- browseridManager.initializeWithCurrentIdentity();
- Assert.ok(!browseridManager._shouldHaveSyncKeyBundle,
- "_shouldHaveSyncKeyBundle should be false so we know we are testing what we think we are.");
- Status.login = LOGIN_FAILED_NO_USERNAME;
- yield Assert.rejects(browseridManager.ensureLoggedIn(), "expecting rejection due to no user");
- Assert.ok(browseridManager._shouldHaveSyncKeyBundle,
- "_shouldHaveSyncKeyBundle should always be true after ensureLogin completes.");
- fxa.internal.currentAccountState.signedInUser = signedInUser;
- Status.login = LOGIN_FAILED_LOGIN_REJECTED;
- yield Assert.rejects(browseridManager.ensureLoggedIn(),
- "LOGIN_FAILED_LOGIN_REJECTED should have caused immediate rejection");
- Assert.equal(Status.login, LOGIN_FAILED_LOGIN_REJECTED,
- "status should remain LOGIN_FAILED_LOGIN_REJECTED");
- Status.login = LOGIN_FAILED_NETWORK_ERROR;
- yield browseridManager.ensureLoggedIn();
- Assert.equal(Status.login, LOGIN_SUCCEEDED, "final ensureLoggedIn worked");
-});
-
-add_test(function test_tokenExpiration() {
- _("BrowserIDManager notices token expiration:");
- let bimExp = new BrowserIDManager();
- configureFxAccountIdentity(bimExp, identityConfig);
-
- let authenticator = bimExp.getResourceAuthenticator();
- do_check_true(!!authenticator);
- let req = {uri: CommonUtils.makeURI(
- "https://example.net/somewhere/over/the/rainbow"),
- method: 'GET'};
- authenticator(req, 'GET');
-
- // Mock the clock.
- _("Forcing the token to expire ...");
- Object.defineProperty(bimExp, "_now", {
- value: function customNow() {
- return (Date.now() + 3000001);
- },
- writable: true,
- });
- do_check_true(bimExp._token.expiration < bimExp._now());
- _("... means BrowserIDManager knows to re-fetch it on the next call.");
- do_check_false(bimExp.hasValidToken());
- run_next_test();
- }
-);
-
-add_test(function test_sha256() {
- // Test vectors from http://www.bichlmeier.info/sha256test.html
- let vectors = [
- ["",
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"],
- ["abc",
- "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"],
- ["message digest",
- "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650"],
- ["secure hash algorithm",
- "f30ceb2bb2829e79e4ca9753d35a8ecc00262d164cc077080295381cbd643f0d"],
- ["SHA256 is considered to be safe",
- "6819d915c73f4d1e77e4e1b52d1fa0f9cf9beaead3939f15874bd988e2a23630"],
- ["abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
- "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"],
- ["For this sample, this 63-byte string will be used as input data",
- "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342"],
- ["This is exactly 64 bytes long, not counting the terminating byte",
- "ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8"]
- ];
- let bidUser = new BrowserIDManager();
- for (let [input,output] of vectors) {
- do_check_eq(CommonUtils.bytesAsHex(bidUser._sha256(input)), output);
- }
- run_next_test();
-});
-
-add_test(function test_computeXClientStateHeader() {
- let kBhex = "fd5c747806c07ce0b9d69dcfea144663e630b65ec4963596a22f24910d7dd15d";
- let kB = CommonUtils.hexToBytes(kBhex);
-
- let bidUser = new BrowserIDManager();
- let header = bidUser._computeXClientState(kB);
-
- do_check_eq(header, "6ae94683571c7a7c54dab4700aa3995f");
- run_next_test();
-});
-
-add_task(function test_getTokenErrors() {
- _("BrowserIDManager correctly handles various failures to get a token.");
-
- _("Arrange for a 401 - Sync should reflect an auth error.");
- initializeIdentityWithTokenServerResponse({
- status: 401,
- headers: {"content-type": "application/json"},
- body: JSON.stringify({}),
- });
- let browseridManager = Service.identity;
-
- yield browseridManager.initializeWithCurrentIdentity();
- yield Assert.rejects(browseridManager.whenReadyToAuthenticate.promise,
- "should reject due to 401");
- Assert.equal(Status.login, LOGIN_FAILED_LOGIN_REJECTED, "login was rejected");
-
- // XXX - other interesting responses to return?
-
- // And for good measure, some totally "unexpected" errors - we generally
- // assume these problems are going to magically go away at some point.
- _("Arrange for an empty body with a 200 response - should reflect a network error.");
- initializeIdentityWithTokenServerResponse({
- status: 200,
- headers: [],
- body: "",
- });
- browseridManager = Service.identity;
- yield browseridManager.initializeWithCurrentIdentity();
- yield Assert.rejects(browseridManager.whenReadyToAuthenticate.promise,
- "should reject due to non-JSON response");
- Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "login state is LOGIN_FAILED_NETWORK_ERROR");
-});
-
-add_task(function test_getTokenErrorWithRetry() {
- _("tokenserver sends an observer notification on various backoff headers.");
-
- // Set Sync's backoffInterval to zero - after we simulated the backoff header
- // it should reflect the value we sent.
- Status.backoffInterval = 0;
- _("Arrange for a 503 with a Retry-After header.");
- initializeIdentityWithTokenServerResponse({
- status: 503,
- headers: {"content-type": "application/json",
- "retry-after": "100"},
- body: JSON.stringify({}),
- });
- let browseridManager = Service.identity;
-
- yield browseridManager.initializeWithCurrentIdentity();
- yield Assert.rejects(browseridManager.whenReadyToAuthenticate.promise,
- "should reject due to 503");
-
- // The observer should have fired - check it got the value in the response.
- Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "login was rejected");
- // Sync will have the value in ms with some slop - so check it is at least that.
- Assert.ok(Status.backoffInterval >= 100000);
-
- _("Arrange for a 200 with an X-Backoff header.");
- Status.backoffInterval = 0;
- initializeIdentityWithTokenServerResponse({
- status: 503,
- headers: {"content-type": "application/json",
- "x-backoff": "200"},
- body: JSON.stringify({}),
- });
- browseridManager = Service.identity;
-
- yield browseridManager.initializeWithCurrentIdentity();
- yield Assert.rejects(browseridManager.whenReadyToAuthenticate.promise,
- "should reject due to no token in response");
-
- // The observer should have fired - check it got the value in the response.
- Assert.ok(Status.backoffInterval >= 200000);
-});
-
-add_task(function test_getKeysErrorWithBackoff() {
- _("Auth server (via hawk) sends an observer notification on backoff headers.");
-
- // Set Sync's backoffInterval to zero - after we simulated the backoff header
- // it should reflect the value we sent.
- Status.backoffInterval = 0;
- _("Arrange for a 503 with a X-Backoff header.");
-
- let config = makeIdentityConfig();
- // We want no kA or kB so we attempt to fetch them.
- delete config.fxaccount.user.kA;
- delete config.fxaccount.user.kB;
- config.fxaccount.user.keyFetchToken = "keyfetchtoken";
- yield initializeIdentityWithHAWKResponseFactory(config, function(method, data, uri) {
- Assert.equal(method, "get");
- Assert.equal(uri, "http://mockedserver:9999/account/keys")
- return {
- status: 503,
- headers: {"content-type": "application/json",
- "x-backoff": "100"},
- body: "{}",
- }
- });
-
- let browseridManager = Service.identity;
- yield Assert.rejects(browseridManager.whenReadyToAuthenticate.promise,
- "should reject due to 503");
-
- // The observer should have fired - check it got the value in the response.
- Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "login was rejected");
- // Sync will have the value in ms with some slop - so check it is at least that.
- Assert.ok(Status.backoffInterval >= 100000);
-});
-
-add_task(function test_getKeysErrorWithRetry() {
- _("Auth server (via hawk) sends an observer notification on retry headers.");
-
- // Set Sync's backoffInterval to zero - after we simulated the backoff header
- // it should reflect the value we sent.
- Status.backoffInterval = 0;
- _("Arrange for a 503 with a Retry-After header.");
-
- let config = makeIdentityConfig();
- // We want no kA or kB so we attempt to fetch them.
- delete config.fxaccount.user.kA;
- delete config.fxaccount.user.kB;
- config.fxaccount.user.keyFetchToken = "keyfetchtoken";
- yield initializeIdentityWithHAWKResponseFactory(config, function(method, data, uri) {
- Assert.equal(method, "get");
- Assert.equal(uri, "http://mockedserver:9999/account/keys")
- return {
- status: 503,
- headers: {"content-type": "application/json",
- "retry-after": "100"},
- body: "{}",
- }
- });
-
- let browseridManager = Service.identity;
- yield Assert.rejects(browseridManager.whenReadyToAuthenticate.promise,
- "should reject due to 503");
-
- // The observer should have fired - check it got the value in the response.
- Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "login was rejected");
- // Sync will have the value in ms with some slop - so check it is at least that.
- Assert.ok(Status.backoffInterval >= 100000);
-});
-
-add_task(function test_getHAWKErrors() {
- _("BrowserIDManager correctly handles various HAWK failures.");
-
- _("Arrange for a 401 - Sync should reflect an auth error.");
- let config = makeIdentityConfig();
- yield initializeIdentityWithHAWKResponseFactory(config, function(method, data, uri) {
- Assert.equal(method, "post");
- Assert.equal(uri, "http://mockedserver:9999/certificate/sign")
- return {
- status: 401,
- headers: {"content-type": "application/json"},
- body: JSON.stringify({}),
- }
- });
- Assert.equal(Status.login, LOGIN_FAILED_LOGIN_REJECTED, "login was rejected");
-
- // XXX - other interesting responses to return?
-
- // And for good measure, some totally "unexpected" errors - we generally
- // assume these problems are going to magically go away at some point.
- _("Arrange for an empty body with a 200 response - should reflect a network error.");
- yield initializeIdentityWithHAWKResponseFactory(config, function(method, data, uri) {
- Assert.equal(method, "post");
- Assert.equal(uri, "http://mockedserver:9999/certificate/sign")
- return {
- status: 200,
- headers: [],
- body: "",
- }
- });
- Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "login state is LOGIN_FAILED_NETWORK_ERROR");
-});
-
-add_task(function test_getGetKeysFailing401() {
- _("BrowserIDManager correctly handles 401 responses fetching keys.");
-
- _("Arrange for a 401 - Sync should reflect an auth error.");
- let config = makeIdentityConfig();
- // We want no kA or kB so we attempt to fetch them.
- delete config.fxaccount.user.kA;
- delete config.fxaccount.user.kB;
- config.fxaccount.user.keyFetchToken = "keyfetchtoken";
- yield initializeIdentityWithHAWKResponseFactory(config, function(method, data, uri) {
- Assert.equal(method, "get");
- Assert.equal(uri, "http://mockedserver:9999/account/keys")
- return {
- status: 401,
- headers: {"content-type": "application/json"},
- body: "{}",
- }
- });
- Assert.equal(Status.login, LOGIN_FAILED_LOGIN_REJECTED, "login was rejected");
-});
-
-add_task(function test_getGetKeysFailing503() {
- _("BrowserIDManager correctly handles 5XX responses fetching keys.");
-
- _("Arrange for a 503 - Sync should reflect a network error.");
- let config = makeIdentityConfig();
- // We want no kA or kB so we attempt to fetch them.
- delete config.fxaccount.user.kA;
- delete config.fxaccount.user.kB;
- config.fxaccount.user.keyFetchToken = "keyfetchtoken";
- yield initializeIdentityWithHAWKResponseFactory(config, function(method, data, uri) {
- Assert.equal(method, "get");
- Assert.equal(uri, "http://mockedserver:9999/account/keys")
- return {
- status: 503,
- headers: {"content-type": "application/json"},
- body: "{}",
- }
- });
- Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR, "state reflects network error");
-});
-
-add_task(function test_getKeysMissing() {
- _("BrowserIDManager correctly handles getKeys succeeding but not returning keys.");
-
- let browseridManager = new BrowserIDManager();
- let identityConfig = makeIdentityConfig();
- // our mock identity config already has kA and kB - remove them or we never
- // try and fetch them.
- delete identityConfig.fxaccount.user.kA;
- delete identityConfig.fxaccount.user.kB;
- identityConfig.fxaccount.user.keyFetchToken = 'keyFetchToken';
-
- configureFxAccountIdentity(browseridManager, identityConfig);
-
- // Mock a fxAccounts object that returns no keys
- let fxa = new FxAccounts({
- fetchAndUnwrapKeys: function () {
- return Promise.resolve({});
- },
- fxAccountsClient: new MockFxAccountsClient()
- });
-
- // Add a mock to the currentAccountState object.
- fxa.internal.currentAccountState.getCertificate = function(data, keyPair, mustBeValidUntil) {
- this.cert = {
- validUntil: fxa.internal.now() + CERT_LIFETIME,
- cert: "certificate",
- };
- return Promise.resolve(this.cert.cert);
- };
-
- // Ensure the new FxAccounts mock has a signed-in user.
- fxa.internal.currentAccountState.signedInUser = browseridManager._fxaService.internal.currentAccountState.signedInUser;
-
- browseridManager._fxaService = fxa;
-
- yield browseridManager.initializeWithCurrentIdentity();
-
- let ex;
- try {
- yield browseridManager.whenReadyToAuthenticate.promise;
- } catch (e) {
- ex = e;
- }
-
- Assert.ok(ex.message.indexOf("missing kA or kB") >= 0);
-});
-
-// End of tests
-// Utility functions follow
-
-// Create a new browserid_identity object and initialize it with a
-// hawk mock that simulates HTTP responses.
-// The callback function will be called each time the mocked hawk server wants
-// to make a request. The result of the callback should be the mock response
-// object that will be returned to hawk.
-// A token server mock will be used that doesn't hit a server, so we move
-// directly to a hawk request.
-function* initializeIdentityWithHAWKResponseFactory(config, cbGetResponse) {
- // A mock request object.
- function MockRESTRequest(uri, credentials, extra) {
- this._uri = uri;
- this._credentials = credentials;
- this._extra = extra;
- };
- MockRESTRequest.prototype = {
- setHeader: function() {},
- post: function(data, callback) {
- this.response = cbGetResponse("post", data, this._uri, this._credentials, this._extra);
- callback.call(this);
- },
- get: function(callback) {
- this.response = cbGetResponse("get", null, this._uri, this._credentials, this._extra);
- callback.call(this);
- }
- }
-
- // The hawk client.
- function MockedHawkClient() {}
- MockedHawkClient.prototype = new HawkClient("http://mockedserver:9999");
- MockedHawkClient.prototype.constructor = MockedHawkClient;
- MockedHawkClient.prototype.newHAWKAuthenticatedRESTRequest = function(uri, credentials, extra) {
- return new MockRESTRequest(uri, credentials, extra);
- }
- // Arrange for the same observerPrefix as FxAccountsClient uses
- MockedHawkClient.prototype.observerPrefix = "FxA:hawk";
-
- // tie it all together - configureFxAccountIdentity isn't useful here :(
- let fxaClient = new MockFxAccountsClient();
- fxaClient.hawk = new MockedHawkClient();
- let internal = {
- fxAccountsClient: fxaClient,
- }
- let fxa = new FxAccounts(internal);
- fxa.internal.currentAccountState.signedInUser = {
- accountData: config.fxaccount.user,
- };
-
- browseridManager._fxaService = fxa;
- browseridManager._signedInUser = null;
- yield browseridManager.initializeWithCurrentIdentity();
- yield Assert.rejects(browseridManager.whenReadyToAuthenticate.promise,
- "expecting rejection due to hawk error");
-}
-
-
-function getTimestamp(hawkAuthHeader) {
- return parseInt(/ts="(\d+)"/.exec(hawkAuthHeader)[1], 10) * SECOND_MS;
-}
-
-function getTimestampDelta(hawkAuthHeader, now=Date.now()) {
- return Math.abs(getTimestamp(hawkAuthHeader) - now);
-}
-
diff --git a/services/sync/tests/unit/test_errorhandler.js b/services/sync/tests/unit/test_errorhandler.js
index c087acc9f..25d79002c 100644
--- a/services/sync/tests/unit/test_errorhandler.js
+++ b/services/sync/tests/unit/test_errorhandler.js
@@ -486,8 +486,6 @@ add_identity_test(this, function test_shouldReportLoginFailureWithNoCluster() {
do_check_false(errorHandler.shouldReportError());
});
-// XXX - how to arrange for 'Service.identity.basicPassword = null;' in
-// an fxaccounts environment?
add_task(function test_login_syncAndReportErrors_non_network_error() {
// Test non-network errors are reported
// when calling syncAndReportErrors
@@ -536,8 +534,6 @@ add_identity_test(this, function test_sync_syncAndReportErrors_non_network_error
yield deferred.promise;
});
-// XXX - how to arrange for 'Service.identity.basicPassword = null;' in
-// an fxaccounts environment?
add_task(function test_login_syncAndReportErrors_prolonged_non_network_error() {
// Test prolonged, non-network errors are
// reported when calling syncAndReportErrors.
diff --git a/services/sync/tests/unit/test_fxa_node_reassignment.js b/services/sync/tests/unit/test_fxa_node_reassignment.js
deleted file mode 100644
index 2f61afd6f..000000000
--- a/services/sync/tests/unit/test_fxa_node_reassignment.js
+++ /dev/null
@@ -1,321 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-_("Test that node reassignment happens correctly using the FxA identity mgr.");
-// The node-reassignment logic is quite different for FxA than for the legacy
-// provider. In particular, there's no special request necessary for
-// reassignment - it comes from the token server - so we need to ensure the
-// Fxa cluster manager grabs a new token.
-
-Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://services-common/rest.js");
-Cu.import("resource://services-sync/constants.js");
-Cu.import("resource://services-sync/service.js");
-Cu.import("resource://services-sync/status.js");
-Cu.import("resource://services-sync/util.js");
-Cu.import("resource://testing-common/services/sync/rotaryengine.js");
-Cu.import("resource://services-sync/browserid_identity.js");
-Cu.import("resource://testing-common/services/sync/utils.js");
-
-Service.engineManager.clear();
-
-function run_test() {
- Log.repository.getLogger("Sync.AsyncResource").level = Log.Level.Trace;
- Log.repository.getLogger("Sync.ErrorHandler").level = Log.Level.Trace;
- Log.repository.getLogger("Sync.Resource").level = Log.Level.Trace;
- Log.repository.getLogger("Sync.RESTRequest").level = Log.Level.Trace;
- Log.repository.getLogger("Sync.Service").level = Log.Level.Trace;
- Log.repository.getLogger("Sync.SyncScheduler").level = Log.Level.Trace;
- initTestLogging();
-
- Service.engineManager.register(RotaryEngine);
-
- // Setup the FxA identity manager and cluster manager.
- Status.__authManager = Service.identity = new BrowserIDManager();
- Service._clusterManager = Service.identity.createClusterManager(Service);
-
- // None of the failures in this file should result in a UI error.
- function onUIError() {
- do_throw("Errors should not be presented in the UI.");
- }
- Svc.Obs.add("weave:ui:login:error", onUIError);
- Svc.Obs.add("weave:ui:sync:error", onUIError);
-
- run_next_test();
-}
-
-
-// API-compatible with SyncServer handler. Bind `handler` to something to use
-// as a ServerCollection handler.
-function handleReassign(handler, req, resp) {
- resp.setStatusLine(req.httpVersion, 401, "Node reassignment");
- resp.setHeader("Content-Type", "application/json");
- let reassignBody = JSON.stringify({error: "401inator in place"});
- resp.bodyOutputStream.write(reassignBody, reassignBody.length);
-}
-
-let numTokenRequests = 0;
-
-function prepareServer(cbAfterTokenFetch) {
- let config = makeIdentityConfig({username: "johndoe"});
- let server = new SyncServer();
- server.registerUser("johndoe");
- server.start();
-
- // Set the token endpoint for the initial token request that's done implicitly
- // via configureIdentity.
- config.fxaccount.token.endpoint = server.baseURI + "1.1/johndoe";
- // And future token fetches will do magic around numReassigns.
- let numReassigns = 0;
- return configureIdentity(config).then(() => {
- Service.identity._tokenServerClient = {
- getTokenFromBrowserIDAssertion: function(uri, assertion, cb) {
- // Build a new URL with trailing zeros for the SYNC_VERSION part - this
- // will still be seen as equivalent by the test server, but different
- // by sync itself.
- numReassigns += 1;
- let trailingZeros = new Array(numReassigns + 1).join('0');
- let token = config.fxaccount.token;
- token.endpoint = server.baseURI + "1.1" + trailingZeros + "/johndoe";
- token.uid = config.username;
- numTokenRequests += 1;
- cb(null, token);
- if (cbAfterTokenFetch) {
- cbAfterTokenFetch();
- }
- },
- };
- Service.clusterURL = config.fxaccount.token.endpoint;
- return server;
- });
-}
-
-function getReassigned() {
- try {
- return Services.prefs.getBoolPref("services.sync.lastSyncReassigned");
- } catch (ex if (ex.result == Cr.NS_ERROR_UNEXPECTED)) {
- return false;
- } catch (ex) {
- do_throw("Got exception retrieving lastSyncReassigned: " +
- Utils.exceptionStr(ex));
- }
-}
-
-/**
- * Make a test request to `url`, then watch the result of two syncs
- * to ensure that a node request was made.
- * Runs `between` between the two. This can be used to undo deliberate failure
- * setup, detach observers, etc.
- */
-function syncAndExpectNodeReassignment(server, firstNotification, between,
- secondNotification, url) {
- _("Starting syncAndExpectNodeReassignment\n");
- let deferred = Promise.defer();
- function onwards() {
- let numTokenRequestsBefore;
- function onFirstSync() {
- _("First sync completed.");
- Svc.Obs.remove(firstNotification, onFirstSync);
- Svc.Obs.add(secondNotification, onSecondSync);
-
- do_check_eq(Service.clusterURL, "");
-
- // Track whether we fetched a new token.
- numTokenRequestsBefore = numTokenRequests;
-
- // Allow for tests to clean up error conditions.
- between();
- }
- function onSecondSync() {
- _("Second sync completed.");
- Svc.Obs.remove(secondNotification, onSecondSync);
- Service.scheduler.clearSyncTriggers();
-
- // Make absolutely sure that any event listeners are done with their work
- // before we proceed.
- waitForZeroTimer(function () {
- _("Second sync nextTick.");
- do_check_eq(numTokenRequests, numTokenRequestsBefore + 1, "fetched a new token");
- Service.startOver();
- server.stop(deferred.resolve);
- });
- }
-
- Svc.Obs.add(firstNotification, onFirstSync);
- Service.sync();
- }
-
- // Make sure that it works!
- _("Making request to " + url + " which should 401");
- let request = new RESTRequest(url);
- request.get(function () {
- do_check_eq(request.response.status, 401);
- Utils.nextTick(onwards);
- });
- yield deferred.promise;
-}
-
-add_task(function test_momentary_401_engine() {
- _("Test a failure for engine URLs that's resolved by reassignment.");
- let server = yield prepareServer();
- let john = server.user("johndoe");
-
- _("Enabling the Rotary engine.");
- let engine = Service.engineManager.get("rotary");
- engine.enabled = true;
-
- // We need the server to be correctly set up prior to experimenting. Do this
- // through a sync.
- let global = {syncID: Service.syncID,
- storageVersion: STORAGE_VERSION,
- rotary: {version: engine.version,
- syncID: engine.syncID}}
- john.createCollection("meta").insert("global", global);
-
- _("First sync to prepare server contents.");
- Service.sync();
-
- _("Setting up Rotary collection to 401.");
- let rotary = john.createCollection("rotary");
- let oldHandler = rotary.collectionHandler;
- rotary.collectionHandler = handleReassign.bind(this, undefined);
-
- // We want to verify that the clusterURL pref has been cleared after a 401
- // inside a sync. Flag the Rotary engine to need syncing.
- john.collection("rotary").timestamp += 1000;
-
- function between() {
- _("Undoing test changes.");
- rotary.collectionHandler = oldHandler;
-
- function onLoginStart() {
- // lastSyncReassigned shouldn't be cleared until a sync has succeeded.
- _("Ensuring that lastSyncReassigned is still set at next sync start.");
- Svc.Obs.remove("weave:service:login:start", onLoginStart);
- do_check_true(getReassigned());
- }
-
- _("Adding observer that lastSyncReassigned is still set on login.");
- Svc.Obs.add("weave:service:login:start", onLoginStart);
- }
-
- yield syncAndExpectNodeReassignment(server,
- "weave:service:sync:finish",
- between,
- "weave:service:sync:finish",
- Service.storageURL + "rotary");
-});
-
-// This test ends up being a failing info fetch *after we're already logged in*.
-add_task(function test_momentary_401_info_collections_loggedin() {
- _("Test a failure for info/collections after login that's resolved by reassignment.");
- let server = yield prepareServer();
-
- _("First sync to prepare server contents.");
- Service.sync();
-
- _("Arrange for info/collections to return a 401.");
- let oldHandler = server.toplevelHandlers.info;
- server.toplevelHandlers.info = handleReassign;
-
- function undo() {
- _("Undoing test changes.");
- server.toplevelHandlers.info = oldHandler;
- }
-
- do_check_true(Service.isLoggedIn, "already logged in");
-
- yield syncAndExpectNodeReassignment(server,
- "weave:service:sync:error",
- undo,
- "weave:service:sync:finish",
- Service.infoURL);
-});
-
-// This test ends up being a failing info fetch *before we're logged in*.
-// In this case we expect to recover during the login phase - so the first
-// sync succeeds.
-add_task(function test_momentary_401_info_collections_loggedout() {
- _("Test a failure for info/collections before login that's resolved by reassignment.");
-
- let oldHandler;
- let sawTokenFetch = false;
-
- function afterTokenFetch() {
- // After a single token fetch, we undo our evil handleReassign hack, so
- // the next /info request returns the collection instead of a 401
- server.toplevelHandlers.info = oldHandler;
- sawTokenFetch = true;
- }
-
- let server = yield prepareServer(afterTokenFetch);
-
- // Return a 401 for the next /info request - it will be reset immediately
- // after a new token is fetched.
- oldHandler = server.toplevelHandlers.info
- server.toplevelHandlers.info = handleReassign;
-
- do_check_false(Service.isLoggedIn, "not already logged in");
-
- Service.sync();
- do_check_eq(Status.sync, SYNC_SUCCEEDED, "sync succeeded");
- // sync was successful - check we grabbed a new token.
- do_check_true(sawTokenFetch, "a new token was fetched by this test.")
- // and we are done.
- Service.startOver();
- let deferred = Promise.defer();
- server.stop(deferred.resolve);
- yield deferred.promise;
-});
-
-// This test ends up being a failing meta/global fetch *after we're already logged in*.
-add_task(function test_momentary_401_storage_loggedin() {
- _("Test a failure for any storage URL after login that's resolved by" +
- "reassignment.");
- let server = yield prepareServer();
-
- _("First sync to prepare server contents.");
- Service.sync();
-
- _("Arrange for meta/global to return a 401.");
- let oldHandler = server.toplevelHandlers.storage;
- server.toplevelHandlers.storage = handleReassign;
-
- function undo() {
- _("Undoing test changes.");
- server.toplevelHandlers.storage = oldHandler;
- }
-
- do_check_true(Service.isLoggedIn, "already logged in");
-
- yield syncAndExpectNodeReassignment(server,
- "weave:service:sync:error",
- undo,
- "weave:service:sync:finish",
- Service.storageURL + "meta/global");
-});
-
-// This test ends up being a failing meta/global fetch *before we've logged in*.
-add_task(function test_momentary_401_storage_loggedout() {
- _("Test a failure for any storage URL before login, not just engine parts. " +
- "Resolved by reassignment.");
- let server = yield prepareServer();
-
- // Return a 401 for all storage requests.
- let oldHandler = server.toplevelHandlers.storage;
- server.toplevelHandlers.storage = handleReassign;
-
- function undo() {
- _("Undoing test changes.");
- server.toplevelHandlers.storage = oldHandler;
- }
-
- do_check_false(Service.isLoggedIn, "already logged in");
-
- yield syncAndExpectNodeReassignment(server,
- "weave:service:login:error",
- undo,
- "weave:service:sync:finish",
- Service.storageURL + "meta/global");
-});
-
diff --git a/services/sync/tests/unit/test_fxa_service_cluster.js b/services/sync/tests/unit/test_fxa_service_cluster.js
deleted file mode 100644
index f6f97184a..000000000
--- a/services/sync/tests/unit/test_fxa_service_cluster.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Cu.import("resource://services-sync/service.js");
-Cu.import("resource://services-sync/util.js");
-Cu.import("resource://testing-common/services/sync/fxa_utils.js");
-Cu.import("resource://testing-common/services/sync/utils.js");
-
-add_task(function test_findCluster() {
- _("Test FxA _findCluster()");
-
- _("_findCluster() throws on 500 errors.");
- initializeIdentityWithTokenServerResponse({
- status: 500,
- headers: [],
- body: "",
- });
-
- yield Service.identity.initializeWithCurrentIdentity();
- yield Assert.rejects(Service.identity.whenReadyToAuthenticate.promise,
- "should reject due to 500");
-
- Assert.throws(function() {
- Service._clusterManager._findCluster();
- });
-
- _("_findCluster() returns null on authentication errors.");
- initializeIdentityWithTokenServerResponse({
- status: 401,
- headers: {"content-type": "application/json"},
- body: "{}",
- });
-
- yield Service.identity.initializeWithCurrentIdentity();
- yield Assert.rejects(Service.identity.whenReadyToAuthenticate.promise,
- "should reject due to 401");
-
- cluster = Service._clusterManager._findCluster();
- Assert.strictEqual(cluster, null);
-
- _("_findCluster() works with correct tokenserver response.");
- let endpoint = "http://example.com/something";
- initializeIdentityWithTokenServerResponse({
- status: 200,
- headers: {"content-type": "application/json"},
- body:
- JSON.stringify({
- api_endpoint: endpoint,
- duration: 300,
- id: "id",
- key: "key",
- uid: "uid",
- })
- });
-
- yield Service.identity.initializeWithCurrentIdentity();
- yield Service.identity.whenReadyToAuthenticate.promise;
- cluster = Service._clusterManager._findCluster();
- // The cluster manager ensures a trailing "/"
- Assert.strictEqual(cluster, endpoint + "/");
-
- Svc.Prefs.resetBranch("");
-});
-
-function run_test() {
- initTestLogging();
- run_next_test();
-}
diff --git a/services/sync/tests/unit/test_fxa_startOver.js b/services/sync/tests/unit/test_fxa_startOver.js
deleted file mode 100644
index e27d86ea0..000000000
--- a/services/sync/tests/unit/test_fxa_startOver.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Cu.import("resource://testing-common/services/sync/utils.js");
-Cu.import("resource://services-sync/identity.js");
-Cu.import("resource://services-sync/browserid_identity.js");
-Cu.import("resource://services-sync/service.js");
-
-function run_test() {
- initTestLogging("Trace");
- run_next_test();
-}
-
-add_task(function* test_startover() {
- let oldValue = Services.prefs.getBoolPref("services.sync-testing.startOverKeepIdentity", true);
- Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", false);
-
- ensureLegacyIdentityManager();
- yield configureIdentity({username: "johndoe"});
-
- // The boolean flag on the xpcom service should reflect a legacy provider.
- let xps = Cc["@mozilla.org/weave/service;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
- do_check_false(xps.fxAccountsEnabled);
-
- // we expect the "legacy" provider (but can't instanceof that, as BrowserIDManager
- // extends it)
- do_check_false(Service.identity instanceof BrowserIDManager);
-
- Service.serverURL = "https://localhost/";
- Service.clusterURL = Service.serverURL;
-
- Service.login();
- // We should have a cluster URL
- do_check_true(Service.clusterURL.length > 0);
-
- // remember some stuff so we can reset it after.
- let oldIdentity = Service.identity;
- let oldClusterManager = Service._clusterManager;
- let deferred = Promise.defer();
- Services.obs.addObserver(function observeStartOverFinished() {
- Services.obs.removeObserver(observeStartOverFinished, "weave:service:start-over:finish");
- deferred.resolve();
- }, "weave:service:start-over:finish", false);
-
- Service.startOver();
- yield deferred.promise; // wait for the observer to fire.
-
- // the xpcom service should indicate FxA is enabled.
- do_check_true(xps.fxAccountsEnabled);
- // should have swapped identities.
- do_check_true(Service.identity instanceof BrowserIDManager);
- // should have clobbered the cluster URL
- do_check_eq(Service.clusterURL, "");
-
- // we should have thrown away the old identity provider and cluster manager.
- do_check_neq(oldIdentity, Service.identity);
- do_check_neq(oldClusterManager, Service._clusterManager);
-
- // reset the world.
- Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", oldValue);
-});
diff --git a/services/sync/tests/unit/test_load_modules.js b/services/sync/tests/unit/test_load_modules.js
index 4f561bae6..8e3fcf1f3 100644
--- a/services/sync/tests/unit/test_load_modules.js
+++ b/services/sync/tests/unit/test_load_modules.js
@@ -37,7 +37,6 @@ const testingModules = [
"fakeservices.js",
"rotaryengine.js",
"utils.js",
- "fxa_utils.js",
];
function run_test() {
diff --git a/services/sync/tests/unit/xpcshell.ini b/services/sync/tests/unit/xpcshell.ini
index 7e97835ac..2f9884751 100644
--- a/services/sync/tests/unit/xpcshell.ini
+++ b/services/sync/tests/unit/xpcshell.ini
@@ -50,7 +50,6 @@ skip-if = os == "win" || os == "android"
[test_syncstoragerequest.js]
# Generic Sync types.
-[test_browserid_identity.js]
[test_collection_inc_get.js]
[test_collections_recovery.js]
[test_identity_manager.js]
@@ -122,11 +121,6 @@ skip-if = os == "android"
[test_syncscheduler.js]
[test_upgrade_old_sync_key.js]
-# Firefox Accounts specific tests
-[test_fxa_startOver.js]
-[test_fxa_service_cluster.js]
-[test_fxa_node_reassignment.js]
-
# Finally, we test each engine.
[test_addons_engine.js]
run-sequentially = Hardcoded port in static files.