summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/test/xpcshell/test_XPIStates.js
blob: f769f8e4fd95627bdcdb9ef198d947bd21505285 (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
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

// Test that we only check manifest age for disabled extensions

createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");

const profileDir = gProfD.clone();
profileDir.append("extensions");

add_task(async function setup() {
  await promiseStartupManager();
  registerCleanupFunction(promiseShutdownManager);

  await promiseInstallWebExtension({
    manifest: {
      browser_specific_settings: { gecko: { id: "enabled@tests.mozilla.org" } },
    },
  });
  await promiseInstallWebExtension({
    manifest: {
      browser_specific_settings: {
        gecko: { id: "disabled@tests.mozilla.org" },
      },
    },
  });

  let addon = await promiseAddonByID("disabled@tests.mozilla.org");
  notEqual(addon, null);
  await addon.disable();
});

// Keep track of the last time stamp we've used, so that we can keep moving
// it forward (if we touch two different files in the same add-on with the same
// timestamp we may not consider the change significant)
var lastTimestamp = Date.now();

/*
 * Helper function to touch a file and then test whether we detect the change.
 * @param XS      The XPIState object.
 * @param aPath   File path to touch.
 * @param aChange True if we should notice the change, False if we shouldn't.
 */
function checkChange(XS, aPath, aChange) {
  Assert.ok(aPath.exists());
  lastTimestamp += 10000;
  info("Touching file " + aPath.path + " with " + lastTimestamp);
  aPath.lastModifiedTime = lastTimestamp;
  Assert.equal(XS.scanForChanges(), aChange);
  // Save the pref so we don't detect this change again
  XS.save();
}

// Get a reference to the XPIState (loaded by startupManager) so we can unit test it.
function getXS() {
  const { XPIInternal } = ChromeUtils.import(
    "resource://gre/modules/addons/XPIProvider.jsm"
  );
  return XPIInternal.XPIStates;
}

async function getXSJSON() {
  await AddonTestUtils.loadAddonsList(true);

  return aomStartup.readStartupData();
}

add_task(async function detect_touches() {
  let XS = getXS();

  // Should be no changes detected here, because everything should start out up-to-date.
  Assert.ok(!XS.scanForChanges());

  let states = XS.getLocation("app-profile");

  // State should correctly reflect enabled/disabled

  let state = states.get("enabled@tests.mozilla.org");
  Assert.notEqual(state, null, "Found xpi state for enabled extension");
  Assert.ok(state.enabled, "enabled extension has correct xpi state");

  state = states.get("disabled@tests.mozilla.org");
  Assert.notEqual(state, null, "Found xpi state for disabled extension");
  Assert.ok(!state.enabled, "disabled extension has correct xpi state");

  // Touch various files and make sure the change is detected.

  // We notice that a packed XPI is touched for an enabled add-on.
  let peFile = profileDir.clone();
  peFile.append("enabled@tests.mozilla.org.xpi");
  checkChange(XS, peFile, true);

  // We should notice the packed XPI change for a disabled add-on too.
  let pdFile = profileDir.clone();
  pdFile.append("disabled@tests.mozilla.org.xpi");
  checkChange(XS, pdFile, true);
});

/*
 * Uninstalling extensions should immediately remove them from XPIStates.
 */
add_task(async function uninstall_bootstrap() {
  let pe = await promiseAddonByID("enabled@tests.mozilla.org");
  await pe.uninstall();

  let xpiState = await getXSJSON();
  Assert.equal(
    false,
    "enabled@tests.mozilla.org" in xpiState["app-profile"].addons
  );
});

/*
 * Installing an extension should immediately add it to XPIState
 */
add_task(async function install_bootstrap() {
  const ID = "addon@tests.mozilla.org";
  let XS = getXS();

  await promiseInstallWebExtension({
    manifest: {
      browser_specific_settings: { gecko: { id: ID } },
    },
  });
  let addon = await promiseAddonByID(ID);

  let xState = XS.getAddon("app-profile", ID);
  Assert.ok(!!xState);
  Assert.ok(xState.enabled);
  Assert.equal(xState.mtime, addon.updateDate.getTime());
  await addon.uninstall();
});