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
|
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
const { AddonTestUtils } = ChromeUtils.import(
"resource://testing-common/AddonTestUtils.jsm"
);
// Lazily import ExtensionParent to allow AddonTestUtils.createAppInfo to
// override Services.appinfo.
ChromeUtils.defineModuleGetter(
this,
"ExtensionParent",
"resource://gre/modules/ExtensionParent.jsm"
);
AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB();
AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",
"XPCShell",
"42",
"42"
);
add_task(async function shutdown_during_search_provider_startup() {
await AddonTestUtils.promiseStartupManager();
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "permanent",
manifest: {
chrome_settings_overrides: {
search_provider: {
is_default: true,
name: "dummy name",
search_url: "https://example.com/",
},
},
},
});
info("Starting up search extension");
await extension.startup();
let extStartPromise = AddonTestUtils.waitForSearchProviderStartup(extension, {
// Search provider registration is expected to be pending because the search
// service has not been initialized yet.
expectPending: true,
});
let initialized = false;
ExtensionParent.apiManager.global.searchInitialized.then(() => {
initialized = true;
});
await extension.addon.disable();
info("Extension managed to shut down despite the uninitialized search");
// Initialize search after extension shutdown to check that it does not cause
// any problems, and that the test can continue to test uninstall behavior.
Assert.ok(!initialized, "Search service should not have been initialized");
extension.addon.enable();
await extension.awaitStartup();
// Check that uninstall is blocked until the search registration at startup
// has finished. This registration only finished once the search service is
// initialized.
let uninstallingPromise = new Promise(resolve => {
let Management = ExtensionParent.apiManager;
Management.on("uninstall", function listener(eventName, { id }) {
Management.off("uninstall", listener);
Assert.equal(id, extension.id, "Expected extension");
resolve();
});
});
let extRestartPromise = AddonTestUtils.waitForSearchProviderStartup(
extension,
{
// Search provider registration is expected to be pending again,
// because the search service has still not been initialized yet.
expectPending: true,
}
);
let uninstalledPromise = extension.addon.uninstall();
let uninstalled = false;
uninstalledPromise.then(() => {
uninstalled = true;
});
await uninstallingPromise;
Assert.ok(!uninstalled, "Uninstall should not be finished yet");
Assert.ok(!initialized, "Search service should still be uninitialized");
await Services.search.init();
Assert.ok(initialized, "Search service should be initialized");
// After initializing the search service, the search provider registration
// promises should settle eventually.
// Despite the interrupted startup, the promise should still resolve without
// an error.
await extStartPromise;
// The extension that is still active. The promise should just resolve.
await extRestartPromise;
// After initializing the search service, uninstall should eventually finish.
await uninstalledPromise;
await AddonTestUtils.promiseShutdownManager();
});
|