summaryrefslogtreecommitdiffstats
path: root/toolkit/components/telemetry/tests/unit/test_UninstallPing.js
blob: d619ebb10e02ddc17ef5db61475895f4ff1a8ce8 (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
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 */
"use strict";

const { BasePromiseWorker } = ChromeUtils.importESModule(
  "resource://gre/modules/PromiseWorker.sys.mjs"
);
const { TelemetryStorage } = ChromeUtils.importESModule(
  "resource://gre/modules/TelemetryStorage.sys.mjs"
);
const { FileUtils } = ChromeUtils.importESModule(
  "resource://gre/modules/FileUtils.sys.mjs"
);

const gFakeInstallPathHash = "0123456789ABCDEF";
let gFakeVendorDirectory;
let gFakeGetUninstallPingPath;

add_setup(async function setup() {
  do_get_profile();

  let fakeVendorDirectoryNSFile = new FileUtils.File(
    PathUtils.join(PathUtils.profileDir, "uninstall-ping-test")
  );
  fakeVendorDirectoryNSFile.createUnique(
    Ci.nsIFile.DIRECTORY_TYPE,
    FileUtils.PERMS_DIRECTORY
  );
  gFakeVendorDirectory = fakeVendorDirectoryNSFile.path;

  gFakeGetUninstallPingPath = id => ({
    directory: fakeVendorDirectoryNSFile.clone(),
    file: `uninstall_ping_${gFakeInstallPathHash}_${id}.json`,
  });

  fakeUninstallPingPath(gFakeGetUninstallPingPath);

  registerCleanupFunction(async () => {
    await IOUtils.remove(gFakeVendorDirectory, { recursive: true });
  });
});

function ping_path(ping) {
  let { directory: pingFile, file } = gFakeGetUninstallPingPath(ping.id);
  pingFile.append(file);
  return pingFile.path;
}

add_task(async function test_store_ping() {
  // Remove shouldn't throw on an empty dir.
  await TelemetryStorage.removeUninstallPings();

  // Write ping
  const ping1 = {
    id: "58b63aac-999e-4efb-9d5a-20f368670721",
    payload: { some: "thing" },
  };
  const ping1Path = ping_path(ping1);
  await TelemetryStorage.saveUninstallPing(ping1);

  // Check the ping
  Assert.ok(await IOUtils.exists(ping1Path));
  const readPing1 = await IOUtils.readJSON(ping1Path);
  Assert.deepEqual(ping1, readPing1);

  // Write another file that shouldn't match the pattern
  const otherFilePath = PathUtils.join(gFakeVendorDirectory, "other_file.json");
  await IOUtils.writeUTF8(otherFilePath, "");
  Assert.ok(await IOUtils.exists(otherFilePath));

  // Write another ping, should remove the earlier one
  const ping2 = {
    id: "7202c564-8f23-41b4-8a50-1744e9549260",
    payload: { another: "thing" },
  };
  const ping2Path = ping_path(ping2);
  await TelemetryStorage.saveUninstallPing(ping2);

  Assert.ok(!(await IOUtils.exists(ping1Path)));
  Assert.ok(await IOUtils.exists(ping2Path));
  Assert.ok(await IOUtils.exists(otherFilePath));

  // Write an additional file manually so there are multiple matching pings to remove
  const ping3 = { id: "yada-yada" };
  const ping3Path = ping_path(ping3);

  await IOUtils.writeUTF8(ping3Path, "");
  Assert.ok(await IOUtils.exists(ping3Path));

  // Remove pings
  await TelemetryStorage.removeUninstallPings();

  // Check our pings are removed but other file isn't
  Assert.ok(!(await IOUtils.exists(ping1Path)));
  Assert.ok(!(await IOUtils.exists(ping2Path)));
  Assert.ok(!(await IOUtils.exists(ping3Path)));
  Assert.ok(await IOUtils.exists(otherFilePath));

  // Remove again, confirming that the remove doesn't cause an error if nothing to remove
  await TelemetryStorage.removeUninstallPings();

  const ping4 = {
    id: "1f113673-753c-4fbe-9143-fe197f936036",
    payload: { any: "thing" },
  };
  const ping4Path = ping_path(ping4);
  await TelemetryStorage.saveUninstallPing(ping4);

  // Use a worker to keep the ping file open, so a delete should fail.
  const worker = new BasePromiseWorker(
    "resource://test/file_UninstallPing.worker.js"
  );
  await worker.post("open", [ping4Path]);

  // Check that there is no error if the file can't be removed.
  await TelemetryStorage.removeUninstallPings();

  // And file should still exist.
  Assert.ok(await IOUtils.exists(ping4Path));

  // Close the file, so it should be possible to remove now.
  await worker.post("close");
  await TelemetryStorage.removeUninstallPings();
  Assert.ok(!(await IOUtils.exists(ping4Path)));
});