Skip to content

Commit 4c1d110

Browse files
authored
Merge pull request #341 from apasel422/user-clear
Add e2e tests for user-initiated data clears
2 parents 050e4d2 + 5c7dcc6 commit 4c1d110

File tree

6 files changed

+159
-12
lines changed

6 files changed

+159
-12
lines changed

api.bs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,7 @@ returning an [=epoch index=]:
13381338
<div algorithm="clear browsing history for attribution">
13391339
To <dfn>clear browsing history for attribution</dfn>,
13401340
given a [=set=] of [=sites=] |sites|,
1341-
a [=boolean=] |forgetVisits|,
1341+
a [=boolean=] <dfn for="clear browsing history for attribution"><var>forgetVisits</var></dfn>,
13421342
and a [=moment=] |now|:
13431343

13441344
1. If |forgetVisits| is false:
@@ -2947,7 +2947,7 @@ When clearing site data at the request of a [=user=],
29472947
but retaining browsing history,
29482948
a [=user agent=] invokes [=clear browsing history for attribution=],
29492949
given the [=set=] of affected [=sites=],
2950-
false (for |forgetVisits|),
2950+
false (for [=clear browsing history for attribution/forgetVisits=]),
29512951
and the time that the action was taken.
29522952
This sets the privacy budget for that site to zero,
29532953
preventing any use of conversion measurement on that site.
@@ -2975,7 +2975,7 @@ when removing browsing history.
29752975
A user agent that clears browsing history
29762976
invokes [=clear browsing history for attribution=],
29772977
given the [=set=] of affected [=sites=],
2978-
true (for |forgetVisits|),
2978+
true (for [=clear browsing history for attribution/forgetVisits=]),
29792979
and the time that the operation was initiated.
29802980

29812981
When clearing browsing history,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"events": [
3+
{
4+
"seconds": 1,
5+
"site": "a.example",
6+
"event": "saveImpression",
7+
"options": { "histogramIndex": 0 }
8+
},
9+
{
10+
"seconds": 2,
11+
"site": "advertiser-1.example",
12+
"event": "measureConversion",
13+
"options": {
14+
"aggregationService": "https://agg-service.example",
15+
"epsilon": 0.1,
16+
"histogramSize": 1
17+
},
18+
"expected": [1]
19+
},
20+
{
21+
"seconds": 3,
22+
"event": "clearBrowsingHistoryForAttribution",
23+
"sites": ["advertiser-1.example"],
24+
"forgetVisits": false
25+
},
26+
{
27+
"seconds": 4,
28+
"site": "advertiser-1.example",
29+
"event": "measureConversion",
30+
"$comment": "re-run query, expecting budget to have been zeroed",
31+
"options": {
32+
"aggregationService": "https://agg-service.example",
33+
"epsilon": 0.1,
34+
"histogramSize": 1
35+
},
36+
"expected": [0]
37+
},
38+
{
39+
"seconds": 5,
40+
"site": "advertiser-2.example",
41+
"$comment": "re-run query with different conversion site, expecting separate budget",
42+
"event": "measureConversion",
43+
"options": {
44+
"aggregationService": "https://agg-service.example",
45+
"epsilon": 0.1,
46+
"histogramSize": 1
47+
},
48+
"expected": [1]
49+
}
50+
]
51+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"$comment": "TODO: Add coverage for other epochs",
3+
"events": [
4+
{
5+
"seconds": 1,
6+
"site": "a.example",
7+
"event": "saveImpression",
8+
"options": { "histogramIndex": 0 }
9+
},
10+
{
11+
"seconds": 2,
12+
"site": "advertiser-1.example",
13+
"event": "measureConversion",
14+
"options": {
15+
"aggregationService": "https://agg-service.example",
16+
"epsilon": 0.1,
17+
"histogramSize": 1
18+
},
19+
"expected": [1]
20+
},
21+
{
22+
"seconds": 3,
23+
"event": "clearBrowsingHistoryForAttribution",
24+
"sites": ["advertiser-1.example"],
25+
"forgetVisits": true
26+
},
27+
{
28+
"seconds": 4,
29+
"site": "a.example",
30+
"event": "saveImpression",
31+
"$comment": "add an impression to be sure that budget is affected below, rather than impressions",
32+
"options": { "histogramIndex": 0 }
33+
},
34+
{
35+
"seconds": 5,
36+
"site": "advertiser-1.example",
37+
"event": "measureConversion",
38+
"$comment": "re-run query, expecting budget to have been zeroed",
39+
"options": {
40+
"aggregationService": "https://agg-service.example",
41+
"epsilon": 0.1,
42+
"histogramSize": 1
43+
},
44+
"expected": [0]
45+
},
46+
{
47+
"seconds": 6,
48+
"site": "advertiser-2.example",
49+
"$comment": "re-run query with different conversion site, expecting epoch to be off-limits",
50+
"event": "measureConversion",
51+
"options": {
52+
"aggregationService": "https://agg-service.example",
53+
"epsilon": 0.1,
54+
"histogramSize": 1
55+
},
56+
"expected": [0]
57+
}
58+
]
59+
}

