summaryrefslogtreecommitdiffstats
path: root/dom/push/test/xpcshell/test_quota_observer.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/push/test/xpcshell/test_quota_observer.js')
-rw-r--r--dom/push/test/xpcshell/test_quota_observer.js210
1 files changed, 210 insertions, 0 deletions
diff --git a/dom/push/test/xpcshell/test_quota_observer.js b/dom/push/test/xpcshell/test_quota_observer.js
new file mode 100644
index 0000000000..447f509967
--- /dev/null
+++ b/dom/push/test/xpcshell/test_quota_observer.js
@@ -0,0 +1,210 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const userAgentID = "28cd09e2-7506-42d8-9e50-b02785adc7ef";
+
+var db;
+
+function run_test() {
+ do_get_profile();
+ setPrefs({
+ userAgentID,
+ });
+ run_next_test();
+}
+
+let putRecord = async function (perm, record) {
+ let uri = Services.io.newURI(record.scope);
+
+ PermissionTestUtils.add(
+ uri,
+ "desktop-notification",
+ Ci.nsIPermissionManager[perm]
+ );
+ registerCleanupFunction(() => {
+ PermissionTestUtils.remove(uri, "desktop-notification");
+ });
+
+ await db.put(record);
+};
+
+add_task(async function test_expiration_history_observer() {
+ db = PushServiceWebSocket.newPushDB();
+ registerCleanupFunction(() => db.drop().then(_ => db.close()));
+
+ // A registration that we'll expire...
+ await putRecord("ALLOW_ACTION", {
+ channelID: "379c0668-8323-44d2-a315-4ee83f1a9ee9",
+ pushEndpoint: "https://example.org/push/1",
+ scope: "https://example.com/deals",
+ pushCount: 0,
+ lastPush: 0,
+ version: null,
+ originAttributes: "",
+ quota: 16,
+ });
+
+ // ...And a registration that we'll evict on startup.
+ await putRecord("ALLOW_ACTION", {
+ channelID: "4cb6e454-37cf-41c4-a013-4e3a7fdd0bf1",
+ pushEndpoint: "https://example.org/push/3",
+ scope: "https://example.com/stuff",
+ pushCount: 0,
+ lastPush: 0,
+ version: null,
+ originAttributes: "",
+ quota: 0,
+ });
+
+ await PlacesTestUtils.addVisits({
+ uri: "https://example.com/infrequent",
+ title: "Infrequently-visited page",
+ visitDate: (Date.now() - 14 * 24 * 60 * 60 * 1000) * 1000,
+ transition: Ci.nsINavHistoryService.TRANSITION_LINK,
+ });
+
+ let unregisterDone;
+ let unregisterPromise = new Promise(resolve => (unregisterDone = resolve));
+ let subChangePromise = promiseObserverNotification(
+ PushServiceComponent.subscriptionChangeTopic,
+ (subject, data) => data == "https://example.com/stuff"
+ );
+
+ PushService.init({
+ serverURI: "wss://push.example.org/",
+ db,
+ makeWebSocket(uri) {
+ return new MockWebSocket(uri, {
+ onHello(request) {
+ this.serverSendMsg(
+ JSON.stringify({
+ messageType: "hello",
+ status: 200,
+ uaid: userAgentID,
+ })
+ );
+ this.serverSendMsg(
+ JSON.stringify({
+ messageType: "notification",
+ updates: [
+ {
+ channelID: "379c0668-8323-44d2-a315-4ee83f1a9ee9",
+ version: 2,
+ },
+ ],
+ })
+ );
+ },
+ onUnregister(request) {
+ equal(
+ request.channelID,
+ "379c0668-8323-44d2-a315-4ee83f1a9ee9",
+ "Dropped wrong channel ID"
+ );
+ equal(request.code, 201, "Expected quota exceeded unregister reason");
+ unregisterDone();
+ },
+ onACK(request) {},
+ });
+ },
+ });
+
+ await subChangePromise;
+ await unregisterPromise;
+
+ let expiredRecord = await db.getByKeyID(
+ "379c0668-8323-44d2-a315-4ee83f1a9ee9"
+ );
+ strictEqual(expiredRecord.quota, 0, "Expired record not updated");
+
+ let notifiedScopes = [];
+ subChangePromise = promiseObserverNotification(
+ PushServiceComponent.subscriptionChangeTopic,
+ (subject, data) => {
+ notifiedScopes.push(data);
+ return notifiedScopes.length == 2;
+ }
+ );
+
+ // Add an expired registration that we'll revive later using the idle
+ // observer.
+ await putRecord("ALLOW_ACTION", {
+ channelID: "eb33fc90-c883-4267-b5cb-613969e8e349",
+ pushEndpoint: "https://example.org/push/2",
+ scope: "https://example.com/auctions",
+ pushCount: 0,
+ lastPush: 0,
+ version: null,
+ originAttributes: "",
+ quota: 0,
+ });
+ // ...And an expired registration that we'll revive on fetch.
+ await putRecord("ALLOW_ACTION", {
+ channelID: "6b2d13fe-d848-4c5f-bdda-e9fc89727dca",
+ pushEndpoint: "https://example.org/push/4",
+ scope: "https://example.net/sales",
+ pushCount: 0,
+ lastPush: 0,
+ version: null,
+ originAttributes: "",
+ quota: 0,
+ });
+
+ // Now visit the site...
+ await PlacesTestUtils.addVisits({
+ uri: "https://example.com/another-page",
+ title: "Infrequently-visited page",
+ visitDate: Date.now() * 1000,
+ transition: Ci.nsINavHistoryService.TRANSITION_LINK,
+ });
+ Services.obs.notifyObservers(null, "idle-daily");
+
+ // And we should receive notifications for both scopes.
+ await subChangePromise;
+ deepEqual(
+ notifiedScopes.sort(),
+ ["https://example.com/auctions", "https://example.com/deals"],
+ "Wrong scopes for subscription changes"
+ );
+
+ let aRecord = await db.getByKeyID("379c0668-8323-44d2-a315-4ee83f1a9ee9");
+ ok(!aRecord, "Should drop expired record");
+
+ let bRecord = await db.getByKeyID("eb33fc90-c883-4267-b5cb-613969e8e349");
+ ok(!bRecord, "Should drop evicted record");
+
+ // Simulate a visit to a site with an expired registration, then fetch the
+ // record. This should drop the expired record and fire an observer
+ // notification.
+ await PlacesTestUtils.addVisits({
+ uri: "https://example.net/sales",
+ title: "Firefox plushies, 99% off",
+ visitDate: Date.now() * 1000,
+ transition: Ci.nsINavHistoryService.TRANSITION_LINK,
+ });
+ subChangePromise = promiseObserverNotification(
+ PushServiceComponent.subscriptionChangeTopic,
+ (subject, data) => {
+ if (data == "https://example.net/sales") {
+ ok(
+ subject.isContentPrincipal,
+ "Should pass subscription principal as the subject"
+ );
+ return true;
+ }
+ return false;
+ }
+ );
+ let record = await PushService.registration({
+ scope: "https://example.net/sales",
+ originAttributes: "",
+ });
+ ok(!record, "Should not return evicted record");
+ ok(
+ !(await db.getByKeyID("6b2d13fe-d848-4c5f-bdda-e9fc89727dca")),
+ "Should drop evicted record on fetch"
+ );
+ await subChangePromise;
+});