summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/sanitize/browser_sanitizeDialog_v2_dataSizes.js
blob: ccb3c7d519def84fd7ecbffd978069e332fbb47e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * This tests the new clear history dialog's data size display functionality
 */
ChromeUtils.defineESModuleGetters(this, {
  sinon: "resource://testing-common/Sinon.sys.mjs",
  Sanitizer: "resource:///modules/Sanitizer.sys.mjs",
});

add_setup(async function () {
  await blankSlate();
  registerCleanupFunction(async function () {
    await blankSlate();
    await PlacesTestUtils.promiseAsyncUpdates();
  });
  await SpecialPowers.pushPrefEnv({
    set: [["privacy.sanitize.useOldClearHistoryDialog", false]],
  });
});

/**
 * Helper function to validate the data sizes shown for each time selection
 *
 * @param {ClearHistoryDialogHelper} dh - dialog object to access window and timespan
 */
async function validateDataSizes(ClearHistoryDialogHelper) {
  let timespans = [
    "TIMESPAN_HOUR",
    "TIMESPAN_2HOURS",
    "TIMESPAN_4HOURS",
    "TIMESPAN_TODAY",
    "TIMESPAN_EVERYTHING",
  ];

  // get current data sizes from siteDataManager
  let cacheUsage = await SiteDataManager.getCacheSize();
  let quotaUsage = await SiteDataManager.getQuotaUsageForTimeRanges(timespans);

  for (let i = 0; i < timespans.length; i++) {
    // select timespan to check
    ClearHistoryDialogHelper.selectDuration(Sanitizer[timespans[i]]);

    // get the elements
    let clearCookiesAndSiteDataCheckbox =
      ClearHistoryDialogHelper.win.document.getElementById("cookiesAndStorage");
    let clearCacheCheckbox =
      ClearHistoryDialogHelper.win.document.getElementById("cache");

    let [convertedQuotaUsage] = DownloadUtils.convertByteUnits(
      quotaUsage[timespans[i]]
    );
    let [, convertedCacheUnit] = DownloadUtils.convertByteUnits(cacheUsage);

    // Ensure l10n is finished before inspecting the category labels.
    await ClearHistoryDialogHelper.win.document.l10n.translateElements([
      clearCookiesAndSiteDataCheckbox,
      clearCacheCheckbox,
    ]);
    ok(
      clearCacheCheckbox.label.includes(convertedCacheUnit),
      "Should show the cache usage"
    );
    ok(
      clearCookiesAndSiteDataCheckbox.label.includes(convertedQuotaUsage),
      `Should show the quota usage as ${convertedQuotaUsage}`
    );
  }
}

/**
 * Helper function to simulate switching timespan selections and
 * validate data sizes before and after clearing
 *
 * @param {Object}
 *    clearCookies - boolean
 *    clearDownloads - boolean
 *    clearCaches - boolean
 *    timespan - one of Sanitizer.TIMESPAN_*
 */
async function clearAndValidateDataSizes({
  clearCache,
  clearDownloads,
  clearCookies,
  timespan,
}) {
  await blankSlate();

  await addToSiteUsage();
  let promiseSanitized = promiseSanitizationComplete();

  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });

  let dh = new ClearHistoryDialogHelper({ checkingDataSizes: true });
  dh.onload = async function () {
    await validateDataSizes(this);
    this.checkPrefCheckbox("cache", clearCache);
    this.checkPrefCheckbox("cookiesAndStorage", clearCookies);
    this.checkPrefCheckbox("historyFormDataAndDownloads", clearDownloads);
    this.selectDuration(timespan);
    this.acceptDialog();
  };
  dh.onunload = async function () {
    await promiseSanitized;
  };
  dh.open();
  await dh.promiseClosed;

  let dh2 = new ClearHistoryDialogHelper({ checkingDataSizes: true });
  // Check if the newly cleared values are reflected
  dh2.onload = async function () {
    await validateDataSizes(this);
    this.acceptDialog();
  };
  dh2.open();
  await dh2.promiseClosed;

  await SiteDataTestUtils.clear();
  BrowserTestUtils.removeTab(gBrowser.selectedTab);
}

add_task(async function test_cookie_sizes() {
  await clearAndValidateDataSizes({
    clearCookies: true,
    clearCache: false,
    clearDownloads: false,
    timespan: Sanitizer.TIMESPAN_HOUR,
  });
  await clearAndValidateDataSizes({
    clearCookies: true,
    clearCache: false,
    clearDownloads: false,
    timespan: Sanitizer.TIMESPAN_4HOURS,
  });
  await clearAndValidateDataSizes({
    clearCookies: true,
    clearCache: false,
    clearDownloads: false,
    timespan: Sanitizer.TIMESPAN_EVERYTHING,
  });
});

