Skip to content

Commit 9ebdf81

Browse files
committed
Add UpdateNativeSettingsHandler to process updateNativeSettings messages from SERP
1 parent 5ee0f38 commit 9ebdf81

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2025 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.settings.impl.serpsettings.messaging
18+
19+
import com.duckduckgo.app.di.AppCoroutineScope
20+
import com.duckduckgo.common.utils.AppUrl
21+
import com.duckduckgo.common.utils.DispatcherProvider
22+
import com.duckduckgo.contentscopescripts.api.ContentScopeJsMessageHandlersPlugin
23+
import com.duckduckgo.di.scopes.AppScope
24+
import com.duckduckgo.js.messaging.api.JsMessage
25+
import com.duckduckgo.js.messaging.api.JsMessageCallback
26+
import com.duckduckgo.js.messaging.api.JsMessageHandler
27+
import com.duckduckgo.js.messaging.api.JsMessaging
28+
import com.duckduckgo.settings.api.SettingsPageFeature
29+
import com.squareup.anvil.annotations.ContributesMultibinding
30+
import kotlinx.coroutines.CoroutineScope
31+
import kotlinx.coroutines.launch
32+
import logcat.logcat
33+
import javax.inject.Inject
34+
35+
/**
36+
* Handles the updateNativeSettings message from SERP to persist setting changes.
37+
*/
38+
@ContributesMultibinding(AppScope::class)
39+
class UpdateNativeSettingsHandler @Inject constructor(
40+
private val dispatcherProvider: DispatcherProvider,
41+
@AppCoroutineScope private val appScope: CoroutineScope,
42+
private val settingsPageFeature: SettingsPageFeature,
43+
// TODO: Inject data store when implemented
44+
) : ContentScopeJsMessageHandlersPlugin {
45+
46+
override fun getJsMessageHandler(): JsMessageHandler =
47+
object : JsMessageHandler {
48+
override fun process(
49+
jsMessage: JsMessage,
50+
jsMessaging: JsMessaging,
51+
jsMessageCallback: JsMessageCallback?,
52+
) {
53+
appScope.launch(dispatcherProvider.io()) {
54+
if (settingsPageFeature.serpSettingsSync().isEnabled()) {
55+
logcat { "SERP-SETTINGS: UpdateNativeSettingsHandler processing message" }
56+
// TODO Use a data store to store the settings from SERP
57+
}
58+
}
59+
}
60+
61+
override val allowedDomains: List<String> = listOf(AppUrl.Url.HOST)
62+
override val featureName: String = "serpSettings"
63+
override val methods: List<String> = listOf("updateNativeSettings")
64+
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2025 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.settings.impl.serpsettings.messaging
18+
19+
import com.duckduckgo.common.test.CoroutineTestRule
20+
import com.duckduckgo.settings.api.SettingsPageFeature
21+
import org.junit.Assert.*
22+
import org.junit.Rule
23+
import org.junit.Test
24+
import org.mockito.kotlin.mock
25+
26+
class UpdateNativeSettingsHandlerTest {
27+
28+
@get:Rule
29+
val coroutineTestRule: CoroutineTestRule = CoroutineTestRule()
30+
31+
private val handler = UpdateNativeSettingsHandler(
32+
dispatcherProvider = coroutineTestRule.testDispatcherProvider,
33+
appScope = coroutineTestRule.testScope,
34+
settingsPageFeature = mock<SettingsPageFeature>(),
35+
).getJsMessageHandler()
36+
37+
@Test
38+
fun `only allow duckduckgo dot com domains`() {
39+
val domains = handler.allowedDomains
40+
assertTrue(domains.size == 1)
41+
assertTrue(domains.first() == "duckduckgo.com")
42+
}
43+
44+
@Test
45+
fun `feature name is serpSettings`() {
46+
assertTrue(handler.featureName == "serpSettings")
47+
}
48+
49+
@Test
50+
fun `only contains updateNativeSettings method`() {
51+
val methods = handler.methods
52+
assertTrue(methods.size == 1)
53+
assertTrue(methods[0] == "updateNativeSettings")
54+
}
55+
}

0 commit comments

Comments
 (0)