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 1e4711016f..d1dc17901a 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 @@ -520,6 +520,7 @@ private fun SearchTextField( .focusRequester(focusRequester) .onKeyEvent { if (it.key == Key.Enter) { + if (searchQuery.isBlank()) return@onKeyEvent false onSearchExplicitlyTriggered() true } else { @@ -534,6 +535,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 ad6ca61123..5d6d0f16d5 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 662afca7d6..52180dfe96 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 @@ -42,6 +42,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 @@ -132,6 +133,43 @@ class SearchViewModelTest { collectJob.cancel() } + @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"