diff options
Diffstat (limited to 'comm/mail/components/extensions/test/browser/browser_ext_spaces.js')
-rw-r--r-- | comm/mail/components/extensions/test/browser/browser_ext_spaces.js | 1047 |
1 files changed, 1047 insertions, 0 deletions
diff --git a/comm/mail/components/extensions/test/browser/browser_ext_spaces.js b/comm/mail/components/extensions/test/browser/browser_ext_spaces.js new file mode 100644 index 0000000000..16f6f4770e --- /dev/null +++ b/comm/mail/components/extensions/test/browser/browser_ext_spaces.js @@ -0,0 +1,1047 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Helper Function, creates a test extension to verify expected button states. + * + * @param {Function} background - The background script executed by the test. + * @param {object} config - Additional config data for the test. Tests can + * include arbitrary data, but the following have a dedicated purpose: + * @param {string} selectedTheme - The selected theme (default, light or dark), + * used to select the expected button/menuitem icon. + * @param {?object} manifestIcons - The icons entry of the extension manifest. + * @param {?object} permissions - Permissions assigned to the extension. + */ +async function test_space(background, config = {}) { + let manifest = { + manifest_version: 3, + browser_specific_settings: { + gecko: { + id: "spaces_toolbar@mochi.test", + }, + }, + permissions: ["tabs"], + background: { scripts: ["utils.js", "background.js"] }, + }; + + if (config.manifestIcons) { + manifest.icons = config.manifestIcons; + } + + if (config.permissions) { + manifest.permissions = config.permissions; + } + + let extension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": background, + "utils.js": await getUtilsJS(), + }, + manifest, + }); + + extension.onMessage("checkTabs", async test => { + let tabmail = document.getElementById("tabmail"); + + if (test.action && test.spaceName && test.url) { + let tabPromise = + test.action == "switch" + ? BrowserTestUtils.waitForEvent(tabmail.tabContainer, "TabSelect") + : contentTabOpenPromise(tabmail, test.url); + let button = window.document.getElementById( + `spaces_toolbar_mochi_test-spacesButton-${test.spaceName}` + ); + button.click(); + await tabPromise; + } + + let tabs = tabmail.tabInfo.filter(tabInfo => !!tabInfo.spaceButtonId); + Assert.equal( + test.openSpacesUrls.length, + tabs.length, + `Should have found the correct number of open add-on spaces tabs.` + ); + for (let expectedUrl of test.openSpacesUrls) { + Assert.ok( + tabmail.tabInfo.find( + tabInfo => + !!tabInfo.spaceButtonId && + tabInfo.browser.currentURI.spec == expectedUrl + ), + `Should have found a spaces tab with the expected url.` + ); + } + extension.sendMessage(); + }); + + extension.onMessage("checkUI", async expected => { + let addonButtons = document.querySelectorAll(".spaces-addon-button"); + Assert.equal( + expected.length, + addonButtons.length, + `Should have found the correct number of buttons.` + ); + + for (let { + name, + url, + title, + icons, + badgeText, + badgeBackgroundColor, + } of expected) { + // Check button. + let button = window.document.getElementById( + `spaces_toolbar_mochi_test-spacesButton-${name}` + ); + Assert.ok(button, `Button for space ${name} should exist.`); + Assert.equal( + title, + button.title, + `Title of button for space ${name} should be correct.` + ); + + // Check button icon. + let imgStyles = window.getComputedStyle(button.querySelector("img")); + Assert.equal( + icons[config.selectedTheme], + imgStyles.content, + `Icon for button of space ${name} with theme ${config.selectedTheme} should be correct.` + ); + + // Check badge. + let badge = button.querySelector(".spaces-badge-container"); + let badgeStyles = window.getComputedStyle(badge); + if (badgeText) { + Assert.equal( + "block", + badgeStyles.display, + `Button of space ${name} should have a badge.` + ); + Assert.equal( + badgeText, + badge.textContent, + `Badge of button of space ${name} should have the correct content.` + ); + if (badgeBackgroundColor) { + Assert.equal( + badgeBackgroundColor, + badgeStyles.backgroundColor, + `Badge of button of space ${name} should have the correct backgroundColor.` + ); + } + } else { + Assert.equal( + "none", + badgeStyles.display, + `Button of space ${name} should not have a badge.` + ); + } + + let collapseButton = document.getElementById("collapseButton"); + let revealButton = document.getElementById("spacesToolbarReveal"); + let pinnedButton = document.getElementById("spacesPinnedButton"); + let pinnedPopup = document.getElementById("spacesButtonMenuPopup"); + + Assert.ok(revealButton.hidden, "The status bar toggle button is hidden"); + Assert.ok(pinnedButton.hidden, "The pinned titlebar button is hidden"); + collapseButton.click(); + Assert.ok( + !revealButton.hidden, + "The status bar toggle button is not hidden" + ); + Assert.ok( + !pinnedButton.hidden, + "The pinned titlebar button is not hidden" + ); + pinnedPopup.openPopup(); + + // Check menuitem. + let menuitem = window.document.getElementById( + `spaces_toolbar_mochi_test-spacesButton-${name}-menuitem` + ); + Assert.ok(menuitem, `Menuitem for id ${name} should exist.`); + Assert.equal( + title, + menuitem.label, + `Label of menuitem of space ${name} should be correct.` + ); + + // Check menuitem icon. + let menuitemStyles = window.getComputedStyle(menuitem); + Assert.equal( + icons[config.selectedTheme], + menuitemStyles.listStyleImage, + `Icon of menuitem for space ${name} with theme ${config.selectedTheme} should be correct.` + ); + + pinnedPopup.hidePopup(); + revealButton.click(); + Assert.ok(revealButton.hidden, "The status bar toggle button is hidden"); + Assert.ok(pinnedButton.hidden, "The pinned titlebar button is hidden"); + + //Check space and url. + let space = window.gSpacesToolbar.spaces.find( + space => space.name == `spaces_toolbar_mochi_test-spacesButton-${name}` + ); + Assert.ok(space, "The space of this button should exists"); + Assert.equal( + url, + space.url, + "The stored url of the space should be correct" + ); + } + extension.sendMessage(); + }); + + extension.onMessage("getConfig", async () => { + extension.sendMessage(config); + }); + + await extension.startup(); + await extension.awaitFinish(); + await extension.unload(); +} + +add_task(async function test_add_update_remove() { + async function background() { + let manifest = browser.runtime.getManifest(); + let extensionIcon = manifest.icons + ? browser.runtime.getURL(manifest.icons[16]) + : "chrome://messenger/content/extension.svg"; + + await window.sendMessage("checkUI", []); + + // Test create(). + browser.test.log("create(): Without id."); + await browser.test.assertThrows( + () => browser.spaces.create(), + /Incorrect argument types for spaces.create./, + "create() without name should throw." + ); + + browser.test.log("create(): Without default url."); + await browser.test.assertThrows( + () => browser.spaces.create("space_1"), + /Incorrect argument types for spaces.create./, + "create() without default url should throw." + ); + + browser.test.log("create(): With invalid default url."); + await browser.test.assertRejects( + browser.spaces.create("space_1", "invalid://url"), + /Failed to create space with name space_1: Invalid default url./, + "create() with an invalid default url should throw." + ); + + browser.test.log("create(): With default url only."); + let space_1 = await browser.spaces.create( + "space_1", + "https://test.invalid" + ); + let expected_space_1 = { + name: "space_1", + title: "Generated extension", + url: "https://test.invalid", + icons: { + default: `url("${extensionIcon}")`, + }, + }; + await window.sendMessage("checkUI", [expected_space_1]); + + browser.test.log("create(): With default url only, but existing id."); + await browser.test.assertRejects( + browser.spaces.create("space_1", "https://test.invalid"), + /Failed to create space with name space_1: Space already exists for this extension./, + "create() with existing id should throw." + ); + + browser.test.log("create(): With most properties."); + let space_2 = await browser.spaces.create("space_2", "/local/file.html", { + title: "Google", + defaultIcons: "default.png", + badgeText: "12", + badgeBackgroundColor: [50, 100, 150, 255], + }); + let expected_space_2 = { + name: "space_2", + title: "Google", + url: browser.runtime.getURL("/local/file.html"), + icons: { + default: `url("${browser.runtime.getURL("default.png")}")`, + }, + badgeText: "12", + badgeBackgroundColor: "rgb(50, 100, 150)", + }; + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + // Test update(). + browser.test.log("update(): Without id."); + await browser.test.assertThrows( + () => browser.spaces.update(), + /Incorrect argument types for spaces.update./, + "update() without id should throw." + ); + + browser.test.log("update(): With invalid id."); + await browser.test.assertRejects( + browser.spaces.update(1234), + /Failed to update space with id 1234: Unknown id./, + "update() with invalid id should throw." + ); + + browser.test.log("update(): Without properties."); + await browser.spaces.update(space_1.id); + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + browser.test.log("update(): Updating the badge."); + await browser.spaces.update(space_2.id, { + badgeText: "ok", + badgeBackgroundColor: "green", + }); + expected_space_2.badgeText = "ok"; + expected_space_2.badgeBackgroundColor = "rgb(0, 128, 0)"; + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + browser.test.log("update(): Removing the badge."); + await browser.spaces.update(space_2.id, { + badgeText: "", + }); + delete expected_space_2.badgeText; + delete expected_space_2.badgeBackgroundColor; + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + browser.test.log("update(): Changing the title."); + await browser.spaces.update(space_2.id, { + title: "Some other title", + }); + expected_space_2.title = "Some other title"; + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + browser.test.log("update(): Removing the title."); + await browser.spaces.update(space_2.id, { + title: "", + }); + expected_space_2.title = "Generated extension"; + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + browser.test.log("update(): Setting invalid default url."); + await browser.test.assertRejects( + browser.spaces.update(space_2.id, "invalid://url"), + `Failed to update space with id ${space_2.id}: Invalid default url.`, + "update() with invalid default url should throw." + ); + + await browser.spaces.update(space_2.id, "https://test.more.invalid", { + title: "Bing", + }); + expected_space_2.title = "Bing"; + expected_space_2.url = "https://test.more.invalid"; + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + // Test remove(). + browser.test.log("remove(): Removing without id."); + await browser.test.assertThrows( + () => browser.spaces.remove(), + /Incorrect argument types for spaces.remove./, + "remove() without id should throw." + ); + + browser.test.log("remove(): Removing with invalid id."); + await browser.test.assertRejects( + browser.spaces.remove(1234), + /Failed to remove space with id 1234: Unknown id./, + "remove() with invalid id should throw." + ); + + browser.test.log("remove(): Removing space_1."); + await browser.spaces.remove(space_1.id); + await window.sendMessage("checkUI", [expected_space_2]); + + browser.test.notifyPass(); + } + await test_space(background, { selectedTheme: "default" }); + await test_space(background, { + selectedTheme: "default", + manifestIcons: { 16: "manifest.png" }, + }); +}); + +add_task(async function test_open_reload_close() { + async function background() { + await window.sendMessage("checkTabs", { openSpacesUrls: [] }); + + // Add spaces. + let url1 = `http://mochi.test:8888/browser/comm/mail/components/extensions/test/browser/data/content.html`; + let space_1 = await browser.spaces.create("space_1", url1); + let url2 = `http://mochi.test:8888/browser/comm/mail/components/extensions/test/browser/data/content_body.html`; + let space_2 = await browser.spaces.create("space_2", url2); + + // Open spaces. + await window.sendMessage("checkTabs", { + action: "open", + url: url1, + spaceName: "space_1", + openSpacesUrls: [url1], + }); + await window.sendMessage("checkTabs", { + action: "open", + url: url2, + spaceName: "space_2", + openSpacesUrls: [url1, url2], + }); + + // Switch to open spaces tab. + await window.sendMessage("checkTabs", { + action: "switch", + url: url1, + spaceName: "space_1", + openSpacesUrls: [url1, url2], + }); + await window.sendMessage("checkTabs", { + action: "switch", + url: url2, + spaceName: "space_2", + openSpacesUrls: [url1, url2], + }); + + // TODO: Add test for tab reloading, once this has been implemented. + + // Remove spaces and check that related spaces tab are closed. + await browser.spaces.remove(space_1.id); + await window.sendMessage("checkTabs", { openSpacesUrls: [url2] }); + await browser.spaces.remove(space_2.id); + await window.sendMessage("checkTabs", { openSpacesUrls: [] }); + + browser.test.notifyPass(); + } + await test_space(background, { selectedTheme: "default" }); +}); + +add_task(async function test_icons() { + async function background() { + let manifest = browser.runtime.getManifest(); + let extensionIcon = manifest.icons + ? browser.runtime.getURL(manifest.icons[16]) + : "chrome://messenger/content/extension.svg"; + + // Test 1: Setting defaultIcons and themeIcons. + browser.test.log("create(): Setting defaultIcons and themeIcons."); + let space_1 = await browser.spaces.create( + "space_1", + "https://test.invalid", + { + title: "Google", + defaultIcons: "default.png", + themeIcons: [ + { + dark: "dark.png", + light: "light.png", + size: 16, + }, + ], + } + ); + let expected_space_1 = { + name: "space_1", + title: "Google", + url: "https://test.invalid", + icons: { + default: `url("${browser.runtime.getURL("default.png")}")`, + dark: `url("${browser.runtime.getURL("dark.png")}")`, + light: `url("${browser.runtime.getURL("light.png")}")`, + }, + }; + await window.sendMessage("checkUI", [expected_space_1]); + + // Clearing defaultIcons. + await browser.spaces.update(space_1.id, { + defaultIcons: "", + }); + expected_space_1.icons = { + default: `url("${browser.runtime.getURL("dark.png")}")`, + dark: `url("${browser.runtime.getURL("dark.png")}")`, + light: `url("${browser.runtime.getURL("light.png")}")`, + }; + await window.sendMessage("checkUI", [expected_space_1]); + + // Setting other defaultIcons. + await browser.spaces.update(space_1.id, { + defaultIcons: "other.png", + }); + expected_space_1.icons = { + default: `url("${browser.runtime.getURL("other.png")}")`, + dark: `url("${browser.runtime.getURL("dark.png")}")`, + light: `url("${browser.runtime.getURL("light.png")}")`, + }; + await window.sendMessage("checkUI", [expected_space_1]); + + // Clearing themeIcons. + await browser.spaces.update(space_1.id, { + themeIcons: [], + }); + expected_space_1.icons = { + default: `url("${browser.runtime.getURL("other.png")}")`, + dark: `url("${browser.runtime.getURL("other.png")}")`, + light: `url("${browser.runtime.getURL("other.png")}")`, + }; + await window.sendMessage("checkUI", [expected_space_1]); + + // Setting other themeIcons. + await browser.spaces.update(space_1.id, { + themeIcons: [ + { + dark: "dark2.png", + light: "light2.png", + size: 16, + }, + ], + }); + expected_space_1.icons = { + default: `url("${browser.runtime.getURL("other.png")}")`, + dark: `url("${browser.runtime.getURL("dark2.png")}")`, + light: `url("${browser.runtime.getURL("light2.png")}")`, + }; + await window.sendMessage("checkUI", [expected_space_1]); + + // Test 2: Setting themeIcons only. + browser.test.log("create(): Setting themeIcons only."); + let space_2 = await browser.spaces.create( + "space_2", + "https://test.other.invalid", + { + title: "Wikipedia", + themeIcons: [ + { + dark: "dark2.png", + light: "light2.png", + size: 16, + }, + ], + } + ); + // Not specifying defaultIcons but only themeIcons should always use the + // theme icons, even for the default theme (and not the extension icon). + let expected_space_2 = { + name: "space_2", + title: "Wikipedia", + url: "https://test.other.invalid", + icons: { + default: `url("${browser.runtime.getURL("dark2.png")}")`, + dark: `url("${browser.runtime.getURL("dark2.png")}")`, + light: `url("${browser.runtime.getURL("light2.png")}")`, + }, + }; + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + // Clearing themeIcons. + await browser.spaces.update(space_2.id, { + themeIcons: [], + }); + expected_space_2.icons = { + default: `url("${extensionIcon}")`, + dark: `url("${extensionIcon}")`, + light: `url("${extensionIcon}")`, + }; + await window.sendMessage("checkUI", [expected_space_1, expected_space_2]); + + // Test 3: Setting defaultIcons only. + browser.test.log("create(): Setting defaultIcons only."); + let space_3 = await browser.spaces.create( + "space_3", + "https://test.more.invalid", + { + title: "Bing", + defaultIcons: "default.png", + } + ); + let expected_space_3 = { + name: "space_3", + title: "Bing", + url: "https://test.more.invalid", + icons: { + default: `url("${browser.runtime.getURL("default.png")}")`, + dark: `url("${browser.runtime.getURL("default.png")}")`, + light: `url("${browser.runtime.getURL("default.png")}")`, + }, + }; + await window.sendMessage("checkUI", [ + expected_space_1, + expected_space_2, + expected_space_3, + ]); + + // Clearing defaultIcons and setting themeIcons. + await browser.spaces.update(space_3.id, { + defaultIcons: "", + themeIcons: [ + { + dark: "dark3.png", + light: "light3.png", + size: 16, + }, + ], + }); + expected_space_3.icons = { + default: `url("${browser.runtime.getURL("dark3.png")}")`, + dark: `url("${browser.runtime.getURL("dark3.png")}")`, + light: `url("${browser.runtime.getURL("light3.png")}")`, + }; + await window.sendMessage("checkUI", [ + expected_space_1, + expected_space_2, + expected_space_3, + ]); + + // Test 4: Setting no icons. + browser.test.log("create(): Setting no icons."); + let space_4 = await browser.spaces.create( + "space_4", + "https://duckduckgo.com", + { + title: "DuckDuckGo", + } + ); + let expected_space_4 = { + name: "space_4", + title: "DuckDuckGo", + url: "https://duckduckgo.com", + icons: { + default: `url("${extensionIcon}")`, + dark: `url("${extensionIcon}")`, + light: `url("${extensionIcon}")`, + }, + }; + await window.sendMessage("checkUI", [ + expected_space_1, + expected_space_2, + expected_space_3, + expected_space_4, + ]); + + // Setting and clearing default icons. + await browser.spaces.update(space_4.id, { + defaultIcons: "default.png", + }); + expected_space_4.icons = { + default: `url("${browser.runtime.getURL("default.png")}")`, + dark: `url("${browser.runtime.getURL("default.png")}")`, + light: `url("${browser.runtime.getURL("default.png")}")`, + }; + await window.sendMessage("checkUI", [ + expected_space_1, + expected_space_2, + expected_space_3, + expected_space_4, + ]); + await browser.spaces.update(space_4.id, { + defaultIcons: "", + }); + expected_space_4.icons = { + default: `url("${extensionIcon}")`, + dark: `url("${extensionIcon}")`, + light: `url("${extensionIcon}")`, + }; + await window.sendMessage("checkUI", [ + expected_space_1, + expected_space_2, + expected_space_3, + expected_space_4, + ]); + + browser.test.notifyPass(); + } + + // Test with and without icons defined in the manifest. + for (let manifestIcons of [null, { 16: "manifest16.png" }]) { + let dark_theme = await AddonManager.getAddonByID( + "thunderbird-compact-dark@mozilla.org" + ); + await dark_theme.enable(); + await test_space(background, { selectedTheme: "light", manifestIcons }); + + let light_theme = await AddonManager.getAddonByID( + "thunderbird-compact-light@mozilla.org" + ); + await light_theme.enable(); + await test_space(background, { selectedTheme: "dark", manifestIcons }); + + // Disabling a theme will enable the default theme. + await light_theme.disable(); + await test_space(background, { selectedTheme: "default", manifestIcons }); + } +}); + +add_task(async function test_open_programmatically() { + async function background() { + await window.sendMessage("checkTabs", { openSpacesUrls: [] }); + + // Add spaces. + let url1 = `http://mochi.test:8888/browser/comm/mail/components/extensions/test/browser/data/content.html`; + let space_1 = await browser.spaces.create("space_1", url1); + let url2 = `http://mochi.test:8888/browser/comm/mail/components/extensions/test/browser/data/content_body.html`; + let space_2 = await browser.spaces.create("space_2", url2); + await window.sendMessage("checkTabs", { openSpacesUrls: [] }); + + async function openSpace(space, url) { + let loadPromise = new Promise(resolve => { + let urlSeen = false; + let listener = (tabId, changeInfo) => { + if (changeInfo.url && changeInfo.url == url) { + urlSeen = true; + } + if (changeInfo.status == "complete" && urlSeen) { + browser.tabs.onUpdated.removeListener(listener); + resolve(); + } + }; + browser.tabs.onUpdated.addListener(listener); + }); + let tab = await browser.spaces.open(space.id); + await loadPromise; + + browser.test.assertEq( + space.id, + tab.spaceId, + "The opened tab should belong to the correct space" + ); + + let queriedTabs = await browser.tabs.query({ spaceId: space.id }); + browser.test.assertEq( + 1, + queriedTabs.length, + "browser.tabs.query() should find exactly one tab belonging to the opened space" + ); + browser.test.assertEq( + tab.id, + queriedTabs[0].id, + "browser.tabs.query() should find the correct tab belonging to the opened space" + ); + } + + // Open space #1. + await openSpace(space_1, url1); + await window.sendMessage("checkTabs", { + spaceName: "space_1", + openSpacesUrls: [url1], + }); + + // Open space #2. + await openSpace(space_2, url2); + await window.sendMessage("checkTabs", { + spaceName: "space_2", + openSpacesUrls: [url1, url2], + }); + + // Switch to open space tab. + await window.sendMessage("checkTabs", { + action: "switch", + url: url1, + spaceName: "space_1", + openSpacesUrls: [url1, url2], + }); + + await window.sendMessage("checkTabs", { + action: "switch", + url: url2, + spaceName: "space_2", + openSpacesUrls: [url1, url2], + }); + + // Remove spaces and check that related spaces tab are closed. + await browser.spaces.remove(space_1.id); + await window.sendMessage("checkTabs", { openSpacesUrls: [url2] }); + await browser.spaces.remove(space_2.id); + await window.sendMessage("checkTabs", { openSpacesUrls: [] }); + + browser.test.notifyPass(); + } + await test_space(background, { selectedTheme: "default" }); +}); + +// Load a second extension parallel to the standard space test, which creates +// two additional spaces. +async function test_query({ permissions }) { + async function query_background() { + function verify(description, expected, spaces) { + browser.test.assertEq( + expected.length, + spaces.length, + `${description}: Should find the correct number of spaces` + ); + window.assertDeepEqual( + spaces, + expected, + `${description}: Should find the correct spaces` + ); + } + + async function query(queryInfo, expected) { + let spaces = + queryInfo === null + ? await browser.spaces.query() + : await browser.spaces.query(queryInfo); + verify(`Query ${JSON.stringify(queryInfo)}`, expected, spaces); + } + + let builtIn = [ + { + id: 1, + name: "mail", + isBuiltIn: true, + isSelfOwned: false, + }, + { + id: 2, + isBuiltIn: true, + isSelfOwned: false, + name: "addressbook", + }, + { + id: 3, + isBuiltIn: true, + isSelfOwned: false, + name: "calendar", + }, + { + id: 4, + isBuiltIn: true, + isSelfOwned: false, + name: "tasks", + }, + { + id: 5, + isBuiltIn: true, + isSelfOwned: false, + name: "chat", + }, + { + id: 6, + isBuiltIn: true, + isSelfOwned: false, + name: "settings", + }, + ]; + + await window.sendMessage("checkTabs", { openSpacesUrls: [] }); + let [{ other_1, other_11, permissions }] = await window.sendMessage( + "getConfig" + ); + let hasManagement = permissions && permissions.includes("management"); + + // Verify space_1 from other extension. + let expected_other_1 = { + name: "space_1", + isBuiltIn: false, + isSelfOwned: true, + }; + if (hasManagement) { + expected_other_1.extensionId = "spaces_toolbar_other@mochi.test"; + } + verify("Check space_1 from other extension", other_1, expected_other_1); + + // Verify space_11 from other extension. + let expected_other_11 = { + name: "space_11", + isBuiltIn: false, + isSelfOwned: true, + }; + if (hasManagement) { + expected_other_11.extensionId = "spaces_toolbar_other@mochi.test"; + } + verify("Check space_11 from other extension", other_11, expected_other_11); + + // Manipulate isSelfOwned, because we got those from the other extension. + other_1.isSelfOwned = false; + other_11.isSelfOwned = false; + + await query(null, [...builtIn, other_1, other_11]); + await query({}, [...builtIn, other_1, other_11]); + await query({ isSelfOwned: false }, [...builtIn, other_1, other_11]); + await query({ isBuiltIn: true }, [...builtIn]); + await query({ isBuiltIn: false }, [other_1, other_11]); + await query({ isSelfOwned: true }, []); + await query( + { extensionId: "spaces_toolbar_other@mochi.test" }, + hasManagement ? [other_1, other_11] : [] + ); + + // Add spaces. + let url1 = `http://mochi.test:8888/browser/comm/mail/components/extensions/test/browser/data/content.html`; + let space_1 = await browser.spaces.create("space_1", url1); + let url2 = `http://mochi.test:8888/browser/comm/mail/components/extensions/test/browser/data/content_body.html`; + let space_2 = await browser.spaces.create("space_2", url2); + + // Verify returned space_1 + let expected_space_1 = { + name: "space_1", + isBuiltIn: false, + isSelfOwned: true, + }; + if (hasManagement) { + expected_space_1.extensionId = "spaces_toolbar@mochi.test"; + } + verify("Check space_1", space_1, expected_space_1); + + // Verify returned space_2 + let expected_space_2 = { + name: "space_2", + isBuiltIn: false, + isSelfOwned: true, + }; + if (hasManagement) { + expected_space_2.extensionId = "spaces_toolbar@mochi.test"; + } + verify("Check space_2", space_2, expected_space_2); + + await query(null, [...builtIn, other_1, other_11, space_1, space_2]); + await query({ isSelfOwned: false }, [...builtIn, other_1, other_11]); + await query({ isBuiltIn: true }, [...builtIn]); + await query({ isBuiltIn: false }, [other_1, other_11, space_1, space_2]); + await query({ isSelfOwned: true }, [space_1, space_2]); + await query( + { extensionId: "spaces_toolbar_other@mochi.test" }, + hasManagement ? [other_1, other_11] : [] + ); + await query( + { extensionId: "spaces_toolbar@mochi.test" }, + hasManagement ? [space_1, space_2] : [] + ); + + await query({ id: space_1.id }, [space_1]); + await query({ id: other_1.id }, [other_1]); + await query({ id: space_2.id }, [space_2]); + await query({ id: other_11.id }, [other_11]); + await query({ name: "space_1" }, [other_1, space_1]); + await query({ name: "space_2" }, [space_2]); + await query({ name: "space_11" }, [other_11]); + + browser.test.notifyPass(); + } + + let otherExtension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": async () => { + let url = `http://mochi.test:8888/browser/comm/mail/components/extensions/test/browser/data/content.html`; + let other_1 = await browser.spaces.create("space_1", url); + let other_11 = await browser.spaces.create("space_11", url); + browser.test.sendMessage("Done", { other_1, other_11 }); + browser.test.notifyPass(); + }, + "utils.js": await getUtilsJS(), + }, + manifest: { + manifest_version: 3, + browser_specific_settings: { + gecko: { + id: "spaces_toolbar_other@mochi.test", + }, + }, + permissions, + background: { scripts: ["utils.js", "background.js"] }, + }, + }); + + await otherExtension.startup(); + let { other_1, other_11 } = await otherExtension.awaitMessage("Done"); + + await test_space(query_background, { + selectedTheme: "default", + other_1, + other_11, + permissions, + }); + + await otherExtension.awaitFinish(); + await otherExtension.unload(); +} + +add_task(async function test_query_no_management_permission() { + await test_query({ permissions: [] }); +}); + +add_task(async function test_query_management_permission() { + await test_query({ permissions: ["management"] }); +}); + +// Test built-in spaces to make sure the space definition of the spaceTracker in +// ext-mails.js is matching the actual space definition in spacesToolbar.js +add_task(async function test_builtIn_spaces() { + let extension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": async () => { + const checkSpace = async (spaceId, spaceName) => { + let spaces = await browser.spaces.query({ id: spaceId }); + browser.test.assertEq(spaces.length, 1, "Should find a single space"); + browser.test.assertEq( + spaces[0].isBuiltIn, + true, + "Should find a built-in space" + ); + browser.test.assertEq( + spaces[0].name, + spaceName, + "Should find the correct space" + ); + }; + + // Test the already open mail space. + + let mailTabs = await browser.tabs.query({ type: "mail" }); + browser.test.assertEq( + mailTabs.length, + 1, + "Should find a single mail tab" + ); + await checkSpace(mailTabs[0].spaceId, "mail"); + + // Test all other spaces. + + let builtInSpaces = [ + "addressbook", + "calendar", + "tasks", + "chat", + "settings", + ]; + + for (let spaceName of builtInSpaces) { + await new Promise(resolve => { + const listener = async tab => { + await checkSpace(tab.spaceId, spaceName); + browser.tabs.remove(tab.id); + browser.tabs.onCreated.removeListener(listener); + resolve(); + }; + browser.tabs.onCreated.addListener(listener); + browser.test.sendMessage("openSpace", spaceName); + }); + } + + browser.test.notifyPass(); + }, + "utils.js": await getUtilsJS(), + }, + manifest: { + manifest_version: 2, + browser_specific_settings: { + gecko: { + id: "built-in-spaces@mochi.test", + }, + }, + background: { scripts: ["utils.js", "background.js"] }, + }, + }); + + extension.onMessage("openSpace", async spaceName => { + window.gSpacesToolbar.openSpace( + window.document.getElementById("tabmail"), + window.gSpacesToolbar.spaces.find(space => space.name == spaceName) + ); + }); + + await extension.startup(); + await extension.awaitFinish(); + await extension.unload(); +}); |