Skip to content

Commit 76907a2

Browse files
Merge branch 'release/5.248.0'
2 parents 51a9ec9 + 8a1ff81 commit 76907a2

File tree

288 files changed

+14512
-2723
lines changed

Some content is hidden

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

288 files changed

+14512
-2723
lines changed

.maestro/tabs/open_multiple_tabs.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ tags:
1717
- inputText: "https://privacy-test-pages.site"
1818
- pressKey: Enter
1919
- runFlow: ../shared/browser_screen/click_on_tabs_button.yaml
20+
- assertVisible:
21+
text: "0 trackers blocked in the last 7 days"
2022
- assertVisible:
2123
text: "Privacy Test Pages - Home"
2224
- tapOn: "New Tab"

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

Lines changed: 70 additions & 285 deletions
Large diffs are not rendered by default.

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

Lines changed: 140 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ import com.duckduckgo.duckplayer.api.DuckPlayer.OpenDuckPlayerInNewTab.On
8484
import com.duckduckgo.duckplayer.api.DuckPlayer.OpenDuckPlayerInNewTab.Unavailable
8585
import com.duckduckgo.feature.toggles.api.Toggle
8686
import com.duckduckgo.history.api.NavigationHistory
87+
import com.duckduckgo.js.messaging.api.AddDocumentStartJavaScriptPlugin
88+
import com.duckduckgo.js.messaging.api.PostMessageWrapperPlugin
89+
import com.duckduckgo.js.messaging.api.SubscriptionEventData
90+
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
91+
import com.duckduckgo.js.messaging.api.WebViewCompatMessageCallback
8792
import com.duckduckgo.privacy.config.api.AmpLinks
8893
import com.duckduckgo.subscriptions.api.Subscriptions
8994
import com.duckduckgo.user.agent.api.ClientBrandHintProvider
@@ -97,6 +102,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
97102
import kotlinx.coroutines.launch
98103
import kotlinx.coroutines.test.TestScope
99104
import kotlinx.coroutines.test.runTest
105+
import org.json.JSONObject
100106
import org.junit.Before
101107
import org.junit.Rule
102108
import org.junit.Test
@@ -112,6 +118,8 @@ import org.mockito.kotlin.verify
112118
import org.mockito.kotlin.verifyNoInteractions
113119
import org.mockito.kotlin.whenever
114120

