@@ -41,6 +41,9 @@ import com.duckduckgo.app.browser.LongPressHandler.RequiredAction.DownloadFile
4141import com.duckduckgo.app.browser.LongPressHandler.RequiredAction.OpenInNewTab
4242import com.duckduckgo.app.browser.addtohome.AddToHomeCapabilityDetector
4343import com.duckduckgo.app.browser.favicon.FaviconDownloader
44+ import com.duckduckgo.app.browser.logindetection.LoginDetected
45+ import com.duckduckgo.app.browser.logindetection.NavigationAwareLoginDetector
46+ import com.duckduckgo.app.browser.logindetection.NavigationEvent.LoginAttempt
4447import com.duckduckgo.app.browser.model.BasicAuthenticationCredentials
4548import com.duckduckgo.app.browser.model.BasicAuthenticationRequest
4649import com.duckduckgo.app.browser.model.LongPressTarget
@@ -49,13 +52,10 @@ import com.duckduckgo.app.browser.session.WebViewSessionStorage
4952import com.duckduckgo.app.cta.db.DismissedCtaDao
5053import com.duckduckgo.app.cta.model.CtaId
5154import com.duckduckgo.app.cta.model.DismissedCta
55+ import com.duckduckgo.app.cta.ui.*
5256import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteDao
5357import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteEntity
54- import com.duckduckgo.app.cta.ui.Cta
55- import com.duckduckgo.app.cta.ui.CtaViewModel
56- import com.duckduckgo.app.cta.ui.DaxBubbleCta
57- import com.duckduckgo.app.cta.ui.DaxDialogCta
58- import com.duckduckgo.app.cta.ui.HomePanelCta
58+ import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteRepository
5959import com.duckduckgo.app.global.db.AppDatabase
6060import com.duckduckgo.app.global.install.AppInstallStore
6161import com.duckduckgo.app.global.model.SiteFactory
@@ -83,14 +83,7 @@ import com.duckduckgo.app.trackerdetection.EntityLookup
8383import com.duckduckgo.app.trackerdetection.model.TrackingEvent
8484import com.duckduckgo.app.usage.search.SearchCountDao
8585import com.duckduckgo.app.widget.ui.WidgetCapabilities
86- import com.nhaarman.mockitokotlin2.any
87- import com.nhaarman.mockitokotlin2.anyOrNull
88- import com.nhaarman.mockitokotlin2.atLeastOnce
89- import com.nhaarman.mockitokotlin2.doReturn
90- import com.nhaarman.mockitokotlin2.firstValue
91- import com.nhaarman.mockitokotlin2.lastValue
92- import com.nhaarman.mockitokotlin2.mock
93- import com.nhaarman.mockitokotlin2.whenever
86+ import com.nhaarman.mockitokotlin2.*
9487import io.reactivex.Observable
9588import io.reactivex.Single
9689import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -101,14 +94,10 @@ import org.junit.Assert.*
10194import org.junit.Before
10295import org.junit.Rule
10396import org.junit.Test
104- import org.mockito.ArgumentCaptor
97+ import org.mockito.*
10598import org.mockito.ArgumentMatchers.anyString
106- import org.mockito.Captor
107- import org.mockito.Mock
108- import org.mockito.Mockito
10999import org.mockito.Mockito.never
110100import org.mockito.Mockito.verify
111- import org.mockito.MockitoAnnotations
112101import java.util.concurrent.TimeUnit
113102
114103@ExperimentalCoroutinesApi
@@ -196,6 +185,9 @@ class BrowserTabViewModelTest {
196185 @Mock
197186 private lateinit var mockUserWhitelistDao: UserWhitelistDao
198187
188+ @Mock
189+ private lateinit var mockNavigationAwareLoginDetector: NavigationAwareLoginDetector
190+
199191 private lateinit var mockAutoCompleteApi: AutoCompleteApi
200192
201193 private lateinit var ctaViewModel: CtaViewModel
@@ -211,6 +203,8 @@ class BrowserTabViewModelTest {
211203
212204 private val selectedTabLiveData = MutableLiveData <TabEntity >()
213205
206+ private val loginEventLiveData = MutableLiveData <LoginDetected >()
207+
214208 @Before
215209 fun before () {
216210 MockitoAnnotations .initMocks(this )
@@ -241,6 +235,7 @@ class BrowserTabViewModelTest {
241235 whenever(mockOmnibarConverter.convertQueryToUrl(any(), any())).thenReturn(" duckduckgo.com" )
242236 whenever(mockVariantManager.getVariant()).thenReturn(DEFAULT_VARIANT )
243237 whenever(mockTabsRepository.liveSelectedTab).thenReturn(selectedTabLiveData)
238+ whenever(mockNavigationAwareLoginDetector.loginEventLiveData).thenReturn(loginEventLiveData)
244239 whenever(mockTabsRepository.retrieveSiteData(any())).thenReturn(MutableLiveData ())
245240 whenever(mockPrivacyPractices.privacyPracticesFor(any())).thenReturn(PrivacyPractices .UNKNOWN )
246241 whenever(mockAppInstallStore.installTimestamp).thenReturn(System .currentTimeMillis() - TimeUnit .DAYS .toMillis(1 ))
@@ -266,7 +261,8 @@ class BrowserTabViewModelTest {
266261 searchCountDao = mockSearchCountDao,
267262 pixel = mockPixel,
268263 dispatchers = coroutineRule.testDispatcherProvider,
269- fireproofWebsiteDao = fireproofWebsiteDao,
264+ fireproofWebsiteRepository = FireproofWebsiteRepository (fireproofWebsiteDao, coroutineRule.testDispatcherProvider),
265+ navigationAwareLoginDetector = mockNavigationAwareLoginDetector,
270266 variantManager = mockVariantManager
271267 )
272268
@@ -1768,23 +1764,25 @@ class BrowserTabViewModelTest {
17681764 }
17691765
17701766 @Test
1771- fun whenUserLoadsNotFireproofWebsiteThenFireproofWebsiteOptionMenuEnabled () {
1767+ fun whenUserLoadsNotFireproofWebsiteThenFireproofWebsiteBrowserStateUpdated () {
17721768 loadUrl(" http://www.example.com/path" , isBrowserShowing = true )
17731769 assertTrue(browserViewState().canFireproofSite)
1770+ assertFalse(browserViewState().isFireproofWebsite)
17741771 }
17751772
17761773 @Test
1777- fun whenUserLoadsFireproofWebsiteThenFireproofWebsiteOptionMenuDisabled () {
1774+ fun whenUserLoadsFireproofWebsiteThenFireproofWebsiteBrowserStateUpdated () {
17781775 givenFireproofWebsiteDomain(" www.example.com" )
17791776 loadUrl(" http://www.example.com/path" , isBrowserShowing = true )
1780- assertFalse (browserViewState().canFireproofSite )
1777+ assertTrue (browserViewState().isFireproofWebsite )
17811778 }
17821779
17831780 @Test
1784- fun whenUserLoadsFireproofWebsiteSubDomainThenFireproofWebsiteOptionMenuEnabled () {
1781+ fun whenUserLoadsFireproofWebsiteSubDomainThenFireproofWebsiteBrowserStateUpdated () {
17851782 givenFireproofWebsiteDomain(" example.com" )
17861783 loadUrl(" http://mobile.example.com/path" , isBrowserShowing = true )
17871784 assertTrue(browserViewState().canFireproofSite)
1785+ assertFalse(browserViewState().isFireproofWebsite)
17881786 }
17891787
17901788 @Test
@@ -1796,64 +1794,127 @@ class BrowserTabViewModelTest {
17961794 }
17971795
17981796 @Test
1799- fun whenUrlIsUpdatedWithNonFireproofWebsiteThenFireproofWebsiteOptionMenuEnabled () {
1797+ fun whenUrlIsUpdatedWithNonFireproofWebsiteThenFireproofWebsiteBrowserStateUpdated () {
18001798 givenFireproofWebsiteDomain(" www.example.com" )
18011799 loadUrl(" http://www.example.com/" , isBrowserShowing = true )
18021800 updateUrl(" http://www.example.com/" , " http://twitter.com/explore" , true )
18031801 assertTrue(browserViewState().canFireproofSite)
1802+ assertFalse(browserViewState().isFireproofWebsite)
18041803 }
18051804
18061805 @Test
1807- fun whenUrlIsUpdatedWithFireproofWebsiteThenFireproofWebsiteOptionMenuDisabled () {
1806+ fun whenUrlIsUpdatedWithFireproofWebsiteThenFireproofWebsiteBrowserStateUpdated () {
18081807 givenFireproofWebsiteDomain(" twitter.com" )
18091808 loadUrl(" http://example.com/" , isBrowserShowing = true )
18101809 updateUrl(" http://example.com/" , " http://twitter.com/explore" , true )
1811- assertFalse (browserViewState().canFireproofSite )
1810+ assertTrue (browserViewState().isFireproofWebsite )
18121811 }
18131812
18141813 @Test
18151814 fun whenUserClicksFireproofWebsiteOptionMenuThenShowConfirmationIsIssued () {
18161815 loadUrl(" http://mobile.example.com/" , isBrowserShowing = true )
1817- testee.onFireproofWebsiteClicked ()
1816+ testee.onFireproofWebsiteMenuClicked ()
18181817 assertCommandIssued<Command .ShowFireproofWebSiteConfirmation > {
18191818 assertEquals(" mobile.example.com" , this .fireproofWebsiteEntity.domain)
18201819 }
18211820 }
18221821
18231822 @Test
1824- fun whenUserClicksFireproofWebsiteOptionMenuThenFireproofWebsiteOptionMenuDisabled () {
1823+ fun whenUserClicksFireproofWebsiteOptionMenuThenFireproofWebsiteBrowserStateUpdated () {
18251824 loadUrl(" http://example.com/" , isBrowserShowing = true )
1826- testee.onFireproofWebsiteClicked ()
1827- assertFalse (browserViewState().canFireproofSite )
1825+ testee.onFireproofWebsiteMenuClicked ()
1826+ assertTrue (browserViewState().isFireproofWebsite )
18281827 }
18291828
18301829 @Test
18311830 fun whenFireproofWebsiteAddedThenPixelSent () {
18321831 loadUrl(" http://example.com/" , isBrowserShowing = true )
1833- testee.onFireproofWebsiteClicked ()
1832+ testee.onFireproofWebsiteMenuClicked ()
18341833 verify(mockPixel).fire(Pixel .PixelName .FIREPROOF_WEBSITE_ADDED )
18351834 }
18361835
1836+ @Test
1837+ fun whenUserRemovesFireproofWebsiteFromOptionMenuThenFireproofWebsiteBrowserStateUpdated () {
1838+ givenFireproofWebsiteDomain(" mobile.example.com" )
1839+ loadUrl(" http://mobile.example.com/" , isBrowserShowing = true )
1840+ testee.onFireproofWebsiteMenuClicked()
1841+ assertFalse(browserViewState().isFireproofWebsite)
1842+ }
1843+
1844+ @Test
1845+ fun whenUserRemovesFireproofWebsiteFromOptionMenuThenPixelSent () {
1846+ givenFireproofWebsiteDomain(" mobile.example.com" )
1847+ loadUrl(" http://mobile.example.com/" , isBrowserShowing = true )
1848+ testee.onFireproofWebsiteMenuClicked()
1849+ verify(mockPixel).fire(Pixel .PixelName .FIREPROOF_WEBSITE_REMOVE )
1850+ }
1851+
18371852 @Test
18381853 fun whenUserClicksOnFireproofWebsiteSnackbarUndoActionThenFireproofWebsiteIsRemoved () {
18391854 loadUrl(" http://example.com/" , isBrowserShowing = true )
1840- testee.onFireproofWebsiteClicked ()
1855+ testee.onFireproofWebsiteMenuClicked ()
18411856 assertCommandIssued<Command .ShowFireproofWebSiteConfirmation > {
18421857 testee.onFireproofWebsiteSnackbarUndoClicked(this .fireproofWebsiteEntity)
18431858 }
18441859 assertTrue(browserViewState().canFireproofSite)
1860+ assertFalse(browserViewState().isFireproofWebsite)
18451861 }
18461862
18471863 @Test
18481864 fun whenUserClicksOnFireproofWebsiteSnackbarUndoActionThenPixelSent () {
18491865 loadUrl(" http://example.com/" , isBrowserShowing = true )
1850- testee.onFireproofWebsiteClicked ()
1866+ testee.onFireproofWebsiteMenuClicked ()
18511867 assertCommandIssued<Command .ShowFireproofWebSiteConfirmation > {
18521868 testee.onFireproofWebsiteSnackbarUndoClicked(this .fireproofWebsiteEntity)
18531869 }
18541870 verify(mockPixel).fire(Pixel .PixelName .FIREPROOF_WEBSITE_UNDO )
18551871 }
18561872
1873+ @Test
1874+ fun whenUserFireproofsWebsiteFromLoginDialogThenShowConfirmationIsIssuedWithExpectedDomain () {
1875+ loadUrl(" http://mobile.example.com/" , isBrowserShowing = true )
1876+ testee.onUserConfirmedFireproofDialog(" login.example.com" )
1877+ assertCommandIssued<Command .ShowFireproofWebSiteConfirmation > {
1878+ assertEquals(" login.example.com" , this .fireproofWebsiteEntity.domain)
1879+ }
1880+ }
1881+
1882+ @Test
1883+ fun whenUserFireproofsWebsiteFromLoginDialogThenPixelSent () {
1884+ testee.onUserConfirmedFireproofDialog(" login.example.com" )
1885+ verify(mockPixel).fire(Pixel .PixelName .FIREPROOF_WEBSITE_LOGIN_ADDED )
1886+ }
1887+
1888+ @Test
1889+ fun whenUserDismissesFireproofWebsiteLoginDialogThenPixelSent () {
1890+ testee.onUserDismissedFireproofLoginDialog()
1891+ verify(mockPixel).fire(Pixel .PixelName .FIREPROOF_WEBSITE_LOGIN_DISMISS )
1892+ }
1893+
1894+ @Test
1895+ fun whenLoginAttempDetectedThenNotifyNavigationAwareLoginDetector () {
1896+ loadUrl(" http://example.com/" , isBrowserShowing = true )
1897+
1898+ testee.loginDetected()
1899+
1900+ verify(mockNavigationAwareLoginDetector).onEvent(LoginAttempt (" http://example.com/" ))
1901+ }
1902+
1903+ @Test
1904+ fun whenLoginDetectedOnAFireproofedWebsiteThenDoNotAskToFireproofWebsite () {
1905+ givenFireproofWebsiteDomain(" example.com" )
1906+ loginEventLiveData.value = givenLoginDetected(" example.com" )
1907+ assertCommandNotIssued<Command .AskToFireproofWebsite >()
1908+ }
1909+
1910+ @Test
1911+ fun whenLoginDetectedThenAskToFireproofWebsite () {
1912+ loginEventLiveData.value = givenLoginDetected(" example.com" )
1913+ assertCommandIssued<Command .AskToFireproofWebsite > {
1914+ assertEquals(FireproofWebsiteEntity (" example.com" ), this .fireproofWebsite)
1915+ }
1916+ }
1917+
18571918 @Test
18581919 fun whenUserBrowsingPressesBackThenCannotAddBookmark () {
18591920 setupNavigation(skipHome = false , isBrowsing = true , canGoBack = false )
@@ -2041,6 +2102,8 @@ class BrowserTabViewModelTest {
20412102 }
20422103 }
20432104
2105+ private fun givenLoginDetected (domain : String ) = LoginDetected (authLoginDomain = " " , forwardedToDomain = domain)
2106+
20442107 private fun setBrowserShowing (isBrowsing : Boolean ) {
20452108 testee.browserViewState.value = browserViewState().copy(browserShowing = isBrowsing)
20462109 }
0 commit comments