browser_fxa_web_channel.js (8499B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ 3 */ 4 5 ChromeUtils.defineESModuleGetters(this, { 6 WebChannel: "resource://gre/modules/WebChannel.sys.mjs", 7 ON_PROFILE_CHANGE_NOTIFICATION: 8 "resource://gre/modules/FxAccountsCommon.sys.mjs", 9 }); 10 11 var { FxAccountsWebChannel } = ChromeUtils.importESModule( 12 "resource://gre/modules/FxAccountsWebChannel.sys.mjs" 13 ); 14 15 const TEST_HTTP_PATH = "https://example.com"; 16 const TEST_BASE_URL = 17 TEST_HTTP_PATH + 18 "/browser/browser/base/content/test/sync/browser_fxa_web_channel.html"; 19 const TEST_CHANNEL_ID = "account_updates_test"; 20 21 var gTests = [ 22 { 23 desc: "FxA Web Channel - should receive message about profile changes", 24 async run() { 25 let client = new FxAccountsWebChannel({ 26 content_uri: TEST_HTTP_PATH, 27 channel_id: TEST_CHANNEL_ID, 28 }); 29 let promiseObserver = new Promise(resolve => { 30 makeObserver( 31 ON_PROFILE_CHANGE_NOTIFICATION, 32 function (subject, topic, data) { 33 Assert.equal(data, "abc123"); 34 client.tearDown(); 35 resolve(); 36 } 37 ); 38 }); 39 40 await BrowserTestUtils.withNewTab( 41 { 42 gBrowser, 43 url: TEST_BASE_URL + "?profile_change", 44 }, 45 async function () { 46 await promiseObserver; 47 } 48 ); 49 }, 50 }, 51 { 52 desc: "fxa web channel - login messages should notify the fxAccounts object", 53 async run() { 54 let promiseLogin = new Promise(resolve => { 55 let login = accountData => { 56 Assert.equal(typeof accountData.authAt, "number"); 57 Assert.equal(accountData.email, "testuser@testuser.com"); 58 Assert.equal(accountData.keyFetchToken, "key_fetch_token"); 59 Assert.equal(accountData.sessionToken, "session_token"); 60 Assert.equal(accountData.uid, "uid"); 61 Assert.equal(accountData.unwrapBKey, "unwrap_b_key"); 62 Assert.equal(accountData.verified, true); 63 }; 64 65 let client = new FxAccountsWebChannel({ 66 content_uri: TEST_HTTP_PATH, 67 channel_id: TEST_CHANNEL_ID, 68 helpers: { 69 login, 70 }, 71 }); 72 73 client._channel.send = (message, _context) => { 74 Assert.equal(message.data.ok, true); 75 client.tearDown(); 76 resolve(); 77 }; 78 }); 79 80 await BrowserTestUtils.withNewTab( 81 { 82 gBrowser, 83 url: TEST_BASE_URL + "?login", 84 }, 85 async function () { 86 await promiseLogin; 87 } 88 ); 89 }, 90 }, 91 { 92 desc: "fxa web channel - can_link_account messages should respond", 93 async run() { 94 let properUrl = TEST_BASE_URL + "?can_link_account"; 95 96 let promiseEcho = new Promise(resolve => { 97 let webChannelOrigin = Services.io.newURI(properUrl); 98 // responses sent to content are echoed back over the 99 // `fxaccounts_webchannel_response_echo` channel. Ensure the 100 // fxaccounts:can_link_account message is responded to. 101 let echoWebChannel = new WebChannel( 102 "fxaccounts_webchannel_response_echo", 103 webChannelOrigin 104 ); 105 echoWebChannel.listen((webChannelId, message) => { 106 Assert.equal(message.command, "fxaccounts:can_link_account"); 107 Assert.equal(message.messageId, 2); 108 Assert.equal(message.data.ok, true); 109 110 client.tearDown(); 111 echoWebChannel.stopListening(); 112 113 resolve(); 114 }); 115 116 let client = new FxAccountsWebChannel({ 117 content_uri: TEST_HTTP_PATH, 118 channel_id: TEST_CHANNEL_ID, 119 helpers: { 120 _selectableProfilesEnabled() { 121 return false; 122 }, 123 shouldAllowRelink(acctData) { 124 if (acctData.uid == "uid") { 125 Assert.equal(acctData.email, "testuser@testuser.com"); 126 return true; 127 } 128 Assert.notEqual(acctData.email, "testuser@testuser.com"); 129 return false; 130 }, 131 promptProfileSyncWarningIfNeeded(acctData) { 132 if (acctData.uid == "uid") { 133 Assert.equal(acctData.email, "testuser@testuser.com"); 134 return { action: "continue" }; 135 } 136 Assert.notEqual(acctData.email, "testuser@testuser.com"); 137 return { action: "cancel" }; 138 }, 139 }, 140 }); 141 }); 142 143 await BrowserTestUtils.withNewTab( 144 { 145 gBrowser, 146 url: properUrl, 147 }, 148 async function () { 149 await promiseEcho; 150 } 151 ); 152 }, 153 }, 154 { 155 desc: "fxa web channel - logout messages should notify the fxAccounts object", 156 async run() { 157 let promiseLogout = new Promise(resolve => { 158 let logout = uid => { 159 Assert.equal(uid, "uid"); 160 }; 161 162 let client = new FxAccountsWebChannel({ 163 content_uri: TEST_HTTP_PATH, 164 channel_id: TEST_CHANNEL_ID, 165 helpers: { 166 logout, 167 }, 168 }); 169 170 client._channel.send = (message, _context) => { 171 Assert.equal(message.data.ok, true); 172 client.tearDown(); 173 resolve(); 174 }; 175 }); 176 177 await BrowserTestUtils.withNewTab( 178 { 179 gBrowser, 180 url: TEST_BASE_URL + "?logout", 181 }, 182 async function () { 183 await promiseLogout; 184 } 185 ); 186 }, 187 }, 188 { 189 desc: "fxa web channel - delete messages should notify the fxAccounts object", 190 async run() { 191 let promiseDelete = new Promise(resolve => { 192 let logout = uid => { 193 Assert.equal(uid, "uid"); 194 }; 195 196 let client = new FxAccountsWebChannel({ 197 content_uri: TEST_HTTP_PATH, 198 channel_id: TEST_CHANNEL_ID, 199 helpers: { 200 logout, 201 }, 202 }); 203 204 client._channel.send = (message, _context) => { 205 Assert.equal(message.data.ok, true); 206 client.tearDown(); 207 resolve(); 208 }; 209 }); 210 211 await BrowserTestUtils.withNewTab( 212 { 213 gBrowser, 214 url: TEST_BASE_URL + "?delete", 215 }, 216 async function () { 217 await promiseDelete; 218 } 219 ); 220 }, 221 }, 222 { 223 desc: "fxa web channel - firefox_view messages should call the openFirefoxView helper", 224 async run() { 225 let wasCalled = false; 226 let promiseMessageHandled = new Promise(resolve => { 227 let openFirefoxView = browser => { 228 wasCalled = true; 229 Assert.ok( 230 !!browser.ownerGlobal, 231 "openFirefoxView called with a browser argument" 232 ); 233 Assert.equal( 234 typeof browser.ownerGlobal.FirefoxViewHandler.openTab, 235 "function", 236 "We can reach the openTab method" 237 ); 238 }; 239 240 let client = new FxAccountsWebChannel({ 241 content_uri: TEST_HTTP_PATH, 242 channel_id: TEST_CHANNEL_ID, 243 helpers: { 244 openFirefoxView, 245 }, 246 }); 247 248 client._channel.send = (message, _context) => { 249 Assert.equal(message.data.ok, true); 250 client.tearDown(); 251 resolve(); 252 }; 253 }); 254 255 await BrowserTestUtils.withNewTab( 256 { 257 gBrowser, 258 url: TEST_BASE_URL + "?firefox_view", 259 }, 260 async function () { 261 await promiseMessageHandled; 262 } 263 ); 264 Assert.ok(wasCalled, "openFirefoxView did get called"); 265 }, 266 }, 267 ]; // gTests 268 269 function makeObserver(aObserveTopic, aObserveFunc) { 270 let callback = function (aSubject, aTopic, aData) { 271 if (aTopic == aObserveTopic) { 272 removeMe(); 273 aObserveFunc(aSubject, aTopic, aData); 274 } 275 }; 276 277 function removeMe() { 278 Services.obs.removeObserver(callback, aObserveTopic); 279 } 280 281 Services.obs.addObserver(callback, aObserveTopic); 282 return removeMe; 283 } 284 285 registerCleanupFunction(function () { 286 Services.prefs.clearUserPref( 287 "browser.tabs.remote.separatePrivilegedMozillaWebContentProcess" 288 ); 289 }); 290 291 function test() { 292 waitForExplicitFinish(); 293 Services.prefs.setBoolPref( 294 "browser.tabs.remote.separatePrivilegedMozillaWebContentProcess", 295 false 296 ); 297 298 (async function () { 299 for (let testCase of gTests) { 300 info("Running: " + testCase.desc); 301 await testCase.run(); 302 } 303 })().then(finish, ex => { 304 Assert.ok(false, "Unexpected Exception: " + ex); 305 finish(); 306 }); 307 }