1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/identity/tests/mochitest/test_syntheticEvents.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,209 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 + https://bugzilla.mozilla.org/show_bug.cgi?id=971379 1.8 +--> 1.9 +<head> 1.10 + <meta charset="utf-8"> 1.11 + <title>Certified/packaged apps may use synthetic events with FXA -- Bug 971379</title> 1.12 + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 1.13 + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> 1.14 +</head> 1.15 +<body> 1.16 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=971379">Mozilla Bug 971379</a> 1.17 +<p id="display"></p> 1.18 +<div id="content"> 1.19 + 1.20 +</div> 1.21 +<pre id="test"> 1.22 +<script type="application/javascript;version=1.8"> 1.23 + 1.24 +SimpleTest.waitForExplicitFinish(); 1.25 + 1.26 +Components.utils.import("resource://gre/modules/Promise.jsm"); 1.27 +Components.utils.import("resource://gre/modules/Services.jsm"); 1.28 +Components.utils.import("resource://gre/modules/DOMIdentity.jsm"); 1.29 +Components.utils.import("resource://gre/modules/identity/jwcrypto.jsm"); 1.30 +Components.utils.import("resource://gre/modules/identity/FirefoxAccounts.jsm"); 1.31 + 1.32 +// Mock the Firefox Accounts manager to give a dummy assertion, just to confirm 1.33 +// that we're making the trip through the dom/identity and toolkit/identity 1.34 +// plumbing. 1.35 +function MockFXAManager() {} 1.36 +MockFXAManager.prototype = { 1.37 + getAssertion: function(audience, options) { 1.38 + if (options.silent) { 1.39 + return Promise.resolve(null); 1.40 + } 1.41 + return Promise.resolve("here~you.go.dude"); 1.42 + } 1.43 +}; 1.44 + 1.45 +let originalManager = FirefoxAccounts.fxAccountsManager; 1.46 +FirefoxAccounts.fxAccountsManager = new MockFXAManager(); 1.47 + 1.48 +// Mock IdentityService (Persona) so we can test request() while not handling 1.49 +// user input on an installed app. Since in this test suite, we have only this 1.50 +// one test for Persona, we additionally cause request() to throw if invoked, as 1.51 +// added security that nsDOMIdentity did not emit a request message. 1.52 +let MockIdentityService = function() { 1.53 + this.RP = this; 1.54 + this.contexts = {}; 1.55 +} 1.56 +MockIdentityService.prototype = { 1.57 + watch: function(context) { 1.58 + this.contexts[context.id] = context; 1.59 + context.doReady(); 1.60 + }, 1.61 + 1.62 + request: function(message) { 1.63 + ok(false, "nsDOMIdentity should block Persona request() in this test suite"); 1.64 + }, 1.65 +}; 1.66 +DOMIdentity._mockIdentityService = new MockIdentityService(); 1.67 + 1.68 +// The manifests for these apps are all declared in 1.69 +// /testing/profiles/webapps_mochitest.json. They are injected into the profile 1.70 +// by /testing/mochitest/runtests.py with the appropriate appStatus. So we don't 1.71 +// have to manually install any apps. 1.72 +let apps = [ 1.73 + { 1.74 + title: "an installed app, which must request() in a native event", 1.75 + manifest: "https://example.com/manifest.webapp", 1.76 + origin: "https://example.com", 1.77 + uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_syntheticEvents.html", 1.78 + wantIssuer: "", // default to persona 1.79 + expected: { 1.80 + success: false, 1.81 + errors: [ 1.82 + "ERROR_REQUEST_WHILE_NOT_HANDLING_USER_INPUT", 1.83 + ], 1.84 + }, 1.85 + }, 1.86 + { 1.87 + title: "an installed app, which must may not use firefox accounts", 1.88 + manifest: "https://example.com/manifest.webapp", 1.89 + origin: "https://example.com", 1.90 + uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_syntheticEvents.html", 1.91 + wantIssuer: "firefox-accounts", 1.92 + expected: { 1.93 + success: false, 1.94 + errors: [ 1.95 + "ERROR_NOT_AUTHORIZED_FOR_FIREFOX_ACCOUNTS", 1.96 + ], 1.97 + }, 1.98 + }, 1.99 + { 1.100 + title: "a privileged app, which may use synthetic events", 1.101 + manifest: "https://example.com/manifest_priv.webapp", 1.102 + origin: "https://example.com", 1.103 + uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_syntheticEvents.html", 1.104 + wantIssuer: "firefox-accounts", 1.105 + expected: { 1.106 + success: true, 1.107 + }, 1.108 + }, 1.109 + { 1.110 + title: "a certified app, which may use synthetic events", 1.111 + manifest: "https://example.com/manifest_cert.webapp", 1.112 + origin: "https://example.com", 1.113 + uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_syntheticEvents.html", 1.114 + wantIssuer: "firefox-accounts", 1.115 + expected: { 1.116 + success: true, 1.117 + }, 1.118 + }, 1.119 +]; 1.120 + 1.121 +let appIndex = 0; 1.122 +let testRunner = runTest(); 1.123 +let receivedErrors = []; 1.124 + 1.125 +function receiveMessage(event) { 1.126 + dump("** Received response: " + event.data + "\n"); 1.127 + let result = JSON.parse(event.data); 1.128 + let app = apps[appIndex]; 1.129 + let expected = app.expected; 1.130 + 1.131 + is(result.success, expected.success, 1.132 + "Assertion request " + (expected.success ? "succeeds" : "fails")); 1.133 + 1.134 + if (result.error) { 1.135 + receivedErrors.push(result.error); 1.136 + } 1.137 + 1.138 + if (receivedErrors.length === (expected.errors || []).length) { 1.139 + receivedErrors.forEach((error) => { 1.140 + ok(expected.errors.indexOf(error) > -1, 1.141 + "Received " + error + ". " + 1.142 + "Expected errors are: " + JSON.stringify(expected.errors)); 1.143 + }); 1.144 + 1.145 + appIndex += 1; 1.146 + 1.147 + if (appIndex === apps.length) { 1.148 + window.removeEventListener("message", receiveMessage); 1.149 + 1.150 + // Remove mock from DOMIdentity 1.151 + DOMIdentity._mockIdentityService = null; 1.152 + 1.153 + // Restore original fxa manager 1.154 + FirefoxAccounts.fxAccountsManager = originalManager; 1.155 + 1.156 + SimpleTest.finish(); 1.157 + return; 1.158 + } 1.159 + 1.160 + testRunner.next(); 1.161 + } 1.162 +} 1.163 + 1.164 +window.addEventListener("message", receiveMessage, false, true); 1.165 + 1.166 +function runTest() { 1.167 + for (let app of apps) { 1.168 + dump("** Testing " + app.title + "\n"); 1.169 + 1.170 + receivedErrors = []; 1.171 + 1.172 + let iframe = document.createElement("iframe"); 1.173 + 1.174 + iframe.setAttribute("mozapp", app.manifest); 1.175 + iframe.setAttribute("mozbrowser", "true"); 1.176 + iframe.src = app.uri; 1.177 + 1.178 + document.getElementById("content").appendChild(iframe); 1.179 + 1.180 + iframe.addEventListener("load", function onLoad() { 1.181 + iframe.removeEventListener("load", onLoad); 1.182 + 1.183 + // Because the <iframe mozapp> can't parent its way back to us, we 1.184 + // provide this handle to our window so it can postMessage to us. 1.185 + iframe.contentWindow.wrappedJSObject.realParent = window; 1.186 + iframe.contentWindow.postMessage({wantIssuer: app.wantIssuer}, "*"); 1.187 + }, false); 1.188 + 1.189 + yield undefined; 1.190 + } 1.191 +} 1.192 + 1.193 +SpecialPowers.pushPrefEnv({"set": 1.194 + [ 1.195 + ["dom.mozBrowserFramesEnabled", true], 1.196 + ["dom.identity.enabled", true], 1.197 + ["identity.fxaccounts.enabled", true], 1.198 + ["toolkit.identity.debug", true], 1.199 + 1.200 + ["security.apps.privileged.CSP.default", ""], 1.201 + ["security.apps.certified.CSP.default", ""], 1.202 + ]}, 1.203 + function() { 1.204 + testRunner.next(); 1.205 + } 1.206 +); 1.207 + 1.208 + 1.209 +</script> 1.210 +</pre> 1.211 +</body> 1.212 +</html>