diff options
Diffstat (limited to 'dom/push/test/test_data.html')
-rw-r--r-- | dom/push/test/test_data.html | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/dom/push/test/test_data.html b/dom/push/test/test_data.html new file mode 100644 index 000000000..8de873fce --- /dev/null +++ b/dom/push/test/test_data.html @@ -0,0 +1,218 @@ +<!DOCTYPE HTML> +<html> +<!-- +Bug 1185544: Add data delivery to the WebSocket backend. + +Any copyright is dedicated to the Public Domain. +http://creativecommons.org/licenses/publicdomain/ + +--> +<head> + <title>Test for Bug 1185544</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> + <script type="text/javascript" src="/tests/dom/push/test/test_utils.js"></script> + <script type="text/javascript" src="/tests/dom/push/test/webpush.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> +</head> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1185544">Mozilla Bug 1185544</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> + +<script class="testbody" type="text/javascript"> + var userAgentID = "ac44402c-85fc-41e4-a0d0-483316d15351"; + var channelID = null; + + var mockSocket = new MockWebSocket(); + mockSocket.onRegister = function(request) { + channelID = request.channelID; + this.serverSendMsg(JSON.stringify({ + messageType: "register", + uaid: userAgentID, + channelID, + status: 200, + pushEndpoint: "https://example.com/endpoint/1" + })); + }; + + var registration; + add_task(function* start() { + yield setupPrefsAndMockSocket(mockSocket); + yield setPushPermission(true); + + var url = "worker.js" + "?" + (Math.random()); + registration = yield navigator.serviceWorker.register(url, {scope: "."}); + yield waitForActive(registration); + }); + + var controlledFrame; + add_task(function* createControlledIFrame() { + controlledFrame = yield injectControlledFrame(); + }); + + var pushSubscription; + add_task(function* subscribe() { + pushSubscription = yield registration.pushManager.subscribe(); + }); + + function base64UrlDecode(s) { + s = s.replace(/-/g, '+').replace(/_/g, '/'); + + // Replace padding if it was stripped by the sender. + // See http://tools.ietf.org/html/rfc4648#section-4 + switch (s.length % 4) { + case 0: + break; // No pad chars in this case + case 2: + s += '=='; + break; // Two pad chars + case 3: + s += '='; + break; // One pad char + default: + throw new Error('Illegal base64url string!'); + } + + // With correct padding restored, apply the standard base64 decoder + var decoded = atob(s); + + var array = new Uint8Array(new ArrayBuffer(decoded.length)); + for (var i = 0; i < decoded.length; i++) { + array[i] = decoded.charCodeAt(i); + } + return array; + } + + add_task(function* compareJSONSubscription() { + var json = pushSubscription.toJSON(); + is(json.endpoint, pushSubscription.endpoint, "Wrong endpoint"); + + ["p256dh", "auth"].forEach(keyName => { + isDeeply( + base64UrlDecode(json.keys[keyName]), + new Uint8Array(pushSubscription.getKey(keyName)), + "Mismatched Base64-encoded key: " + keyName + ); + }); + }); + + add_task(function* comparePublicKey() { + var data = yield sendRequestToWorker({ type: "publicKey" }); + var p256dhKey = new Uint8Array(pushSubscription.getKey("p256dh")); + is(p256dhKey.length, 65, "Key share should be 65 octets"); + isDeeply( + p256dhKey, + new Uint8Array(data.p256dh), + "Mismatched key share" + ); + var authSecret = new Uint8Array(pushSubscription.getKey("auth")); + ok(authSecret.length, 16, "Auth secret should be 16 octets"); + isDeeply( + authSecret, + new Uint8Array(data.auth), + "Mismatched auth secret" + ); + }); + + var version = 0; + function sendEncryptedMsg(pushSubscription, message) { + return webPushEncrypt(pushSubscription, message) + .then((encryptedData) => { + mockSocket.serverSendMsg(JSON.stringify({ + messageType: 'notification', + version: version++, + channelID: channelID, + data: encryptedData.data, + headers: { + encryption: encryptedData.encryption, + encryption_key: encryptedData.encryption_key, + encoding: encryptedData.encoding + } + })); + }); + } + + function waitForMessage(pushSubscription, message) { + return Promise.all([ + controlledFrame.waitOnWorkerMessage("finished"), + sendEncryptedMsg(pushSubscription, message), + ]).then(([message]) => message); + } + + add_task(function* sendPushMessageFromPage() { + var typedArray = new Uint8Array([226, 130, 40, 240, 40, 140, 188]); + var json = { hello: "world" }; + + var message = yield waitForMessage(pushSubscription, "Text message from page"); + is(message.data.text, "Text message from page", "Wrong text message data"); + + message = yield waitForMessage( + pushSubscription, + typedArray + ); + isDeeply(new Uint8Array(message.data.arrayBuffer), typedArray, + "Wrong array buffer message data"); + + message = yield waitForMessage( + pushSubscription, + JSON.stringify(json) + ); + ok(message.data.json.ok, "Unexpected error parsing JSON"); + isDeeply(message.data.json.value, json, "Wrong JSON message data"); + + message = yield waitForMessage( + pushSubscription, + "" + ); + ok(message, "Should include data for empty messages"); + is(message.data.text, "", "Wrong text for empty message"); + is(message.data.arrayBuffer.byteLength, 0, "Wrong buffer length for empty message"); + ok(!message.data.json.ok, "Expected JSON parse error for empty message"); + + message = yield waitForMessage( + pushSubscription, + new Uint8Array([0x48, 0x69, 0x21, 0x20, 0xf0, 0x9f, 0x91, 0x80]) + ); + is(message.data.text, "Hi! \ud83d\udc40", "Wrong text for message with emoji"); + var text = yield new Promise((resolve, reject) => { + var reader = new FileReader(); + reader.onloadend = event => { + if (reader.error) { + reject(reader.error); + } else { + resolve(reader.result); + } + }; + reader.readAsText(message.data.blob); + }); + is(text, "Hi! \ud83d\udc40", "Wrong blob data for message with emoji"); + + var finishedPromise = controlledFrame.waitOnWorkerMessage("finished"); + // Send a blank message. + mockSocket.serverSendMsg(JSON.stringify({ + messageType: "notification", + version: "vDummy", + channelID: channelID + })); + + var message = yield finishedPromise; + ok(!message.data, "Should exclude data for blank messages"); + }); + + add_task(function* unsubscribe() { + controlledFrame.remove(); + yield pushSubscription.unsubscribe(); + }); + + add_task(function* unregister() { + yield registration.unregister(); + }); + +</script> +</body> +</html> |