diff --git a/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/WebExtensionBrowserMenuBuilder.kt b/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/WebExtensionBrowserMenuBuilder.kt index a825d469df22..95da8cf328e2 100644 --- a/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/WebExtensionBrowserMenuBuilder.kt +++ b/android-components/components/browser/menu/src/main/java/mozilla/components/browser/menu/WebExtensionBrowserMenuBuilder.kt @@ -5,6 +5,7 @@ package mozilla.components.browser.menu import android.content.Context +import androidx.annotation.ColorRes import mozilla.components.browser.menu.item.BackPressMenuItem import mozilla.components.browser.menu.item.BrowserMenuDivider import mozilla.components.browser.menu.item.BrowserMenuImageText @@ -32,7 +33,7 @@ class WebExtensionBrowserMenuBuilder( extras: Map = emptyMap(), endOfMenuAlwaysVisible: Boolean = false, private val store: BrowserStore, - private val webExtIconTintColorResource: Int = NO_ID, + @ColorRes private val webExtIconTintColorResource: Int = NO_ID, private val onAddonsManagerTapped: () -> Unit = {}, private val appendExtensionSubMenuAtStart: Boolean = false ) : BrowserMenuBuilder(items, extras, endOfMenuAlwaysVisible) { diff --git a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/Action.kt b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/Action.kt index dde901b7fcfe..0f813c64c6d0 100644 --- a/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/Action.kt +++ b/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/Action.kt @@ -28,13 +28,14 @@ data class Action( ) { /** * Returns a copy of this [Action] with the provided override applied e.g. for tab-specific overrides. + * If the override is null, the original class is returned without making a new instance. * * @param override the action to use for overriding properties. Note that only the provided * (non-null) properties of the override will be applied, all other properties will remain * unchanged. An extension can send a tab-specific action and only include the properties * it wants to override for the tab. */ - fun copyWithOverride(override: Action) = + fun copyWithOverride(override: Action?) = if (override != null) { Action( title = override.title ?: title, enabled = override.enabled ?: enabled, @@ -44,6 +45,9 @@ data class Action( loadIcon = override.loadIcon ?: loadIcon, onClick = override.onClick ) + } else { + this + } } typealias WebExtensionBrowserAction = Action diff --git a/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/webextension/ActionTest.kt b/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/webextension/ActionTest.kt new file mode 100644 index 000000000000..19bce577555f --- /dev/null +++ b/android-components/components/concept/engine/src/test/java/mozilla/components/concept/engine/webextension/ActionTest.kt @@ -0,0 +1,56 @@ +/* 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/. */ + +package mozilla.components.concept.engine.webextension + +import android.graphics.Color +import org.junit.Assert.assertEquals +import org.junit.Test + +class ActionTest { + + private val onClick: () -> Unit = {} + private val baseAction = Action( + title = "title", + enabled = false, + loadIcon = null, + badgeText = "badge", + badgeTextColor = Color.BLACK, + badgeBackgroundColor = Color.BLUE, + onClick = onClick + ) + + @Test + fun `override using non-null attributes`() { + val overridden = baseAction.copyWithOverride(Action( + title = "other", + enabled = null, + loadIcon = null, + badgeText = null, + badgeTextColor = Color.WHITE, + badgeBackgroundColor = null, + onClick = onClick + )) + + assertEquals( + Action( + title = "other", + enabled = false, + loadIcon = null, + badgeText = "badge", + badgeTextColor = Color.WHITE, + badgeBackgroundColor = Color.BLUE, + onClick = onClick + ), + overridden + ) + } + + @Test + fun `override using null action`() { + val overridden = baseAction.copyWithOverride(null) + + assertEquals(baseAction, overridden) + } +} diff --git a/android-components/components/feature/addons/build.gradle b/android-components/components/feature/addons/build.gradle index 906678aa6db8..10afc6027d42 100644 --- a/android-components/components/feature/addons/build.gradle +++ b/android-components/components/feature/addons/build.gradle @@ -63,6 +63,7 @@ dependencies { implementation project(':browser-state') implementation project(':concept-engine') implementation project(':concept-fetch') + implementation project(':concept-menu') implementation project(':support-base') implementation project(':support-ktx') implementation project(':support-webextensions') diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/menu/WebExtensionActionMenuCandidate.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/menu/WebExtensionActionMenuCandidate.kt new file mode 100644 index 000000000000..8dc6b9733d12 --- /dev/null +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/menu/WebExtensionActionMenuCandidate.kt @@ -0,0 +1,54 @@ +/* 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/. */ + +package mozilla.components.feature.addons.menu + +import android.content.Context +import androidx.appcompat.content.res.AppCompatResources.getDrawable +import androidx.core.graphics.drawable.toDrawable +import mozilla.components.concept.engine.webextension.Action +import mozilla.components.concept.menu.candidate.AsyncDrawableMenuIcon +import mozilla.components.concept.menu.candidate.ContainerStyle +import mozilla.components.concept.menu.candidate.TextMenuCandidate +import mozilla.components.concept.menu.candidate.TextMenuIcon +import mozilla.components.concept.menu.candidate.TextStyle +import mozilla.components.feature.addons.R + +/** + * Create a browser menu item for displaying a web extension action. + * + * @param onClick a callback to be invoked when this menu item is clicked. + */ +fun Action.createMenuCandidate( + context: Context, + onClick: () -> Unit = this.onClick +): TextMenuCandidate { + return TextMenuCandidate( + title.orEmpty(), + start = loadIcon?.let { loadIcon -> + val defaultIcon = getDrawable(context, R.drawable.mozac_ic_web_extension_default_icon) + AsyncDrawableMenuIcon( + loadDrawable = { _, height -> + loadIcon(height)?.toDrawable(context.resources) + }, + loadingDrawable = defaultIcon, + fallbackDrawable = defaultIcon + ) + }, + end = badgeText?.let { badgeText -> + TextMenuIcon( + badgeText, + backgroundTint = badgeBackgroundColor, + textStyle = TextStyle( + color = badgeTextColor + ) + ) + }, + containerStyle = ContainerStyle( + isVisible = true, + isEnabled = enabled ?: false + ), + onClick = onClick + ) +} diff --git a/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/menu/WebExtensionNestedMenuCandidate.kt b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/menu/WebExtensionNestedMenuCandidate.kt new file mode 100644 index 000000000000..5cb96c3d71ce --- /dev/null +++ b/android-components/components/feature/addons/src/main/java/mozilla/components/feature/addons/menu/WebExtensionNestedMenuCandidate.kt @@ -0,0 +1,148 @@ +/* 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/. */ + +package mozilla.components.feature.addons.menu + +import android.content.Context +import androidx.annotation.ColorInt +import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.SessionState +import mozilla.components.browser.state.state.WebExtensionState +import mozilla.components.concept.menu.Side +import mozilla.components.concept.menu.candidate.DividerMenuCandidate +import mozilla.components.concept.menu.candidate.DrawableMenuIcon +import mozilla.components.concept.menu.candidate.MenuCandidate +import mozilla.components.concept.menu.candidate.NestedMenuCandidate +import mozilla.components.concept.menu.candidate.TextMenuCandidate +import mozilla.components.feature.addons.R + +private fun createBackMenuItem( + context: Context, + @ColorInt webExtIconTintColor: Int? +) = NestedMenuCandidate( + id = R.drawable.mozac_ic_back, + text = context.getString(R.string.mozac_feature_addons_addons), + start = DrawableMenuIcon( + context, + R.drawable.mozac_ic_back, + tint = webExtIconTintColor + ), + subMenuItems = null +) + +private fun createAddonsManagerItem( + context: Context, + @ColorInt webExtIconTintColor: Int?, + onAddonsManagerTapped: () -> Unit +) = TextMenuCandidate( + text = context.getString(R.string.mozac_feature_addons_addons_manager), + start = DrawableMenuIcon( + context, + R.drawable.mozac_ic_extensions, + tint = webExtIconTintColor + ), + onClick = onAddonsManagerTapped +) + +private fun createWebExtensionSubMenuItems( + context: Context, + extensions: Collection, + tab: SessionState?, + onAddonsItemTapped: (String) -> Unit +): List { + val menuItems = mutableListOf() + + extensions + .filter { it.enabled } + .filterNot { !it.allowedInPrivateBrowsing && tab?.content?.private == true } + .sortedBy { it.name } + .forEach { extension -> + val tabExtensionState = tab?.extensionState?.get(extension.id) + extension.browserAction?.let { browserAction -> + menuItems.add( + browserAction.copyWithOverride(tabExtensionState?.browserAction).createMenuCandidate( + context + ) { + onAddonsItemTapped(extension.id) + browserAction.onClick() + } + ) + } + + extension.pageAction?.let { pageAction -> + menuItems.add( + pageAction.copyWithOverride(tabExtensionState?.pageAction).createMenuCandidate( + context + ) { + onAddonsItemTapped(extension.id) + pageAction.onClick() + } + ) + } + } + + return menuItems +} + +/** + * Create a browser menu item for displaying a list of web extensions. + * + * @param tabId ID of tab used to load tab-specific extension state. + * @param webExtIconTintColor Optional color used to tint the icons of back and add-ons manager menu items. + * @param appendExtensionSubMenuAt If web extension sub menu should appear at the top (start) of + * the menu, or if web extensions should appear at the bottom of the menu (end). + * @param onAddonsItemTapped Callback to be invoked when a web extension action item is selected. + * Can be used to emit telemetry. + * @param onAddonsManagerTapped Callback to be invoked when add-ons manager menu item is selected. + */ +@Suppress("LongParameterList") +fun BrowserState.createWebExtensionMenuCandidate( + context: Context, + tabId: String? = null, + @ColorInt webExtIconTintColor: Int? = null, + appendExtensionSubMenuAt: Side = Side.END, + onAddonsItemTapped: (String) -> Unit = {}, + onAddonsManagerTapped: () -> Unit = {} +): MenuCandidate { + val items = createWebExtensionSubMenuItems( + context, + extensions = extensions.values, + tab = findTabOrCustomTabOrSelectedTab(tabId), + onAddonsItemTapped = onAddonsItemTapped + ) + + val addonsManagerItem = createAddonsManagerItem( + context, + webExtIconTintColor = webExtIconTintColor, + onAddonsManagerTapped = onAddonsManagerTapped + ) + + return if (items.isNotEmpty()) { + val firstItem: MenuCandidate + val lastItem: MenuCandidate + when (appendExtensionSubMenuAt) { + Side.START -> { + firstItem = createBackMenuItem(context, webExtIconTintColor) + lastItem = addonsManagerItem + } + Side.END -> { + firstItem = addonsManagerItem + lastItem = createBackMenuItem(context, webExtIconTintColor) + } + } + + NestedMenuCandidate( + id = R.string.mozac_feature_addons_addons, + text = context.getString(R.string.mozac_feature_addons_addons), + start = addonsManagerItem.start, + subMenuItems = listOf(firstItem, DividerMenuCandidate()) + + items + listOf(DividerMenuCandidate(), lastItem) + ) + } else { + addonsManagerItem.copy( + text = context.getString(R.string.mozac_feature_addons_addons) + ) + } +} diff --git a/android-components/components/feature/addons/src/main/res/values/strings.xml b/android-components/components/feature/addons/src/main/res/values/strings.xml index 920efe6a16ca..f46e66a91835 100644 --- a/android-components/components/feature/addons/src/main/res/values/strings.xml +++ b/android-components/components/feature/addons/src/main/res/values/strings.xml @@ -129,6 +129,8 @@ %1$.02f/5 Add-ons + + Add-ons Manager Allow diff --git a/android-components/components/feature/addons/src/test/java/AddonManagerTest.kt b/android-components/components/feature/addons/src/test/java/AddonManagerTest.kt index 0c5aef51f6ae..610fded6b926 100644 --- a/android-components/components/feature/addons/src/test/java/AddonManagerTest.kt +++ b/android-components/components/feature/addons/src/test/java/AddonManagerTest.kt @@ -2,7 +2,7 @@ * 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/. */ -package mozilla.components.feature.addons.amo +package mozilla.components.feature.addons import android.graphics.Bitmap import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -23,11 +23,7 @@ import mozilla.components.concept.engine.webextension.DisabledFlags import mozilla.components.concept.engine.webextension.EnableSource import mozilla.components.concept.engine.webextension.Metadata import mozilla.components.concept.engine.webextension.WebExtension -import mozilla.components.feature.addons.Addon -import mozilla.components.feature.addons.AddonManager import mozilla.components.feature.addons.AddonManager.Companion.TEMPORARY_ADDON_ICON_SIZE -import mozilla.components.feature.addons.AddonManagerException -import mozilla.components.feature.addons.AddonsProvider import mozilla.components.feature.addons.update.AddonUpdater.Status import mozilla.components.support.test.any import mozilla.components.support.test.argumentCaptor diff --git a/android-components/components/feature/addons/src/test/java/AddonTest.kt b/android-components/components/feature/addons/src/test/java/AddonTest.kt index 087ee513f07a..5d56654b9013 100644 --- a/android-components/components/feature/addons/src/test/java/AddonTest.kt +++ b/android-components/components/feature/addons/src/test/java/AddonTest.kt @@ -2,11 +2,9 @@ * 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/. */ -package mozilla.components.feature.addons.amo +package mozilla.components.feature.addons import androidx.test.ext.junit.runners.AndroidJUnit4 -import mozilla.components.feature.addons.Addon -import mozilla.components.feature.addons.R import mozilla.components.support.test.robolectric.testContext import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse @@ -347,4 +345,4 @@ class AddonTest { assertEquals(R.string.mozac_feature_addons_permissions_all_urls_description, stringId) } } -} \ No newline at end of file +} diff --git a/android-components/components/feature/addons/src/test/java/AddonCollectionProviderTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/amo/AddonCollectionProviderTest.kt similarity index 100% rename from android-components/components/feature/addons/src/test/java/AddonCollectionProviderTest.kt rename to android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/amo/AddonCollectionProviderTest.kt diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/menu/WebExtensionActionMenuCandidateTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/menu/WebExtensionActionMenuCandidateTest.kt new file mode 100644 index 000000000000..b47baaa7a253 --- /dev/null +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/menu/WebExtensionActionMenuCandidateTest.kt @@ -0,0 +1,126 @@ +/* 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/. */ + +package mozilla.components.feature.addons.menu + +import android.graphics.Color +import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runBlockingTest +import mozilla.components.concept.engine.webextension.Action +import mozilla.components.concept.menu.candidate.AsyncDrawableMenuIcon +import mozilla.components.concept.menu.candidate.TextMenuIcon +import mozilla.components.concept.menu.candidate.TextStyle +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +@ExperimentalCoroutinesApi +class WebExtensionActionMenuCandidateTest { + + private val baseAction = Action( + title = "action", + enabled = false, + loadIcon = null, + badgeText = "", + badgeTextColor = 0, + badgeBackgroundColor = 0, + onClick = {} + ) + + @Test + fun `create menu candidate from null action`() { + val onClick = {} + val candidate = Action( + title = null, + enabled = null, + loadIcon = null, + badgeText = null, + badgeTextColor = null, + badgeBackgroundColor = null, + onClick = onClick + ).createMenuCandidate(testContext) + + assertEquals("", candidate.text) + assertFalse(candidate.containerStyle.isEnabled) + assertEquals(onClick, candidate.onClick) + + assertNull(candidate.start) + assertNull(candidate.end) + } + + @Test + fun `create menu candidate with text and no badge`() { + val candidate = baseAction + .copy(badgeText = null) + .createMenuCandidate(testContext) + + assertEquals("action", candidate.text) + assertFalse(candidate.containerStyle.isEnabled) + + assertNull(candidate.start) + assertNull(candidate.end) + } + + @Test + fun `create menu candidate with badge`() { + val candidate = baseAction + .copy( + badgeText = "10", + badgeTextColor = Color.DKGRAY, + badgeBackgroundColor = Color.YELLOW, + enabled = true + ) + .createMenuCandidate(testContext) + + assertEquals("action", candidate.text) + assertTrue(candidate.containerStyle.isEnabled) + + assertNull(candidate.start) + assertTrue(candidate.end is TextMenuIcon) + + assertEquals( + TextMenuIcon( + text = "10", + backgroundTint = Color.YELLOW, + textStyle = TextStyle(color = Color.DKGRAY) + ), + candidate.end + ) + } + + @Test + fun `create menu candidate with icon`() = runBlockingTest { + var calledWith: Int = -1 + val candidate = baseAction + .copy( + badgeText = null, + loadIcon = { height -> + calledWith = height + null + } + ) + .createMenuCandidate(testContext) + + assertEquals("action", candidate.text) + assertFalse(candidate.containerStyle.isEnabled) + + assertTrue(candidate.start is AsyncDrawableMenuIcon) + assertNull(candidate.end) + + val start = candidate.start as AsyncDrawableMenuIcon + assertNotNull(start.loadingDrawable) + assertNotNull(start.fallbackDrawable) + assertNull(start.effect) + + assertNull(start.loadDrawable(40, 30)) + assertEquals(30, calledWith) + } +} diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/menu/WebExtensionNestedMenuCandidateTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/menu/WebExtensionNestedMenuCandidateTest.kt new file mode 100644 index 000000000000..58eca875487e --- /dev/null +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/menu/WebExtensionNestedMenuCandidateTest.kt @@ -0,0 +1,180 @@ +/* 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/. */ + +package mozilla.components.feature.addons.menu + +import android.graphics.Color +import androidx.test.ext.junit.runners.AndroidJUnit4 +import kotlinx.coroutines.ExperimentalCoroutinesApi +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.WebExtensionState +import mozilla.components.browser.state.state.createTab +import mozilla.components.concept.engine.webextension.Action +import mozilla.components.concept.menu.Side +import mozilla.components.concept.menu.candidate.AsyncDrawableMenuIcon +import mozilla.components.concept.menu.candidate.DividerMenuCandidate +import mozilla.components.concept.menu.candidate.NestedMenuCandidate +import mozilla.components.concept.menu.candidate.TextMenuCandidate +import mozilla.components.concept.menu.candidate.TextMenuIcon +import mozilla.components.support.test.mock +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +@ExperimentalCoroutinesApi +class WebExtensionNestedMenuCandidateTest { + + private val pageAction = Action( + title = "page title", + loadIcon = { mock() }, + enabled = true, + badgeText = "pageBadge", + badgeTextColor = Color.WHITE, + badgeBackgroundColor = Color.BLUE + ) {} + + private val browserAction = Action( + title = "browser title", + loadIcon = { mock() }, + enabled = true, + badgeText = "browserBadge", + badgeTextColor = Color.WHITE, + badgeBackgroundColor = Color.BLUE + ) {} + + @Test + fun `create nested menu from browser extensions and actions`() { + val state = BrowserState(extensions = mapOf( + "1" to WebExtensionState(id = "1", browserAction = browserAction, pageAction = pageAction) + )) + val candidate = state.createWebExtensionMenuCandidate( + testContext, + appendExtensionSubMenuAt = Side.END + ) as NestedMenuCandidate + + assertEquals(6, candidate.subMenuItems!!.size) + + assertEquals( + "Add-ons Manager", + (candidate.subMenuItems!![0] as TextMenuCandidate).text + ) + assertEquals( + DividerMenuCandidate(), + candidate.subMenuItems!![1] + ) + + val ext1 = candidate.subMenuItems!![2] as TextMenuCandidate + assertTrue(ext1.containerStyle.isEnabled) + assertEquals("browser title", ext1.text) + assertTrue(ext1.start is AsyncDrawableMenuIcon) + assertEquals( + "browserBadge", + (ext1.end as TextMenuIcon).text + ) + + val ext2 = candidate.subMenuItems!![3] as TextMenuCandidate + assertTrue(ext2.containerStyle.isEnabled) + assertEquals("page title", ext2.text) + assertTrue(ext2.start is AsyncDrawableMenuIcon) + assertEquals( + "pageBadge", + (ext2.end as TextMenuIcon).text + ) + + assertEquals( + DividerMenuCandidate(), + candidate.subMenuItems!![4] + ) + assertEquals( + "Add-ons", + (candidate.subMenuItems!![5] as NestedMenuCandidate).text + ) + } + + @Test + fun `browser actions can be overridden per tab`() { + val pageActionOverride = Action( + title = "updatedTitle", + loadIcon = null, + enabled = true, + badgeText = "updatedText", + badgeTextColor = Color.RED, + badgeBackgroundColor = Color.GREEN + ) {} + val browserActionOverride = Action( + title = "updatedTitle", + loadIcon = null, + enabled = false, + badgeText = "updatedText", + badgeTextColor = Color.RED, + badgeBackgroundColor = Color.GREEN + ) {} + + val state = BrowserState( + extensions = mapOf( + "1" to WebExtensionState(id = "1", browserAction = browserAction, pageAction = pageAction) + ), + tabs = listOf( + createTab( + id = "tab-1", + url = "https://mozilla.org", + extensions = mapOf( + "1" to WebExtensionState( + id = "1", + browserAction = browserActionOverride, + pageAction = pageActionOverride + ) + ) + ) + ) + ) + val candidate = state.createWebExtensionMenuCandidate( + testContext, + tabId = "tab-1", + appendExtensionSubMenuAt = Side.START + ) as NestedMenuCandidate + + assertEquals(6, candidate.subMenuItems!!.size) + + assertEquals( + "Add-ons", + (candidate.subMenuItems!![0] as NestedMenuCandidate).text + ) + assertNull((candidate.subMenuItems!![0] as NestedMenuCandidate).subMenuItems) + assertEquals( + DividerMenuCandidate(), + candidate.subMenuItems!![1] + ) + + val ext1 = candidate.subMenuItems!![2] as TextMenuCandidate + assertFalse(ext1.containerStyle.isEnabled) + assertEquals("updatedTitle", ext1.text) + assertEquals( + "updatedText", + (ext1.end as TextMenuIcon).text + ) + + val ext2 = candidate.subMenuItems!![3] as TextMenuCandidate + assertTrue(ext2.containerStyle.isEnabled) + assertEquals("updatedTitle", ext2.text) + assertEquals( + "updatedText", + (ext2.end as TextMenuIcon).text + ) + + assertEquals( + DividerMenuCandidate(), + candidate.subMenuItems!![4] + ) + assertEquals( + "Add-ons Manager", + (candidate.subMenuItems!![5] as TextMenuCandidate).text + ) + } +} diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragmentTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragmentTest.kt index 905917c7f712..95e3aec3a8e8 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragmentTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonInstallationDialogFragmentTest.kt @@ -2,7 +2,7 @@ * 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/. */ -package mozilla.components.feature.addons.amo.mozilla.components.feature.addons.ui +package mozilla.components.feature.addons.ui import android.graphics.Bitmap import android.view.Gravity @@ -21,10 +21,6 @@ import kotlinx.coroutines.test.TestCoroutineScope import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.R import mozilla.components.feature.addons.amo.AddonCollectionProvider -import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment -import mozilla.components.feature.addons.ui.KEY_ICON -import mozilla.components.feature.addons.ui.KEY_INSTALLED_ADDON -import mozilla.components.feature.addons.ui.translatedName import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.rule.MainCoroutineRule diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt index e6978fc5afb4..9b13434d74b0 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/AddonsManagerAdapterTest.kt @@ -2,7 +2,7 @@ * 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/. */ -package mozilla.components.feature.addons.amo.mozilla.components.feature.addons.ui +package mozilla.components.feature.addons.ui import android.graphics.Bitmap import android.graphics.drawable.BitmapDrawable @@ -20,12 +20,9 @@ import kotlinx.coroutines.test.TestCoroutineScope import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.R import mozilla.components.feature.addons.amo.AddonCollectionProvider -import mozilla.components.feature.addons.ui.AddonsManagerAdapter import mozilla.components.feature.addons.ui.AddonsManagerAdapter.NotYetSupportedSection import mozilla.components.feature.addons.ui.AddonsManagerAdapter.Section import mozilla.components.feature.addons.ui.AddonsManagerAdapter.DifferCallback -import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate -import mozilla.components.feature.addons.ui.CustomViewHolder import mozilla.components.support.test.argumentCaptor import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/ExtensionsTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/ExtensionsTest.kt index c9986602d004..493e29e247c3 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/ExtensionsTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/ExtensionsTest.kt @@ -2,17 +2,11 @@ * 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/. */ -package mozilla.components.feature.addons.amo.mozilla.components.feature.addons.ui +package mozilla.components.feature.addons.ui import androidx.test.ext.junit.runners.AndroidJUnit4 import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.R -import mozilla.components.feature.addons.ui.createdAtDate -import mozilla.components.feature.addons.ui.getFormattedAmount -import mozilla.components.feature.addons.ui.toLocalizedString -import mozilla.components.feature.addons.ui.translate -import mozilla.components.feature.addons.ui.translatedName -import mozilla.components.feature.addons.ui.updatedAtDate import mozilla.components.feature.addons.update.AddonUpdater import mozilla.components.feature.addons.update.AddonUpdater.Status.Error import mozilla.components.feature.addons.update.AddonUpdater.Status.NoUpdateAvailable diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/PermissionsDialogFragmentTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/PermissionsDialogFragmentTest.kt index b3321c39eb5d..743363fd8362 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/PermissionsDialogFragmentTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/PermissionsDialogFragmentTest.kt @@ -2,7 +2,7 @@ * 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/. */ -package mozilla.components.feature.addons.amo.mozilla.components.feature.addons.ui +package mozilla.components.feature.addons.ui import android.view.Gravity.TOP import android.view.ViewGroup @@ -13,9 +13,7 @@ import androidx.fragment.app.FragmentTransaction import androidx.test.ext.junit.runners.AndroidJUnit4 import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.R -import mozilla.components.feature.addons.ui.PermissionsDialogFragment import mozilla.components.feature.addons.ui.PermissionsDialogFragment.PromptsStyling -import mozilla.components.feature.addons.ui.translatedName import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext import org.junit.Assert.assertTrue diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/UnsupportedAddonsAdapterTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/UnsupportedAddonsAdapterTest.kt index d76c4b7346c6..bdc79d7d84a9 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/UnsupportedAddonsAdapterTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/ui/UnsupportedAddonsAdapterTest.kt @@ -2,7 +2,7 @@ * 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/. */ -package mozilla.components.feature.addons.amo.mozilla.components.feature.addons.ui +package mozilla.components.feature.addons.ui import android.widget.ImageButton import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -10,8 +10,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineDispatcher import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManager -import mozilla.components.feature.addons.ui.UnsupportedAddonsAdapter -import mozilla.components.feature.addons.ui.UnsupportedAddonsAdapterDelegate import mozilla.components.support.test.any import mozilla.components.support.test.argumentCaptor import mozilla.components.support.test.mock diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/update/GlobalAddonDependencyProviderTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/update/GlobalAddonDependencyProviderTest.kt index f0c487dcbf1a..42465ea33174 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/update/GlobalAddonDependencyProviderTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/update/GlobalAddonDependencyProviderTest.kt @@ -2,13 +2,11 @@ * 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/. */ -package mozilla.components.feature.addons.amo.mozilla.components.feature.addons.update +package mozilla.components.feature.addons.update import androidx.test.ext.junit.runners.AndroidJUnit4 import junit.framework.TestCase.assertEquals import mozilla.components.feature.addons.AddonManager -import mozilla.components.feature.addons.update.AddonUpdater -import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider import mozilla.components.support.test.mock import org.junit.Before import org.junit.Test diff --git a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/update/NotificationHandlerServiceTest.kt b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/update/NotificationHandlerServiceTest.kt index 0b13ef83d617..13498244dbac 100644 --- a/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/update/NotificationHandlerServiceTest.kt +++ b/android-components/components/feature/addons/src/test/java/mozilla/components/feature/addons/update/NotificationHandlerServiceTest.kt @@ -2,17 +2,14 @@ * 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/. */ -package mozilla.components.feature.addons.amo.mozilla.components.feature.addons.update +package mozilla.components.feature.addons.update import android.content.Intent import androidx.test.ext.junit.runners.AndroidJUnit4 import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue -import mozilla.components.feature.addons.update.AddonUpdater -import mozilla.components.feature.addons.update.DefaultAddonUpdater import mozilla.components.feature.addons.update.DefaultAddonUpdater.NotificationHandlerService import mozilla.components.feature.addons.update.DefaultAddonUpdater.UpdateStatusStorage -import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext import org.junit.Test