1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
6 const { AppConstants } = ChromeUtils.importESModule(
7 "resource://gre/modules/AppConstants.sys.mjs"
9 const { FileUtils } = ChromeUtils.importESModule(
10 "resource://gre/modules/FileUtils.sys.mjs"
12 const { FirefoxBridgeExtensionUtils } = ChromeUtils.importESModule(
13 "resource:///modules/FirefoxBridgeExtensionUtils.sys.mjs"
16 const DUAL_BROWSER_EXTENSION_ORIGIN = ["chrome-extension://fake-origin/"];
17 const NATIVE_MESSAGING_HOST_ID = "org.mozilla.firefox_bridge_test";
19 let dir = FileUtils.getDir("TmpD", ["NativeMessagingHostsTest"]);
20 dir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
22 let userDir = dir.clone();
23 userDir.append("user");
24 userDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
26 let appDir = dir.clone();
28 appDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
32 if (property == "Home") {
33 return userDir.clone();
34 } else if (property == "AppData") {
35 return appDir.clone();
42 Services.dirsvc.undefine("Home");
45 Services.dirsvc.undefine("AppData");
47 Services.dirsvc.registerProvider(dirProvider);
49 registerCleanupFunction(() => {
50 Services.dirsvc.unregisterProvider(dirProvider);
54 const USER_TEST_PATH = PathUtils.join(userDir.path, "manifestDir");
57 add_setup(async function () {
58 binFile = Services.dirsvc.get("XREExeF", Ci.nsIFile).parent.clone();
59 if (AppConstants.platform == "win") {
60 binFile.append("nmhproxy.exe");
61 } else if (AppConstants.platform == "macosx") {
62 binFile.append("nmhproxy");
64 throw new Error("Unsupported platform");
68 function getExpectedOutput() {
70 name: NATIVE_MESSAGING_HOST_ID,
71 description: "Firefox Native Messaging Host",
74 allowed_origins: DUAL_BROWSER_EXTENSION_ORIGIN,
78 add_task(async function test_maybeWriteManifestFiles() {
79 await FirefoxBridgeExtensionUtils.maybeWriteManifestFiles(
81 NATIVE_MESSAGING_HOST_ID,
82 DUAL_BROWSER_EXTENSION_ORIGIN
84 let expectedOutput = JSON.stringify(getExpectedOutput());
85 let nmhManifestFilePath = PathUtils.join(
87 `${NATIVE_MESSAGING_HOST_ID}.json`
89 let nmhManifestFileContent = await IOUtils.readUTF8(nmhManifestFilePath);
90 await IOUtils.remove(nmhManifestFilePath);
91 Assert.equal(nmhManifestFileContent, expectedOutput);
94 add_task(async function test_maybeWriteManifestFilesIncorrect() {
95 let nmhManifestFile = await IOUtils.getFile(
97 `${NATIVE_MESSAGING_HOST_ID}.json`
100 let incorrectInput = {
101 name: NATIVE_MESSAGING_HOST_ID,
102 description: "Manifest with unexpected description",
105 allowed_origins: DUAL_BROWSER_EXTENSION_ORIGIN,
107 await IOUtils.writeJSON(nmhManifestFile.path, incorrectInput);
109 // Write correct JSON to the file and check to make sure it matches
110 // the expected output
111 await FirefoxBridgeExtensionUtils.maybeWriteManifestFiles(
113 NATIVE_MESSAGING_HOST_ID,
114 DUAL_BROWSER_EXTENSION_ORIGIN
116 let expectedOutput = JSON.stringify(getExpectedOutput());
118 let nmhManifestFilePath = PathUtils.join(
120 `${NATIVE_MESSAGING_HOST_ID}.json`
122 let nmhManifestFileContent = await IOUtils.readUTF8(nmhManifestFilePath);
123 await IOUtils.remove(nmhManifestFilePath);
124 Assert.equal(nmhManifestFileContent, expectedOutput);
127 add_task(async function test_maybeWriteManifestFilesAlreadyExists() {
128 // Write file and confirm it exists
129 await FirefoxBridgeExtensionUtils.maybeWriteManifestFiles(
131 NATIVE_MESSAGING_HOST_ID,
132 DUAL_BROWSER_EXTENSION_ORIGIN
134 let nmhManifestFile = await IOUtils.getFile(
136 `${NATIVE_MESSAGING_HOST_ID}.json`
139 // Modify file modificatiomn time to be older than the write time
140 let oldModificationTime = Date.now() - 1000000;
141 let setModificationTime = await IOUtils.setModificationTime(
142 nmhManifestFile.path,
145 Assert.equal(oldModificationTime, setModificationTime);
147 // Call function which writes correct JSON to the file and make sure
148 // the modification time is the same, meaning we haven't written anything
149 await FirefoxBridgeExtensionUtils.maybeWriteManifestFiles(
151 NATIVE_MESSAGING_HOST_ID,
152 DUAL_BROWSER_EXTENSION_ORIGIN
154 let stat = await IOUtils.stat(nmhManifestFile.path);
155 await IOUtils.remove(nmhManifestFile.path);
156 Assert.equal(stat.lastModified, oldModificationTime);
159 add_task(async function test_maybeWriteManifestFilesDirDoesNotExist() {
160 let testDir = dir.clone();
161 // This folder does not exist, so we want to make sure it's created
162 testDir.append("dirDoesNotExist");
163 await FirefoxBridgeExtensionUtils.maybeWriteManifestFiles(
165 NATIVE_MESSAGING_HOST_ID,
166 DUAL_BROWSER_EXTENSION_ORIGIN
169 ok(await IOUtils.exists(testDir.path));
171 await IOUtils.exists(
172 PathUtils.join(testDir.path, `${NATIVE_MESSAGING_HOST_ID}.json`)
175 await IOUtils.remove(testDir.path, { recursive: true });
178 add_task(async function test_ensureRegistered() {
179 let expectedJSONDirPath = null;
180 let nativeHostId = "org.mozilla.firefox_bridge_nmh";
181 if (AppConstants.NIGHTLY_BUILD) {
182 nativeHostId = "org.mozilla.firefox_bridge_nmh_nightly";
183 } else if (AppConstants.MOZ_DEV_EDITION) {
184 nativeHostId = "org.mozilla.firefox_bridge_nmh_dev";
185 } else if (AppConstants.IS_ESR) {
186 nativeHostId = "org.mozilla.firefox_bridge_nmh_esr";
189 if (AppConstants.platform == "macosx") {
190 expectedJSONDirPath = PathUtils.joinRelative(
192 "Library/Application Support/Google/Chrome/NativeMessagingHosts/"
194 } else if (AppConstants.platform == "win") {
195 expectedJSONDirPath = PathUtils.joinRelative(
200 throw new Error("Unsupported platform");
203 ok(!(await IOUtils.exists(expectedJSONDirPath)));
204 let expectedJSONPath = PathUtils.join(
206 `${nativeHostId}.json`
209 await FirefoxBridgeExtensionUtils.ensureRegistered();
212 description: "Firefox Native Messaging Host",
215 allowed_origins: FirefoxBridgeExtensionUtils.getExtensionOrigins(),
218 let expectedOutput = JSON.stringify(realOutput);
219 let JSONContent = await IOUtils.readUTF8(expectedJSONPath);
220 await IOUtils.remove(expectedJSONPath);
221 Assert.equal(JSONContent, expectedOutput);