@@ -24,6 +24,9 @@ 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.OnboardingStore
28+ import com.duckduckgo.app.statistics.pixels.Pixel
29+ import com.duckduckgo.app.statistics.pixels.Pixel.PixelName.*
2730import com.duckduckgo.app.systemsearch.SystemSearchViewModel.Command
2831import com.duckduckgo.app.systemsearch.SystemSearchViewModel.Command.LaunchDuckDuckGo
2932import com.nhaarman.mockitokotlin2.argumentCaptor
@@ -51,8 +54,10 @@ class SystemSearchViewModelTest {
5154 @get:Rule
5255 var coroutineRule = CoroutineTestRule ()
5356
57+ private val mockOnboardingStore: OnboardingStore = mock()
5458 private val mockDeviceAppLookup: DeviceAppLookup = mock()
5559 private val mockAutoComplete: AutoComplete = mock()
60+ private val mockPixel: Pixel = mock()
5661
5762 private val commandObserver: Observer <Command > = mock()
5863 private val commandCaptor = argumentCaptor<Command >()
@@ -65,7 +70,7 @@ class SystemSearchViewModelTest {
6570 whenever(mockAutoComplete.autoComplete(BLANK_QUERY )).thenReturn(Observable .just(autocompleteBlankResult))
6671 whenever(mockDeviceAppLookup.query(QUERY )).thenReturn(appQueryResult)
6772 whenever(mockDeviceAppLookup.query(BLANK_QUERY )).thenReturn(appBlankResult)
68- testee = SystemSearchViewModel (mockAutoComplete, mockDeviceAppLookup, coroutineRule.testDispatcherProvider)
73+ testee = SystemSearchViewModel (mockOnboardingStore, mockAutoComplete, mockDeviceAppLookup, mockPixel , coroutineRule.testDispatcherProvider)
6974 testee.command.observeForever(commandObserver)
7075 }
7176
@@ -74,11 +79,70 @@ class SystemSearchViewModelTest {
7479 testee.command.removeObserver(commandObserver)
7580 }
7681
82+ @Test
83+ fun whenOnboardingShouldNotShowThenViewIsNotVisibleAndUnexpanded () = runBlockingTest {
84+ whenever(mockOnboardingStore.shouldShow).thenReturn(false )
85+ testee.resetViewState()
86+
87+ val viewState = testee.onboardingViewState.value
88+ assertFalse(viewState!! .visible)
89+ assertFalse(viewState!! .expanded)
90+ }
91+
92+ @Test
93+ fun whenOnboardingShouldShowThenViewIsVisibleAndUnexpanded () = runBlockingTest {
94+ whenever(mockOnboardingStore.shouldShow).thenReturn(true )
95+ testee.resetViewState()
96+
97+ val viewState = testee.onboardingViewState.value
98+ assertTrue(viewState!! .visible)
99+ assertFalse(viewState!! .expanded)
100+ }
101+
102+ @Test
103+ fun whenOnboardingShownThenPixelSent () = runBlockingTest {
104+ whenever(mockOnboardingStore.shouldShow).thenReturn(true )
105+ testee.resetViewState()
106+ verify(mockPixel).fire(INTERSTITIAL_ONBOARDING_SHOWN )
107+ }
108+
109+ @Test
110+ fun whenOnboardingIsUnexpandedAndUserPressesToggleThenItIsExpandedAndPixelSent () = runBlockingTest {
111+ whenOnboardingShowing()
112+ testee.userTappedOnboardingToggle()
113+
114+ val viewState = testee.onboardingViewState.value
115+ assertTrue(viewState!! .expanded)
116+ verify(mockPixel).fire(INTERSTITIAL_ONBOARDING_MORE_PRESSED )
117+ }
118+
119+ @Test
120+ fun whenOnboardingIsExpandedAndUserPressesToggleThenItIsUnexpandedAndPixelSent () = runBlockingTest {
121+ whenOnboardingShowing()
122+ testee.userTappedOnboardingToggle() // first press to expand
123+ testee.userTappedOnboardingToggle() // second press to minimize
124+
125+ val viewState = testee.onboardingViewState.value
126+ assertFalse(viewState!! .expanded)
127+ verify(mockPixel).fire(INTERSTITIAL_ONBOARDING_LESS_PRESSED )
128+ }
129+
130+ @Test
131+ fun whenOnboardingIsDismissedThenViewHiddenPixelSentAndOnboardingStoreNotified () = runBlockingTest {
132+ whenOnboardingShowing()
133+ testee.userDismissedOnboarding()
134+
135+ val viewState = testee.onboardingViewState.value
136+ assertFalse(viewState!! .visible)
137+ verify(mockPixel).fire(INTERSTITIAL_ONBOARDING_DISMISSED )
138+ verify(mockOnboardingStore).onboardingShown()
139+ }
140+
77141 @Test
78142 fun whenUserUpdatesQueryThenViewStateUpdated () = ruleRunBlockingTest {
79143 testee.userUpdatedQuery(QUERY )
80144
81- val newViewState = testee.viewState .value
145+ val newViewState = testee.resultsViewState .value
82146 assertNotNull(newViewState)
83147 assertEquals(QUERY , newViewState?.queryText)
84148 assertEquals(appQueryResult, newViewState?.appResults)
@@ -90,7 +154,7 @@ class SystemSearchViewModelTest {
90154 testee.userUpdatedQuery(QUERY )
91155 testee.userUpdatedQuery(" $QUERY " )
92156
93- val newViewState = testee.viewState .value
157+ val newViewState = testee.resultsViewState .value
94158 assertNotNull(newViewState)
95159 assertEquals(" $QUERY " , newViewState?.queryText)
96160 assertEquals(appQueryResult, newViewState?.appResults)
@@ -102,7 +166,7 @@ class SystemSearchViewModelTest {
102166 testee.userUpdatedQuery(QUERY )
103167 testee.userClearedQuery()
104168
105- val newViewState = testee.viewState .value
169+ val newViewState = testee.resultsViewState .value
106170 assertNotNull(newViewState)
107171 assertTrue(newViewState!! .queryText.isEmpty())
108172 assertTrue(newViewState.appResults.isEmpty())
@@ -114,39 +178,43 @@ class SystemSearchViewModelTest {
114178 testee.userUpdatedQuery(QUERY )
115179 testee.userUpdatedQuery(BLANK_QUERY )
116180
117- val newViewState = testee.viewState .value
181+ val newViewState = testee.resultsViewState .value
118182 assertNotNull(newViewState)
119183 assertTrue(newViewState!! .queryText.isEmpty())
120184 assertTrue(newViewState.appResults.isEmpty())
121185 assertEquals(AutoCompleteResult (" " , emptyList()), newViewState.autocompleteResults)
122186 }
123187
124188 @Test
125- fun whenUserSubmitsQueryThenBrowserLaunched () {
189+ fun whenUserSubmitsQueryThenBrowserLaunchedAndPixelSent () {
126190 testee.userSubmittedQuery(QUERY )
127191 verify(commandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
128192 assertEquals(Command .LaunchBrowser (QUERY ), commandCaptor.lastValue)
193+ verify(mockPixel).fire(INTERSTITIAL_LAUNCH_BROWSER_QUERY )
129194 }
130195
131196 @Test
132- fun whenUserSubmitsAutocompleteResultThenBrowserLaunched () {
197+ fun whenUserSubmitsAutocompleteResultThenBrowserLaunchedAndPixelSent () {
133198 testee.userSubmittedAutocompleteResult(AUTOCOMPLETE_RESULT )
134199 verify(commandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
135200 assertEquals(Command .LaunchBrowser (AUTOCOMPLETE_RESULT ), commandCaptor.lastValue)
201+ verify(mockPixel).fire(INTERSTITIAL_LAUNCH_BROWSER_QUERY )
136202 }
137203
138204 @Test
139- fun whenUserSelectsAppResultThenAppLaunched () {
205+ fun whenUserSelectsAppResultThenAppLaunchedAndPixelSent () {
140206 testee.userSelectedApp(deviceApp)
141207 verify(commandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
142208 assertEquals(Command .LaunchDeviceApplication (deviceApp), commandCaptor.lastValue)
209+ verify(mockPixel).fire(INTERSTITIAL_LAUNCH_DEVICE_APP )
143210 }
144211
145212 @Test
146- fun whenUserTapsDaxThenAppLaunched () {
213+ fun whenUserTapsDaxThenAppLaunchedAndPixelSent () {
147214 testee.userTappedDax()
148215 verify(commandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
149216 assertTrue(commandCaptor.lastValue is LaunchDuckDuckGo )
217+ verify(mockPixel).fire(INTERSTITIAL_LAUNCH_DAX )
150218 }
151219
152220 @Test
@@ -157,6 +225,11 @@ class SystemSearchViewModelTest {
157225 assertEquals(Command .ShowAppNotFoundMessage (deviceApp.shortName), commandCaptor.lastValue)
158226 }
159227
228+ private fun whenOnboardingShowing () {
229+ whenever(mockOnboardingStore.shouldShow).thenReturn(true )
230+ testee.resetViewState()
231+ }
232+
160233 private fun ruleRunBlockingTest (block : suspend TestCoroutineScope .() -> Unit ) =
161234 coroutineRule.testDispatcher.runBlockingTest(block)
162235
0 commit comments