@@ -24,14 +24,15 @@ import com.duckduckgo.app.InstantSchedulersRule
2424import com.duckduckgo.app.autocomplete.api.AutoComplete
2525import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteResult
2626import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteSearchSuggestion
27- import com.duckduckgo.app.onboarding.store.AppStage
28- import com.duckduckgo.app.onboarding.store.UserStageStore
27+ import com.duckduckgo.app.onboarding.store.*
28+ import com.duckduckgo.app.runBlocking
2929import com.duckduckgo.app.statistics.pixels.Pixel
3030import com.duckduckgo.app.statistics.pixels.Pixel.PixelName.*
3131import com.duckduckgo.app.systemsearch.SystemSearchViewModel.Command
3232import com.duckduckgo.app.systemsearch.SystemSearchViewModel.Command.LaunchDuckDuckGo
3333import com.nhaarman.mockitokotlin2.*
3434import io.reactivex.Observable
35+ import kotlinx.coroutines.test.TestCoroutineDispatcher
3536import kotlinx.coroutines.test.TestCoroutineScope
3637import kotlinx.coroutines.test.runBlockingTest
3738import org.junit.After
@@ -98,6 +99,17 @@ class SystemSearchViewModelTest {
9899 assertFalse(viewState!! .expanded)
99100 }
100101
102+ @Test
103+ fun whenDatabaseIsSlowThenIntroducingTextDoesNotCrashTheApp () = coroutineRule.runBlocking {
104+ (coroutineRule.testDispatcherProvider.io() as TestCoroutineDispatcher ).pauseDispatcher()
105+ testee =
106+ SystemSearchViewModel (givenEmptyUserStageStore(), mockAutoComplete, mockDeviceAppLookup, mockPixel, coroutineRule.testDispatcherProvider)
107+ testee.resetViewState()
108+ testee.userUpdatedQuery(" test" )
109+
110+ // no crash
111+ }
112+
101113 @Test
102114 fun whenOnboardingShownThenPixelSent () = runBlockingTest {
103115 whenever(mockUserStageStore.getUserAppStage()).thenReturn(AppStage .NEW )
@@ -138,7 +150,7 @@ class SystemSearchViewModelTest {
138150 }
139151
140152 @Test
141- fun whenUserUpdatesQueryThenViewStateUpdated () = ruleRunBlockingTest {
153+ fun whenUserUpdatesQueryThenViewStateUpdated () = coroutineRule.runBlocking {
142154 testee.userUpdatedQuery(QUERY )
143155
144156 val newViewState = testee.resultsViewState.value
@@ -149,7 +161,7 @@ class SystemSearchViewModelTest {
149161 }
150162
151163 @Test
152- fun whenUserAddsSpaceToQueryThenViewStateMatchesAndSpaceTrimmedFromAutocomplete () = ruleRunBlockingTest {
164+ fun whenUserAddsSpaceToQueryThenViewStateMatchesAndSpaceTrimmedFromAutocomplete () = coroutineRule.runBlocking {
153165 testee.userUpdatedQuery(QUERY )
154166 testee.userUpdatedQuery(" $QUERY " )
155167
@@ -161,7 +173,7 @@ class SystemSearchViewModelTest {
161173 }
162174
163175 @Test
164- fun whenUserClearsQueryThenViewStateReset () = ruleRunBlockingTest {
176+ fun whenUserClearsQueryThenViewStateReset () = coroutineRule.runBlocking {
165177 testee.userUpdatedQuery(QUERY )
166178 testee.userClearedQuery()
167179
@@ -173,7 +185,7 @@ class SystemSearchViewModelTest {
173185 }
174186
175187 @Test
176- fun whenUsersUpdatesWithBlankQueryThenViewStateReset () = ruleRunBlockingTest {
188+ fun whenUsersUpdatesWithBlankQueryThenViewStateReset () = coroutineRule.runBlocking {
177189 testee.userUpdatedQuery(QUERY )
178190 testee.userUpdatedQuery(BLANK_QUERY )
179191
@@ -193,7 +205,7 @@ class SystemSearchViewModelTest {
193205 }
194206
195207 @Test
196- fun whenUserSubmitsQueryThenOnboardingCompleted () = ruleRunBlockingTest {
208+ fun whenUserSubmitsQueryThenOnboardingCompleted () = coroutineRule.runBlocking {
197209 testee.userSubmittedQuery(QUERY )
198210 verify(mockUserStageStore).stageCompleted(AppStage .NEW )
199211 }
@@ -224,18 +236,18 @@ class SystemSearchViewModelTest {
224236 }
225237
226238 @Test
227- fun whenUserTapsDaxThenOnboardingCompleted () = ruleRunBlockingTest {
239+ fun whenUserTapsDaxThenOnboardingCompleted () = coroutineRule.runBlocking {
228240 testee.userTappedDax()
229241 verify(mockUserStageStore).stageCompleted(AppStage .NEW )
230242 }
231243
232244 @Test
233- fun whenViewModelCreatedThenAppsRefreshed () = ruleRunBlockingTest {
245+ fun whenViewModelCreatedThenAppsRefreshed () = coroutineRule.runBlocking {
234246 verify(mockDeviceAppLookup).refreshAppList()
235247 }
236248
237249 @Test
238- fun whenUserSelectsAppThatCannotBeFoundThenAppsRefreshedAndUserMessageShown () = ruleRunBlockingTest {
250+ fun whenUserSelectsAppThatCannotBeFoundThenAppsRefreshedAndUserMessageShown () = coroutineRule.runBlocking {
239251 testee.appNotFound(deviceApp)
240252 verify(mockDeviceAppLookup, times(2 )).refreshAppList()
241253 verify(commandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
@@ -247,8 +259,13 @@ class SystemSearchViewModelTest {
247259 testee.resetViewState()
248260 }
249261
250- private fun ruleRunBlockingTest (block : suspend TestCoroutineScope .() -> Unit ) =
251- coroutineRule.testDispatcher.runBlockingTest(block)
262+ private fun givenEmptyUserStageStore (): UserStageStore {
263+ val emptyUserStageDao = object : UserStageDao {
264+ override suspend fun currentUserAppStage () = UserStage (appStage = AppStage .NEW )
265+ override fun insert (userStage : UserStage ) {}
266+ }
267+ return AppUserStageStore (emptyUserStageDao, coroutineRule.testDispatcherProvider)
268+ }
252269
253270 companion object {
254271 const val QUERY = " abc"
0 commit comments