121+
private val mockToggle: Toggle = mock()
122+
115123
class BrowserWebViewClientTest {
116124

117125
@get:Rule
@@ -158,6 +166,10 @@ class BrowserWebViewClientTest {
158166
private val openInNewTabFlow: MutableSharedFlow<OpenDuckPlayerInNewTab> = MutableSharedFlow()
159167
private val mockUriLoadedManager: UriLoadedManager = mock()
160168
private val mockAndroidBrowserConfigFeature: AndroidBrowserConfigFeature = mock()
169+
private val mockContentScopeExperiments: ContentScopeExperiments = mock()
170+
private val fakeAddDocumentStartJavaScriptPlugins = FakeAddDocumentStartJavaScriptPluginPoint()
171+
private val fakeMessagingPlugins = FakeWebMessagingPluginPoint()
172+
private val fakePostMessageWrapperPlugins = FakePostMessageWrapperPluginPoint()
161173
private val mockAndroidFeaturesHeaderPlugin = AndroidFeaturesHeaderPlugin(
162174
mockDuckDuckGoUrlDetector,
163175
mockCustomHeaderGracePeriodChecker,
@@ -166,15 +178,13 @@ class BrowserWebViewClientTest {
166178
mock(),
167179
)
168180
private val mockDuckChat: DuckChat = mock()
169-
private val mockContentScopeExperiments: ContentScopeExperiments = mock()
170181

171182
@UiThreadTest
172183
@Before
173184
fun setup() = runTest {
174185
webView = TestWebView(context)
175186
whenever(mockDuckPlayer.observeShouldOpenInNewTab()).thenReturn(openInNewTabFlow)
176-
val toggle: Toggle = mock()
177-
whenever(mockContentScopeExperiments.getActiveExperiments()).thenReturn(listOf(toggle))
187+
whenever(mockContentScopeExperiments.getActiveExperiments()).thenReturn(listOf(mockToggle))
178188
testee = BrowserWebViewClient(
179189
webViewHttpAuthStore,
180190
trustedCertificateStore,
@@ -208,6 +218,9 @@ class BrowserWebViewClientTest {
208218
mockAndroidFeaturesHeaderPlugin,
209219
mockDuckChat,
210220
mockContentScopeExperiments,
221+
fakeAddDocumentStartJavaScriptPlugins,
222+
fakeMessagingPlugins,
223+
fakePostMessageWrapperPlugins,
211224
)
212225
testee.webViewClientListener = listener
213226
whenever(webResourceRequest.url).thenReturn(Uri.EMPTY)
@@ -227,11 +240,8 @@ class BrowserWebViewClientTest {
227240
@UiThreadTest
228241
@Test
229242
fun whenOnPageStartedCalledThenListenerNotified() = runTest {
230-
val toggle: Toggle = mock()
231-
whenever(mockContentScopeExperiments.getActiveExperiments()).thenReturn(listOf(toggle))
232-
233243
testee.onPageStarted(webView, EXAMPLE_URL, null)
234-
verify(listener).pageStarted(any(), eq(listOf(toggle)))
244+
verify(listener).pageStarted(any(), eq(listOf(mockToggle)))
235245
}
236246

237247
@UiThreadTest
@@ -333,6 +343,55 @@ class BrowserWebViewClientTest {
333343
assertEquals(0, jsPlugins.plugin.countStarted)
334344
}
335345

346+
@UiThreadTest
347+
@Test
348+
fun whenOnPageStartedThenReturnActiveExperiments() {
349+
val captor = argumentCaptor<List<Toggle>>()
350+
testee.onPageStarted(webView, EXAMPLE_URL, null)
351+
verify(listener).pageStarted(any(), captor.capture())
352+
assertTrue(captor.firstValue.contains(mockToggle))
353+
}
354+
355+
@UiThreadTest
356+
@Test
357+
fun whenConfigureWebViewThenInjectJsCode() {
358+
assertEquals(0, fakeAddDocumentStartJavaScriptPlugins.plugin.countInitted)
359+
val mockCallback = mock<WebViewCompatMessageCallback>()
360+
testee.configureWebView(DuckDuckGoWebView(context), mockCallback)
361+
assertEquals(1, fakeAddDocumentStartJavaScriptPlugins.plugin.countInitted)
362+
}
363+
364+
@UiThreadTest
365+
@Test
366+
fun whenConfigureWebViewThenAddWebMessageListener() {
367+
assertFalse(fakeMessagingPlugins.plugin.registered)
368+
val mockCallback = mock<WebViewCompatMessageCallback>()
369+
testee.configureWebView(DuckDuckGoWebView(context), mockCallback)
370+
assertTrue(fakeMessagingPlugins.plugin.registered)
371+
}
372+
373+
@UiThreadTest
374+
@Test
375+
fun whenDestroyThenRemoveWebMessageListener() = runTest {
376+
val mockCallback = mock<WebViewCompatMessageCallback>()
377+
val webView = DuckDuckGoWebView(context)
378+
testee.configureWebView(webView, mockCallback)
379+
assertTrue(fakeMessagingPlugins.plugin.registered)
380+
testee.destroy(webView)
381+
assertFalse(fakeMessagingPlugins.plugin.registered)
382+
}
383+
384+
@Test
385+
fun whenPostMessageThenCallPostContentScopeMessage() = runTest {
386+
val data = SubscriptionEventData("feature", "method", JSONObject())
387+
388+
assertFalse(fakePostMessageWrapperPlugins.plugin.postMessageCalled)
389+
390+
testee.postContentScopeMessage(data)
391+
392+
assertTrue(fakePostMessageWrapperPlugins.plugin.postMessageCalled)
393+
}
394+
336395
@UiThreadTest
337396
@Test
338397
fun whenOnReceivedHttpAuthRequestThenListenerNotified() {
@@ -1203,7 +1262,11 @@ class BrowserWebViewClientTest {
12031262
countStarted++
12041263
}
12051264

1206-
override fun onPageFinished(webView: WebView, url: String?, site: Site?) {
1265+
override fun onPageFinished(
1266+
webView: WebView,
1267+
url: String?,
1268+
site: Site?,
1269+
) {
12071270
countFinished++
12081271
}
12091272
}
@@ -1266,4 +1329,73 @@ class BrowserWebViewClientTest {
12661329
companion object {
12671330
const val EXAMPLE_URL = "https://example.com"
12681331
}
1332+
1333+
class FakeAddDocumentStartJavaScriptPlugin : AddDocumentStartJavaScriptPlugin {
1334+
1335+
var countInitted = 0
1336+
private set
1337+
1338+
override fun addDocumentStartJavaScript(
1339+
webView: WebView,
1340+
) {
1341+
countInitted++
1342+
}
1343+
}
1344+
1345+
class FakeAddDocumentStartJavaScriptPluginPoint : PluginPoint<AddDocumentStartJavaScriptPlugin> {
1346+
1347+
val plugin = FakeAddDocumentStartJavaScriptPlugin()
1348+
1349+
override fun getPlugins() = listOf(plugin)
1350+
}
1351+
1352+
class FakeWebMessagingPlugin : WebMessagingPlugin {
1353+
var registered = false
1354+
private set
1355+
1356+
override fun unregister(webView: WebView) {
1357+
registered = false
1358+
}
1359+
1360+
override fun register(
1361+
jsMessageCallback: WebViewCompatMessageCallback,
1362+
webView: WebView,
1363+
) {
1364+
registered = true
1365+
}
1366+
1367+
override fun postMessage(subscriptionEventData: SubscriptionEventData) {
1368+
}
1369+
1370+
override val context: String
1371+
get() = "test"
1372+
}
1373+
1374+
class FakeWebMessagingPluginPoint : PluginPoint<WebMessagingPlugin> {
1375+
val plugin = FakeWebMessagingPlugin()
1376+
1377+
override fun getPlugins(): Collection<WebMessagingPlugin> {
1378+
return listOf(plugin)
1379+
}
1380+
}
1381+
1382+
class FakePostMessageWrapperPlugin : PostMessageWrapperPlugin {
1383+
var postMessageCalled = false
1384+
private set
1385+
1386+
override fun postMessage(message: SubscriptionEventData) {
1387+
postMessageCalled = true
1388+
}
1389+
1390+
override val context: String
1391+
get() = "contentScopeScripts"
1392+
}
1393+
1394+
class FakePostMessageWrapperPluginPoint : PluginPoint<PostMessageWrapperPlugin> {
1395+
val plugin = FakePostMessageWrapperPlugin()
1396+
1397+
override fun getPlugins(): Collection<PostMessageWrapperPlugin> {
1398+
return listOf(plugin)
1399+
}
1400+
}
12691401
}

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,28 @@
1717
package com.duckduckgo.app.browser
1818

1919
import androidx.test.annotation.UiThreadTest
20+
import androidx.test.ext.junit.runners.AndroidJUnit4
2021
import androidx.test.platform.app.InstrumentationRegistry
2122
import org.junit.Assert.assertFalse
23+
import org.junit.Before
2224
import org.junit.Test
25+
import org.junit.runner.RunWith
2326

27+
@RunWith(AndroidJUnit4::class)
2428
class DuckDuckGoWebViewTest {
2529

30+
private lateinit var testee: DuckDuckGoWebView
31+
32+
@Before
33+
@UiThreadTest
34+
fun setUp() {
35+
val context = InstrumentationRegistry.getInstrumentation().targetContext
36+
testee = DuckDuckGoWebView(context)
37+
}
38+
2639
@Test
2740
@UiThreadTest
2841
fun whenWebViewInitialisedThenSafeBrowsingDisabled() {
29-
val context = InstrumentationRegistry.getInstrumentation().targetContext
30-
val testee = DuckDuckGoWebView(context)
3142
assertFalse(testee.settings.safeBrowsingEnabled)
3243
}
3344
}

app/src/androidTest/java/com/duckduckgo/app/cta/ui/CtaViewModelTest.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import androidx.test.platform.app.InstrumentationRegistry
2626
import com.duckduckgo.app.browser.DuckDuckGoUrlDetectorImpl
2727
import com.duckduckgo.app.browser.R
2828
import com.duckduckgo.app.browser.defaultbrowsing.prompts.ui.experiment.OnboardingHomeScreenWidgetExperiment
29-
import com.duckduckgo.app.browser.senseofprotection.SenseOfProtectionExperiment
3029
import com.duckduckgo.app.cta.db.DismissedCtaDao
3130
import com.duckduckgo.app.cta.model.CtaId
3231
import com.duckduckgo.app.cta.model.DismissedCta
@@ -122,7 +121,6 @@ class CtaViewModelTest {
122121

123122
private val mockBrokenSitePrompt: BrokenSitePrompt = mock()
124123

125-
private val mockSenseOfProtectionExperiment: SenseOfProtectionExperiment = mock()
126124
private val mockOnboardingHomeScreenWidgetExperiment: OnboardingHomeScreenWidgetExperiment = mock()
127125

128126
private val mockOnboardingDesignExperimentManager: OnboardingDesignExperimentManager = mock()
@@ -185,7 +183,6 @@ class CtaViewModelTest {
185183
subscriptions = mockSubscriptions,
186184
duckPlayer = mockDuckPlayer,
187185
brokenSitePrompt = mockBrokenSitePrompt,
188-
senseOfProtectionExperiment = mockSenseOfProtectionExperiment,
189186
onboardingHomeScreenWidgetExperiment = mockOnboardingHomeScreenWidgetExperiment,
190187
onboardingDesignExperimentManager = mockOnboardingDesignExperimentManager,
191188
rebrandingFeatureToggle = mockRebrandingFeatureToggle,

app/src/androidTest/java/com/duckduckgo/widget/SearchAndFavoritesGridCalculatorKtTest.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ class SearchAndFavoritesGridCalculatorKtTest {
5252
return arrayOf(
5353
TestCase(2, 100),
5454
TestCase(2, 144),
55-
TestCase(3, 212),
55+
TestCase(2, 212),
5656
TestCase(3, 279),
57-
TestCase(4, 280),
58-
TestCase(5, 348),
59-
TestCase(6, 416),
60-
TestCase(7, 484),
61-
TestCase(8, 552),
57+
TestCase(3, 280),
58+
TestCase(4, 348),
59+
TestCase(4, 416),
60+
TestCase(4, 484),
61+
TestCase(4, 552),
6262
)
6363
}
6464
}
@@ -90,10 +90,10 @@ class SearchAndFavoritesGridCalculatorKtTest {
9090
return arrayOf(
9191
TestCase(1, 100),
9292
TestCase(1, 172),
93-
TestCase(2, 270),
94-
TestCase(3, 368),
93+
TestCase(1, 270),
94+
TestCase(2, 368),
9595
TestCase(3, 465),
96-
TestCase(4, 466),
96+
TestCase(3, 466),
9797
TestCase(4, 564),
9898
TestCase(4, 662),
9999
TestCase(4, 760),

app/src/internal/java/com/duckduckgo/app/dev/settings/DevSettingsActivity.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ class DevSettingsActivity : DuckDuckGoActivity() {
105105
binding.customTabs.setOnClickListener { viewModel.customTabsClicked() }
106106
binding.notifications.setOnClickListener { viewModel.notificationsClicked() }
107107
binding.tabs.setOnClickListener { viewModel.tabsClicked() }
108-
binding.showTabSwitcherAnimatedTile.setOnClickListener { viewModel.showAnimatedTileClicked() }
109108
}
110109

111110
private fun observeViewModel() {

app/src/internal/java/com/duckduckgo/app/dev/settings/DevSettingsViewModel.kt

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ import com.duckduckgo.anvil.annotations.ContributesViewModel
2222
import com.duckduckgo.app.dev.settings.db.DevSettingsDataStore
2323
import com.duckduckgo.app.dev.settings.db.UAOverride
2424
import com.duckduckgo.app.survey.api.SurveyEndpointDataStore
25-
import com.duckduckgo.app.tabs.store.TabSwitcherPrefsDataStore
26-
import com.duckduckgo.common.utils.DispatcherProvider
2725
import com.duckduckgo.di.scopes.ActivityScope
2826
import com.duckduckgo.traces.api.StartupTraces
2927
import com.duckduckgo.user.agent.api.UserAgentProvider
@@ -43,9 +41,7 @@ class DevSettingsViewModel @Inject constructor(
4341
private val devSettingsDataStore: DevSettingsDataStore,
4442
private val startupTraces: StartupTraces,
4543
private val userAgentProvider: UserAgentProvider,
46-
private val dispatcherProvider: DispatcherProvider,
4744
private val surveyEndpointDataStore: SurveyEndpointDataStore,
48-
private val tabSwitcherPrefsDataStore: TabSwitcherPrefsDataStore,
4945
) : ViewModel() {
5046

5147
data class ViewState(
@@ -141,11 +137,4 @@ class DevSettingsViewModel @Inject constructor(
141137
fun tabsClicked() {
142138
viewModelScope.launch { command.send(Command.Tabs) }
143139
}
144-
145-
fun showAnimatedTileClicked() {
146-
viewModelScope.launch {
147-
tabSwitcherPrefsDataStore.setIsAnimationTileDismissed(isDismissed = false)
148-
command.send(Command.Toast("Animated tile dismissal has been reset"))
149-
}
150-
}
151140
}

0 commit comments

Comments
 (0)