commit 8caf08560218ea2c1c68100cbf356194de04ccd4 parent 6c814296eba3f639052e4e1aa02bb522a192ca31 Author: Moyin <madeyemi@mozilla.com> Date: Thu, 4 Dec 2025 16:31:03 +0000 Bug 1993154 - Merge the PrivateModeUpdated and EnterEditMode BrowserToolbarStore Actions r=android-reviewers,petru Differential Revision: https://phabricator.services.mozilla.com/D275063 Diffstat:
11 files changed, 54 insertions(+), 65 deletions(-)
diff --git a/mobile/android/android-components/components/compose/browser-toolbar/src/main/java/mozilla/components/compose/browser/toolbar/store/BrowserToolbarAction.kt b/mobile/android/android-components/components/compose/browser-toolbar/src/main/java/mozilla/components/compose/browser/toolbar/store/BrowserToolbarAction.kt @@ -17,8 +17,10 @@ import mozilla.components.compose.browser.toolbar.concept.Action as ToolbarActio sealed interface BrowserToolbarAction : Action { /** * Allow typing a search term or URL. + * + * @property isPrivate [Boolean] Indicates that the toolbar is used for private mode / incognito queries. */ - object EnterEditMode : BrowserToolbarAction + data class EnterEditMode(val isPrivate: Boolean) : BrowserToolbarAction /** * Show the current URL. @@ -131,11 +133,6 @@ sealed class BrowserEditToolbarAction : BrowserToolbarAction { ) : BrowserEditToolbarAction() /** - * Indicates that the toolbar is used for private mode / incognito queries. - */ - data class PrivateModeUpdated(val inPrivateMode: Boolean) : BrowserEditToolbarAction() - - /** * Indicates that a new autocomplete suggestion is available or that the previous one is not valid anymore. * * @property autocompletedSuggestion The new autocomplete suggestion. `null` if none is available. diff --git a/mobile/android/android-components/components/compose/browser-toolbar/src/main/java/mozilla/components/compose/browser/toolbar/store/BrowserToolbarStore.kt b/mobile/android/android-components/components/compose/browser-toolbar/src/main/java/mozilla/components/compose/browser/toolbar/store/BrowserToolbarStore.kt @@ -52,6 +52,9 @@ private fun reduce(state: BrowserToolbarState, action: BrowserToolbarAction): Br is BrowserToolbarAction.EnterEditMode -> state.copy( mode = Mode.EDIT, + editState = state.editState.copy( + isQueryPrivate = action.isPrivate, + ), ) is BrowserToolbarAction.ExitEditMode -> state.copy( @@ -110,12 +113,6 @@ private fun reduce(state: BrowserToolbarState, action: BrowserToolbarAction): Br ), ) - is BrowserEditToolbarAction.PrivateModeUpdated -> state.copy( - editState = state.editState.copy( - isQueryPrivate = action.inPrivateMode, - ), - ) - is AutocompleteSuggestionUpdated -> state.copy( editState = state.editState.copy( suggestion = action.autocompletedSuggestion, diff --git a/mobile/android/android-components/components/compose/browser-toolbar/src/test/java/mozilla/components/compose/browser/toolbar/store/BrowserToolbarStoreTest.kt b/mobile/android/android-components/components/compose/browser-toolbar/src/test/java/mozilla/components/compose/browser/toolbar/store/BrowserToolbarStoreTest.kt @@ -32,11 +32,26 @@ class BrowserToolbarStoreTest { val store = BrowserToolbarStore() assertEquals(Mode.DISPLAY, store.state.mode) + assertFalse(store.state.editState.isQueryPrivate) + + store.dispatch(BrowserToolbarAction.EnterEditMode(false)) + + assertEquals(Mode.EDIT, store.state.mode) + assertEquals("", store.state.editState.query.current) + assertEquals(false, store.state.editState.isQueryPrivate) + } + + @Test + fun `WHEN enter edit mode action in private mode is dispatched THEN replace the old details with the new one`() { + val store = BrowserToolbarStore() + assertEquals(Mode.DISPLAY, store.state.mode) + assertFalse(store.state.editState.isQueryPrivate) - store.dispatch(BrowserToolbarAction.EnterEditMode) + store.dispatch(BrowserToolbarAction.EnterEditMode(true)) assertEquals(Mode.EDIT, store.state.mode) assertEquals("", store.state.editState.query.current) + assertEquals(true, store.state.editState.isQueryPrivate) } @Test @@ -209,16 +224,6 @@ class BrowserToolbarStoreTest { assertEquals(Bottom, store.state.gravity) } - @Test - fun `WHEN the private mode is updated THEN replace the old details with the new one`() { - val store = BrowserToolbarStore() - assertFalse(store.state.editState.isQueryPrivate) - - store.dispatch(BrowserEditToolbarAction.PrivateModeUpdated(true)) - - assertEquals(true, store.state.editState.isQueryPrivate) - } - private fun fakeActionButton() = ActionButtonRes( drawableResId = Random.nextInt(), contentDescription = Random.nextInt(), diff --git a/mobile/android/android-components/samples/compose-browser/src/main/java/org/mozilla/samples/compose/browser/browser/BrowserScreen.kt b/mobile/android/android-components/samples/compose-browser/src/main/java/org/mozilla/samples/compose/browser/browser/BrowserScreen.kt @@ -167,7 +167,7 @@ fun TabsTray( selectTab = true, ) store.dispatch(BrowserScreenAction.HideTabs) - toolbarStore.dispatch(BrowserToolbarAction.EnterEditMode) + toolbarStore.dispatch(BrowserToolbarAction.EnterEditMode(false)) }, ) { Text("+") diff --git a/mobile/android/android-components/samples/compose-browser/src/main/java/org/mozilla/samples/compose/browser/browser/BrowserToolbarMiddleware.kt b/mobile/android/android-components/samples/compose-browser/src/main/java/org/mozilla/samples/compose/browser/browser/BrowserToolbarMiddleware.kt @@ -68,7 +68,7 @@ internal class BrowserToolbarMiddleware( } is PageOriginClicked -> { - next(EnterEditMode) + next(EnterEditMode(false)) } is TabCounterClicked -> { diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/BrowserToolbarSearchStatusSyncMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/search/BrowserToolbarSearchStatusSyncMiddleware.kt @@ -8,7 +8,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.launch -import mozilla.components.compose.browser.toolbar.store.BrowserEditToolbarAction.PrivateModeUpdated import mozilla.components.compose.browser.toolbar.store.BrowserToolbarAction import mozilla.components.compose.browser.toolbar.store.BrowserToolbarAction.EnterEditMode import mozilla.components.compose.browser.toolbar.store.BrowserToolbarAction.ExitEditMode @@ -61,10 +60,7 @@ class BrowserToolbarSearchStatusSyncMiddleware( .distinctUntilChangedBy { it.searchState.isSearchActive } .collect { if (it.searchState.isSearchActive) { - context.dispatch( - PrivateModeUpdated(browsingModeManager.mode.isPrivate), - ) - context.dispatch(EnterEditMode) + context.dispatch(EnterEditMode(browsingModeManager.mode.isPrivate)) } else { context.dispatch(ExitEditMode) } diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/bookmarks/BrowserToolbarSyncToBookmarksMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/bookmarks/BrowserToolbarSyncToBookmarksMiddlewareTest.kt @@ -59,7 +59,7 @@ class BrowserToolbarSyncToBookmarksMiddlewareTest { middleware = listOf(middleware), ) - toolbarStore.dispatch(EnterEditMode) + toolbarStore.dispatch(EnterEditMode(false)) assertFalse(bookmarksStore.state.isSearching) } diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/library/history/BrowserToolbarSyncToHistoryMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/library/history/BrowserToolbarSyncToHistoryMiddlewareTest.kt @@ -59,7 +59,7 @@ class BrowserToolbarSyncToHistoryMiddlewareTest { middleware = listOf(BrowserToolbarSyncToHistoryMiddleware(historyStore)), ) - toolbarStore.dispatch(EnterEditMode) + toolbarStore.dispatch(EnterEditMode(false)) verify(exactly = 0) { historyStore.dispatch(any()) } } diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/BrowserToolbarSearchMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/BrowserToolbarSearchMiddlewareTest.kt @@ -130,7 +130,7 @@ class BrowserToolbarSearchMiddlewareTest { fun `WHEN the toolbar enters in edit mode THEN a new search selector button is added`() { val (_, store) = buildMiddlewareAndAddToStore() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) assertSearchSelectorEquals( expectedSearchSelector(), @@ -142,7 +142,7 @@ class BrowserToolbarSearchMiddlewareTest { fun `WHEN the toolbar enters in edit mode with non-blank query THEN a clear button is shown`() { val (_, store) = buildMiddlewareAndAddToStore() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) store.dispatch(SearchQueryUpdated(BrowserToolbarQuery("test"))) assertEquals( @@ -155,7 +155,7 @@ class BrowserToolbarSearchMiddlewareTest { fun `WHEN the toolbar enters in edit mode with blank query THEN a qr scanner button is shown`() { val (_, store) = buildMiddlewareAndAddToStore() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) store.dispatch(SearchQueryUpdated(BrowserToolbarQuery(""))) assertEquals( @@ -168,7 +168,7 @@ class BrowserToolbarSearchMiddlewareTest { fun `WHEN the toolbar enters in edit mode with blank query AND user starts typing THEN qr button is replaced by clear button`() { val (_, store) = buildMiddlewareAndAddToStore() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) store.dispatch(SearchQueryUpdated(BrowserToolbarQuery(""))) assertEquals( @@ -188,7 +188,7 @@ class BrowserToolbarSearchMiddlewareTest { fun `WHEN the toolbar enters in edit mode with non-blank query AND the clear button is clicked THEN text is cleared and telemetry is recorded`() { val (_, store) = buildMiddlewareAndAddToStore() store.dispatch(SearchQueryUpdated(BrowserToolbarQuery("test"))) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val clearButton = store.state.editState.editActionsEnd.last() as ActionButtonRes assertEquals(expectedClearButton, clearButton) @@ -205,7 +205,7 @@ class BrowserToolbarSearchMiddlewareTest { fakeSearchState().customSearchEngines.first() } val (_, store) = buildMiddlewareAndAddToStore(appStore = appStore) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val qrButton = store.state.editState.editActionsEnd.last() as ActionButtonRes assertEquals(expectedQrButton, qrButton) @@ -224,7 +224,7 @@ class BrowserToolbarSearchMiddlewareTest { val middleware = spyk(buildMiddleware(appStore = appStore)) every { middleware.isSpeechRecognitionAvailable() } returns true val store = buildStore(middleware) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val voiceSearchButton = store.state.editState.editActionsEnd.last() as ActionButtonRes assertEquals(expectedVoiceSearchButton, voiceSearchButton) @@ -249,7 +249,7 @@ class BrowserToolbarSearchMiddlewareTest { val appStore = AppStore(middlewares = listOf(captorMiddleware)) val (_, store) = buildMiddlewareAndAddToStore(appStore = appStore) appStore.dispatch(SearchStarted()) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) store.dispatch(SearchQueryUpdated(BrowserToolbarQuery("test"))) assertTrue(store.state.isEditMode()) assertTrue(appStore.state.searchState.isSearchActive) @@ -272,7 +272,7 @@ class BrowserToolbarSearchMiddlewareTest { fun `GIVEN the search selector menu is open WHEN a menu item is clicked THEN update the selected search engine and rebuild the menu`() { val (_, store) = buildMiddlewareAndAddToStore() val newEngineSelection = fakeSearchState().searchEngineShortcuts.last() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) assertSearchSelectorEquals( expectedSearchSelector(), store.state.editState.editActionsStart[0] as SearchSelectorAction, @@ -314,7 +314,7 @@ class BrowserToolbarSearchMiddlewareTest { val store = buildStore(middleware) val autocompleteProvidersSlot = slot<List<AutocompleteProvider>>() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) shadowOf(Looper.getMainLooper()).idle() coVerify(exactly = 0) { middleware.fetchAutocomplete( @@ -364,7 +364,7 @@ class BrowserToolbarSearchMiddlewareTest { val store = buildStore(middleware) val autocompleteProvidersSlot = slot<List<AutocompleteProvider>>() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) shadowOf(Looper.getMainLooper()).idle() coVerify(exactly = 0) { middleware.fetchAutocomplete( @@ -407,7 +407,7 @@ class BrowserToolbarSearchMiddlewareTest { val store = buildStore(middleware) val autocompleteProvidersSlot = slot<List<AutocompleteProvider>>() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) shadowOf(Looper.getMainLooper()).idle() coVerify(exactly = 0) { middleware.fetchAutocomplete( @@ -451,7 +451,7 @@ class BrowserToolbarSearchMiddlewareTest { val store = buildStore(middleware) val autocompleteProvidersSlot = slot<List<AutocompleteProvider>>() - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) shadowOf(Looper.getMainLooper()).idle() coVerify(exactly = 0) { middleware.fetchAutocomplete( @@ -650,7 +650,7 @@ class BrowserToolbarSearchMiddlewareTest { val store = buildStore(middleware) store.dispatch(SearchSelectorItemClicked(mockk(relaxed = true))) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) shadowOf(Looper.getMainLooper()).idle() coVerify(exactly = 0) { @@ -669,7 +669,7 @@ class BrowserToolbarSearchMiddlewareTest { fun `WHEN the search engines are updated in BrowserStore THEN update the search selector and search providers`() { val browserStore = BrowserStore() val (_, store) = buildMiddlewareAndAddToStore(browserStore = browserStore) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val newSearchEngines = fakeSearchState().applicationSearchEngines browserStore.dispatch(ApplicationSearchEnginesLoaded(newSearchEngines)) @@ -693,7 +693,7 @@ class BrowserToolbarSearchMiddlewareTest { ) val browserStore = BrowserStore() val (_, store) = buildMiddlewareAndAddToStore(testContext, appStore, browserStore) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val newSearchEngines = fakeSearchState().applicationSearchEngines browserStore.dispatch(ApplicationSearchEnginesLoaded(newSearchEngines)) @@ -919,9 +919,7 @@ class BrowserToolbarSearchMiddlewareTest { val middleware = spyk(buildMiddleware(appStore = appStore)) every { middleware.isSpeechRecognitionAvailable() } returns true val store = buildStore(middleware) - store.dispatch(EnterEditMode) - - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val actions = store.state.editState.editActionsEnd assertEquals(2, actions.size) @@ -934,9 +932,8 @@ class BrowserToolbarSearchMiddlewareTest { val middleware = spyk(buildMiddleware(appStore = appStore)) every { middleware.isSpeechRecognitionAvailable() } returns false val store = buildStore(middleware) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) store.dispatch(SearchQueryUpdated(BrowserToolbarQuery(""))) - store.dispatch(EnterEditMode) val actions = store.state.editState.editActionsEnd assertTrue(actions.size == 1) @@ -957,7 +954,7 @@ class BrowserToolbarSearchMiddlewareTest { components = components, browsingModeManager = browsingModeManager, ) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val qrScannerButton = store.state.editState.editActionsEnd.last() as ActionButtonRes store.dispatch(qrScannerButton.onClick as BrowserToolbarEvent) @@ -991,7 +988,7 @@ class BrowserToolbarSearchMiddlewareTest { components = components, browsingModeManager = browsingModeManager, ) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(true)) val qrScannerButton = store.state.editState.editActionsEnd.last() as ActionButtonRes store.dispatch(qrScannerButton.onClick as BrowserToolbarEvent) @@ -1030,7 +1027,7 @@ class BrowserToolbarSearchMiddlewareTest { components = components, browsingModeManager = browsingModeManager, ) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val qrScannerButton = store.state.editState.editActionsEnd.last() as ActionButtonRes store.dispatch(qrScannerButton.onClick as BrowserToolbarEvent) @@ -1059,7 +1056,7 @@ class BrowserToolbarSearchMiddlewareTest { val middleware = spyk(buildMiddleware(appStore = appStore)) every { middleware.isSpeechRecognitionAvailable() } returns true val store = buildStore(middleware) - store.dispatch(EnterEditMode) + store.dispatch(EnterEditMode(false)) val voiceAction = store.state.editState.editActionsEnd.first() as ActionButtonRes store.dispatch(voiceAction.onClick as BrowserToolbarEvent) diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/BrowserToolbarSearchStatusSyncMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/BrowserToolbarSearchStatusSyncMiddlewareTest.kt @@ -57,10 +57,11 @@ class BrowserToolbarSearchStatusSyncMiddlewareTest { assertFalse(toolbarStore.state.isEditMode()) assertFalse(appStore.state.searchState.isSearchActive) - toolbarStore.dispatch(EnterEditMode) + toolbarStore.dispatch(EnterEditMode(false)) mainLooperRule.idle() assertFalse(appStore.state.searchState.isSearchActive) + assertFalse(toolbarStore.state.editState.isQueryPrivate) } @Test diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/BrowserToolbarToFenixSearchMapperMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/search/BrowserToolbarToFenixSearchMapperMiddlewareTest.kt @@ -7,11 +7,7 @@ package org.mozilla.fenix.search import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.MainScope -import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.UnconfinedTestDispatcher -import mozilla.components.browser.state.selector.selectedTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore @@ -50,7 +46,7 @@ class BrowserToolbarToFenixSearchMapperMiddlewareTest { val captorMiddleware = CaptureActionsMiddleware<SearchFragmentState, SearchFragmentAction>() val searchStore = buildSearchStore(listOf(searchStatusMapperMiddleware, captorMiddleware)) - toolbarStore.dispatch(EnterEditMode) + toolbarStore.dispatch(EnterEditMode(false)) mainLooperRule.idle() captorMiddleware.assertLastAction(SearchStarted::class) { @@ -62,7 +58,7 @@ class BrowserToolbarToFenixSearchMapperMiddlewareTest { @Test fun `GIVEN search was started WHEN there's a new query in the toolbar THEN update the search state`() { val searchStore = buildSearchStore(listOf(buildMiddleware())) - toolbarStore.dispatch(EnterEditMode) + toolbarStore.dispatch(EnterEditMode(false)) searchStore.dispatch(SearchStarted(mockk(), false, false, searchStartedForCurrentUrl = false)) mainLooperRule.idle() @@ -94,7 +90,7 @@ class BrowserToolbarToFenixSearchMapperMiddlewareTest { ), ) val searchStore = buildSearchStore(listOf(buildMiddleware(browserStore = browserStore))) - toolbarStore.dispatch(EnterEditMode) + toolbarStore.dispatch(EnterEditMode(false)) toolbarStore.dispatch( SearchQueryUpdated(BrowserToolbarQuery("https://mozilla.org"), isQueryPrefilled = true),