diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /toolkit/components/cleardata/tests/browser/browser_sessionStorage.js | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/cleardata/tests/browser/browser_sessionStorage.js')
-rw-r--r-- | toolkit/components/cleardata/tests/browser/browser_sessionStorage.js | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/toolkit/components/cleardata/tests/browser/browser_sessionStorage.js b/toolkit/components/cleardata/tests/browser/browser_sessionStorage.js new file mode 100644 index 0000000000..013ae0fa92 --- /dev/null +++ b/toolkit/components/cleardata/tests/browser/browser_sessionStorage.js @@ -0,0 +1,235 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const BASE_DOMAIN_A = "example.com"; +const ORIGIN_A = `https://${BASE_DOMAIN_A}`; +const ORIGIN_A_HTTP = `http://${BASE_DOMAIN_A}`; +const ORIGIN_A_SUB = `https://test1.${BASE_DOMAIN_A}`; + +const BASE_DOMAIN_B = "example.org"; +const ORIGIN_B = `https://${BASE_DOMAIN_B}`; +const ORIGIN_B_HTTP = `http://${BASE_DOMAIN_B}`; +const ORIGIN_B_SUB = `https://test1.${BASE_DOMAIN_B}`; + +const TEST_ROOT_DIR = getRootDirectory(gTestPath); + +// Session storage is only valid for the lifetime of a tab, so we need to keep +// tabs open for the duration of a test. +let originToTabs = {}; + +function getTestURLForOrigin(origin) { + return TEST_ROOT_DIR.replace("chrome://mochitests/content", origin); +} + +function getTestEntryName(origin, partitioned) { + return `${origin}${partitioned ? "_partitioned" : ""}`; +} + +async function testHasEntry(originFirstParty, isSet, originThirdParty) { + let tabs = originToTabs[originFirstParty]; + + for (let tab of tabs) { + // For the partition test we inspect the sessionStorage of the iframe. + let browsingContext = originThirdParty + ? tab.linkedBrowser.browsingContext.children[0] + : tab.linkedBrowser.browsingContext; + let actualSet = await SpecialPowers.spawn( + browsingContext, + [ + getTestEntryName( + originThirdParty || originFirstParty, + !!originThirdParty + ), + ], + key => { + return !!content.sessionStorage.getItem(key); + } + ); + + let msg = `${originFirstParty}${isSet ? " " : " not "}set`; + if (originThirdParty) { + msg = "Partitioned under " + msg; + } + + is(actualSet, isSet, msg); + } +} + +/** + * Creates tabs and sets sessionStorage entries in first party and third party + * context. + * @returns {Promise} - Promise which resolves once all tabs are initialized, + * {@link originToTabs} is populated and (sub-)resources have loaded. + */ +function addTestTabs() { + let promises = [ + [ORIGIN_A, ORIGIN_B], + [ORIGIN_A_SUB, ORIGIN_B_SUB], + [ORIGIN_A_HTTP, ORIGIN_B_HTTP], + [ORIGIN_B, ORIGIN_A], + [ORIGIN_B_SUB, ORIGIN_A_SUB], + [ORIGIN_B_HTTP, ORIGIN_A_HTTP], + ].map(async ([firstParty, thirdParty]) => { + info("Creating new tab for " + firstParty); + let tab = BrowserTestUtils.addTab(gBrowser, firstParty); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + + info("Creating iframe for " + thirdParty); + await SpecialPowers.spawn( + tab.linkedBrowser, + [getTestEntryName(firstParty, false), thirdParty], + async (storageKey, url) => { + // Set unpartitioned sessionStorage for firstParty. + content.sessionStorage.setItem(storageKey, "foo"); + + let iframe = content.document.createElement("iframe"); + iframe.src = url; + + let loadPromise = ContentTaskUtils.waitForEvent(iframe, "load", false); + content.document.body.appendChild(iframe); + await loadPromise; + } + ); + + await SpecialPowers.spawn( + tab.linkedBrowser.browsingContext.children[0], + [getTestEntryName(thirdParty, true)], + async storageKey => { + // Set sessionStorage in partitioned third-party iframe. + content.sessionStorage.setItem(storageKey, "foo"); + } + ); + + let tabs = originToTabs[firstParty]; + if (!tabs) { + tabs = []; + originToTabs[firstParty] = tabs; + } + tabs.push(tab); + }); + + return Promise.all(promises); +} + +function cleanup() { + Object.values(originToTabs).flat().forEach(BrowserTestUtils.removeTab); + originToTabs = {}; + Services.obs.notifyObservers(null, "browser:purge-sessionStorage"); +} + +add_setup(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["network.cookie.cookieBehavior", 5]], + }); + cleanup(); +}); + +add_task(async function test_deleteByBaseDomain() { + await addTestTabs(); + + info("Clearing sessionStorage for base domain A " + BASE_DOMAIN_A); + await new Promise(resolve => { + Services.clearData.deleteDataFromBaseDomain( + BASE_DOMAIN_A, + false, + Ci.nsIClearDataService.CLEAR_DOM_QUOTA, + resolve + ); + }); + + info("All entries for A should have been cleared."); + await testHasEntry(ORIGIN_A, false); + await testHasEntry(ORIGIN_A_SUB, false); + await testHasEntry(ORIGIN_A_HTTP, false); + + info("Entries for B should still exist."); + await testHasEntry(ORIGIN_B, true); + await testHasEntry(ORIGIN_B_SUB, true); + await testHasEntry(ORIGIN_B_HTTP, true); + + info("All partitioned entries for B under A should have been cleared."); + await testHasEntry(ORIGIN_A, false, ORIGIN_B); + await testHasEntry(ORIGIN_A_SUB, false, ORIGIN_B_SUB); + await testHasEntry(ORIGIN_A_HTTP, false, ORIGIN_B_HTTP); + + info("All partitioned entries of A under B should have been cleared."); + await testHasEntry(ORIGIN_B, false, ORIGIN_A); + await testHasEntry(ORIGIN_B_SUB, false, ORIGIN_A_SUB); + await testHasEntry(ORIGIN_B_HTTP, false, ORIGIN_A_HTTP); + + cleanup(); +}); + +add_task(async function test_deleteAll() { + await addTestTabs(); + + info("Clearing sessionStorage for base domain A " + BASE_DOMAIN_A); + await new Promise(resolve => { + Services.clearData.deleteData( + Ci.nsIClearDataService.CLEAR_DOM_QUOTA, + resolve + ); + }); + + info("All entries should have been cleared."); + await testHasEntry(ORIGIN_A, false); + await testHasEntry(ORIGIN_A_SUB, false); + await testHasEntry(ORIGIN_A_HTTP, false); + await testHasEntry(ORIGIN_B, false); + await testHasEntry(ORIGIN_B_SUB, false); + await testHasEntry(ORIGIN_B_HTTP, false); + + info("All partitioned entries should have been cleared."); + await testHasEntry(ORIGIN_A, false, ORIGIN_B); + await testHasEntry(ORIGIN_A_SUB, false, ORIGIN_B_SUB); + await testHasEntry(ORIGIN_A_HTTP, false, ORIGIN_B_HTTP); + await testHasEntry(ORIGIN_B, false, ORIGIN_A); + await testHasEntry(ORIGIN_B_SUB, false, ORIGIN_A_SUB); + await testHasEntry(ORIGIN_B_HTTP, false, ORIGIN_A_HTTP); + + cleanup(); +}); + +add_task(async function test_deleteFromPrincipal() { + await addTestTabs(); + + info("Clearing sessionStorage for partitioned principal A " + BASE_DOMAIN_A); + + let principalA = Services.scriptSecurityManager.createContentPrincipal( + Services.io.newURI(ORIGIN_A), + { partitionKey: `(https,${BASE_DOMAIN_B})` } + ); + + info("principal: " + principalA.origin); + info("principal partitionKey " + principalA.originAttributes.partitionKey); + await new Promise(resolve => { + Services.clearData.deleteDataFromPrincipal( + principalA, + false, + Ci.nsIClearDataService.CLEAR_DOM_QUOTA, + resolve + ); + }); + + info("Unpartitioned entries should still exist."); + await testHasEntry(ORIGIN_A, true); + await testHasEntry(ORIGIN_A_SUB, true); + await testHasEntry(ORIGIN_A_HTTP, true); + await testHasEntry(ORIGIN_B, true); + await testHasEntry(ORIGIN_B_SUB, true); + await testHasEntry(ORIGIN_B_HTTP, true); + + info("Only entries of principal should have been cleared."); + await testHasEntry(ORIGIN_A, true, ORIGIN_B); + await testHasEntry(ORIGIN_A_SUB, true, ORIGIN_B_SUB); + await testHasEntry(ORIGIN_A_HTTP, true, ORIGIN_B_HTTP); + + await testHasEntry(ORIGIN_B, false, ORIGIN_A); + + await testHasEntry(ORIGIN_B_SUB, true, ORIGIN_A_SUB); + await testHasEntry(ORIGIN_B_HTTP, true, ORIGIN_A_HTTP); + + cleanup(); +}); |