diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt index c5459a76037e..7e3978854166 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt @@ -49,12 +49,10 @@ import org.junit.Assert.* import org.junit.Before import org.junit.Rule import org.junit.Test -import org.mockito.ArgumentCaptor -import org.mockito.ArgumentMatchers -import org.mockito.Mock +import org.mockito.* +import org.mockito.ArgumentCaptor.forClass import org.mockito.Mockito.never import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations class BrowserViewModelTest { @@ -78,7 +76,7 @@ class BrowserViewModelTest { lateinit var mockQueryObserver: Observer @Mock - lateinit var mockNavigationObserver: Observer + lateinit var mockCommandObserver: Observer @Mock lateinit var mockTermsOfServiceStore: TermsOfServiceStore @@ -121,7 +119,7 @@ class BrowserViewModelTest { appConfigurationDao = appConfigurationDao) testee.url.observeForever(mockQueryObserver) - testee.command.observeForever(mockNavigationObserver) + testee.command.observeForever(mockCommandObserver) whenever(mockOmnibarConverter.convertQueryToUri(any())).thenReturn(Uri.parse("duckduckgo.com")) @@ -132,7 +130,7 @@ class BrowserViewModelTest { testee.onCleared() db.close() testee.url.removeObserver(mockQueryObserver) - testee.command.removeObserver(mockNavigationObserver) + testee.command.removeObserver(mockCommandObserver) } @Test @@ -242,8 +240,8 @@ class BrowserViewModelTest { @Test fun whenSharedTextReceivedThenNavigationTriggered() { testee.onSharedTextReceived("http://example.com") - val captor: ArgumentCaptor = ArgumentCaptor.forClass(Command::class.java) - verify(mockNavigationObserver, times(2)).onChanged(captor.capture()) + val captor: ArgumentCaptor = forClass(Command::class.java) + verify(mockCommandObserver, times(2)).onChanged(captor.capture()) assertNotNull(captor.value) assertTrue(captor.value is Navigate) } @@ -263,13 +261,13 @@ class BrowserViewModelTest { @Test fun whenUserDismissesKeyboardBeforeBrowserShownThenShouldNavigateToLandingPage() { testee.userDismissedKeyboard() - verify(mockNavigationObserver).onChanged(ArgumentMatchers.any(LandingPage::class.java)) + verify(mockCommandObserver).onChanged(ArgumentMatchers.any(LandingPage::class.java)) } @Test fun whenUserDismissesKeyboardAfterBrowserShownThenShouldNotNavigateToLandingPage() { testee.urlChanged("") - verify(mockNavigationObserver, never()).onChanged(ArgumentMatchers.any(LandingPage::class.java)) + verify(mockCommandObserver, never()).onChanged(ArgumentMatchers.any(LandingPage::class.java)) } @Test @@ -387,4 +385,18 @@ class BrowserViewModelTest { testee.onOmnibarInputStateChanged("", true) assertFalse(testee.viewState.value!!.showAutoCompleteSuggestions) } + + @Test + fun whenEnteringEmptyQueryThenHideKeyboardCommandNotIssued() { + testee.onUserSubmittedQuery("") + verify(mockCommandObserver, never()).onChanged(Mockito.any(Command.HideKeyboard.javaClass)) + } + + @Test + fun whenEnteringNonEmptyQueryThenHideKeyboardCommandIssued() { + val captor = ArgumentCaptor.forClass(BrowserViewModel.Command::class.java) + testee.onUserSubmittedQuery("foo") + verify(mockCommandObserver, Mockito.atLeastOnce()).onChanged(captor.capture()) + assertTrue(captor.value == Command.HideKeyboard) + } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt index bf8c589041d7..34dcb8adf31a 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt @@ -41,6 +41,7 @@ import android.widget.Toast import com.duckduckgo.app.bookmarks.ui.BookmarkAddEditDialogFragment import com.duckduckgo.app.bookmarks.ui.BookmarkAddEditDialogFragment.BookmarkDialogCreationListener import com.duckduckgo.app.bookmarks.ui.BookmarksActivity +import com.duckduckgo.app.browser.BrowserViewModel.Command import com.duckduckgo.app.browser.autoComplete.BrowserAutoCompleteSuggestionsAdapter import com.duckduckgo.app.browser.omnibar.OnBackKeyListener import com.duckduckgo.app.global.DuckDuckGoActivity @@ -129,38 +130,45 @@ class BrowserActivity : DuckDuckGoActivity(), BookmarkDialogCreationListener { }) viewModel.command.observe(this, Observer { - when (it) { - is BrowserViewModel.Command.Refresh -> webView.reload() - is BrowserViewModel.Command.Navigate -> { - focusDummy.requestFocus() - webView.loadUrl(it.url) - } - is BrowserViewModel.Command.LandingPage -> finishActivityAnimated() - is BrowserViewModel.Command.DialNumber -> { - val intent = Intent(Intent.ACTION_DIAL) - intent.data = Uri.parse("tel:${it.telephoneNumber}") - launchExternalActivity(intent) - } - is BrowserViewModel.Command.SendEmail -> { - val intent = Intent(Intent.ACTION_SENDTO) - intent.data = Uri.parse(it.emailAddress) - launchExternalActivity(intent) - } - is BrowserViewModel.Command.SendSms -> { - val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:${it.telephoneNumber}")) - startActivity(intent) - } - is BrowserViewModel.Command.ShowKeyboard -> { - Timber.i("Command: showing keyboard") - omnibarTextInput.postDelayed({omnibarTextInput.showKeyboard()}, 300) - } - is BrowserViewModel.Command.ReinitialiseWebView -> { - webView.clearHistory() - } - } + processCommand(it) }) } + private fun processCommand(it: Command?) { + when (it) { + Command.Refresh -> webView.reload() + is Command.Navigate -> { + focusDummy.requestFocus() + webView.loadUrl(it.url) + } + Command.LandingPage -> finishActivityAnimated() + is Command.DialNumber -> { + val intent = Intent(Intent.ACTION_DIAL) + intent.data = Uri.parse("tel:${it.telephoneNumber}") + launchExternalActivity(intent) + } + is Command.SendEmail -> { + val intent = Intent(Intent.ACTION_SENDTO) + intent.data = Uri.parse(it.emailAddress) + launchExternalActivity(intent) + } + is Command.SendSms -> { + val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:${it.telephoneNumber}")) + startActivity(intent) + } + Command.ShowKeyboard -> { + omnibarTextInput.postDelayed({omnibarTextInput.showKeyboard()}, 300) + } + Command.HideKeyboard -> { + omnibarTextInput.hideKeyboard() + focusDummy.requestFocus() + } + Command.ReinitialiseWebView -> { + webView.clearHistory() + } + } + } + private fun configureAutoComplete() { autoCompleteSuggestionsList.layoutManager = LinearLayoutManager(this) autoCompleteSuggestionsAdapter = BrowserAutoCompleteSuggestionsAdapter( @@ -288,8 +296,6 @@ class BrowserActivity : DuckDuckGoActivity(), BookmarkDialogCreationListener { } private fun userEnteredQuery(query: String) { - omnibarTextInput.hideKeyboard() - focusDummy.requestFocus() viewModel.onUserSubmittedQuery(query) } diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserViewModel.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserViewModel.kt index 89eb267fae84..f3b3fb853e14 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserViewModel.kt @@ -77,14 +77,15 @@ class BrowserViewModel( ) sealed class Command { - class LandingPage : Command() - class Refresh : Command() + object LandingPage : Command() + object Refresh : Command() class Navigate(val url: String) : Command() class DialNumber(val telephoneNumber: String) : Command() class SendSms(val telephoneNumber: String) : Command() class SendEmail(val emailAddress: String) : Command() - class ShowKeyboard : Command() - class ReinitialiseWebView : Command() + object ShowKeyboard : Command() + object HideKeyboard : Command() + object ReinitialiseWebView : Command() } /* Observable data for Activity to subscribe to */ @@ -109,7 +110,7 @@ class BrowserViewModel( private var appConfigurationDownloaded = false init { - command.value = Command.ShowKeyboard() + command.value = Command.ShowKeyboard viewState.value = ViewState(canAddBookmarks = false) appConfigurationObservable.observeForever(appConfigurationObserver) @@ -150,6 +151,8 @@ class BrowserViewModel( return } + command.value = Command.HideKeyboard + val trimmedInput = input.trim() url.value = buildUrl(trimmedInput) viewState.value = currentViewState().copy( @@ -294,14 +297,14 @@ class BrowserViewModel( */ fun userDismissedKeyboard(): Boolean { if (!currentViewState().browserShowing) { - command.value = Command.LandingPage() + command.value = Command.LandingPage return true } return false } fun receivedDashboardResult(resultCode: Int) { - if (resultCode == RELOAD_RESULT_CODE) command.value = Command.Refresh() + if (resultCode == RELOAD_RESULT_CODE) command.value = Command.Refresh } @WorkerThread