add_task(async function test_cache_sizes() {
  await clearAndValidateDataSizes({
    clearCookies: false,
    clearCache: true,
    clearDownloads: false,
    timespan: Sanitizer.TIMESPAN_HOUR,
  });
  await clearAndValidateDataSizes({
    clearCookies: false,
    clearCache: true,
    clearDownloads: false,
    timespan: Sanitizer.TIMESPAN_4HOURS,
  });
  await clearAndValidateDataSizes({
    clearCookies: false,
    clearCache: true,
    clearDownloads: false,
    timespan: Sanitizer.TIMESPAN_EVERYTHING,
  });
});

add_task(async function test_all_data_sizes() {
  await clearAndValidateDataSizes({
    clearCookies: true,
    clearCache: true,
    clearDownloads: true,
    timespan: Sanitizer.TIMESPAN_HOUR,
  });
  await clearAndValidateDataSizes({
    clearCookies: true,
    clearCache: true,
    clearDownloads: true,
    timespan: Sanitizer.TIMESPAN_4HOURS,
  });
  await clearAndValidateDataSizes({
    clearCookies: true,
    clearCache: true,
    clearDownloads: true,
    timespan: Sanitizer.TIMESPAN_EVERYTHING,
  });
});

// This test makes sure that the user can change their timerange option
// even if the data sizes are not loaded yet.
add_task(async function testUIWithDataSizesLoading() {
  await blankSlate();
  await addToSiteUsage();

  let origGetQuotaUsageForTimeRanges =
    SiteDataManager.getQuotaUsageForTimeRanges.bind(SiteDataManager);
  let resolveStubFn;
  let resolverAssigned = false;

  let dh = new ClearHistoryDialogHelper();
  // Create a sandbox for isolated stubbing within the test
  let sandbox = sinon.createSandbox();
  sandbox
    .stub(SiteDataManager, "getQuotaUsageForTimeRanges")
    .callsFake(async (...args) => {
      info("stub called");

      let dataSizesReadyToLoadPromise = new Promise(resolve => {
        resolveStubFn = resolve;
        info("Sending message to notify dialog that the resolver is assigned");
        window.postMessage("resolver-assigned", "*");
        resolverAssigned = true;
      });
      await dataSizesReadyToLoadPromise;
      return origGetQuotaUsageForTimeRanges(...args);
    });
  dh.onload = async function () {
    // we add this event listener in the case where init finishes before the resolver is assigned
    if (!resolverAssigned) {
      await new Promise(resolve => {
        let listener = event => {
          if (event.data === "resolver-assigned") {
            window.removeEventListener("message", listener);
            // we are ready to test the dialog without any data sizes loaded
            resolve();
          }
        };
        window.addEventListener("message", listener);
      });
    }

    ok(
      !this.win.gSanitizePromptDialog._dataSizesUpdated,
      "Data sizes should not have loaded yet"
    );
    this.selectDuration(Sanitizer.TIMESPAN_2HOURS);

    info("triggering loading state end");
    resolveStubFn();

    await this.win.gSanitizePromptDialog.dataSizesFinishedUpdatingPromise;

    validateDataSizes(this);
    this.cancelDialog();
  };
  dh.open();
  await dh.promiseClosed;

  // Restore the sandbox after the test is complete
  sandbox.restore();
});

add_task(async function testClearingBeforeDataSizesLoad() {
  await blankSlate();
  await addToSiteUsage();

  // add site data that we can verify if it gets cleared
  await createDummyDataForHost("example.org");
  await createDummyDataForHost("example.com");

  ok(
    await SiteDataTestUtils.hasIndexedDB("https://example.org"),
    "We have indexedDB data for example.org"
  );
  ok(
    await SiteDataTestUtils.hasIndexedDB("https://example.com"),
    "We have indexedDB data for example.com"
  );

  let dh = new ClearHistoryDialogHelper();
  let promiseSanitized = promiseSanitizationComplete();
  // Create a sandbox for isolated stubbing within the test
  let sandbox = sinon.createSandbox();
  sandbox
    .stub(SiteDataManager, "getQuotaUsageForTimeRanges")
    .callsFake(async () => {
      info("stub called");

      info("This promise should never resolve");
      await new Promise(resolve => {});
    });
  dh.onload = async function () {
    // we don't need to initiate a event listener to wait for the resolver to be assigned for this
    // test since we do not want the data sizes to load
    ok(
      !this.win.gSanitizePromptDialog._dataSizesUpdated,
      "Data sizes should not be loaded yet"
    );
    this.selectDuration(Sanitizer.TIMESPAN_2HOURS);
    this.checkPrefCheckbox("cookiesAndStorage", true);
    this.acceptDialog();
  };
  dh.onunload = async () => {
    await promiseSanitized;
  };
  dh.open();
  await dh.promiseClosed;

  // Data for example.org should be cleared
  ok(
    !(await SiteDataTestUtils.hasIndexedDB("https://example.org")),
    "We don't have indexedDB data for example.org"
  );
  // Data for example.com should be cleared
  ok(
    !(await SiteDataTestUtils.hasIndexedDB("https://example.com")),
    "We don't have indexedDB data for example.com"
  );

  // Restore the sandbox after the test is complete
  sandbox.restore();
});