From 3086d8a6945f25a7ed66babd27507846278cdd51 Mon Sep 17 00:00:00 2001 From: Tiger Oakes Date: Fri, 7 Aug 2020 15:24:11 -0700 Subject: [PATCH] Add test for search dialog controller --- .../SearchDialogControllerTest.kt | 320 ++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 app/src/test/java/org/mozilla/fenix/searchdialog/SearchDialogControllerTest.kt diff --git a/app/src/test/java/org/mozilla/fenix/searchdialog/SearchDialogControllerTest.kt b/app/src/test/java/org/mozilla/fenix/searchdialog/SearchDialogControllerTest.kt new file mode 100644 index 000000000..cfa3649c6 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/searchdialog/SearchDialogControllerTest.kt @@ -0,0 +1,320 @@ +/* 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 org.mozilla.fenix.searchdialog + +import androidx.navigation.NavController +import androidx.navigation.NavDirections +import io.mockk.MockKAnnotations +import io.mockk.Runs +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.just +import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.unmockkObject +import io.mockk.verify +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runBlockingTest +import mozilla.components.browser.search.SearchEngine +import mozilla.components.browser.session.Session +import mozilla.components.browser.session.SessionManager +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mozilla.fenix.BrowserDirection +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.R +import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.components.metrics.MetricController +import org.mozilla.fenix.components.metrics.MetricsUtils +import org.mozilla.fenix.ext.navigateSafe +import org.mozilla.fenix.search.SearchFragmentAction +import org.mozilla.fenix.settings.SupportUtils +import org.mozilla.fenix.utils.Settings + +@ExperimentalCoroutinesApi +class SearchDialogControllerTest { + + @MockK(relaxed = true) private lateinit var activity: HomeActivity + @MockK(relaxed = true) private lateinit var store: SearchDialogFragmentStore + @MockK(relaxed = true) private lateinit var navController: NavController + @MockK private lateinit var searchEngine: SearchEngine + @MockK(relaxed = true) private lateinit var metrics: MetricController + @MockK(relaxed = true) private lateinit var settings: Settings + @MockK private lateinit var sessionManager: SessionManager + @MockK(relaxed = true) private lateinit var clearToolbarFocus: () -> Unit + + private lateinit var controller: SearchDialogController + + @Before + fun setUp() { + MockKAnnotations.init(this) + mockkObject(MetricsUtils) + + every { store.state.tabId } returns "test-tab-id" + every { store.state.searchEngineSource.searchEngine } returns searchEngine + every { sessionManager.select(any()) } just Runs + every { MetricsUtils.createSearchEvent(searchEngine, activity, any()) } returns null + + controller = SearchDialogController( + activity = activity, + sessionManager = sessionManager, + store = store, + navController = navController, + settings = settings, + metrics = metrics, + clearToolbarFocus = clearToolbarFocus + ) + } + + @After + fun teardown() { + unmockkObject(MetricsUtils) + } + + @Test + fun handleUrlCommitted() { + val url = "https://www.google.com/" + + controller.handleUrlCommitted(url) + + verify { + activity.openToBrowserAndLoad( + searchTermOrURL = url, + newTab = false, + from = BrowserDirection.FromSearchDialog, + engine = searchEngine + ) + } + verify { metrics.track(Event.EnteredUrl(false)) } + } + + @Test + fun handleSearchCommitted() { + val searchTerm = "Firefox" + + controller.handleUrlCommitted(searchTerm) + + verify { + activity.openToBrowserAndLoad( + searchTermOrURL = searchTerm, + newTab = false, + from = BrowserDirection.FromSearchDialog, + engine = searchEngine + ) + } + verify { settings.incrementActiveSearchCount() } + } + + @Test + fun handleCrashesUrlCommitted() { + val url = "about:crashes" + every { activity.packageName } returns "org.mozilla.fenix" + + controller.handleUrlCommitted(url) + + verify { + activity.startActivity(any()) + } + } + + @Test + fun handleMozillaUrlCommitted() { + val url = "moz://a" + + controller.handleUrlCommitted(url) + + verify { + activity.openToBrowserAndLoad( + searchTermOrURL = SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.MANIFESTO), + newTab = false, + from = BrowserDirection.FromSearchDialog, + engine = searchEngine + ) + } + verify { metrics.track(Event.EnteredUrl(false)) } + } + + @Test + fun handleEditingCancelled() = runBlockingTest { + controller.handleEditingCancelled() + + verify { + clearToolbarFocus() + } + } + + @Test + fun handleTextChangedNonEmpty() { + val text = "fenix" + + controller.handleTextChanged(text) + + verify { store.dispatch(SearchFragmentAction.UpdateQuery(text)) } + } + + @Test + fun handleTextChangedEmpty() { + val text = "" + + controller.handleTextChanged(text) + + verify { store.dispatch(SearchFragmentAction.UpdateQuery(text)) } + } + + @Test + fun `show search shortcuts when setting enabled AND query empty`() { + val text = "" + every { settings.shouldShowSearchShortcuts } returns true + + controller.handleTextChanged(text) + + verify { store.dispatch(SearchFragmentAction.ShowSearchShortcutEnginePicker(true)) } + } + + @Test + fun `show search shortcuts when setting enabled AND query equals url`() { + val text = "mozilla.org" + every { store.state.url } returns "mozilla.org" + every { settings.shouldShowSearchShortcuts } returns true + + controller.handleTextChanged(text) + + verify { store.dispatch(SearchFragmentAction.ShowSearchShortcutEnginePicker(true)) } + } + + @Test + fun `do not show search shortcuts when setting enabled AND query non-empty`() { + val text = "mozilla" + + controller.handleTextChanged(text) + + verify { store.dispatch(SearchFragmentAction.ShowSearchShortcutEnginePicker(false)) } + } + + @Test + fun `do not show search shortcuts when setting disabled AND query empty AND url not matching query`() { + every { settings.shouldShowSearchShortcuts } returns false + + val text = "" + + controller.handleTextChanged(text) + + verify { store.dispatch(SearchFragmentAction.ShowSearchShortcutEnginePicker(false)) } + } + + @Test + fun `do not show search shortcuts when setting disabled AND query non-empty`() { + every { settings.shouldShowSearchShortcuts } returns false + + val text = "mozilla" + + controller.handleTextChanged(text) + + verify { store.dispatch(SearchFragmentAction.ShowSearchShortcutEnginePicker(false)) } + } + + @Test + fun handleUrlTapped() { + val url = "https://www.google.com/" + + controller.handleUrlTapped(url) + + verify { + activity.openToBrowserAndLoad( + searchTermOrURL = url, + newTab = false, + from = BrowserDirection.FromSearchDialog + ) + } + verify { metrics.track(Event.EnteredUrl(false)) } + } + + @Test + fun handleSearchTermsTapped() { + val searchTerms = "fenix" + + controller.handleSearchTermsTapped(searchTerms) + + verify { + activity.openToBrowserAndLoad( + searchTermOrURL = searchTerms, + newTab = false, + from = BrowserDirection.FromSearchDialog, + engine = searchEngine, + forceSearch = true + ) + } + } + + @Test + fun handleSearchShortcutEngineSelected() { + val searchEngine: SearchEngine = mockk(relaxed = true) + + controller.handleSearchShortcutEngineSelected(searchEngine) + + verify { store.dispatch(SearchFragmentAction.SearchShortcutEngineSelected(searchEngine)) } + verify { metrics.track(Event.SearchShortcutSelected(searchEngine, false)) } + } + + @Test + fun handleClickSearchEngineSettings() { + val directions: NavDirections = + SearchDialogFragmentDirections.actionGlobalSearchEngineFragment() + + controller.handleClickSearchEngineSettings() + + verify { navController.navigateSafe(R.id.searchEngineFragment, directions) } + } + + @Test + fun handleSearchShortcutsButtonClicked_alreadyOpen() { + every { store.state.showSearchShortcuts } returns true + + controller.handleSearchShortcutsButtonClicked() + + verify { store.dispatch(SearchFragmentAction.ShowSearchShortcutEnginePicker(false)) } + } + + @Test + fun handleSearchShortcutsButtonClicked_notYetOpen() { + every { store.state.showSearchShortcuts } returns false + + controller.handleSearchShortcutsButtonClicked() + + verify { store.dispatch(SearchFragmentAction.ShowSearchShortcutEnginePicker(true)) } + } + + @Test + fun handleExistingSessionSelected() { + val session = mockk() + + controller.handleExistingSessionSelected(session) + + verify { sessionManager.select(session) } + verify { activity.openToBrowser(from = BrowserDirection.FromSearchDialog) } + } + + @Test + fun handleExistingSessionSelected_tabId_nullSession() { + every { sessionManager.findSessionById("tab-id") } returns null + + controller.handleExistingSessionSelected("tab-id") + + verify(inverse = true) { sessionManager.select(any()) } + verify(inverse = true) { activity.openToBrowser(from = BrowserDirection.FromSearchDialog) } + } + + @Test + fun handleExistingSessionSelected_tabId() { + val session = mockk() + every { sessionManager.findSessionById("tab-id") } returns session + + controller.handleExistingSessionSelected("tab-id") + + verify { sessionManager.select(any()) } + verify { activity.openToBrowser(from = BrowserDirection.FromSearchDialog) } + } +}