Files
sousa-gecko/browser/modules/test/unit/test_SiteDataManagerContainers.js
T
Emma Zuehlcke bf9ab44218 Bug 2041131 - Find container cookies in SiteDataManager.hasSiteData. r=necko-reviewers,cookie-reviewers,jesup,timhuang
countCookiesFromHost only looks at the default-OriginAttributes bucket of the
cookie storage hashtable, so cookies stored in a Multi-Account Container
(non-zero userContextId) or under a partitionKey are invisible to it. Since
bug 2019928, the address-bar trust panel's "Clear cookies and site data" menu
item is gated on SiteDataManager.hasSiteData, which calls countCookiesFromHost
and therefore reports no data for containerised sites even when cookies exist.

Add nsICookieManager.hasCookiesForSite(host, OriginAttributesPattern). It
iterates mHostTable and returns true greedily on the first non-empty entry
whose base domain matches and whose OriginAttributes match the supplied
pattern, so containers and partition keys are covered. SiteDataManager.hasSiteData
now uses it with privateBrowsingId: 0, preserving the existing non-PB
scoping. Document the OA limitation on countCookiesFromHost.

Adds:
- gtest covering empty storage, default OA, container, PBM isolation, and partitionKey.
- xpcshell coverage in test_SiteDataManager.js (non-container smoke) and
  test_SiteDataManagerContainers.js (the direct regression case).

Differential Revision: https://phabricator.services.mozilla.com/D302040
2026-05-26 12:37:54 +00:00

182 lines
4.7 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
const { SiteDataManager } = ChromeUtils.importESModule(
"resource:///modules/SiteDataManager.sys.mjs"
);
const { SiteDataTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/SiteDataTestUtils.sys.mjs"
);
const EXAMPLE_ORIGIN = "https://www.example.com";
const EXAMPLE_ORIGIN_2 = "https://example.org";
add_task(function setup() {
do_get_profile();
});
add_task(async function testGetSitesByContainers() {
SiteDataTestUtils.addToCookies({
origin: EXAMPLE_ORIGIN,
name: "foo1",
value: "bar1",
originAttributes: { userContextId: "1" },
});
SiteDataTestUtils.addToCookies({
origin: EXAMPLE_ORIGIN,
name: "foo2",
value: "bar2",
originAttributes: { userContextId: "2" },
});
SiteDataTestUtils.addToCookies({
origin: EXAMPLE_ORIGIN,
name: "foo3",
value: "bar3",
originAttributes: { userContextId: "2" },
});
SiteDataTestUtils.addToCookies({
origin: EXAMPLE_ORIGIN_2,
name: "foo",
value: "bar",
originAttributes: { userContextId: "3" },
});
await SiteDataTestUtils.addToIndexedDB(
EXAMPLE_ORIGIN + "^userContextId=1",
4096
);
await SiteDataTestUtils.addToIndexedDB(
EXAMPLE_ORIGIN_2 + "^userContextId=3",
2048
);
await SiteDataManager.updateSites();
let sites = await SiteDataManager.getSites();
let site1Container1 = sites
.find(site => site.baseDomain == "example.com")
.containersData.get(1);
let site1Container2 = sites
.find(site => site.baseDomain == "example.com")
.containersData.get(2);
let site2Container3 = sites
.find(site => site.baseDomain == "example.org")
.containersData.get(3);
Assert.equal(
sites.reduce(
(accumulator, site) => accumulator + site.containersData.size,
0
),
3,
"Has the correct number of sites by containers"
);
Assert.equal(
site1Container1.cookiesBlocked,
1,
"Has the correct number of cookiesBlocked by containers"
);
Assert.greater(
site1Container1.quotaUsage,
4096,
"Has correct usage for example.com^userContextId=1"
);
Assert.equal(
typeof site1Container1.lastAccessed.getDate,
"function",
"lastAccessed for example.com^userContextId=1 is a Date"
);
// Note: this is comparing a date and a number, and Assert.greater requires
// inputs to be the same type. bug 1973910 covers fixing this.
// eslint-disable-next-line mozilla/no-comparison-or-assignment-inside-ok
Assert.ok(
site1Container1.lastAccessed > Date.now() - 60 * 1000,
"lastAccessed for example.com^userContextId=1 happened recently"
);
Assert.equal(
site1Container2.cookiesBlocked,
2,
"Has the correct number of cookiesBlocked by containers"
);
Assert.equal(
site1Container2.quotaUsage,
0,
"Has correct usage for example.org^userContextId=2"
);
Assert.equal(
typeof site1Container2.lastAccessed.getDate,
"function",
"lastAccessed for example.com^userContextId=2 is a Date"
);
Assert.equal(
site2Container3.cookiesBlocked,
1,
"Has the correct number of cookiesBlocked by containers"
);
Assert.greater(
site2Container3.quotaUsage,
2048,
"Has correct usage for example.org^userContextId=3"
);
Assert.equal(
typeof site2Container3.lastAccessed.getDate,
"function",
"lastAccessed for example.org^userContextId=3 is a Date"
);
// Note: this is comparing a date and a number, and Assert.greater requires
// inputs to be the same type. bug 1973910 covers fixing this.
// eslint-disable-next-line mozilla/no-comparison-or-assignment-inside-ok
Assert.ok(
site2Container3.lastAccessed > Date.now() - 60 * 1000,
"lastAccessed for example.org^userContextId=3 happened recently"
);
await SiteDataTestUtils.clear();
});
// Regression test for Bug 2041131: SiteDataManager.hasSiteData must return
// true when the only cookies for a host live inside a container. The shield
// icon's "Clear cookies and site data" button is gated on this.
add_task(async function testHasSiteDataForContainerCookies() {
Assert.equal(
await SiteDataManager.hasSiteData("www.example.com"),
false,
"hasSiteData returns false when no data exists"
);
SiteDataTestUtils.addToCookies({
origin: EXAMPLE_ORIGIN,
name: "container-only",
value: "v",
originAttributes: { userContextId: "1" },
});
Assert.equal(
await SiteDataManager.hasSiteData("www.example.com"),
true,
"hasSiteData finds cookies stored in a non-default container"
);
Assert.equal(
await SiteDataManager.hasSiteData("no-data.example"),
false,
"hasSiteData returns false for a host with no data"
);
await SiteDataTestUtils.clear();
});