test_notification_duplicate.js (4539B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const userAgentID = "1500e7d9-8cbe-4ee6-98da-7fa5d6a39852"; 7 8 function run_test() { 9 do_get_profile(); 10 setPrefs({ 11 maxRecentMessageIDsPerSubscription: 4, 12 userAgentID, 13 }); 14 run_next_test(); 15 Services.fog.initializeFOG(); 16 } 17 18 // Should acknowledge duplicate notifications, but not notify apps. 19 add_task(async function test_notification_duplicate() { 20 Services.fog.testResetFOG(); 21 let db = PushServiceWebSocket.newPushDB(); 22 registerCleanupFunction(() => { 23 return db.drop().then(_ => db.close()); 24 }); 25 let records = [ 26 { 27 channelID: "has-recents", 28 pushEndpoint: "https://example.org/update/1", 29 scope: "https://example.com/1", 30 originAttributes: "", 31 recentMessageIDs: ["dupe"], 32 quota: Infinity, 33 systemRecord: true, 34 }, 35 { 36 channelID: "no-recents", 37 pushEndpoint: "https://example.org/update/2", 38 scope: "https://example.com/2", 39 originAttributes: "", 40 quota: Infinity, 41 systemRecord: true, 42 }, 43 { 44 channelID: "dropped-recents", 45 pushEndpoint: "https://example.org/update/3", 46 scope: "https://example.com/3", 47 originAttributes: "", 48 recentMessageIDs: ["newest", "newer", "older", "oldest"], 49 quota: Infinity, 50 systemRecord: true, 51 }, 52 ]; 53 for (let record of records) { 54 await db.put(record); 55 } 56 57 let testData = [ 58 { 59 channelID: "has-recents", 60 updates: 1, 61 acks: [ 62 { 63 version: "dupe", 64 code: 102, 65 }, 66 { 67 version: "not-dupe", 68 code: 100, 69 }, 70 ], 71 recents: ["not-dupe", "dupe"], 72 }, 73 { 74 channelID: "no-recents", 75 updates: 1, 76 acks: [ 77 { 78 version: "not-dupe", 79 code: 100, 80 }, 81 ], 82 recents: ["not-dupe"], 83 }, 84 { 85 channelID: "dropped-recents", 86 acks: [ 87 { 88 version: "overflow", 89 code: 100, 90 }, 91 { 92 version: "oldest", 93 code: 100, 94 }, 95 ], 96 updates: 2, 97 recents: ["oldest", "overflow", "newest", "newer"], 98 }, 99 ]; 100 101 let expectedUpdates = testData.reduce((sum, { updates }) => sum + updates, 0); 102 let notifiedScopes = []; 103 let notifyPromise = promiseObserverNotification( 104 PushServiceComponent.pushTopic, 105 (subject, data) => { 106 notifiedScopes.push(data); 107 return notifiedScopes.length == expectedUpdates; 108 } 109 ); 110 111 let expectedAcks = testData.reduce((sum, { acks }) => sum + acks.length, 0); 112 let ackDone; 113 let ackPromise = new Promise( 114 resolve => (ackDone = after(expectedAcks, resolve)) 115 ); 116 PushService.init({ 117 serverURI: "wss://push.example.org/", 118 db, 119 makeWebSocket(uri) { 120 return new MockWebSocket(uri, { 121 onHello() { 122 this.serverSendMsg( 123 JSON.stringify({ 124 messageType: "hello", 125 status: 200, 126 uaid: userAgentID, 127 use_webpush: true, 128 }) 129 ); 130 for (let { channelID, acks } of testData) { 131 for (let { version } of acks) { 132 this.serverSendMsg( 133 JSON.stringify({ 134 messageType: "notification", 135 channelID, 136 version, 137 }) 138 ); 139 } 140 } 141 }, 142 onACK(request) { 143 let [ack] = request.updates; 144 let expectedData = testData.find( 145 test => test.channelID == ack.channelID 146 ); 147 ok(expectedData, `Unexpected channel ${ack.channelID}`); 148 let expectedAck = expectedData.acks.find( 149 a => a.version == ack.version 150 ); 151 ok( 152 expectedAck, 153 `Unexpected ack for message ${ack.version} on ${ack.channelID}` 154 ); 155 equal( 156 expectedAck.code, 157 ack.code, 158 `Wrong ack status for message ${ack.version} on ${ack.channelID}` 159 ); 160 ackDone(); 161 }, 162 }); 163 }, 164 }); 165 166 await notifyPromise; 167 await ackPromise; 168 169 for (let { channelID, recents } of testData) { 170 let record = await db.getByKeyID(channelID); 171 deepEqual( 172 record.recentMessageIDs, 173 recents, 174 `Wrong recent message IDs for ${channelID}` 175 ); 176 } 177 Assert.equal( 178 Glean.webPush.detectedDuplicatedMessageIds.testGetValue(), 179 1, 180 "Should observe one duplicate" 181 ); 182 });