162 lines
5.8 KiB
JavaScript
162 lines
5.8 KiB
JavaScript
// META: script=/resources/testdriver.js
|
|
// META: script=/resources/testdriver-vendor.js
|
|
// META: script=/common/utils.js
|
|
// META: script=resources/fledge-util.sub.js
|
|
// META: script=/common/subset-tests.js
|
|
// META: timeout=long
|
|
// META: variant=?1-last
|
|
|
|
"use strict";
|
|
|
|
const SERVICE_WORKER_SCRIPT = "resources/service-worker-helper.js";
|
|
|
|
// List of URL fragments that uniquely identify private requests.
|
|
// These are used to detect if a service worker has inadvertently
|
|
// accessed any of these private requests, which should not be visible to it.
|
|
const PRIVATE_REQUEST_FILE_NAMES = [
|
|
'trusted-bidding-signals.py',
|
|
'update-url.py', // This requires another test, since it takes a while,
|
|
// see TODO file for more info.
|
|
'wasm-helper.py',
|
|
'bidding-logic.py',
|
|
'decision-logic.py',
|
|
'trusted-scoring-signals.py',
|
|
'trusted-bidding-signals.py',
|
|
'bidder_report',
|
|
'seller_report'
|
|
];
|
|
|
|
// List of URL fragments that uniquely identify public requests.
|
|
// These are used to verify that a service worker can correctly
|
|
// access and intercept these public requests as expected.
|
|
const PUBLIC_REQUEST_FILE_NAMES = [
|
|
'direct-from-seller-signals.py',
|
|
];
|
|
|
|
const COMPLETE_TEST_URL = 'complete-test'
|
|
|
|
const CURRENT_SCOPE = "/fledge/tentative/"
|
|
|
|
async function registerAndActivateServiceWorker(test) {
|
|
// Unregister existing service worker (if any)
|
|
const existingRegistration = await navigator.serviceWorker.getRegistration(CURRENT_SCOPE);
|
|
if (existingRegistration) {
|
|
await existingRegistration.unregister();
|
|
}
|
|
|
|
// Register new service worker
|
|
var newRegistration = await navigator.serviceWorker.register(`./${SERVICE_WORKER_SCRIPT}`, { scope: CURRENT_SCOPE });
|
|
|
|
test.add_cleanup(async () => {
|
|
await newRegistration.unregister();
|
|
});
|
|
|
|
await navigator.serviceWorker.ready;
|
|
|
|
// Wait for the page to be controlled by the service worker.
|
|
// This is needed as navigator.serviceWorker.ready does not
|
|
// guarantee that the page is being controlled.
|
|
// See https://github.com/slightlyoff/ServiceWorker/issues/799.
|
|
await new Promise(resolve => {
|
|
if (navigator.serviceWorker.controller) {
|
|
resolve();
|
|
} else {
|
|
navigator.serviceWorker.addEventListener('controllerchange', resolve);
|
|
}
|
|
});
|
|
|
|
// Validate the service worker
|
|
if (!navigator.serviceWorker.controller.scriptURL.includes(SERVICE_WORKER_SCRIPT)) {
|
|
throw new Error('Failed to register service worker');
|
|
}
|
|
}
|
|
|
|
async function setUpServiceWorkerAndGetBroadcastChannel(test) {
|
|
await registerAndActivateServiceWorker(test);
|
|
return new BroadcastChannel("requests-test");
|
|
}
|
|
|
|
// Waits for a service worker to observe specific URL filenames via a BroadcastChannel.
|
|
// Resolves when all expected URL filenames are seen.
|
|
function awaitServiceWorkerURLPromise(broadcastChannel, expectedURLFileNames,
|
|
unexpectedURLFileNames) {
|
|
const seenURLs = new Set();
|
|
return new Promise((resolve, reject) => {
|
|
broadcastChannel.addEventListener('message', (event) => {
|
|
var url = event.data.url;
|
|
var fileName = url.substring(url.lastIndexOf('/') + 1);
|
|
if (expectedURLFileNames.includes(fileName)) {
|
|
seenURLs.add(fileName);
|
|
}
|
|
if (unexpectedURLFileNames.includes(fileName)) {
|
|
reject(`unexpected result: ${fileName}`);
|
|
}
|
|
// Resolve when all `expectedURLs` have been seen.
|
|
if (seenURLs.size === expectedURLFileNames.length) {
|
|
resolve();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Tests that public requests are seen by the service worker.
|
|
// Specifically anything that contains:
|
|
// - 'direct-from-seller-signals.py'
|
|
|
|
// This test works by having the service worker send a message over
|
|
// the broadcastChannel, if it sees a request that contains any of
|
|
// the following strings above, it will send a 'passed' result and
|
|
// also change the variable 'finish_test', to true, so that guarantees
|
|
// that the request was seen before we complete the test.
|
|
subsetTest(promise_test, async test => {
|
|
const broadcastChannel = await setUpServiceWorkerAndGetBroadcastChannel(test);
|
|
let finishTest = awaitServiceWorkerURLPromise(
|
|
broadcastChannel,
|
|
PUBLIC_REQUEST_FILE_NAMES,
|
|
PRIVATE_REQUEST_FILE_NAMES);
|
|
|
|
await fetchDirectFromSellerSignals({ 'Buyer-Origin': window.location.origin });
|
|
await finishTest;
|
|
}, "Make sure service workers do see public requests.");
|
|
|
|
// Tests that private requests are not seen by the service worker.
|
|
// Specifically anything that contains:
|
|
// - 'resources/trusted-bidding-signals.py'
|
|
// - 'resources/trusted-scoring-signals.py'
|
|
// - 'wasm-helper.py'
|
|
// - 'bidding-logic.py'
|
|
// - 'decision-logic.py'
|
|
// - 'seller_report'
|
|
// - 'bidder_report'
|
|
|
|
// This test works by having the service worker send a message
|
|
// over the broadcastChannel, if it sees a request that contains
|
|
// any of the following strings above, it will send a 'failed'
|
|
// result which will cause assert_false case to fail.
|
|
subsetTest(promise_test, async test => {
|
|
const uuid = generateUuid(test);
|
|
const broadcastChannel = await setUpServiceWorkerAndGetBroadcastChannel(test);
|
|
|
|
let finishTest = awaitServiceWorkerURLPromise(
|
|
broadcastChannel,
|
|
/*expectedURLFileNames=*/[COMPLETE_TEST_URL],
|
|
PRIVATE_REQUEST_FILE_NAMES)
|
|
|
|
let interestGroupOverrides = {
|
|
biddingWasmHelperURL: `${RESOURCE_PATH}wasm-helper.py`,
|
|
trustedBiddingSignalsURL: TRUSTED_BIDDING_SIGNALS_URL,
|
|
trustedScoringSignalsURL: TRUSTED_SCORING_SIGNALS_URL,
|
|
};
|
|
|
|
await joinInterestGroup(test, uuid, interestGroupOverrides);
|
|
await runBasicFledgeAuctionAndNavigate(test, uuid);
|
|
// By verifying that these requests are observed we can assume
|
|
// none of the other requests were seen by the service-worker.
|
|
await waitForObservedRequests(
|
|
uuid,
|
|
[createBidderReportURL(uuid), createSellerReportURL(uuid)]);
|
|
|
|
// We use this fetch to complete the test.
|
|
await fetch(COMPLETE_TEST_URL);
|
|
await finishTest;
|
|
}, "Make sure service workers do not see private requests");
|