test_ext_url_overrides_newtab.js (10064B)
1 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* vim: set sts=2 sw=2 et tw=80: */ 3 "use strict"; 4 5 ChromeUtils.defineESModuleGetters(this, { 6 AddonManager: "resource://gre/modules/AddonManager.sys.mjs", 7 Management: "resource://gre/modules/Extension.sys.mjs", 8 }); 9 10 const { AboutNewTab } = ChromeUtils.importESModule( 11 "resource:///modules/AboutNewTab.sys.mjs" 12 ); 13 14 const { AddonTestUtils } = ChromeUtils.importESModule( 15 "resource://testing-common/AddonTestUtils.sys.mjs" 16 ); 17 18 const { 19 createAppInfo, 20 promiseRestartManager, 21 promiseShutdownManager, 22 promiseStartupManager, 23 } = AddonTestUtils; 24 25 AddonTestUtils.init(this); 26 AddonTestUtils.overrideCertDB(); 27 28 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "42", "42"); 29 30 function awaitEvent(eventName) { 31 return new Promise(resolve => { 32 Management.once(eventName, (e, ...args) => resolve(...args)); 33 }); 34 } 35 36 const DEFAULT_NEW_TAB_URL = AboutNewTab.newTabURL; 37 38 add_task(async function test_multiple_extensions_overriding_newtab_page() { 39 const NEWTAB_URI_2 = "webext-newtab-1.html"; 40 const NEWTAB_URI_3 = "webext-newtab-2.html"; 41 const EXT_2_ID = "ext2@tests.mozilla.org"; 42 const EXT_3_ID = "ext3@tests.mozilla.org"; 43 44 const CONTROLLED_BY_THIS = "controlled_by_this_extension"; 45 const CONTROLLED_BY_OTHER = "controlled_by_other_extensions"; 46 const NOT_CONTROLLABLE = "not_controllable"; 47 48 const NEW_TAB_PRIVATE_ALLOWED = "browser.newtab.privateAllowed"; 49 const NEW_TAB_EXTENSION_CONTROLLED = "browser.newtab.extensionControlled"; 50 51 function background() { 52 browser.test.onMessage.addListener(async msg => { 53 switch (msg) { 54 case "checkNewTabPage": { 55 let newTabPage = await browser.browserSettings.newTabPageOverride.get( 56 {} 57 ); 58 browser.test.sendMessage("newTabPage", newTabPage); 59 break; 60 } 61 case "trySet": { 62 let setResult = await browser.browserSettings.newTabPageOverride.set({ 63 value: "foo", 64 }); 65 browser.test.assertFalse( 66 setResult, 67 "Calling newTabPageOverride.set returns false." 68 ); 69 browser.test.sendMessage("newTabPageSet"); 70 break; 71 } 72 case "tryClear": { 73 let clearResult = 74 await browser.browserSettings.newTabPageOverride.clear({}); 75 browser.test.assertFalse( 76 clearResult, 77 "Calling newTabPageOverride.clear returns false." 78 ); 79 browser.test.sendMessage("newTabPageCleared"); 80 break; 81 } 82 } 83 }); 84 } 85 86 async function checkNewTabPageOverride( 87 ext, 88 expectedValue, 89 expectedLevelOfControl 90 ) { 91 ext.sendMessage("checkNewTabPage"); 92 let newTabPage = await ext.awaitMessage("newTabPage"); 93 94 ok( 95 newTabPage.value.endsWith(expectedValue), 96 `newTabPageOverride setting returns the expected value ending with: ${expectedValue}.` 97 ); 98 equal( 99 newTabPage.levelOfControl, 100 expectedLevelOfControl, 101 `newTabPageOverride setting returns the expected levelOfControl: ${expectedLevelOfControl}.` 102 ); 103 } 104 105 function verifyNewTabSettings(ext, expectedLevelOfControl) { 106 if (expectedLevelOfControl !== NOT_CONTROLLABLE) { 107 // Verify the preferences are set as expected. 108 let policy = WebExtensionPolicy.getByID(ext.id); 109 equal( 110 policy && policy.privateBrowsingAllowed, 111 Services.prefs.getBoolPref(NEW_TAB_PRIVATE_ALLOWED), 112 "private browsing flag set correctly" 113 ); 114 ok( 115 Services.prefs.getBoolPref(NEW_TAB_EXTENSION_CONTROLLED), 116 `extension controlled flag set correctly` 117 ); 118 } else { 119 ok( 120 !Services.prefs.prefHasUserValue(NEW_TAB_PRIVATE_ALLOWED), 121 "controlled flag reset" 122 ); 123 ok( 124 !Services.prefs.prefHasUserValue(NEW_TAB_EXTENSION_CONTROLLED), 125 "controlled flag reset" 126 ); 127 } 128 } 129 130 let extObj = { 131 manifest: { 132 chrome_url_overrides: {}, 133 permissions: ["browserSettings"], 134 }, 135 useAddonManager: "temporary", 136 background, 137 }; 138 139 let ext1 = ExtensionTestUtils.loadExtension(extObj); 140 141 extObj.manifest.chrome_url_overrides = { newtab: NEWTAB_URI_2 }; 142 extObj.manifest.browser_specific_settings = { gecko: { id: EXT_2_ID } }; 143 let ext2 = ExtensionTestUtils.loadExtension(extObj); 144 145 extObj.manifest.chrome_url_overrides = { newtab: NEWTAB_URI_3 }; 146 extObj.manifest.browser_specific_settings.gecko.id = EXT_3_ID; 147 extObj.incognitoOverride = "spanning"; 148 let ext3 = ExtensionTestUtils.loadExtension(extObj); 149 150 equal( 151 AboutNewTab.newTabURL, 152 DEFAULT_NEW_TAB_URL, 153 "newTabURL is set to the default." 154 ); 155 156 await promiseStartupManager(); 157 158 await ext1.startup(); 159 equal( 160 AboutNewTab.newTabURL, 161 DEFAULT_NEW_TAB_URL, 162 "newTabURL is still set to the default." 163 ); 164 165 await checkNewTabPageOverride(ext1, AboutNewTab.newTabURL, NOT_CONTROLLABLE); 166 verifyNewTabSettings(ext1, NOT_CONTROLLABLE); 167 168 await ext2.startup(); 169 ok( 170 AboutNewTab.newTabURL.endsWith(NEWTAB_URI_2), 171 "newTabURL is overridden by the second extension." 172 ); 173 await checkNewTabPageOverride(ext1, NEWTAB_URI_2, CONTROLLED_BY_OTHER); 174 verifyNewTabSettings(ext2, CONTROLLED_BY_THIS); 175 176 // Verify that calling set and clear do nothing. 177 ext2.sendMessage("trySet"); 178 await ext2.awaitMessage("newTabPageSet"); 179 await checkNewTabPageOverride(ext1, NEWTAB_URI_2, CONTROLLED_BY_OTHER); 180 verifyNewTabSettings(ext2, CONTROLLED_BY_THIS); 181 182 ext2.sendMessage("tryClear"); 183 await ext2.awaitMessage("newTabPageCleared"); 184 await checkNewTabPageOverride(ext1, NEWTAB_URI_2, CONTROLLED_BY_OTHER); 185 verifyNewTabSettings(ext2, CONTROLLED_BY_THIS); 186 187 // Disable the second extension. 188 let addon = await AddonManager.getAddonByID(EXT_2_ID); 189 let disabledPromise = awaitEvent("shutdown"); 190 await addon.disable(); 191 await disabledPromise; 192 equal( 193 AboutNewTab.newTabURL, 194 DEFAULT_NEW_TAB_URL, 195 "newTabURL url is reset to the default after second extension is disabled." 196 ); 197 await checkNewTabPageOverride(ext1, AboutNewTab.newTabURL, NOT_CONTROLLABLE); 198 verifyNewTabSettings(ext1, NOT_CONTROLLABLE); 199 200 // Re-enable the second extension. 201 let enabledPromise = awaitEvent("ready"); 202 await addon.enable(); 203 await enabledPromise; 204 ok( 205 AboutNewTab.newTabURL.endsWith(NEWTAB_URI_2), 206 "newTabURL is overridden by the second extension." 207 ); 208 await checkNewTabPageOverride(ext2, NEWTAB_URI_2, CONTROLLED_BY_THIS); 209 verifyNewTabSettings(ext2, CONTROLLED_BY_THIS); 210 211 await ext1.unload(); 212 ok( 213 AboutNewTab.newTabURL.endsWith(NEWTAB_URI_2), 214 "newTabURL is still overridden by the second extension." 215 ); 216 await checkNewTabPageOverride(ext2, NEWTAB_URI_2, CONTROLLED_BY_THIS); 217 verifyNewTabSettings(ext2, CONTROLLED_BY_THIS); 218 219 await ext3.startup(); 220 ok( 221 AboutNewTab.newTabURL.endsWith(NEWTAB_URI_3), 222 "newTabURL is overridden by the third extension." 223 ); 224 await checkNewTabPageOverride(ext2, NEWTAB_URI_3, CONTROLLED_BY_OTHER); 225 verifyNewTabSettings(ext3, CONTROLLED_BY_THIS); 226 227 // Disable the second extension. 228 disabledPromise = awaitEvent("shutdown"); 229 await addon.disable(); 230 await disabledPromise; 231 ok( 232 AboutNewTab.newTabURL.endsWith(NEWTAB_URI_3), 233 "newTabURL is still overridden by the third extension." 234 ); 235 await checkNewTabPageOverride(ext3, NEWTAB_URI_3, CONTROLLED_BY_THIS); 236 verifyNewTabSettings(ext3, CONTROLLED_BY_THIS); 237 238 // Re-enable the second extension. 239 enabledPromise = awaitEvent("ready"); 240 await addon.enable(); 241 await enabledPromise; 242 ok( 243 AboutNewTab.newTabURL.endsWith(NEWTAB_URI_3), 244 "newTabURL is still overridden by the third extension." 245 ); 246 await checkNewTabPageOverride(ext3, NEWTAB_URI_3, CONTROLLED_BY_THIS); 247 verifyNewTabSettings(ext3, CONTROLLED_BY_THIS); 248 249 await ext3.unload(); 250 ok( 251 AboutNewTab.newTabURL.endsWith(NEWTAB_URI_2), 252 "newTabURL reverts to being overridden by the second extension." 253 ); 254 await checkNewTabPageOverride(ext2, NEWTAB_URI_2, CONTROLLED_BY_THIS); 255 verifyNewTabSettings(ext2, CONTROLLED_BY_THIS); 256 257 await ext2.unload(); 258 equal( 259 AboutNewTab.newTabURL, 260 DEFAULT_NEW_TAB_URL, 261 "newTabURL url is reset to the default." 262 ); 263 ok( 264 !Services.prefs.prefHasUserValue(NEW_TAB_PRIVATE_ALLOWED), 265 "controlled flag reset" 266 ); 267 ok( 268 !Services.prefs.prefHasUserValue(NEW_TAB_EXTENSION_CONTROLLED), 269 "controlled flag reset" 270 ); 271 272 await promiseShutdownManager(); 273 }); 274 275 // Tests that we handle the upgrade/downgrade process correctly 276 // when an extension is installed temporarily on top of a permanently 277 // installed one. 278 add_task(async function test_temporary_installation() { 279 const ID = "newtab@tests.mozilla.org"; 280 const PAGE1 = "page1.html"; 281 const PAGE2 = "page2.html"; 282 283 equal( 284 AboutNewTab.newTabURL, 285 DEFAULT_NEW_TAB_URL, 286 "newTabURL is set to the default." 287 ); 288 289 await promiseStartupManager(); 290 291 let permanent = ExtensionTestUtils.loadExtension({ 292 manifest: { 293 browser_specific_settings: { 294 gecko: { id: ID }, 295 }, 296 chrome_url_overrides: { 297 newtab: PAGE1, 298 }, 299 }, 300 useAddonManager: "permanent", 301 }); 302 303 await permanent.startup(); 304 ok( 305 AboutNewTab.newTabURL.endsWith(PAGE1), 306 "newTabURL is overridden by permanent extension." 307 ); 308 309 let temporary = ExtensionTestUtils.loadExtension({ 310 manifest: { 311 browser_specific_settings: { 312 gecko: { id: ID }, 313 }, 314 chrome_url_overrides: { 315 newtab: PAGE2, 316 }, 317 }, 318 useAddonManager: "temporary", 319 }); 320 321 await temporary.startup(); 322 ok( 323 AboutNewTab.newTabURL.endsWith(PAGE2), 324 "newTabURL is overridden by temporary extension." 325 ); 326 327 await promiseRestartManager(); 328 await permanent.awaitStartup(); 329 330 ok( 331 AboutNewTab.newTabURL.endsWith(PAGE1), 332 "newTabURL is back to the value set by permanent extension." 333 ); 334 335 await permanent.unload(); 336 337 equal( 338 AboutNewTab.newTabURL, 339 DEFAULT_NEW_TAB_URL, 340 "newTabURL is set back to the default." 341 ); 342 await promiseShutdownManager(); 343 });