1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/identity/tests/unit/test_firefox_accounts.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,270 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +"use strict"; 1.8 + 1.9 +Cu.import("resource://gre/modules/Promise.jsm"); 1.10 +Cu.import("resource://gre/modules/DOMIdentity.jsm"); 1.11 + 1.12 +XPCOMUtils.defineLazyModuleGetter(this, "FirefoxAccounts", 1.13 + "resource://gre/modules/identity/FirefoxAccounts.jsm"); 1.14 + 1.15 +// Make the profile dir available; this is necessary so that 1.16 +// services/fxaccounts/FxAccounts.jsm can read and write its signed-in user 1.17 +// data. 1.18 +do_get_profile(); 1.19 + 1.20 +function MockFXAManager() { 1.21 + this.signedInUser = true; 1.22 +} 1.23 +MockFXAManager.prototype = { 1.24 + getAssertion: function(audience) { 1.25 + let result = this.signedInUser ? TEST_ASSERTION : null; 1.26 + return Promise.resolve(result); 1.27 + }, 1.28 + 1.29 + signOut: function() { 1.30 + this.signedInUser = false; 1.31 + return Promise.resolve(null); 1.32 + }, 1.33 + 1.34 + signIn: function(user) { 1.35 + this.signedInUser = user; 1.36 + return Promise.resolve(user); 1.37 + }, 1.38 +} 1.39 + 1.40 +let originalManager = FirefoxAccounts.fxAccountsManager; 1.41 +FirefoxAccounts.fxAccountsManager = new MockFXAManager(); 1.42 +do_register_cleanup(() => { 1.43 + log("restoring fxaccountsmanager"); 1.44 + FirefoxAccounts.fxAccountsManager = originalManager; 1.45 +}); 1.46 + 1.47 +function withNobodySignedIn() { 1.48 + return FirefoxAccounts.fxAccountsManager.signOut(); 1.49 +} 1.50 + 1.51 +function withSomebodySignedIn() { 1.52 + return FirefoxAccounts.fxAccountsManager.signIn('Pertelote'); 1.53 +} 1.54 + 1.55 +function test_overall() { 1.56 + do_check_neq(FirefoxAccounts, null); 1.57 + run_next_test(); 1.58 +} 1.59 + 1.60 +function test_mock() { 1.61 + do_test_pending(); 1.62 + 1.63 + withSomebodySignedIn().then(() => { 1.64 + FirefoxAccounts.fxAccountsManager.getAssertion().then(assertion => { 1.65 + do_check_eq(assertion, TEST_ASSERTION); 1.66 + do_test_finished(); 1.67 + run_next_test(); 1.68 + }); 1.69 + }); 1.70 +} 1.71 + 1.72 +function test_watch_signed_in() { 1.73 + do_test_pending(); 1.74 + 1.75 + let received = []; 1.76 + 1.77 + let mockedRP = mock_fxa_rp(null, TEST_URL, function(method, data) { 1.78 + received.push([method, data]); 1.79 + 1.80 + if (method == "ready") { 1.81 + // confirm that we were signed in and then ready was called 1.82 + do_check_eq(received.length, 2); 1.83 + do_check_eq(received[0][0], "login"); 1.84 + do_check_eq(received[0][1], TEST_ASSERTION); 1.85 + do_check_eq(received[1][0], "ready"); 1.86 + do_test_finished(); 1.87 + run_next_test(); 1.88 + } 1.89 + }); 1.90 + 1.91 + withSomebodySignedIn().then(() => { 1.92 + FirefoxAccounts.RP.watch(mockedRP); 1.93 + }); 1.94 +} 1.95 + 1.96 +function test_watch_signed_out() { 1.97 + do_test_pending(); 1.98 + 1.99 + let received = []; 1.100 + 1.101 + let mockedRP = mock_fxa_rp(null, TEST_URL, function(method) { 1.102 + received.push(method); 1.103 + 1.104 + if (method == "ready") { 1.105 + // confirm that we were signed out and then ready was called 1.106 + do_check_eq(received.length, 2); 1.107 + do_check_eq(received[0], "logout"); 1.108 + do_check_eq(received[1], "ready"); 1.109 + 1.110 + do_test_finished(); 1.111 + run_next_test(); 1.112 + } 1.113 + }); 1.114 + 1.115 + withNobodySignedIn().then(() => { 1.116 + FirefoxAccounts.RP.watch(mockedRP); 1.117 + }); 1.118 +} 1.119 + 1.120 +function test_request() { 1.121 + do_test_pending(); 1.122 + 1.123 + let received = []; 1.124 + 1.125 + let mockedRP = mock_fxa_rp(null, TEST_URL, function(method, data) { 1.126 + received.push([method, data]); 1.127 + 1.128 + // On watch(), we are signed out. Then we call request(). 1.129 + if (received.length === 2) { 1.130 + do_check_eq(received[0][0], "logout"); 1.131 + do_check_eq(received[1][0], "ready"); 1.132 + 1.133 + // Pretend request() showed ux and the user signed in 1.134 + withSomebodySignedIn().then(() => { 1.135 + FirefoxAccounts.RP.request(mockedRP.id); 1.136 + }); 1.137 + } 1.138 + 1.139 + if (received.length === 3) { 1.140 + do_check_eq(received[2][0], "login"); 1.141 + do_check_eq(received[2][1], TEST_ASSERTION); 1.142 + 1.143 + do_test_finished(); 1.144 + run_next_test(); 1.145 + } 1.146 + }); 1.147 + 1.148 + // First, call watch() with nobody signed in 1.149 + withNobodySignedIn().then(() => { 1.150 + FirefoxAccounts.RP.watch(mockedRP); 1.151 + }); 1.152 +} 1.153 + 1.154 +function test_logout() { 1.155 + do_test_pending(); 1.156 + 1.157 + let received = []; 1.158 + 1.159 + let mockedRP = mock_fxa_rp(null, TEST_URL, function(method) { 1.160 + received.push(method); 1.161 + 1.162 + // At first, watch() signs us in automatically. Then we sign out. 1.163 + if (received.length === 2) { 1.164 + do_check_eq(received[0], "login"); 1.165 + do_check_eq(received[1], "ready"); 1.166 + 1.167 + FirefoxAccounts.RP.logout(mockedRP.id); 1.168 + } 1.169 + 1.170 + if (received.length === 3) { 1.171 + do_check_eq(received[2], "logout"); 1.172 + do_test_finished(); 1.173 + run_next_test(); 1.174 + } 1.175 + }); 1.176 + 1.177 + // First, call watch() 1.178 + withSomebodySignedIn().then(() => { 1.179 + FirefoxAccounts.RP.watch(mockedRP); 1.180 + }); 1.181 +} 1.182 + 1.183 +function test_error() { 1.184 + do_test_pending(); 1.185 + 1.186 + let received = []; 1.187 + 1.188 + // Mock the fxAccountsManager so that getAssertion rejects its promise and 1.189 + // triggers our onerror handler. (This is the method that's used internally 1.190 + // by FirefoxAccounts.RP.request().) 1.191 + let originalGetAssertion = FirefoxAccounts.fxAccountsManager.getAssertion; 1.192 + FirefoxAccounts.fxAccountsManager.getAssertion = function(audience) { 1.193 + return Promise.reject(new Error("barf!")); 1.194 + }; 1.195 + 1.196 + let mockedRP = mock_fxa_rp(null, TEST_URL, function(method, message) { 1.197 + // We will immediately receive an error, due to watch()'s attempt 1.198 + // to getAssertion(). 1.199 + do_check_eq(method, "error"); 1.200 + do_check_true(/barf/.test(message)); 1.201 + 1.202 + // Put things back the way they were 1.203 + FirefoxAccounts.fxAccountsManager.getAssertion = originalGetAssertion; 1.204 + 1.205 + do_test_finished(); 1.206 + run_next_test(); 1.207 + }); 1.208 + 1.209 + // First, call watch() 1.210 + withSomebodySignedIn().then(() => { 1.211 + FirefoxAccounts.RP.watch(mockedRP); 1.212 + }); 1.213 +} 1.214 + 1.215 +function test_child_process_shutdown() { 1.216 + do_test_pending(); 1.217 + let rpCount = FirefoxAccounts.RP._rpFlows.size; 1.218 + 1.219 + makeObserver("identity-child-process-shutdown", (aTopic, aSubject, aData) => { 1.220 + // Last of all, the shutdown observer message will be fired. 1.221 + // This takes place after the RP has a chance to delete flows 1.222 + // and clean up. 1.223 + do_check_eq(FirefoxAccounts.RP._rpFlows.size, rpCount); 1.224 + do_test_finished(); 1.225 + run_next_test(); 1.226 + }); 1.227 + 1.228 + let mockedRP = mock_fxa_rp(null, TEST_URL, (method) => { 1.229 + // We should enter this function for 'ready' and 'child-process-shutdown'. 1.230 + // After we have a chance to do our thing, the shutdown observer message 1.231 + // will fire and be caught by the function above. 1.232 + do_check_eq(FirefoxAccounts.RP._rpFlows.size, rpCount + 1); 1.233 + switch (method) { 1.234 + case "ready": 1.235 + DOMIdentity._childProcessShutdown("my message manager"); 1.236 + break; 1.237 + 1.238 + case "child-process-shutdown": 1.239 + // We have to call this explicitly because there's no real 1.240 + // dom window here. 1.241 + FirefoxAccounts.RP.childProcessShutdown(mockedRP._mm); 1.242 + break; 1.243 + 1.244 + default: 1.245 + break; 1.246 + } 1.247 + }); 1.248 + 1.249 + mockedRP._mm = "my message manager"; 1.250 + withSomebodySignedIn().then(() => { 1.251 + FirefoxAccounts.RP.watch(mockedRP); 1.252 + }); 1.253 + 1.254 + // fake a dom window context 1.255 + DOMIdentity.newContext(mockedRP, mockedRP._mm); 1.256 +} 1.257 + 1.258 +let TESTS = [ 1.259 + test_overall, 1.260 + test_mock, 1.261 + test_watch_signed_in, 1.262 + test_watch_signed_out, 1.263 + test_request, 1.264 + test_logout, 1.265 + test_error, 1.266 + test_child_process_shutdown, 1.267 +]; 1.268 + 1.269 +TESTS.forEach(add_test); 1.270 + 1.271 +function run_test() { 1.272 + run_next_test(); 1.273 +}