impl/e2e.schema.json

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"type": "object",
6565
"oneOf": [
6666
{
67-
"$ref": "#/$defs/commonEvent",
67+
"$ref": "#/$defs/siteEvent",
6868
"properties": {
6969
"event": {
7070
"const": "saveImpression"
@@ -83,7 +83,7 @@
8383
"unevaluatedProperties": false
8484
},
8585
{
86-
"$ref": "#/$defs/commonEvent",
86+
"$ref": "#/$defs/siteEvent",
8787
"properties": {
8888
"event": {
8989
"const": "measureConversion"
@@ -113,13 +113,29 @@
113113
"unevaluatedProperties": false
114114
},
115115
{
116-
"$ref": "#/$defs/commonEvent",
116+
"$ref": "#/$defs/siteEvent",
117117
"properties": {
118118
"event": {
119119
"const": "clearImpressionsForSite"
120120
}
121121
},
122122
"unevaluatedProperties": false
123+
},
124+
{
125+
"$ref": "#/$defs/commonEvent",
126+
"properties": {
127+
"event": {
128+
"const": "clearBrowsingHistoryForAttribution"
129+
},
130+
"forgetVisits": {
131+
"type": "boolean"
132+
},
133+
"sites": {
134+
"$ref": "#/$defs/siteList"
135+
}
136+
},
137+
"required": ["forgetVisits", "sites"],
138+
"unevaluatedProperties": false
123139
}
124140
]
125141
}
@@ -205,12 +221,9 @@
205221
},
206222
"seconds": {
207223
"type": "integer"
208-
},
209-
"site": {
210-
"type": "string"
211224
}
212225
},
213-
"required": ["seconds", "site"]
226+
"required": ["seconds"]
214227
},
215228
"expectedError": {
216229
"oneOf": [
@@ -232,6 +245,16 @@
232245
}
233246
]
234247
},
248+
"siteEvent": {
249+
"$ref": "#/$defs/commonEvent",
250+
"type": "object",
251+
"properties": {
252+
"site": {
253+
"type": "string"
254+
}
255+
},
256+
"required": ["site"]
257+
},
235258
"siteList": {
236259
"type": "array",
237260
"items": {

impl/src/clear.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ void test("forget-one-site-conversions", async () => {
127127

128128
backend.clearState(["conv-one.example"], true);
129129

130-
// Conversions are unaffected, and conversion state is gone.
130+
// Impressions are unaffected, and conversion state is gone.
131131
assert.equal(backend.impressions.length, siteTable.length);
132132
assert.deepEqual(backend.privacyBudgetEntries, []);
133133
assert.deepEqual(backend.epochStarts, new Map());

impl/src/e2e.test.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ interface TestCase {
1919
events: Event[];
2020
}
2121

22-
type Event = SaveImpression | MeasureConversion | ClearImpressionsForSite;
22+
type Event =
23+
| SaveImpression
24+
| MeasureConversion
25+
| ClearImpressionsForSite
26+
| ClearBrowsingHistoryForAttribution;
2327

2428
type ExpectedError =
2529
| "RangeError"
@@ -53,6 +57,13 @@ interface ClearImpressionsForSite {
5357
site: string;
5458
}
5559

60+
interface ClearBrowsingHistoryForAttribution {
61+
event: "clearBrowsingHistoryForAttribution";
62+
seconds: number;
63+
sites: string[];
64+
forgetVisits: boolean;
65+
}
66+
5667
function assertThrows(
5768
call: () => unknown,
5869
expectedError: ExpectedError,
@@ -148,6 +159,9 @@ function runTest(
148159
case "clearImpressionsForSite":
149160
backend.clearImpressionsForSite(event.site);
150161
break;
162+
case "clearBrowsingHistoryForAttribution":
163+
backend.clearState(event.sites, event.forgetVisits);
164+
break;
151165
}
152166
}
153167
}

0 commit comments

Comments
 (0)