blob: 225e58266e2e0210299f9defef1d28eaeeb9403c [file] [log] [blame]
self.GLOBAL = {
isWindow: function() { return false; },
isWorker: function() { return true; },
};
importScripts("/resources/testharness.js");
self.addEventListener('install', (event) => {
event.waitUntil((async () => {
// The subscribeToChanges calls are not done in parallel on purpose. Having
// multiple in-flight requests introduces failure modes aside from the
// cookie change logic that this test aims to cover.
try {
await cookieStore.subscribeToChanges([
{ name: 'cookie-name1', matchType: 'equals', url: '/scope/path1' }]);
await cookieStore.subscribeToChanges([
{ }, // Test the default values for subscription properties.
{ name: 'cookie-prefix', matchType: 'starts-with' },
]);
// If the worker enters the "redundant" state, the UA may terminate it
// before all tests have been reported to the client. Stifle errors in
// order to avoid this and ensure all tests are consistently reported.
} catch (err) {}
})());
});
// Workaround because add_cleanup doesn't support async functions yet.
// See https://github.com/web-platform-tests/wpt/issues/6075
async function async_cleanup(cleanup_function) {
try {
await cleanup_function();
} catch (e) {
// Errors in cleanup functions shouldn't result in test failures.
}
}
// Resolves when the service worker receives the 'activate' event.
const kServiceWorkerActivatedPromise = new Promise(resolve => {
self.addEventListener('activate', event => { resolve(); });
});
// sort() comparator that uses the < operator.
//
// This is intended to be used for sorting strings. Using < is preferred to
// localeCompare() because the latter has some implementation-dependent
// behavior.
function CompareStrings(a, b) {
return a < b ? -1 : (b < a ? 1 : 0);
}
promise_test(async testCase => {
await kServiceWorkerActivatedPromise;
const subscriptions = await cookieStore.getChangeSubscriptions();
assert_equals(subscriptions.length, 3);
subscriptions.sort((a, b) => CompareStrings(`${a.name}`, `${b.name}`));
assert_equals(subscriptions[0].name, 'cookie-name1');
assert_equals('equals', subscriptions[0].matchType);
assert_equals(subscriptions[1].name, 'cookie-prefix');
assert_equals('starts-with', subscriptions[1].matchType);
assert_false('name' in subscriptions[2]);
assert_equals('starts-with', subscriptions[2].matchType);
}, 'getChangeSubscriptions returns subscriptions passed to subscribeToChanges');
promise_test(async testCase => {
promise_rejects(
testCase, new TypeError(),
cookieStore.subscribeToChanges([{ name: 'cookie-name2' }]));
}, 'subscribeToChanges rejects when called outside the install handler');
// Accumulates cookiechange events dispatched to the service worker.
let g_cookie_changes = [];
// Resolved when a cookiechange event is received. Rearmed by
// ResetCookieChangeReceivedPromise().
let g_cookie_change_received_promise = null;
let g_cookie_change_received_promise_resolver = null;
self.addEventListener('cookiechange', (event) => {
g_cookie_changes.push(event);
if (g_cookie_change_received_promise_resolver)
g_cookie_change_received_promise_resolver();
});
function RearmCookieChangeReceivedPromise() {
g_cookie_change_received_promise = new Promise((resolve) => {
g_cookie_change_received_promise_resolver = resolve;
});
}
RearmCookieChangeReceivedPromise();
promise_test(async testCase => {
await kServiceWorkerActivatedPromise;
await cookieStore.set('cookie-name', 'cookie-value');
await g_cookie_change_received_promise;
assert_equals(g_cookie_changes.length, 1);
const event = g_cookie_changes[0]
assert_equals(event.type, 'cookiechange');
assert_equals(event.changed.length, 1);
assert_equals(event.changed[0].name, 'cookie-name');
assert_equals(event.changed[0].value, 'cookie-value');
assert_equals(event.deleted.length, 0);
assert_true(event instanceof ExtendableCookieChangeEvent);
assert_true(event instanceof ExtendableEvent);
await async_cleanup(async () => {
await cookieStore.delete('cookie-name');
g_cookie_changes = [];
RearmCookieChangeReceivedPromise();
});
}, 'cookiechange dispatched with cookie change that matches subscription');
done();