Bug 949526 - FxAccountsManager and B2G implementation. Part 4: Tests. r=markh
authorFernando Jiménez <ferjmoreno@gmail.com>
Fri, 13 Dec 2013 12:25:27 +0100
changeset 160324 da3dcd40f826241e1244323c4504aa7be90bb969
parent 160323 be0847f85ca9679d0a15769b1f8c8e631ffdfedb
child 160325 b3d70eda988d109045abba665677f1e279112841
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmarkh
bugs949526
milestone29.0a1
Bug 949526 - FxAccountsManager and B2G implementation. Part 4: Tests. r=markh
services/fxaccounts/tests/xpcshell/test_manager.js
services/fxaccounts/tests/xpcshell/xpcshell.ini
new file mode 100644
--- /dev/null
+++ b/services/fxaccounts/tests/xpcshell/test_manager.js
@@ -0,0 +1,583 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const Cm = Components.manager;
+
+Cu.import("resource://gre/modules/FxAccounts.jsm");
+Cu.import("resource://gre/modules/FxAccountsConsts.js");
+Cu.import("resource://gre/modules/FxAccountsManager.jsm");
+Cu.import("resource://gre/modules/Promise.jsm");
+
+// === Mocks ===
+
+// Override FxAccountsUIGlue.
+const kFxAccountsUIGlueUUID = "{8f6d5d87-41ed-4bb5-aa28-625de57564c5}";
+const kFxAccountsUIGlueContractID =
+  "@mozilla.org/fxaccounts/fxaccounts-ui-glue;1";
+
+// Save original FxAccountsUIGlue factory.
+const kFxAccountsUIGlueFactory =
+  Cm.getClassObject(Cc[kFxAccountsUIGlueContractID], Ci.nsIFactory);
+
+let fakeFxAccountsUIGlueFactory = {
+  createInstance: function(aOuter, aIid) {
+    return FxAccountsUIGlue.QueryInterface(aIid);
+  }
+};
+
+// FxAccountsUIGlue fake component.
+let FxAccountsUIGlue = {
+  _reject: false,
+
+  _error: 'error',
+
+  _signInFlowCalled: false,
+
+  _reset: function() {
+    this._reject = false;
+    this._error = 'error';
+    this._signInFlowCalled = false;
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFxAccountsUIGlue]),
+
+  getUserPermission: function() {},
+
+  signInFlow: function() {
+    this._signInFlowCalled = true;
+    let deferred = Promise.defer();
+
+    if (this._reject) {
+      deferred.reject(this._error);
+    } else {
+      FxAccountsManager._activeSession = {
+        email: "user@domain.org",
+        verified: false,
+        sessionToken: "1234"
+      };
+      FxAccountsManager._fxAccounts
+                       .setSignedInUser(FxAccountsManager._activeSession);
+      deferred.resolve();
+    }
+
+    return deferred.promise;
+  }
+};
+
+(function registerFakeFxAccountsUIGlue() {
+  Cm.QueryInterface(Ci.nsIComponentRegistrar)
+    .registerFactory(Components.ID(kFxAccountsUIGlueUUID),
+                     "FxAccountsUIGlue",
+                     kFxAccountsUIGlueContractID,
+                     fakeFxAccountsUIGlueFactory);
+})();
+
+// Save original fxAccounts instance
+const kFxAccounts = fxAccounts;
+// and change it for a mock FxAccounts.
+FxAccountsManager._fxAccounts = {
+  _reject: false,
+  _getSignedInUserCalled: false,
+  _setSignedInUserCalled: false,
+
+  _error: 'error',
+  _assertion: 'assertion',
+  _signedInUser: null,
+
+  _reset: function() {
+    this._getSignedInUserCalled = false;
+    this._setSignedInUserCalled = false;
+    this._reject = false;
+  },
+
+  getAssertion: function() {
+    if (!this._signedInUser) {
+      return null;
+    }
+
+    let deferred = Promise.defer();
+    deferred.resolve(this._assertion);
+    return deferred.promise;
+  },
+
+  getSignedInUser: function() {
+    this._getSignedInUserCalled = true;
+    let deferred = Promise.defer();
+    this._reject ? deferred.reject(this._error)
+                 : deferred.resolve(this._signedInUser);
+    return deferred.promise;
+  },
+
+  setSignedInUser: function(user) {
+    this._setSignedInUserCalled = true;
+    let deferred = Promise.defer();
+    this._signedInUser = user;
+    deferred.resolve();
+    return deferred.promise;
+  },
+
+  signOut: function() {
+    let deferred = Promise.defer();
+    this._signedInUser = null;
+    deferred.resolve();
+    return deferred.promise;
+  }
+};
+
+// Save original FxAccountsClient factory from FxAccountsManager.
+const kFxAccountsClient = FxAccountsManager._createFxAccountsClient;
+// and change it for a fake client factory.
+let FakeFxAccountsClient = {
+  _reject: false,
+  _recoveryEmailStatusCalled: false,
+  _signInCalled: false,
+  _signUpCalled: false,
+  _signOutCalled: false,
+
+  _accountExists: false,
+  _verified: false,
+  _password: null,
+
+  _reset: function() {
+    this._reject = false;
+    this._recoveryEmailStatusCalled = false;
+    this._signInCalled = false;
+    this._signUpCalled = false;
+    this._signOutCalled = false;
+  },
+
+  recoveryEmailStatus: function() {
+    this._recoveryEmailStatusCalled = true;
+    let deferred = Promise.defer();
+    this._reject ? deferred.reject()
+                 : deferred.resolve({ verified: this._verified });
+    return deferred.promise;
+  },
+
+  signIn: function(user, password) {
+    this._signInCalled = true;
+    this._password = password;
+    let deferred = Promise.defer();
+    this._reject ? deferred.reject()
+                 : deferred.resolve({ email: user,
+                                      uid: "whatever",
+                                      verified: this._verified,
+                                      sessionToken: "1234" });
+    return deferred.promise;
+  },
+
+  signUp: function(user, password) {
+    this._signUpCalled = true;
+    return this.signIn(user, password);
+  },
+
+  signOut: function() {
+    this._signOutCalled = true;
+    let deferred = Promise.defer();
+    this._reject ? deferred.reject()
+                 : deferred.resolve();
+    return deferred.promise;
+  },
+
+  accountExists: function() {
+    let deferred = Promise.defer();
+    this._reject ? deferred.reject()
+                 : deferred.resolve(this._accountExists);
+    return deferred.promise;
+  }
+};
+FxAccountsManager._createFxAccountsClient = function() {
+  return FakeFxAccountsClient;
+}
+
+// === Global cleanup ===
+
+// Unregister mocks and restore original code.
+do_register_cleanup(function() {
+  // Unregister the factory so we do not leak
+  Cm.QueryInterface(Ci.nsIComponentRegistrar)
+    .unregisterFactory(Components.ID(kFxAccountsUIGlueUUID),
+                       fakeFxAccountsUIGlueFactory);
+
+  // Restore the original factory.
+  Cm.QueryInterface(Ci.nsIComponentRegistrar)
+    .registerFactory(Components.ID(kFxAccountsUIGlueUUID),
+                     "FxAccountsUIGlue",
+                     kFxAccountsUIGlueContractID,
+                     kFxAccountsUIGlueFactory);
+
+  // Restore the original FxAccounts instance from FxAccountsManager.
+  FxAccountsManager._fxAccounts = kFxAccounts;
+
+  // Restore the FxAccountsClient getter from FxAccountsManager.
+  FxAccountsManager._createFxAccountsClient = kFxAccountsClient;
+});
+
+
+// === Tests ===
+
+function run_test() {
+  run_next_test();
+}
+
+add_test(function test_initial_state() {
+  do_print("= Test 0 | Initial state =");
+  do_check_neq(FxAccountsManager, undefined);
+  do_check_null(FxAccountsManager._activeSession);
+  do_check_null(FxAccountsManager._user);
+  run_next_test();
+});
+
+add_test(function(test_getAccount_no_session) {
+  do_print("= Test 1 | getAccount no session =");
+  FxAccountsManager.getAccount().then(
+    result => {
+      do_check_null(result);
+      do_check_null(FxAccountsManager._activeSession);
+      do_check_null(FxAccountsManager._user);
+      do_check_true(FxAccountsManager._fxAccounts._getSignedInUserCalled);
+      FxAccountsManager._fxAccounts._reset();
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_getAssertion_no_audience) {
+  do_print("= Test 2 | getAssertion no audience =");
+  FxAccountsManager.getAssertion().then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_INVALID_AUDIENCE);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_getAssertion_no_session_ui_error) {
+  do_print("= Test 3 | getAssertion no session, UI error =");
+  FxAccountsUIGlue._reject = true;
+  FxAccountsManager.getAssertion("audience").then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_UI_ERROR);
+      do_check_eq(error.details, "error");
+      FxAccountsUIGlue._reset();
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_getAssertion_no_session_ui_success) {
+  do_print("= Test 4 | getAssertion no session, UI success =");
+  FxAccountsManager.getAssertion("audience").then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_true(FxAccountsUIGlue._signInFlowCalled);
+      do_check_eq(error.error, ERROR_UNVERIFIED_ACCOUNT);
+      FxAccountsUIGlue._reset();
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_getAssertion_active_session_unverified_account) {
+  do_print("= Test 5 | getAssertion active session, unverified account =");
+  FxAccountsManager.getAssertion("audience").then(
+    result => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_false(FxAccountsUIGlue._signInFlowCalled);
+      do_check_eq(error.error, ERROR_UNVERIFIED_ACCOUNT);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_getAssertion_active_session_verified_account) {
+  do_print("= Test 6 | getAssertion active session, verified account =");
+  FxAccountsManager._fxAccounts._signedInUser.verified = true;
+  FxAccountsManager._activeSession.verified = true;
+  FxAccountsManager.getAssertion("audience").then(
+    result => {
+      do_check_false(FxAccountsUIGlue._signInFlowCalled);
+      do_check_eq(result, "assertion");
+      FxAccountsManager._fxAccounts._reset();
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_getAccount_existing_verified_session) {
+  do_print("= Test 7 | getAccount, existing verified session =");
+  FxAccountsManager.getAccount().then(
+    result => {
+      do_check_false(FxAccountsManager._fxAccounts._getSignedInUserCalled);
+      do_check_eq(result.accountId, FxAccountsManager._user.accountId);
+      do_check_eq(result.verified, FxAccountsManager._user.verified);
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_getAccount_existing_unverified_session_unverified_user) {
+  do_print("= Test 8 | getAccount, existing unverified session, unverified user =");
+  FxAccountsManager._activeSession.verified = false;
+  FxAccountsManager._fxAccounts._signedInUser.verified = false;
+  FxAccountsManager.getAccount().then(
+    result => {
+      do_check_true(FakeFxAccountsClient._recoveryEmailStatusCalled);
+      do_check_false(result.verified);
+      do_check_eq(result.accountId, FxAccountsManager._user.accountId);
+      FakeFxAccountsClient._reset();
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_getAccount_existing_unverified_session_verified_user) {
+  do_print("= Test 8 | getAccount, existing unverified session, verified user =");
+  FxAccountsManager._activeSession.verified = false;
+  FxAccountsManager._fxAccounts._signedInUser.verified = false;
+  FakeFxAccountsClient._verified = true;
+  FxAccountsManager.getAccount().then(
+    result => {
+      do_check_true(FakeFxAccountsClient._recoveryEmailStatusCalled);
+      do_check_true(result.verified);
+      do_check_eq(result.accountId, FxAccountsManager._user.accountId);
+      FakeFxAccountsClient._reset();
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_signOut) {
+  do_print("= Test 9 | signOut =");
+  do_check_true(FxAccountsManager._activeSession != null);
+  FxAccountsManager.signOut().then(
+    result => {
+      do_check_null(result);
+      do_check_null(FxAccountsManager._activeSession);
+      do_check_true(FakeFxAccountsClient._signOutCalled);
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_verificationStatus_no_token_session) {
+  do_print("= Test 10 | verificationStatus, no token session =");
+  do_check_null(FxAccountsManager._activeSession);
+  FxAccountsManager.verificationStatus().then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_NO_TOKEN_SESSION);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_signUp_no_accountId) {
+  do_print("= Test 11 | signUp, no accountId=");
+  FxAccountsManager.signUp().then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_INVALID_ACCOUNTID);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_signIn_no_accountId) {
+  do_print("= Test 12 | signIn, no accountId=");
+  FxAccountsManager.signIn().then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_INVALID_ACCOUNTID);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_signUp_no_password) {
+  do_print("= Test 13 | signUp, no accountId=");
+  FxAccountsManager.signUp("user@domain.org").then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_INVALID_PASSWORD);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_signIn_no_accountId) {
+  do_print("= Test 14 | signIn, no accountId=");
+  FxAccountsManager.signIn("user@domain.org").then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_INVALID_PASSWORD);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_signUp) {
+  do_print("= Test 15 | signUp =");
+  FakeFxAccountsClient._verified = false;
+  FxAccountsManager.signUp("user@domain.org", "password").then(
+    result => {
+      do_check_true(FakeFxAccountsClient._signInCalled);
+      do_check_true(FakeFxAccountsClient._signUpCalled);
+      do_check_true(FxAccountsManager._fxAccounts._getSignedInUserCalled);
+      do_check_eq(FxAccountsManager._fxAccounts._signedInUser.email, "user@domain.org");
+      do_check_eq(FakeFxAccountsClient._password, "password");
+      do_check_true(result.accountCreated);
+      do_check_eq(result.user.accountId, "user@domain.org");
+      do_check_false(result.user.verified);
+      FakeFxAccountsClient._reset();
+      FxAccountsManager._fxAccounts._reset();
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error.error);
+    }
+  );
+});
+
+add_test(function(test_signUp_already_signed_user) {
+  do_print("= Test 16 | signUp, already signed user =");
+  FxAccountsManager.signUp("user@domain.org", "password").then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_false(FakeFxAccountsClient._signInCalled);
+      do_check_eq(error.error, ERROR_ALREADY_SIGNED_IN_USER);
+      do_check_eq(error.details.user.accountId, "user@domain.org");
+      do_check_false(error.details.user.verified);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_signIn_already_signed_user) {
+  do_print("= Test 17 | signIn, already signed user =");
+  FxAccountsManager.signIn("user@domain.org", "password").then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_ALREADY_SIGNED_IN_USER);
+      do_check_eq(error.details.user.accountId, "user@domain.org");
+      do_check_false(error.details.user.verified);
+      run_next_test();
+    }
+  );
+});
+
+add_test(function(test_verificationStatus_unverified_session_unverified_user) {
+  do_print("= Test 18 | verificationStatus unverified session and user =");
+  FakeFxAccountsClient._verified = false;
+  FxAccountsManager.verificationStatus().then(
+    user => {
+      do_check_false(user.verified);
+      do_check_true(FakeFxAccountsClient._recoveryEmailStatusCalled);
+      do_check_false(FxAccountsManager._fxAccounts._setSignedInUserCalled);
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_verificationStatus_unverified_session_verified_user) {
+  do_print("= Test 19 | verificationStatus unverified session, verified user =");
+  FakeFxAccountsClient._verified = true;
+  FxAccountsManager.verificationStatus().then(
+    user => {
+      do_check_true(user.verified);
+      do_check_true(FakeFxAccountsClient._recoveryEmailStatusCalled);
+      do_check_true(FxAccountsManager._fxAccounts._setSignedInUserCalled);
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_queryAccount_no_exists) {
+  do_print("= Test 20 | queryAccount, no exists =");
+  FxAccountsManager.queryAccount("user@domain.org").then(
+    result => {
+      do_check_false(result.registered);
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_queryAccount_exists) {
+  do_print("= Test 21 | queryAccount, exists =");
+  FakeFxAccountsClient._accountExists = true;
+  FxAccountsManager.queryAccount("user@domain.org").then(
+    result => {
+      do_check_true(result.registered);
+      run_next_test();
+    },
+    error => {
+      do_throw("Unexpected error: " + error);
+    }
+  );
+});
+
+add_test(function(test_queryAccount_no_accountId) {
+  do_print("= Test 22 | queryAccount, no accountId =");
+  FxAccountsManager.queryAccount().then(
+    () => {
+      do_throw("Unexpected success");
+    },
+    error => {
+      do_check_eq(error.error, ERROR_INVALID_ACCOUNTID);
+      run_next_test();
+    }
+  );
+});
--- a/services/fxaccounts/tests/xpcshell/xpcshell.ini
+++ b/services/fxaccounts/tests/xpcshell/xpcshell.ini
@@ -1,7 +1,9 @@
 [DEFAULT]
 head = head.js ../../../common/tests/unit/head_helpers.js ../../../common/tests/unit/head_http.js
 tail =
 
 [test_accounts.js]
 [test_client.js]
-
+[test_manager.js]
+run-if = appname == 'b2g'
+reason = FxAccountsManager is only available for B2G for now