michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "IDService", michael@0: "resource://gre/modules/identity/Identity.jsm", michael@0: "IdentityService"); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "jwcrypto", michael@0: "resource://gre/modules/identity/jwcrypto.jsm"); michael@0: michael@0: function test_begin_authentication_flow() { michael@0: do_test_pending(); michael@0: let _provId = null; michael@0: michael@0: // set up a watch, to be consistent michael@0: let mockedDoc = mock_doc(null, TEST_URL, function(action, params) {}); michael@0: IDService.RP.watch(mockedDoc); michael@0: michael@0: // The identity-auth notification is sent up to the UX from the michael@0: // _doAuthentication function. Be ready to receive it and call michael@0: // beginAuthentication michael@0: makeObserver("identity-auth", function (aSubject, aTopic, aData) { michael@0: do_check_neq(aSubject, null); michael@0: michael@0: do_check_eq(aSubject.wrappedJSObject.provId, _provId); michael@0: michael@0: do_test_finished(); michael@0: run_next_test(); michael@0: }); michael@0: michael@0: setup_provisioning( michael@0: TEST_USER, michael@0: function(caller) { michael@0: _provId = caller.id; michael@0: IDService.IDP.beginProvisioning(caller); michael@0: }, function() {}, michael@0: { michael@0: beginProvisioningCallback: function(email, duration_s) { michael@0: michael@0: // let's say this user needs to authenticate michael@0: IDService.IDP._doAuthentication(_provId, {idpParams:TEST_IDPPARAMS}); michael@0: } michael@0: } michael@0: ); michael@0: } michael@0: michael@0: function test_complete_authentication_flow() { michael@0: do_test_pending(); michael@0: let _provId = null; michael@0: let _authId = null; michael@0: let id = TEST_USER; michael@0: michael@0: let callbacksFired = false; michael@0: let loginStateChanged = false; michael@0: let identityAuthComplete = false; michael@0: michael@0: // The result of authentication should be a successful login michael@0: IDService.reset(); michael@0: michael@0: setup_test_identity(id, TEST_CERT, function() { michael@0: // set it up so we're supposed to be logged in to TEST_URL michael@0: michael@0: get_idstore().setLoginState(TEST_URL, true, id); michael@0: michael@0: // When we authenticate, our ready callback will be fired. michael@0: // At the same time, a separate topic will be sent up to the michael@0: // the observer in the UI. The test is complete when both michael@0: // events have occurred. michael@0: let mockedDoc = mock_doc(id, TEST_URL, call_sequentially( michael@0: function(action, params) { michael@0: do_check_eq(action, 'ready'); michael@0: do_check_eq(params, undefined); michael@0: michael@0: // if notification already received by observer, test is done michael@0: callbacksFired = true; michael@0: if (loginStateChanged && identityAuthComplete) { michael@0: do_test_finished(); michael@0: run_next_test(); michael@0: } michael@0: } michael@0: )); michael@0: michael@0: makeObserver("identity-auth-complete", function(aSubject, aTopic, aData) { michael@0: identityAuthComplete = true; michael@0: do_test_finished(); michael@0: run_next_test(); michael@0: }); michael@0: michael@0: makeObserver("identity-login-state-changed", function (aSubject, aTopic, aData) { michael@0: do_check_neq(aSubject, null); michael@0: michael@0: do_check_eq(aSubject.wrappedJSObject.rpId, mockedDoc.id); michael@0: do_check_eq(aData, id); michael@0: michael@0: // if callbacks in caller doc already fired, test is done. michael@0: loginStateChanged = true; michael@0: if (callbacksFired && identityAuthComplete) { michael@0: do_test_finished(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: IDService.RP.watch(mockedDoc); michael@0: michael@0: // Create a provisioning flow for our auth flow to attach to michael@0: setup_provisioning( michael@0: TEST_USER, michael@0: function(provFlow) { michael@0: _provId = provFlow.id; michael@0: michael@0: IDService.IDP.beginProvisioning(provFlow); michael@0: }, function() {}, michael@0: { michael@0: beginProvisioningCallback: function(email, duration_s) { michael@0: // let's say this user needs to authenticate michael@0: IDService.IDP._doAuthentication(_provId, {idpParams:TEST_IDPPARAMS}); michael@0: michael@0: // test_begin_authentication_flow verifies that the right michael@0: // message is sent to the UI. So that works. Moving on, michael@0: // the UI calls setAuthenticationFlow ... michael@0: _authId = uuid(); michael@0: IDService.IDP.setAuthenticationFlow(_authId, _provId); michael@0: michael@0: // ... then the UI calls beginAuthentication ... michael@0: authCaller.id = _authId; michael@0: IDService.IDP._provisionFlows[_provId].caller = authCaller; michael@0: IDService.IDP.beginAuthentication(authCaller); michael@0: } michael@0: } michael@0: ); michael@0: }); michael@0: michael@0: // A mock calling context michael@0: let authCaller = { michael@0: doBeginAuthenticationCallback: function doBeginAuthenticationCallback(identity) { michael@0: do_check_eq(identity, TEST_USER); michael@0: // completeAuthentication will emit "identity-auth-complete" michael@0: IDService.IDP.completeAuthentication(_authId); michael@0: }, michael@0: michael@0: doError: function(err) { michael@0: log("OW! My doError callback hurts!", err); michael@0: }, michael@0: }; michael@0: michael@0: } michael@0: michael@0: let TESTS = []; michael@0: michael@0: TESTS.push(test_begin_authentication_flow); michael@0: TESTS.push(test_complete_authentication_flow); michael@0: michael@0: TESTS.forEach(add_test); michael@0: michael@0: function run_test() { michael@0: run_next_test(); michael@0: }