Source code

Revision control

Copy as Markdown

Other Tools

// META: script=/common/utils.js
// META: script=/fenced-frame/resources/utils.js
'use strict';
async function IsSharedStorageSelectUrlAllowedByPermissionsPolicy() {
const errorMessage = 'The \"shared-storage-select-url\" Permissions Policy denied the usage of window.sharedStorage.selectURL().';
let allowedByPermissionsPolicy = true;
try {
// Run selectURL() with without addModule() and this should always fail.
// Check the error message to distinguish between the permissions policy
// error and the missing addModule() error.
await sharedStorage.selectURL("operation", [{url: "1.html"}]);
assert_unreached("did not fail");
} catch (e) {
if (e.message === errorMessage) {
allowedByPermissionsPolicy = false;
}
}
return allowedByPermissionsPolicy;
}
// Execute all shared storage methods and capture their errors. Return true if
// the permissions policy allows all of them; return false if the permissions
// policy disallows all of them. Precondition: only these two outcomes are
// possible.
async function AreSharedStorageMethodsAllowedByPermissionsPolicy() {
let permissionsPolicyDeniedCount = 0;
const errorMessage = 'The \"shared-storage\" Permissions Policy denied the method on window.sharedStorage.';
try {
await window.sharedStorage.worklet.addModule('/shared-storage/resources/simple-module.js');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}
try {
await window.sharedStorage.run('operation');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}
try {
// Run selectURL() with without addModule() and this should always fail.
// Check the error message to distinguish between the permissions policy
// error and the missing addModule() error.
await sharedStorage.selectURL("operation", [{url: "1.html"}]);
assert_unreached("did not fail");
} catch (e) {
if (e.message === errorMessage) {
++permissionsPolicyDeniedCount;
}
}
try {
await window.sharedStorage.set('a', 'b');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}
try {
await window.sharedStorage.append('a', 'b');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}
try {
await window.sharedStorage.clear();
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}
try {
await window.sharedStorage.delete('a');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}
if (permissionsPolicyDeniedCount === 0)
return true;
return false;
}
// Run sharedStorage.worklet.addModule once.
// @param {string} module - The URL to the module.
async function addModuleOnce(module) {
try {
await sharedStorage.worklet.addModule(module);
} catch (e) {
// Shared Storage needs to have a module added before we can operate on it.
// It is generated on the fly with this call, and since there's no way to
// tell through the API if a module already exists, wrap the addModule call
// in a try/catch so that if it runs a second time in a test, it will
// gracefully fail rather than bring the whole test down.
}
}
// Validate the type of the result of sharedStorage.worklet.selectURL.
// @param result - The result of sharedStorage.worklet.selectURL.
// @param {boolean} - Whether sharedStorage.worklet.selectURL is resolved to
// a fenced frame config (true) or an urn:uuid (false).
// @return {boolean} Whether sharedStorage.worklet.selectURL returns an expected
// result type or not.
function validateSelectURLResult(result, resolve_to_config) {
if (resolve_to_config) {
return result instanceof FencedFrameConfig;
}
return result.startsWith('urn:uuid:');
}
function updateUrlToUseNewOrigin(url, newOriginString) {
const origin = url.origin;
return new URL(url.toString().replace(origin, newOriginString));
}
function appendExpectedKeyAndValue(url, expectedKey, expectedValue) {
url.searchParams.append('expectedKey', expectedKey);
url.searchParams.append('expectedValue', expectedValue);
return url;
}
function parseExpectedKeyAndValueData() {
const url = new URL(location.href);
const key = url.searchParams.get('expectedKey');
const value = url.searchParams.get('expectedValue');
return {'expectedKey': key, 'expectedValue': value};
}
function appendExpectedKey(url, expectedKey) {
url.searchParams.append('expectedKey', expectedKey);
return url;
}
function parseExpectedKeyData() {
const url = new URL(location.href);
const key = url.searchParams.get('expectedKey');
return {'expectedKey': key};
}
async function verifyKeyValueForOrigin(key, value, origin) {
const outerKey = token();
const innerKey = token();
let iframeUrl = generateURL(
'/shared-storage/resources/verify-key-value.https.html',
[outerKey, innerKey]);
iframeUrl = updateUrlToUseNewOrigin(iframeUrl, origin);
iframeUrl = appendExpectedKeyAndValue(iframeUrl, key, value);
attachIFrame(iframeUrl);
const result = await nextValueFromServer(outerKey);
assert_equals(result, 'verify_key_value_loaded');
}
async function verifyKeyNotFoundForOrigin(key, origin) {
const outerKey = token();
const innerKey = token();
let iframeUrl = generateURL(
'/shared-storage/resources/verify-key-not-found.https.html',
[outerKey, innerKey]);
iframeUrl = updateUrlToUseNewOrigin(iframeUrl, origin);
iframeUrl = appendExpectedKey(iframeUrl, key);
attachIFrame(iframeUrl);
const result = await nextValueFromServer(outerKey);
assert_equals(result, 'verify_key_not_found_loaded');
}
async function setKeyValueForOrigin(key, value, origin) {
const outerKey = token();
let setIframeUrl = generateURL(
'/shared-storage/resources/set-key-value.https.html', [outerKey]);
setIframeUrl = updateUrlToUseNewOrigin(setIframeUrl, origin);
setIframeUrl = appendExpectedKeyAndValue(setIframeUrl, key, value);
attachIFrame(setIframeUrl);
const result = await nextValueFromServer(outerKey);
assert_equals(result, 'set_key_value_loaded');
}
async function deleteKeyForOrigin(key, origin) {
const outerKey = token();
let deleteIframeUrl = generateURL(
'/shared-storage/resources/delete-key.https.html', [outerKey]);
deleteIframeUrl = updateUrlToUseNewOrigin(deleteIframeUrl, origin);
deleteIframeUrl = appendExpectedKey(deleteIframeUrl, key);
attachIFrame(deleteIframeUrl);
const result = await nextValueFromServer(outerKey);
assert_equals(result, 'delete_key_loaded');
}
function getFetchedUrls(worker) {
return new Promise(function(resolve) {
var channel = new MessageChannel();
channel.port1.onmessage = function(msg) {
resolve(msg);
};
worker.postMessage({port: channel.port2}, [channel.port2]);
});
}
function checkInterceptedUrls(worker, expectedRequests) {
return getFetchedUrls(worker).then(function(msg) {
let actualRequests = msg.data.requests;
assert_equals(actualRequests.length, expectedRequests.length);
assert_equals(
JSON.stringify(actualRequests), JSON.stringify(expectedRequests));
});
}