@@ -112,7 +112,8 @@ import io.reactivex.Observable
112112import io.reactivex.Single
113113import kotlinx.coroutines.ExperimentalCoroutinesApi
114114import kotlinx.coroutines.channels.Channel
115- import kotlinx.coroutines.flow.*
115+ import kotlinx.coroutines.flow.consumeAsFlow
116+ import kotlinx.coroutines.flow.flowOf
116117import kotlinx.coroutines.runBlocking
117118import kotlinx.coroutines.test.runBlockingTest
118119import org.junit.After
@@ -124,6 +125,7 @@ import org.mockito.*
124125import org.mockito.ArgumentMatchers.anyString
125126import org.mockito.Mockito.never
126127import org.mockito.Mockito.verify
128+ import org.mockito.internal.util.DefaultMockingDetails
127129import java.io.File
128130import java.util.*
129131import java.util.concurrent.TimeUnit
@@ -256,7 +258,7 @@ class BrowserTabViewModelTest {
256258
257259 @Before
258260 fun before () {
259- MockitoAnnotations .initMocks (this )
261+ MockitoAnnotations .openMocks (this )
260262 db = Room .inMemoryDatabaseBuilder(getInstrumentation().targetContext, AppDatabase ::class .java)
261263 .allowMainThreadQueries()
262264 .build()
@@ -541,7 +543,7 @@ class BrowserTabViewModelTest {
541543 testee.onUserSubmittedQuery(" foo" )
542544
543545 coroutineRule.runBlocking {
544- verify(mockTabsRepository).delete(selectedTabLiveData.value !! )
546+ verify(mockTabsRepository).deleteCurrentTabAndSelectSource( )
545547 }
546548 }
547549
@@ -636,6 +638,16 @@ class BrowserTabViewModelTest {
636638 assertCommandNotIssued<Command .HideWebContent >()
637639 }
638640
641+ @Test
642+ fun whenUserRedirectedThenNotifyLoginDetector () = coroutineRule.runBlocking {
643+ loadUrl(" http://duckduckgo.com" )
644+ testee.progressChanged(100 )
645+
646+ overrideUrl(" http://example.com" )
647+
648+ verify(mockNavigationAwareLoginDetector).onEvent(NavigationEvent .Redirect (" http://example.com" ))
649+ }
650+
639651 @Test
640652 fun whenLoadingProgressReaches50ThenShowWebContent () = coroutineRule.runBlocking {
641653 loadUrl(" http://duckduckgo.com" )
@@ -953,7 +965,7 @@ class BrowserTabViewModelTest {
953965
954966 @Test
955967 fun whenEnteringQueryWithAutoCompleteEnabledThenAutoCompleteSuggestionsShown () {
956- whenever(mockBookmarksDao.bookmarksByQuery( " %foo% " )).thenReturn(Single .just(emptyList()))
968+ whenever(mockBookmarksDao.bookmarksObservable( )).thenReturn(Single .just(emptyList()))
957969 whenever(mockAutoCompleteService.autoComplete(" foo" )).thenReturn(Observable .just(emptyList()))
958970 doReturn(true ).whenever(mockSettingsStore).autoCompleteSuggestionsEnabled
959971 testee.onOmnibarInputStateChanged(" foo" , true , hasQueryChanged = true )
@@ -1196,7 +1208,7 @@ class BrowserTabViewModelTest {
11961208 testee.onRefreshRequested()
11971209
11981210 coroutineRule.runBlocking {
1199- verify(mockTabsRepository).delete(selectedTabLiveData.value !! )
1211+ verify(mockTabsRepository).deleteCurrentTabAndSelectSource( )
12001212 }
12011213 }
12021214
@@ -1446,7 +1458,7 @@ class BrowserTabViewModelTest {
14461458 showErrorWithAction.action()
14471459
14481460 coroutineRule.runBlocking {
1449- verify(mockTabsRepository).delete(selectedTabLiveData.value !! )
1461+ verify(mockTabsRepository).deleteCurrentTabAndSelectSource( )
14501462 }
14511463 }
14521464
@@ -1618,7 +1630,7 @@ class BrowserTabViewModelTest {
16181630 fun whenCloseCurrentTabSelectedThenTabDeletedFromRepository () = runBlocking {
16191631 givenOneActiveTabSelected()
16201632 testee.closeCurrentTab()
1621- verify(mockTabsRepository).delete(selectedTabLiveData.value !! )
1633+ verify(mockTabsRepository).deleteCurrentTabAndSelectSource( )
16221634 }
16231635
16241636 @Test
@@ -2460,12 +2472,12 @@ class BrowserTabViewModelTest {
24602472 givenDeviceLocationSharingIsEnabled(true )
24612473 givenLocationPermissionIsEnabled(true )
24622474 givenCurrentSite(domain)
2463-
2475+ givenNewPermissionRequestFromDomain(domain)
24642476 testee.onSiteLocationPermissionSelected(domain, LocationPermissionType .ALLOW_ONCE )
24652477
24662478 givenNewPermissionRequestFromDomain(domain)
24672479
2468- assertCommandNotIssued <Command .CheckSystemLocationPermission >()
2480+ assertCommandIssuedTimes <Command .CheckSystemLocationPermission >(times = 1 )
24692481 }
24702482
24712483 @Test
@@ -2704,11 +2716,7 @@ class BrowserTabViewModelTest {
27042716 givenLocationPermissionIsEnabled(true )
27052717
27062718 loadUrl(" https://www.example.com" , isBrowserShowing = true )
2707-
2708- assertCommandIssued<Command .ShowDomainHasPermissionMessage >()
2709-
27102719 loadUrl(" https://www.example.com" , isBrowserShowing = true )
2711-
27122720 assertCommandIssuedTimes<Command .ShowDomainHasPermissionMessage >(1 )
27132721 }
27142722
@@ -3032,7 +3040,7 @@ class BrowserTabViewModelTest {
30323040 loadUrl(" http://duckduckgo.com" )
30333041 testee.progressChanged(100 )
30343042
3035- assertCommandNotIssued <Command .RefreshUserAgent >()
3043+ assertCommandIssued <Command .RefreshUserAgent >()
30363044 }
30373045
30383046 @Test
@@ -3062,6 +3070,34 @@ class BrowserTabViewModelTest {
30623070 assertFalse(browserViewState().canChangeBrowsingMode)
30633071 }
30643072
3073+ @Test
3074+ fun whenRequestFileDownloadAndUrlIsBlobThenConvertBlobToDataUriCommandSent () {
3075+ val blobUrl = " blob:https://example.com/283nasdho23jkasdAjd"
3076+ val mime = " application/plain"
3077+
3078+ testee.requestFileDownload(blobUrl, null , mime, true )
3079+
3080+ assertCommandIssued<Command .ConvertBlobToDataUri > {
3081+ assertEquals(blobUrl, url)
3082+ assertEquals(mime, mimeType)
3083+ }
3084+ }
3085+
3086+ @Test
3087+ fun whenRequestFileDownloadAndUrlIsNotBlobThenRquestFileDownloadCommandSent () {
3088+ val normalUrl = " https://example.com/283nasdho23jkasdAjd"
3089+ val mime = " application/plain"
3090+
3091+ testee.requestFileDownload(normalUrl, null , mime, true )
3092+
3093+ assertCommandIssued<Command .RequestFileDownload > {
3094+ assertEquals(normalUrl, url)
3095+ assertEquals(mime, mimeType)
3096+ assertNull(contentDisposition)
3097+ assertTrue(requestUserConfirmation)
3098+ }
3099+ }
3100+
30653101 private suspend fun givenFireButtonPulsing () {
30663102 whenever(mockUserStageStore.getUserAppStage()).thenReturn(AppStage .DAX_ONBOARDING )
30673103 dismissedCtaDaoChannel.send(listOf (DismissedCta (CtaId .DAX_DIALOG_TRACKERS_FOUND )))
@@ -3097,13 +3133,22 @@ class BrowserTabViewModelTest {
30973133 }
30983134
30993135 private inline fun <reified T : Command > assertCommandNotIssued () {
3100- val issuedCommand = commandCaptor.allValues.find { it is T }
3101- assertNull(issuedCommand)
3136+ val defaultMockingDetails = DefaultMockingDetails (mockCommandObserver)
3137+ if (defaultMockingDetails.invocations.isNotEmpty()) {
3138+ verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
3139+ val issuedCommand = commandCaptor.allValues.find { it is T }
3140+ assertNull(issuedCommand)
3141+ }
31023142 }
31033143
31043144 private inline fun <reified T : Command > assertCommandIssuedTimes (times : Int ) {
3105- val timesIssued = commandCaptor.allValues.count { it is T }
3106- assertEquals(times, timesIssued)
3145+ if (times == 0 ) {
3146+ assertCommandNotIssued<T >()
3147+ } else {
3148+ verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
3149+ val timesIssued = commandCaptor.allValues.count { it is T }
3150+ assertEquals(times, timesIssued)
3151+ }
31073152 }
31083153
31093154 private fun pixelParams (showedBookmarks : Boolean , bookmarkCapable : Boolean ) = mapOf (
0 commit comments