Skip to content

Commit 3d20ea9

Browse files
authored
Fix fallback subscriptions (#6810)
Task/Issue URL: https://app.asana.com/1/137249556945/task/1211382186881405?focus=true ### Description Fallback for subscriptions when new APIs not enabled was failing due to injecting different instances in the fragment and the messaging wrapper, so WebView was not initialized and messages were never sent ### Steps to test this PR _Feature 1_ - [ ] Add a log in `JsMessageHelper#sendSubscriptionEvent` - [ ] Disable `useNewWebCompatApis` - [ ] Load a site - [ ] Open menu - [ ] Check the log is shown for breakage report values ### UI changes | Before | After | | ------ | ----- | !(Upload before screenshot)|(Upload after screenshot)|
1 parent 58d99e7 commit 3d20ea9

File tree

6 files changed

+64
-19
lines changed

6 files changed

+64
-19
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ class BrowserWebViewClientTest {
387387

388388
assertFalse(fakePostMessageWrapperPlugins.plugin.postMessageCalled)
389389

390-
testee.postContentScopeMessage(data)
390+
testee.postContentScopeMessage(data, webView)
391391

392392
assertTrue(fakePostMessageWrapperPlugins.plugin.postMessageCalled)
393393
}
@@ -1383,7 +1383,7 @@ class BrowserWebViewClientTest {
13831383
var postMessageCalled = false
13841384
private set
13851385

1386-
override fun postMessage(message: SubscriptionEventData) {
1386+
override fun postMessage(message: SubscriptionEventData, webView: WebView) {
13871387
postMessageCalled = true
13881388
}
13891389

app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,9 @@ class BrowserTabFragment :
11971197

11981198
private fun postBreakageReportingEvent() {
11991199
val eventData = createBreakageReportingEventData()
1200-
webViewClient.postContentScopeMessage(eventData)
1200+
webView?.let {
1201+
webViewClient.postContentScopeMessage(eventData, it)
1202+
}
12011203
}
12021204

12031205
private fun onFireButtonPressed() {

app/src/main/java/com/duckduckgo/app/browser/BrowserWebViewClient.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,10 +769,11 @@ class BrowserWebViewClient @Inject constructor(
769769

770770
fun postContentScopeMessage(
771771
eventData: SubscriptionEventData,
772+
webView: WebView,
772773
) {
773774
postMessageWrapperPlugins.getPlugins()
774775
.firstOrNull { it.context == "contentScopeScripts" }
775-
?.postMessage(eventData)
776+
?.postMessage(eventData, webView)
776777
}
777778
}
778779

content-scope-scripts/content-scope-scripts-impl/src/main/java/com/duckduckgo/contentscopescripts/impl/messaging/ContentScopeScriptsPostMessageWrapperPlugin.kt

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717
package com.duckduckgo.contentscopescripts.impl.messaging
1818

1919
import android.annotation.SuppressLint
20+
import android.webkit.WebView
2021
import com.duckduckgo.app.di.AppCoroutineScope
22+
import com.duckduckgo.contentscopescripts.impl.CoreContentScopeScripts
2123
import com.duckduckgo.contentscopescripts.impl.WebViewCompatContentScopeScripts
2224
import com.duckduckgo.di.scopes.FragmentScope
25+
import com.duckduckgo.js.messaging.api.JsMessageHelper
2326
import com.duckduckgo.js.messaging.api.PostMessageWrapperPlugin
27+
import com.duckduckgo.js.messaging.api.SubscriptionEvent
2428
import com.duckduckgo.js.messaging.api.SubscriptionEventData
2529
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
2630
import com.squareup.anvil.annotations.ContributesMultibinding
@@ -32,25 +36,32 @@ import kotlinx.coroutines.launch
3236
@ContributesMultibinding(FragmentScope::class)
3337
class ContentScopeScriptsPostMessageWrapperPlugin @Inject constructor(
3438
@Named("contentScopeScripts") private val webMessagingPlugin: WebMessagingPlugin,
35-
private val contentScopeScriptsJsMessaging: ContentScopeScriptsJsMessaging,
39+
private val jsMessageHelper: JsMessageHelper,
40+
private val coreContentScopeScripts: CoreContentScopeScripts,
3641
private val webViewCompatContentScopeScripts: WebViewCompatContentScopeScripts,
3742
@AppCoroutineScope private val coroutineScope: CoroutineScope,
3843
) : PostMessageWrapperPlugin {
3944
@SuppressLint("PostMessageUsage")
40-
override fun postMessage(message: SubscriptionEventData) {
45+
override fun postMessage(message: SubscriptionEventData, webView: WebView) {
4146
coroutineScope.launch {
4247
if (webViewCompatContentScopeScripts.isEnabled()) {
4348
webMessagingPlugin.postMessage(message)
4449
} else {
45-
contentScopeScriptsJsMessaging.sendSubscriptionEvent(message)
50+
jsMessageHelper.sendSubscriptionEvent(
51+
subscriptionEvent = SubscriptionEvent(
52+
context = webMessagingPlugin.context,
53+
featureName = message.featureName,
54+
subscriptionName = message.subscriptionName,
55+
params = message.params,
56+
),
57+
callbackName = coreContentScopeScripts.callbackName,
58+
secret = coreContentScopeScripts.secret,
59+
webView = webView,
60+
)
4661
}
4762
}
4863
}
4964

5065
override val context: String
51-
get() = if (webMessagingPlugin.context == contentScopeScriptsJsMessaging.context) {
52-
webMessagingPlugin.context
53-
} else {
54-
throw Exception("Mismatched contexts between WebMessagingPlugin and ContentScopeScriptsJsMessaging")
55-
}
66+
get() = webMessagingPlugin.context
5667
}
Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
package com.duckduckgo.contentscopescripts.impl.messaging
22

3+
import android.webkit.WebView
34
import com.duckduckgo.common.test.CoroutineTestRule
5+
import com.duckduckgo.contentscopescripts.impl.CoreContentScopeScripts
46
import com.duckduckgo.contentscopescripts.impl.WebViewCompatContentScopeScripts
7+
import com.duckduckgo.js.messaging.api.JsMessageHelper
8+
import com.duckduckgo.js.messaging.api.SubscriptionEvent
59
import com.duckduckgo.js.messaging.api.SubscriptionEventData
610
import com.duckduckgo.js.messaging.api.WebMessagingPlugin
711
import kotlinx.coroutines.test.runTest
812
import org.json.JSONObject
13+
import org.junit.Before
914
import org.junit.Rule
1015
import org.junit.Test
1116
import org.mockito.Mockito.mock
17+
import org.mockito.kotlin.eq
1218
import org.mockito.kotlin.verify
1319
import org.mockito.kotlin.whenever
1420

@@ -18,26 +24,44 @@ class ContentScopeScriptsPostMessageWrapperPluginTest {
1824
var coroutineRule = CoroutineTestRule()
1925

2026
private val mockWebMessagingPlugin: WebMessagingPlugin = mock()
21-
private val mockContentScopeScriptsJsMessaging: ContentScopeScriptsJsMessaging = mock()
27+
private val mockJsHelper: JsMessageHelper = mock()
28+
private val mockCoreContentScopeScripts: CoreContentScopeScripts = mock()
2229
private val mockWebViewCompatContentScopeScripts: WebViewCompatContentScopeScripts = mock()
30+
private val mockWebView: WebView = mock()
31+
private val mockJsonObject: JSONObject = mock()
2332
private val subscriptionEventData = SubscriptionEventData(
2433
featureName = "testFeature",
2534
subscriptionName = "testSubscription",
26-
params = JSONObject(),
35+
params = mockJsonObject,
36+
)
37+
private val subscriptionEvent = SubscriptionEvent(
38+
context = "contentScopeScripts",
39+
featureName = "testFeature",
40+
subscriptionName = "testSubscription",
41+
params = mockJsonObject,
2742
)
2843

2944
val testee = ContentScopeScriptsPostMessageWrapperPlugin(
3045
webMessagingPlugin = mockWebMessagingPlugin,
31-
contentScopeScriptsJsMessaging = mockContentScopeScriptsJsMessaging,
46+
jsMessageHelper = mockJsHelper,
47+
coreContentScopeScripts = mockCoreContentScopeScripts,
3248
webViewCompatContentScopeScripts = mockWebViewCompatContentScopeScripts,
3349
coroutineScope = coroutineRule.testScope,
3450
)
3551

52+
@Before
53+
fun setup() {
54+
whenever(mockCoreContentScopeScripts.callbackName).thenReturn("callbackName")
55+
whenever(mockCoreContentScopeScripts.secret).thenReturn("secret")
56+
whenever(mockWebMessagingPlugin.context).thenReturn("contentScopeScripts")
57+
whenever(mockJsonObject.toString()).thenReturn("{}")
58+
}
59+
3660
@Test
3761
fun whenWebViewCompatContentScopeScriptsIsEnabledThenPostMessageToWebMessagingPlugin() = runTest {
3862
whenever(mockWebViewCompatContentScopeScripts.isEnabled()).thenReturn(true)
3963

40-
testee.postMessage(subscriptionEventData)
64+
testee.postMessage(subscriptionEventData, mockWebView)
4165

4266
verify(mockWebMessagingPlugin).postMessage(subscriptionEventData)
4367
}
@@ -46,8 +70,13 @@ class ContentScopeScriptsPostMessageWrapperPluginTest {
4670
fun whenWebViewCompatContentScopeScriptsIsNotEnabledThenPostMessageToContentScopeScriptsJsMessaging() = runTest {
4771
whenever(mockWebViewCompatContentScopeScripts.isEnabled()).thenReturn(false)
4872

49-
testee.postMessage(subscriptionEventData)
73+
testee.postMessage(subscriptionEventData, mockWebView)
5074

51-
verify(mockContentScopeScriptsJsMessaging).sendSubscriptionEvent(subscriptionEventData)
75+
verify(mockJsHelper).sendSubscriptionEvent(
76+
eq(subscriptionEvent),
77+
eq("callbackName"),
78+
eq("secret"),
79+
eq(mockWebView),
80+
)
5281
}
5382
}

js-messaging/js-messaging-api/src/main/java/com/duckduckgo/js/messaging/api/PostMessageWrapperPlugin.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
package com.duckduckgo.js.messaging.api
1818

19+
import android.webkit.WebView
20+
1921
interface PostMessageWrapperPlugin {
20-
fun postMessage(message: SubscriptionEventData)
22+
fun postMessage(message: SubscriptionEventData, webView: WebView)
2123

2224
val context: String
2325
}

0 commit comments

Comments
 (0)