Skip to content

Commit ff6d35e

Browse files
committed
Merge branch 'release/5.80.0' into main
2 parents a785ce2 + 43b5dee commit ff6d35e

File tree

79 files changed

+2259
-1030
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+2259
-1030
lines changed

LICENSE

Lines changed: 52 additions & 206 deletions
Large diffs are not rendered by default.

app/schemas/com.duckduckgo.app.global.db.AppDatabase/31.json

Lines changed: 866 additions & 0 deletions
Large diffs are not rendered by default.

app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ import io.reactivex.Observable
114114
import io.reactivex.Single
115115
import kotlinx.coroutines.ExperimentalCoroutinesApi
116116
import kotlinx.coroutines.channels.Channel
117+
import kotlinx.coroutines.flow.MutableSharedFlow
118+
import kotlinx.coroutines.flow.asSharedFlow
117119
import kotlinx.coroutines.flow.consumeAsFlow
118120
import kotlinx.coroutines.flow.flowOf
119121
import kotlinx.coroutines.runBlocking
@@ -173,7 +175,7 @@ class BrowserTabViewModelTest {
173175
private lateinit var mockOmnibarConverter: OmnibarEntryConverter
174176

175177
@Mock
176-
private lateinit var mockTabsRepository: TabRepository
178+
private lateinit var mockTabRepository: TabRepository
177179

178180
@Mock
179181
private lateinit var webViewSessionStorage: WebViewSessionStorage
@@ -229,9 +231,6 @@ class BrowserTabViewModelTest {
229231
@Mock
230232
private lateinit var mockFileDownloader: FileDownloader
231233

232-
@Mock
233-
private lateinit var mockTabRepository: TabRepository
234-
235234
@Mock
236235
private lateinit var geoLocationPermissions: GeoLocationPermissions
237236

@@ -263,6 +262,10 @@ class BrowserTabViewModelTest {
263262

264263
private val dismissedCtaDaoChannel = Channel<List<DismissedCta>>()
265264

265+
private val childClosedTabsSharedFlow = MutableSharedFlow<String>()
266+
267+
private val childClosedTabsFlow = childClosedTabsSharedFlow.asSharedFlow()
268+
266269
@Before
267270
fun before() {
268271
MockitoAnnotations.openMocks(this)
@@ -299,9 +302,10 @@ class BrowserTabViewModelTest {
299302

300303
whenever(mockOmnibarConverter.convertQueryToUrl(any(), any())).thenReturn("duckduckgo.com")
301304
whenever(mockVariantManager.getVariant()).thenReturn(DEFAULT_VARIANT)
302-
whenever(mockTabsRepository.liveSelectedTab).thenReturn(selectedTabLiveData)
305+
whenever(mockTabRepository.liveSelectedTab).thenReturn(selectedTabLiveData)
303306
whenever(mockNavigationAwareLoginDetector.loginEventLiveData).thenReturn(loginEventLiveData)
304-
whenever(mockTabsRepository.retrieveSiteData(any())).thenReturn(MutableLiveData())
307+
whenever(mockTabRepository.retrieveSiteData(any())).thenReturn(MutableLiveData())
308+
whenever(mockTabRepository.childClosedTabs).thenReturn(childClosedTabsFlow)
305309
whenever(mockPrivacyPractices.privacyPracticesFor(any())).thenReturn(PrivacyPractices.UNKNOWN)
306310
whenever(mockAppInstallStore.installTimestamp).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1))
307311
whenever(mockUserWhitelistDao.contains(anyString())).thenReturn(false)
@@ -312,7 +316,7 @@ class BrowserTabViewModelTest {
312316
queryUrlConverter = mockOmnibarConverter,
313317
duckDuckGoUrlDetector = DuckDuckGoUrlDetector(),
314318
siteFactory = siteFactory,
315-
tabRepository = mockTabsRepository,
319+
tabRepository = mockTabRepository,
316320
userWhitelistDao = mockUserWhitelistDao,
317321
networkLeaderboardDao = mockNetworkLeaderboardDao,
318322
autoComplete = mockAutoCompleteApi,
@@ -389,7 +393,7 @@ class BrowserTabViewModelTest {
389393
verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
390394
assertTrue(commandCaptor.lastValue is Command.OpenInNewBackgroundTab)
391395

392-
verify(mockTabsRepository).addNewTabAfterExistingTab(url, "abc")
396+
verify(mockTabRepository).addNewTabAfterExistingTab(url, "abc")
393397
}
394398

395399
@Test
@@ -553,7 +557,7 @@ class BrowserTabViewModelTest {
553557
testee.onUserSubmittedQuery("foo")
554558

555559
coroutineRule.runBlocking {
556-
verify(mockTabsRepository).deleteTabAndSelectSource(selectedTabLiveData.value!!.tabId)
560+
verify(mockTabRepository).deleteTabAndSelectSource(selectedTabLiveData.value!!.tabId)
557561
}
558562
}
559563

@@ -1218,7 +1222,7 @@ class BrowserTabViewModelTest {
12181222
testee.onRefreshRequested()
12191223

12201224
coroutineRule.runBlocking {
1221-
verify(mockTabsRepository).deleteTabAndSelectSource(selectedTabLiveData.value!!.tabId)
1225+
verify(mockTabRepository).deleteTabAndSelectSource(selectedTabLiveData.value!!.tabId)
12221226
}
12231227
}
12241228

@@ -1519,7 +1523,7 @@ class BrowserTabViewModelTest {
15191523
showErrorWithAction.action()
15201524

15211525
coroutineRule.runBlocking {
1522-
verify(mockTabsRepository).deleteTabAndSelectSource(selectedTabLiveData.value!!.tabId)
1526+
verify(mockTabRepository).deleteTabAndSelectSource(selectedTabLiveData.value!!.tabId)
15231527
}
15241528
}
15251529

@@ -1691,7 +1695,7 @@ class BrowserTabViewModelTest {
16911695
fun whenCloseCurrentTabSelectedThenTabDeletedFromRepository() = runBlocking {
16921696
givenOneActiveTabSelected()
16931697
testee.closeCurrentTab()
1694-
verify(mockTabsRepository).deleteTabAndSelectSource(selectedTabLiveData.value!!.tabId)
1698+
verify(mockTabRepository).deleteTabAndSelectSource(selectedTabLiveData.value!!.tabId)
16951699
}
16961700

16971701
@Test
@@ -1723,7 +1727,7 @@ class BrowserTabViewModelTest {
17231727

17241728
testee.onUserPressedBack()
17251729

1726-
verify(mockTabsRepository).deleteTabAndSelectSource("TAB_ID")
1730+
verify(mockTabRepository).deleteTabAndSelectSource("TAB_ID")
17271731
}
17281732

17291733
@Test
@@ -1815,14 +1819,6 @@ class BrowserTabViewModelTest {
18151819
verify(mockPixel).fire(cta.shownPixel!!, cta.pixelShownParameters())
18161820
}
18171821

1818-
@Test
1819-
fun whenManualCtaShownThenFirePixel() {
1820-
val cta = HomePanelCta.Survey(Survey("abc", "http://example.com", daysInstalled = 1, status = Survey.Status.SCHEDULED))
1821-
1822-
testee.onManualCtaShown(cta)
1823-
verify(mockPixel).fire(cta.shownPixel!!, cta.pixelShownParameters())
1824-
}
1825-
18261822
@Test
18271823
fun whenRegisterDaxBubbleCtaDismissedThenRegisterInDatabase() = coroutineRule.runBlocking {
18281824
val cta = DaxBubbleCta.DaxIntroCta(mockOnboardingStore, mockAppInstallStore)
@@ -2870,7 +2866,7 @@ class BrowserTabViewModelTest {
28702866

28712867
testee.prefetchFavicon(url)
28722868

2873-
verify(mockTabsRepository).updateTabFavicon("TAB_ID", file.name)
2869+
verify(mockTabRepository).updateTabFavicon("TAB_ID", file.name)
28742870
}
28752871

28762872
@Test
@@ -2879,7 +2875,7 @@ class BrowserTabViewModelTest {
28792875

28802876
testee.prefetchFavicon("url")
28812877

2882-
verify(mockTabsRepository, never()).updateTabFavicon(any(), any())
2878+
verify(mockTabRepository, never()).updateTabFavicon(any(), any())
28832879
}
28842880

28852881
@Test
@@ -2901,7 +2897,7 @@ class BrowserTabViewModelTest {
29012897

29022898
testee.iconReceived(bitmap)
29032899

2904-
verify(mockTabsRepository).updateTabFavicon("TAB_ID", file.name)
2900+
verify(mockTabRepository).updateTabFavicon("TAB_ID", file.name)
29052901
}
29062902

29072903
@Test
@@ -2912,7 +2908,7 @@ class BrowserTabViewModelTest {
29122908

29132909
testee.iconReceived(bitmap)
29142910

2915-
verify(mockTabsRepository, never()).updateTabFavicon(any(), any())
2911+
verify(mockTabRepository, never()).updateTabFavicon(any(), any())
29162912
}
29172913

29182914
@Test
@@ -3136,6 +3132,24 @@ class BrowserTabViewModelTest {
31363132
}
31373133
}
31383134

3135+
@Test
3136+
fun whenChildrenTabClosedIfViewModelIsParentThenChildTabClosedCommandSent() = coroutineRule.runBlocking {
3137+
givenOneActiveTabSelected()
3138+
3139+
childClosedTabsSharedFlow.emit("TAB_ID")
3140+
3141+
assertCommandIssued<Command.ChildTabClosed>()
3142+
}
3143+
3144+
@Test
3145+
fun whenChildrenTabClosedIfViewModelIsNotParentThenChildTabClosedCommandNotSent() = coroutineRule.runBlocking {
3146+
givenOneActiveTabSelected()
3147+
3148+
childClosedTabsSharedFlow.emit("other_tab")
3149+
3150+
assertCommandNotIssued<Command.ChildTabClosed>()
3151+
}
3152+
31393153
private suspend fun givenFireButtonPulsing() {
31403154
whenever(mockUserStageStore.getUserAppStage()).thenReturn(AppStage.DAX_ONBOARDING)
31413155
dismissedCtaDaoChannel.send(listOf(DismissedCta(CtaId.DAX_DIALOG_TRACKERS_FOUND)))
@@ -3222,7 +3236,7 @@ class BrowserTabViewModelTest {
32223236
whenever(site.url).thenReturn(USE_OUR_APP_DOMAIN)
32233237
val siteLiveData = MutableLiveData<Site>()
32243238
siteLiveData.value = site
3225-
whenever(mockTabsRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
3239+
whenever(mockTabRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
32263240
testee.loadData("TAB_ID", USE_OUR_APP_DOMAIN, false)
32273241
}
32283242

@@ -3232,7 +3246,7 @@ class BrowserTabViewModelTest {
32323246
whenever(site.url).thenReturn("example.com")
32333247
val siteLiveData = MutableLiveData<Site>()
32343248
siteLiveData.value = site
3235-
whenever(mockTabsRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
3249+
whenever(mockTabRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
32363250
testee.loadData("TAB_ID", "example.com", false)
32373251
}
32383252

@@ -3250,7 +3264,7 @@ class BrowserTabViewModelTest {
32503264
whenever(site.uri).thenReturn(Uri.parse(domain))
32513265
val siteLiveData = MutableLiveData<Site>()
32523266
siteLiveData.value = site
3253-
whenever(mockTabsRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
3267+
whenever(mockTabRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
32543268
testee.loadData("TAB_ID", domain, false)
32553269
}
32563270

app/src/androidTest/java/com/duckduckgo/app/browser/BrowserWebViewClientTest.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ package com.duckduckgo.app.browser
1919
import android.content.Context
2020
import android.os.Build
2121
import android.webkit.*
22+
import androidx.core.net.toUri
2223
import androidx.test.annotation.UiThreadTest
2324
import androidx.test.filters.SdkSuppress
2425
import androidx.test.platform.app.InstrumentationRegistry
2526
import com.duckduckgo.app.CoroutineTestRule
2627
import com.duckduckgo.app.browser.certificates.rootstore.TrustedCertificateStore
28+
import com.duckduckgo.app.browser.cookies.ThirdPartyCookieManager
2729
import com.duckduckgo.app.browser.httpauth.WebViewHttpAuthStore
2830
import com.duckduckgo.app.browser.logindetection.DOMLoginDetector
2931
import com.duckduckgo.app.browser.logindetection.WebNavigationEvent
@@ -34,6 +36,8 @@ import com.duckduckgo.app.runBlocking
3436
import com.duckduckgo.app.statistics.store.OfflinePixelCountDataStore
3537
import com.nhaarman.mockitokotlin2.*
3638
import kotlinx.coroutines.ExperimentalCoroutinesApi
39+
import kotlinx.coroutines.GlobalScope
40+
import kotlinx.coroutines.runBlocking
3741
import org.junit.Before
3842
import org.junit.Rule
3943
import org.junit.Test
@@ -59,6 +63,7 @@ class BrowserWebViewClientTest {
5963
private val globalPrivacyControl: GlobalPrivacyControl = mock()
6064
private val trustedCertificateStore: TrustedCertificateStore = mock()
6165
private val webViewHttpAuthStore: WebViewHttpAuthStore = mock()
66+
private val thirdPartyCookieManager: ThirdPartyCookieManager = mock()
6267

6368
@UiThreadTest
6469
@Before
@@ -75,7 +80,10 @@ class BrowserWebViewClientTest {
7580
cookieManager,
7681
loginDetector,
7782
dosDetector,
78-
globalPrivacyControl
83+
globalPrivacyControl,
84+
thirdPartyCookieManager,
85+
GlobalScope,
86+
coroutinesTestRule.testDispatcherProvider
7987
)
8088
testee.webViewClientListener = listener
8189
}
@@ -117,6 +125,13 @@ class BrowserWebViewClientTest {
117125
verify(globalPrivacyControl).injectDoNotSellToDom(webView)
118126
}
119127

128+
@UiThreadTest
129+
@Test
130+
fun whenOnPageStartedCalledThenProcessUriForThirdPartyCookiesCalled() = coroutinesTestRule.runBlocking {
131+
testee.onPageStarted(webView, EXAMPLE_URL, null)
132+
verify(thirdPartyCookieManager).processUriForThirdPartyCookies(webView, EXAMPLE_URL.toUri())
133+
}
134+
120135
@UiThreadTest
121136
@Test
122137
fun whenOnPageFinishedCalledThenListenerInstructedToUpdateNavigationState() {

0 commit comments

Comments
 (0)