summaryrefslogtreecommitdiffstats
path: root/dom/push/test/xpcshell/test_notification_data.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/push/test/xpcshell/test_notification_data.js')
-rw-r--r--dom/push/test/xpcshell/test_notification_data.js314
1 files changed, 314 insertions, 0 deletions
diff --git a/dom/push/test/xpcshell/test_notification_data.js b/dom/push/test/xpcshell/test_notification_data.js
new file mode 100644
index 0000000000..2cb9ae853d
--- /dev/null
+++ b/dom/push/test/xpcshell/test_notification_data.js
@@ -0,0 +1,314 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { PushDB, PushService, PushServiceWebSocket } = serviceExports;
+
+let db;
+let userAgentID = "f5b47f8d-771f-4ea3-b999-91c135f8766d";
+
+function run_test() {
+ do_get_profile();
+ setPrefs({
+ userAgentID,
+ });
+ run_next_test();
+}
+
+function putRecord(channelID, scope, publicKey, privateKey, authSecret) {
+ return db.put({
+ channelID,
+ pushEndpoint: "https://example.org/push/" + channelID,
+ scope,
+ pushCount: 0,
+ lastPush: 0,
+ originAttributes: "",
+ quota: Infinity,
+ systemRecord: true,
+ p256dhPublicKey: ChromeUtils.base64URLDecode(publicKey, {
+ padding: "reject",
+ }),
+ p256dhPrivateKey: privateKey,
+ authenticationSecret: ChromeUtils.base64URLDecode(authSecret, {
+ padding: "reject",
+ }),
+ });
+}
+
+let ackDone;
+let server;
+add_task(async function test_notification_ack_data_setup() {
+ db = PushServiceWebSocket.newPushDB();
+ registerCleanupFunction(() => {
+ return db.drop().then(_ => db.close());
+ });
+
+ await putRecord(
+ "subscription1",
+ "https://example.com/page/1",
+ "BPCd4gNQkjwRah61LpdALdzZKLLnU5UAwDztQ5_h0QsT26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA",
+ {
+ crv: "P-256",
+ d: "1jUPhzVsRkzV0vIzwL4ZEsOlKdNOWm7TmaTfzitJkgM",
+ ext: true,
+ key_ops: ["deriveBits"],
+ kty: "EC",
+ x: "8J3iA1CSPBFqHrUul0At3NkosudTlQDAPO1Dn-HRCxM",
+ y: "26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA",
+ },
+ "c_sGN6uCv9Hu7JOQT34jAQ"
+ );
+ await putRecord(
+ "subscription2",
+ "https://example.com/page/2",
+ "BPnWyUo7yMnuMlyKtERuLfWE8a09dtdjHSW2lpC9_BqR5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E",
+ {
+ crv: "P-256",
+ d: "lFm4nPsUKYgNGBJb5nXXKxl8bspCSp0bAhCYxbveqT4",
+ ext: true,
+ key_ops: ["deriveBits"],
+ kty: "EC",
+ x: "-dbJSjvIye4yXIq0RG4t9YTxrT1212MdJbaWkL38GpE",
+ y: "5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E",
+ },
+ "t3P246Gj9vjKDHHRYaY6hw"
+ );
+ await putRecord(
+ "subscription3",
+ "https://example.com/page/3",
+ "BDhUHITSeVrWYybFnb7ylVTCDDLPdQWMpf8gXhcWwvaaJa6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI",
+ {
+ crv: "P-256",
+ d: "Q1_SE1NySTYzjbqgWwPgrYh7XRg3adqZLkQPsy319G8",
+ ext: true,
+ key_ops: ["deriveBits"],
+ kty: "EC",
+ x: "OFQchNJ5WtZjJsWdvvKVVMIMMs91BYyl_yBeFxbC9po",
+ y: "Ja6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI",
+ },
+ "E0qiXGWvFSR0PS352ES1_Q"
+ );
+
+ let setupDone;
+ let setupDonePromise = new Promise(r => (setupDone = r));
+
+ PushService.init({
+ serverURI: "wss://push.example.org/",
+ db,
+ makeWebSocket(uri) {
+ return new MockWebSocket(uri, {
+ onHello(request) {
+ equal(
+ request.uaid,
+ userAgentID,
+ "Should send matching device IDs in handshake"
+ );
+ this.serverSendMsg(
+ JSON.stringify({
+ messageType: "hello",
+ uaid: userAgentID,
+ status: 200,
+ use_webpush: true,
+ })
+ );
+ server = this;
+ setupDone();
+ },
+ onACK(request) {
+ if (ackDone) {
+ ackDone(request);
+ }
+ },
+ });
+ },
+ });
+ await setupDonePromise;
+});
+
+add_task(async function test_notification_ack_data() {
+ let allTestData = [
+ {
+ channelID: "subscription1",
+ version: "v1",
+ send: {
+ headers: {
+ encryption_key:
+ 'keyid="notification1"; dh="BO_tgGm-yvYAGLeRe16AvhzaUcpYRiqgsGOlXpt0DRWDRGGdzVLGlEVJMygqAUECarLnxCiAOHTP_znkedrlWoU"',
+ encryption: 'keyid="notification1";salt="uAZaiXpOSfOLJxtOCZ09dA"',
+ encoding: "aesgcm128",
+ },
+ data: "NwrrOWPxLE8Sv5Rr0Kep7n0-r_j3rsYrUw_CXPo",
+ version: "v1",
+ },
+ ackCode: 100,
+ receive: {
+ scope: "https://example.com/page/1",
+ data: "Some message",
+ },
+ },
+ {
+ channelID: "subscription2",
+ version: "v2",
+ send: {
+ headers: {
+ encryption_key:
+ 'keyid="notification2"; dh="BKVdQcgfncpNyNWsGrbecX0zq3eHIlHu5XbCGmVcxPnRSbhjrA6GyBIeGdqsUL69j5Z2CvbZd-9z1UBH0akUnGQ"',
+ encryption: 'keyid="notification2";salt="vFn3t3M_k42zHBdpch3VRw"',
+ encoding: "aesgcm128",
+ },
+ data: "Zt9dEdqgHlyAL_l83385aEtb98ZBilz5tgnGgmwEsl5AOCNgesUUJ4p9qUU",
+ },
+ ackCode: 100,
+ receive: {
+ scope: "https://example.com/page/2",
+ data: "Some message",
+ },
+ },
+ {
+ channelID: "subscription3",
+ version: "v3",
+ send: {
+ headers: {
+ encryption_key:
+ 'keyid="notification3";dh="BD3xV_ACT8r6hdIYES3BJj1qhz9wyv7MBrG9vM2UCnjPzwE_YFVpkD-SGqE-BR2--0M-Yf31wctwNsO1qjBUeMg"',
+ encryption:
+ 'keyid="notification3"; salt="DFq188piWU7osPBgqn4Nlg"; rs=24',
+ encoding: "aesgcm128",
+ },
+ data:
+ "LKru3ZzxBZuAxYtsaCfaj_fehkrIvqbVd1iSwnwAUgnL-cTeDD-83blxHXTq7r0z9ydTdMtC3UjAcWi8LMnfY-BFzi0qJAjGYIikDA",
+ },
+ ackCode: 100,
+ receive: {
+ scope: "https://example.com/page/3",
+ data: "Some message",
+ },
+ },
+ // A message encoded with `aesgcm` (2 bytes of padding, authenticated).
+ {
+ channelID: "subscription1",
+ version: "v5",
+ send: {
+ headers: {
+ crypto_key:
+ 'keyid=v4;dh="BMh_vsnqu79ZZkMTYkxl4gWDLdPSGE72Lr4w2hksSFW398xCMJszjzdblAWXyhSwakRNEU_GopAm4UGzyMVR83w"',
+ encryption: 'keyid="v4";salt="C14Wb7rQTlXzrgcPHtaUzw"',
+ encoding: "aesgcm",
+ },
+ data: "pus4kUaBWzraH34M-d_oN8e0LPpF_X6acx695AMXovDe",
+ },
+ ackCode: 100,
+ receive: {
+ scope: "https://example.com/page/1",
+ data: "Another message",
+ },
+ },
+ // A message with 17 bytes of padding and rs of 24
+ {
+ channelID: "subscription2",
+ version: "v5",
+ send: {
+ headers: {
+ crypto_key:
+ 'keyid="v5"; dh="BOp-DpyR9eLY5Ci11_loIFqeHzWfc_0evJmq7N8NKzgp60UAMMM06XIi2VZp2_TSdw1omk7E19SyeCCwRp76E-U"',
+ encryption: 'keyid=v5;salt="TvjOou1TqJOQY_ZsOYV3Ww";rs=24',
+ encoding: "aesgcm",
+ },
+ data:
+ "rG9WYQ2ZwUgfj_tMlZ0vcIaNpBN05FW-9RUBZAM-UUZf0_9eGpuENBpUDAw3mFmd2XJpmvPvAtLVs54l3rGwg1o",
+ },
+ ackCode: 100,
+ receive: {
+ scope: "https://example.com/page/2",
+ data: "Some message",
+ },
+ },
+ // A message without key identifiers.
+ {
+ channelID: "subscription3",
+ version: "v6",
+ send: {
+ headers: {
+ crypto_key:
+ 'dh="BEEjwWbF5jZKCgW0kmUWgG-wNcRvaa9_3zZElHAF8przHwd4cp5_kQsc-IMNZcVA0iUix31jxuMOytU-5DwWtyQ"',
+ encryption: "salt=aAQcr2khAksgNspPiFEqiQ",
+ encoding: "aesgcm",
+ },
+ data: "pEYgefdI-7L46CYn5dR9TIy2AXGxe07zxclbhstY",
+ },
+ ackCode: 100,
+ receive: {
+ scope: "https://example.com/page/3",
+ data: "Some message",
+ },
+ },
+ // A malformed encrypted message.
+ {
+ channelID: "subscription3",
+ version: "v7",
+ send: {
+ headers: {
+ crypto_key: "dh=AAAAAAAA",
+ encryption: "salt=AAAAAAAA",
+ },
+ data: "AAAAAAAA",
+ },
+ ackCode: 101,
+ receive: null,
+ },
+ ];
+
+ let sendAndReceive = testData => {
+ let messageReceived = testData.receive
+ ? promiseObserverNotification(
+ PushServiceComponent.pushTopic,
+ (subject, data) => {
+ let notification = subject.QueryInterface(Ci.nsIPushMessage).data;
+ equal(
+ notification.text(),
+ testData.receive.data,
+ "Check data for notification " + testData.version
+ );
+ equal(
+ data,
+ testData.receive.scope,
+ "Check scope for notification " + testData.version
+ );
+ return true;
+ }
+ )
+ : Promise.resolve();
+
+ let ackReceived = new Promise(resolve => (ackDone = resolve)).then(
+ ackData => {
+ deepEqual(
+ {
+ messageType: "ack",
+ updates: [
+ {
+ channelID: testData.channelID,
+ version: testData.version,
+ code: testData.ackCode,
+ },
+ ],
+ },
+ ackData,
+ "Check updates for acknowledgment " + testData.version
+ );
+ }
+ );
+
+ let msg = JSON.parse(JSON.stringify(testData.send));
+ msg.messageType = "notification";
+ msg.channelID = testData.channelID;
+ msg.version = testData.version;
+ server.serverSendMsg(JSON.stringify(msg));
+
+ return Promise.all([messageReceived, ackReceived]);
+ };
+
+ await allTestData.reduce((p, testData) => {
+ return p.then(_ => sendAndReceive(testData));
+ }, Promise.resolve());
+});