summaryrefslogtreecommitdiff
path: root/dom/push/test/xpcshell/test_permissions.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/push/test/xpcshell/test_permissions.js')
-rw-r--r--dom/push/test/xpcshell/test_permissions.js296
1 files changed, 296 insertions, 0 deletions
diff --git a/dom/push/test/xpcshell/test_permissions.js b/dom/push/test/xpcshell/test_permissions.js
new file mode 100644
index 0000000000..ff9de26ad8
--- /dev/null
+++ b/dom/push/test/xpcshell/test_permissions.js
@@ -0,0 +1,296 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+'use strict';
+
+const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
+
+const userAgentID = '2c43af06-ab6e-476a-adc4-16cbda54fb89';
+
+let db;
+
+function run_test() {
+ do_get_profile();
+ setPrefs({
+ userAgentID,
+ });
+
+ db = PushServiceWebSocket.newPushDB();
+ do_register_cleanup(() => {return db.drop().then(_ => db.close());});
+
+ run_next_test();
+}
+
+let unregisterDefers = {};
+
+function promiseUnregister(keyID) {
+ return new Promise(r => unregisterDefers[keyID] = r);
+}
+
+function makePushPermission(url, capability) {
+ return {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIPermission]),
+ capability: Ci.nsIPermissionManager[capability],
+ expireTime: 0,
+ expireType: Ci.nsIPermissionManager.EXPIRE_NEVER,
+ principal: Services.scriptSecurityManager.getCodebasePrincipal(
+ Services.io.newURI(url, null, null)
+ ),
+ type: 'desktop-notification',
+ };
+}
+
+function promiseObserverNotifications(topic, count) {
+ let notifiedScopes = [];
+ let subChangePromise = promiseObserverNotification(topic, (subject, data) => {
+ notifiedScopes.push(data);
+ return notifiedScopes.length == count;
+ });
+ return subChangePromise.then(_ => notifiedScopes.sort());
+}
+
+function promiseSubscriptionChanges(count) {
+ return promiseObserverNotifications(
+ PushServiceComponent.subscriptionChangeTopic, count);
+}
+
+function promiseSubscriptionModifications(count) {
+ return promiseObserverNotifications(
+ PushServiceComponent.subscriptionModifiedTopic, count);
+}
+
+function allExpired(...keyIDs) {
+ return Promise.all(keyIDs.map(
+ keyID => db.getByKeyID(keyID)
+ )).then(records =>
+ records.every(record => record.isExpired())
+ );
+}
+
+add_task(function* setUp() {
+ // Active registration; quota should be reset to 16. Since the quota isn't
+ // exposed to content, we shouldn't receive a subscription change event.
+ yield putTestRecord(db, 'active-allow', 'https://example.info/page/1', 8);
+
+ // Expired registration; should be dropped.
+ yield putTestRecord(db, 'expired-allow', 'https://example.info/page/2', 0);
+
+ // Active registration; should be expired when we change the permission
+ // to "deny".
+ yield putTestRecord(db, 'active-deny-changed', 'https://example.xyz/page/1', 16);
+
+ // Two active registrations for a visited site. These will expire when we
+ // add a "deny" permission.
+ yield putTestRecord(db, 'active-deny-added-1', 'https://example.net/ham', 16);
+ yield putTestRecord(db, 'active-deny-added-2', 'https://example.net/green', 8);
+
+ // An already-expired registration for a visited site. We shouldn't send an
+ // `unregister` request for this one, but still receive an observer
+ // notification when we restore permissions.
+ yield putTestRecord(db, 'expired-deny-added', 'https://example.net/eggs', 0);
+
+ // A registration that should not be affected by permission list changes
+ // because its quota is set to `Infinity`.
+ yield putTestRecord(db, 'never-expires', 'app://chrome/only', Infinity);
+
+ // A registration that should be dropped when we clear the permission
+ // list.
+ yield putTestRecord(db, 'drop-on-clear', 'https://example.edu/lonely', 16);
+
+ let handshakeDone;
+ let handshakePromise = new Promise(resolve => handshakeDone = resolve);
+ 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,
+ }));
+ handshakeDone();
+ },
+ onUnregister(request) {
+ let resolve = unregisterDefers[request.channelID];
+ equal(typeof resolve, 'function',
+ 'Dropped unexpected channel ID ' + request.channelID);
+ delete unregisterDefers[request.channelID];
+ equal(request.code, 202,
+ 'Expected permission revoked unregister reason');
+ resolve();
+ this.serverSendMsg(JSON.stringify({
+ messageType: 'unregister',
+ status: 200,
+ channelID: request.channelID,
+ }));
+ },
+ onACK(request) {},
+ });
+ }
+ });
+ yield handshakePromise;
+});
+
+add_task(function* test_permissions_allow_added() {
+ let subChangePromise = promiseSubscriptionChanges(1);
+
+ yield PushService._onPermissionChange(
+ makePushPermission('https://example.info', 'ALLOW_ACTION'),
+ 'added'
+ );
+ let notifiedScopes = yield subChangePromise;
+
+ deepEqual(notifiedScopes, [
+ 'https://example.info/page/2',
+ ], 'Wrong scopes after adding allow');
+
+ let record = yield db.getByKeyID('active-allow');
+ equal(record.quota, 16,
+ 'Should reset quota for active records after adding allow');
+
+ record = yield db.getByKeyID('expired-allow');
+ ok(!record, 'Should drop expired records after adding allow');
+});
+
+add_task(function* test_permissions_allow_deleted() {
+ let subModifiedPromise = promiseSubscriptionModifications(1);
+
+ let unregisterPromise = promiseUnregister('active-allow');
+
+ yield PushService._onPermissionChange(
+ makePushPermission('https://example.info', 'ALLOW_ACTION'),
+ 'deleted'
+ );
+
+ yield unregisterPromise;
+
+ let notifiedScopes = yield subModifiedPromise;
+ deepEqual(notifiedScopes, [
+ 'https://example.info/page/1',
+ ], 'Wrong scopes modified after deleting allow');
+
+ let record = yield db.getByKeyID('active-allow');
+ ok(record.isExpired(),
+ 'Should expire active record after deleting allow');
+});
+
+add_task(function* test_permissions_deny_added() {
+ let subModifiedPromise = promiseSubscriptionModifications(2);
+
+ let unregisterPromise = Promise.all([
+ promiseUnregister('active-deny-added-1'),
+ promiseUnregister('active-deny-added-2'),
+ ]);
+
+ yield PushService._onPermissionChange(
+ makePushPermission('https://example.net', 'DENY_ACTION'),
+ 'added'
+ );
+ yield unregisterPromise;
+
+ let notifiedScopes = yield subModifiedPromise;
+ deepEqual(notifiedScopes, [
+ 'https://example.net/green',
+ 'https://example.net/ham',
+ ], 'Wrong scopes modified after adding deny');
+
+ let isExpired = yield allExpired(
+ 'active-deny-added-1',
+ 'expired-deny-added'
+ );
+ ok(isExpired, 'Should expire all registrations after adding deny');
+});
+
+add_task(function* test_permissions_deny_deleted() {
+ yield PushService._onPermissionChange(
+ makePushPermission('https://example.net', 'DENY_ACTION'),
+ 'deleted'
+ );
+
+ let isExpired = yield allExpired(
+ 'active-deny-added-1',
+ 'expired-deny-added'
+ );
+ ok(isExpired, 'Should retain expired registrations after deleting deny');
+});
+
+add_task(function* test_permissions_allow_changed() {
+ let subChangePromise = promiseSubscriptionChanges(3);
+
+ yield PushService._onPermissionChange(
+ makePushPermission('https://example.net', 'ALLOW_ACTION'),
+ 'changed'
+ );
+
+ let notifiedScopes = yield subChangePromise;
+
+ deepEqual(notifiedScopes, [
+ 'https://example.net/eggs',
+ 'https://example.net/green',
+ 'https://example.net/ham'
+ ], 'Wrong scopes after changing to allow');
+
+ let droppedRecords = yield Promise.all([
+ db.getByKeyID('active-deny-added-1'),
+ db.getByKeyID('active-deny-added-2'),
+ db.getByKeyID('expired-deny-added'),
+ ]);
+ ok(!droppedRecords.some(Boolean),
+ 'Should drop all expired registrations after changing to allow');
+});
+
+add_task(function* test_permissions_deny_changed() {
+ let subModifiedPromise = promiseSubscriptionModifications(1);
+
+ let unregisterPromise = promiseUnregister('active-deny-changed');
+
+ yield PushService._onPermissionChange(
+ makePushPermission('https://example.xyz', 'DENY_ACTION'),
+ 'changed'
+ );
+
+ yield unregisterPromise;
+
+ let notifiedScopes = yield subModifiedPromise;
+ deepEqual(notifiedScopes, [
+ 'https://example.xyz/page/1',
+ ], 'Wrong scopes modified after changing to deny');
+
+ let record = yield db.getByKeyID('active-deny-changed');
+ ok(record.isExpired(),
+ 'Should expire active record after changing to deny');
+});
+
+add_task(function* test_permissions_clear() {
+ let subModifiedPromise = promiseSubscriptionModifications(3);
+
+ deepEqual(yield getAllKeyIDs(db), [
+ 'active-allow',
+ 'active-deny-changed',
+ 'drop-on-clear',
+ 'never-expires',
+ ], 'Wrong records in database before clearing');
+
+ let unregisterPromise = Promise.all([
+ promiseUnregister('active-allow'),
+ promiseUnregister('active-deny-changed'),
+ promiseUnregister('drop-on-clear'),
+ ]);
+
+ yield PushService._onPermissionChange(null, 'cleared');
+
+ yield unregisterPromise;
+
+ let notifiedScopes = yield subModifiedPromise;
+ deepEqual(notifiedScopes, [
+ 'https://example.edu/lonely',
+ 'https://example.info/page/1',
+ 'https://example.xyz/page/1',
+ ], 'Wrong scopes modified after clearing registrations');
+
+ deepEqual(yield getAllKeyIDs(db), [
+ 'never-expires',
+ ], 'Unrestricted registrations should not be dropped');
+});