diff --git a/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt index ff91941a8..b617f98a9 100644 --- a/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt +++ b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt @@ -522,6 +522,7 @@ private fun SearchTextField( .focusRequester(focusRequester) .onKeyEvent { if (it.key == Key.Enter) { + if (searchQuery.isBlank()) return@onKeyEvent false onSearchExplicitlyTriggered() true } else { @@ -536,6 +537,7 @@ private fun SearchTextField( ), keyboardActions = KeyboardActions( onSearch = { + if (searchQuery.isBlank()) return@KeyboardActions onSearchExplicitlyTriggered() }, ), diff --git a/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt index 6c2af240c..36947880e 100644 --- a/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt +++ b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt @@ -59,7 +59,7 @@ class SearchViewModel @Inject constructor( flowOf(SearchResultUiState.SearchNotReady) } else { searchQuery.flatMapLatest { query -> - if (query.length < SEARCH_QUERY_MIN_LENGTH) { + if (query.trim().length < SEARCH_QUERY_MIN_LENGTH) { flowOf(SearchResultUiState.EmptyQuery) } else { getSearchContentsUseCase(query) @@ -102,6 +102,7 @@ class SearchViewModel @Inject constructor( * search query in the search text field, defining this method. */ fun onSearchTriggered(query: String) { + if (query.isBlank()) return viewModelScope.launch { recentSearchRepository.insertOrReplaceRecentSearch(searchQuery = query) } diff --git a/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt index a62965b52..1b866cec2 100644 --- a/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt +++ b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt @@ -41,6 +41,7 @@ import org.junit.Rule import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertIs +import kotlin.test.assertNull /** * To learn more about how this test handles Flows created with stateIn, see @@ -122,6 +123,43 @@ class SearchViewModelTest { assertEquals(SearchNotReady, viewModel.searchResultUiState.value) } + @Test + fun emptySearchText_isNotAddedToRecentSearches() = runTest { + viewModel.onSearchTriggered("") + + val recentSearchQueriesStream = getRecentQueryUseCase() + val recentSearchQueries = recentSearchQueriesStream.first() + val recentSearchQuery = recentSearchQueries.firstOrNull() + + assertNull(recentSearchQuery) + } + + @Test + fun searchTextWithThreeSpaces_isEmptyQuery() = runTest { + searchContentsRepository.addNewsResources(newsResourcesTestData) + searchContentsRepository.addTopics(topicsTestData) + val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } + + viewModel.onSearchQueryChanged(" ") + + assertIs(viewModel.searchResultUiState.value) + + collectJob.cancel() + } + + @Test + fun searchTextWithThreeSpacesAndOneLetter_isEmptyQuery() = runTest { + searchContentsRepository.addNewsResources(newsResourcesTestData) + searchContentsRepository.addTopics(topicsTestData) + val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() } + + viewModel.onSearchQueryChanged(" a") + + assertIs(viewModel.searchResultUiState.value) + + collectJob.cancel() + } + @Test fun whenToggleNewsResourceSavedIsCalled_bookmarkStateIsUpdated() = runTest { val newsResourceId = "123"