summaryrefslogtreecommitdiffstats
path: root/browser/components/attribution/test/xpcshell/head.js
blob: 2e6c46e72266fb4a82b1c2d43536f2ee1c1d5924 (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
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 */
"use strict";

const { AttributionCode } = ChromeUtils.import(
  "resource:///modules/AttributionCode.jsm"
);

let validAttrCodes = [
  {
    code:
      "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)%26content%3D(not%20set)",
    parsed: {
      source: "google.com",
      medium: "organic",
      campaign: "(not%20set)",
      content: "(not%20set)",
    },
  },
  {
    code: "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D%26content%3D",
    parsed: { source: "google.com", medium: "organic" },
    doesNotRoundtrip: true, // `campaign=` and `=content` are dropped.
  },
  {
    code: "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)",
    parsed: {
      source: "google.com",
      medium: "organic",
      campaign: "(not%20set)",
    },
  },
  {
    code: "source%3Dgoogle.com%26medium%3Dorganic",
    parsed: { source: "google.com", medium: "organic" },
  },
  { code: "source%3Dgoogle.com", parsed: { source: "google.com" } },
  { code: "medium%3Dgoogle.com", parsed: { medium: "google.com" } },
  { code: "campaign%3Dgoogle.com", parsed: { campaign: "google.com" } },
  { code: "content%3Dgoogle.com", parsed: { content: "google.com" } },
  {
    code: "experiment%3Dexperimental",
    parsed: { experiment: "experimental" },
  },
  { code: "variation%3Dvaried", parsed: { variation: "varied" } },
  {
    code: "ua%3DGoogle%20Chrome%20123",
    parsed: { ua: "Google%20Chrome%20123" },
  },
  {
    code: "dltoken%3Dc18f86a3-f228-4d98-91bb-f90135c0aa9c",
    parsed: { dltoken: "c18f86a3-f228-4d98-91bb-f90135c0aa9c" },
  },
];

let invalidAttrCodes = [
  // Empty string
  "",
  // Not escaped
  "source=google.com&medium=organic&campaign=(not set)&content=(not set)",
  // Too long
  "campaign%3D" + "a".repeat(1000),
  // Unknown key name
  "source%3Dgoogle.com%26medium%3Dorganic%26large%3Dgeneticallymodified",
  // Empty key name
  "source%3Dgoogle.com%26medium%3Dorganic%26%3Dgeneticallymodified",
];

/**
 * Arrange for each test to have a unique application path for storing
 * quarantine data.
 *
 * The quarantine data is necessarily a shared system resource, managed by the
 * OS, so we need to avoid polluting it during tests.
 *
 * There are at least two ways to achieve this.  Here we use Sinon to stub the
 * relevant accessors: this has the advantage of being local and relatively easy
 * to follow.  In the App Update Service tests, an `nsIDirectoryServiceProvider`
 * is installed, which is global and much harder to extract for re-use.
 */
async function setupStubs() {
  // Local imports to avoid polluting the global namespace.
  const { AppConstants } = ChromeUtils.import(
    "resource://gre/modules/AppConstants.jsm"
  );
  const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
  const { sinon } = ChromeUtils.import("resource://testing-common/Sinon.jsm");

  // This depends on the caller to invoke it by name.  We do try to
  // prevent the most obvious incorrect invocation, namely
  // `add_task(setupStubs)`.
  let caller = Components.stack.caller;
  const testID = caller.filename
    .toString()
    .split("/")
    .pop()
    .split(".")[0];
  notEqual(testID, "head");

  let applicationFile = do_get_tempdir();
  applicationFile.append(testID);
  applicationFile.append("App.app");

  if (AppConstants.platform == "macosx") {
    // We're implicitly using the fact that modules are shared between importers here.
    const { MacAttribution } = ChromeUtils.import(
      "resource:///modules/MacAttribution.jsm"
    );
    sinon
      .stub(MacAttribution, "applicationPath")
      .get(() => applicationFile.path);
  }

  // The macOS quarantine database applies to existing paths only, so make
  // sure our mock application path exists.  This also creates the parent
  // directory for the attribution file, needed on both macOS and Windows.  We
  // don't ignore existing paths because we're inside a temporary directory:
  // this should never be invoked twice for the same test.
  await OS.File.makeDir(applicationFile.path, { from: do_get_tempdir().path });
}