Skip to content

Commit 53a06fd

Browse files
authored
Add surfaces parameter to RemoteMessage and updated related classes. (#7063)
Task/Issue URL: https://app.asana.com/1/137249556945/project/1200581511062568/task/1211783737656573?focus=true ### Description Added support in the RemoteMessage model for displaying remote messages on different surfaces. This PR introduces a new `Surface` enum with two values: `MODAL` and `NEW_TAB_PAGE` and a new `surfaces` field in the RemoteMessage. If no surfaces are specified in the JSON, messages will default to appearing on the `NEW_TAB_PAGE` surface. ### Steps to test this PR - [ ] Checkout this branch. - [ ] Ensure you are using a custom JSON RMF config. See details in the "Useful for testing" section in the Asana Task https://app.asana.com/1/137249556945/project/1200581511062568/task/1211783737656573?focus=true. - [ ] Verify that remote messages are parsed and stored properly. ### NO UI changes
1 parent f93d616 commit 53a06fd

File tree

12 files changed

+80
-27
lines changed

12 files changed

+80
-27
lines changed

app/src/test/java/com/duckduckgo/app/browser/newtab/NewTabLegacyPageViewModelTest.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class NewTabLegacyPageViewModelTest {
101101

102102
@Test
103103
fun whenViewModelIsInitializedThenViewStateShouldEmitInitialState() = runTest {
104-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
104+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
105105
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
106106
whenever(mockDismissedCtaDao.exists(DAX_END)).thenReturn(false)
107107

@@ -119,7 +119,7 @@ class NewTabLegacyPageViewModelTest {
119119

120120
@Test
121121
fun whenRemoteMessageAvailableAndOnboardingNotCompleteThenMessageNotShown() = runTest {
122-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
122+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
123123
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
124124
whenever(mockDismissedCtaDao.exists(DAX_END)).thenReturn(false)
125125

@@ -137,7 +137,7 @@ class NewTabLegacyPageViewModelTest {
137137

138138
@Test
139139
fun whenRemoteMessageAvailableAndOnboardingCompleteThenMessageShown() = runTest {
140-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
140+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
141141
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
142142
whenever(mockDismissedCtaDao.exists(DAX_END)).thenReturn(true)
143143

@@ -155,7 +155,7 @@ class NewTabLegacyPageViewModelTest {
155155

156156
@Test
157157
fun whenRemoteMessageShownThenFirePixelAndMarkAsShown() = runTest {
158-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
158+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
159159
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
160160

161161
testee.onStart(mockLifecycleOwner)
@@ -167,7 +167,7 @@ class NewTabLegacyPageViewModelTest {
167167

168168
@Test
169169
fun whenRemoteMessageCloseButtonClickedThenFirePixelAndDismiss() = runTest {
170-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
170+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
171171
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
172172

173173
testee.onStart(mockLifecycleOwner)
@@ -179,7 +179,7 @@ class NewTabLegacyPageViewModelTest {
179179

180180
@Test
181181
fun whenRemoteMessagePrimaryButtonClickedThenFirePixelAndDismiss() = runTest {
182-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
182+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
183183
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
184184

185185
val action = Action.Dismiss
@@ -199,7 +199,7 @@ class NewTabLegacyPageViewModelTest {
199199

200200
@Test
201201
fun whenRemoteMessageSecondaryButtonClickedThenFirePixelAndDismiss() = runTest {
202-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
202+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
203203
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
204204

205205
val action = Action.Dismiss
@@ -219,7 +219,7 @@ class NewTabLegacyPageViewModelTest {
219219

220220
@Test
221221
fun whenRemoteMessageActionButtonClickedThenFirePixelAndDismiss() = runTest {
222-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
222+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
223223
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
224224

225225
val action = Action.Dismiss
@@ -252,7 +252,7 @@ class NewTabLegacyPageViewModelTest {
252252

253253
@Test
254254
fun whenRemoteMessageAvailableAndLowPriorityMessageAvailableThenLowPriorityMessageIsNull() = runTest {
255-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
255+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
256256
val lowPriorityMessage = LowPriorityMessage.DefaultBrowserMessage(
257257
message = MessageCta.Message(
258258
topIllustration = R.drawable.ic_device_mobile_default,
@@ -372,7 +372,7 @@ class NewTabLegacyPageViewModelTest {
372372

373373
@Test
374374
fun `when onboarding complete and RMF available, then hide logo`() = runTest {
375-
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList())
375+
val remoteMessage = RemoteMessage("id1", Content.Small("", ""), emptyList(), emptyList(), emptyList())
376376
whenever(mockRemoteMessageModel.getActiveMessages()).thenReturn(flowOf(remoteMessage))
377377
whenever(mockDismissedCtaDao.exists(DAX_END)).thenReturn(true)
378378

remote-messaging/remote-messaging-api/src/main/java/com/duckduckgo/remote/messaging/api/RemoteMessage.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,14 @@ data class RemoteMessage(
3636
val content: Content,
3737
val matchingRules: List<Int>,
3838
val exclusionRules: List<Int>,
39+
val surfaces: List<Surface>,
3940
)
4041

42+
enum class Surface(val jsonValue: String) {
43+
MODAL("modal"),
44+
NEW_TAB_PAGE("new_tab_page"),
45+
}
46+
4147
sealed class Content(val messageType: MessageType) {
4248
data class Small(val titleText: String, val descriptionText: String) : Content(SMALL)
4349
data class Medium(val titleText: String, val descriptionText: String, val placeholder: Placeholder) : Content(MEDIUM)

remote-messaging/remote-messaging-impl/src/main/java/com/duckduckgo/remote/messaging/impl/AppRemoteMessagingRepository.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class AppRemoteMessagingRepository(
6969
content = remoteMessage.content,
7070
emptyList(),
7171
emptyList(),
72+
emptyList(),
7273
)
7374
return remoteMessage
7475
}
@@ -83,6 +84,7 @@ class AppRemoteMessagingRepository(
8384
content = message.content,
8485
emptyList(),
8586
emptyList(),
87+
emptyList(),
8688
)
8789
}
8890
}

remote-messaging/remote-messaging-impl/src/main/java/com/duckduckgo/remote/messaging/impl/mappers/JsonRemoteMessageMapper.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.duckduckgo.remote.messaging.api.Content.Small
2727
import com.duckduckgo.remote.messaging.api.JsonMessageAction
2828
import com.duckduckgo.remote.messaging.api.MessageActionMapperPlugin
2929
import com.duckduckgo.remote.messaging.api.RemoteMessage
30+
import com.duckduckgo.remote.messaging.api.Surface
3031
import com.duckduckgo.remote.messaging.impl.models.*
3132
import com.duckduckgo.remote.messaging.impl.models.JsonMessageType.BIG_SINGLE_ACTION
3233
import com.duckduckgo.remote.messaging.impl.models.JsonMessageType.BIG_TWO_ACTION
@@ -109,13 +110,19 @@ private fun JsonRemoteMessage.map(
109110
content = this.content!!.mapToContent(this.content.messageType, actionMappers),
110111
matchingRules = this.matchingRules.orEmpty(),
111112
exclusionRules = this.exclusionRules.orEmpty(),
113+
surfaces = this.surfaces.toSurfaceList(),
112114
)
113115
remoteMessage.localizeMessage(this.translations, locale)
114116
}.onFailure {
115117
logcat(ERROR) { "RMF: error $it" }
116118
}.getOrNull()
117119
}
118120

121+
private fun List<String>?.toSurfaceList(): List<Surface> {
122+
return this?.mapNotNull { value ->
123+
Surface.entries.firstOrNull { it.jsonValue == value }
124+
} ?: listOf(Surface.NEW_TAB_PAGE)
125+
}
119126
private fun RemoteMessage.localizeMessage(translations: Map<String, JsonContentTranslations>?, locale: Locale): RemoteMessage {
120127
if (translations == null) return this
121128

remote-messaging/remote-messaging-impl/src/main/java/com/duckduckgo/remote/messaging/impl/models/JsonRemoteMessagingConfig.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ data class JsonRemoteMessage(
3131
val exclusionRules: List<Int>,
3232
val matchingRules: List<Int>,
3333
val translations: Map<String, JsonContentTranslations>,
34+
val surfaces: List<String>?,
3435
)
3536

3637
data class JsonContent(

remote-messaging/remote-messaging-impl/src/test/java/com/duckduckgo/remote/messaging/fixtures/JsonRemoteMessageOM.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,14 @@ object JsonRemoteMessageOM {
111111
exclusionRules: List<Int> = emptyList(),
112112
matchingRules: List<Int> = emptyList(),
113113
translations: Map<String, JsonContentTranslations> = emptyMap(),
114+
surfaces: List<String>? = null,
114115
) = JsonRemoteMessage(
115116
id = id,
116117
content = content,
117118
exclusionRules = exclusionRules,
118119
matchingRules = matchingRules,
119120
translations = translations,
121+
surfaces = surfaces,
120122
)
121123

122124
fun aJsonRemoteMessagingConfig(

remote-messaging/remote-messaging-impl/src/test/java/com/duckduckgo/remote/messaging/fixtures/RemoteMessageOM.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.duckduckgo.remote.messaging.api.Content.Placeholder
2222
import com.duckduckgo.remote.messaging.api.Content.Placeholder.ANNOUNCE
2323
import com.duckduckgo.remote.messaging.api.Content.Placeholder.MAC_AND_WINDOWS
2424
import com.duckduckgo.remote.messaging.api.RemoteMessage
25+
import com.duckduckgo.remote.messaging.api.Surface
2526

2627
@Suppress("MemberVisibilityCanBePrivate")
2728
object RemoteMessageOM {
@@ -98,12 +99,14 @@ object RemoteMessageOM {
9899
content: Content = smallContent(),
99100
exclusionRules: List<Int> = emptyList(),
100101
matchingRules: List<Int> = emptyList(),
102+
surfaces: List<Surface> = emptyList(),
101103
): RemoteMessage {
102104
return RemoteMessage(
103105
id = id,
104106
content = content,
105107
exclusionRules = exclusionRules,
106108
matchingRules = matchingRules,
109+
surfaces = surfaces,
107110
)
108111
}
109112

@@ -112,12 +115,14 @@ object RemoteMessageOM {
112115
content: Content = mediumContent(),
113116
exclusionRules: List<Int> = emptyList(),
114117
matchingRules: List<Int> = emptyList(),
118+
surfaces: List<Surface> = emptyList(),
115119
): RemoteMessage {
116120
return RemoteMessage(
117121
id = id,
118122
content = content,
119123
exclusionRules = exclusionRules,
120124
matchingRules = matchingRules,
125+
surfaces = surfaces,
121126
)
122127
}
123128

@@ -126,12 +131,14 @@ object RemoteMessageOM {
126131
content: Content = bigSingleActionContent(),
127132
exclusionRules: List<Int> = emptyList(),
128133
matchingRules: List<Int> = emptyList(),
134+
surfaces: List<Surface> = emptyList(),
129135
): RemoteMessage {
130136
return RemoteMessage(
131137
id = id,
132138
content = content,
133139
exclusionRules = exclusionRules,
134140
matchingRules = matchingRules,
141+
surfaces = surfaces,
135142
)
136143
}
137144

@@ -140,12 +147,14 @@ object RemoteMessageOM {
140147
content: Content = bigTwoActionsContent(),
141148
exclusionRules: List<Int> = emptyList(),
142149
matchingRules: List<Int> = emptyList(),
150+
surfaces: List<Surface> = emptyList(),
143151
): RemoteMessage {
144152
return RemoteMessage(
145153
id = id,
146154
content = content,
147155
exclusionRules = exclusionRules,
148156
matchingRules = matchingRules,
157+
surfaces = surfaces,
149158
)
150159
}
151160

@@ -154,12 +163,14 @@ object RemoteMessageOM {
154163
content: Content = promoSingleActionContent(),
155164
exclusionRules: List<Int> = emptyList(),
156165
matchingRules: List<Int> = emptyList(),
166+
surfaces: List<Surface> = emptyList(),
157167
): RemoteMessage {
158168
return RemoteMessage(
159169
id = id,
160170
content = content,
161171
exclusionRules = exclusionRules,
162172
matchingRules = matchingRules,
173+
surfaces = surfaces,
163174
)
164175
}
165176
}

remote-messaging/remote-messaging-impl/src/test/java/com/duckduckgo/remote/messaging/impl/AppRemoteMessagingRepositoryTest.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class AppRemoteMessagingRepositoryTest {
8686
),
8787
matchingRules = emptyList(),
8888
exclusionRules = emptyList(),
89+
surfaces = emptyList(),
8990
),
9091
)
9192

@@ -102,6 +103,7 @@ class AppRemoteMessagingRepositoryTest {
102103
),
103104
matchingRules = emptyList(),
104105
exclusionRules = emptyList(),
106+
surfaces = emptyList(),
105107
),
106108
message,
107109
)
@@ -120,6 +122,7 @@ class AppRemoteMessagingRepositoryTest {
120122
),
121123
matchingRules = emptyList(),
122124
exclusionRules = emptyList(),
125+
surfaces = emptyList(),
123126
),
124127
)
125128

@@ -135,6 +138,7 @@ class AppRemoteMessagingRepositoryTest {
135138
),
136139
matchingRules = emptyList(),
137140
exclusionRules = emptyList(),
141+
surfaces = emptyList(),
138142
),
139143
message,
140144
)
@@ -156,6 +160,7 @@ class AppRemoteMessagingRepositoryTest {
156160
),
157161
matchingRules = emptyList(),
158162
exclusionRules = emptyList(),
163+
surfaces = emptyList(),
159164
),
160165
)
161166

@@ -174,6 +179,7 @@ class AppRemoteMessagingRepositoryTest {
174179
),
175180
matchingRules = emptyList(),
176181
exclusionRules = emptyList(),
182+
surfaces = emptyList(),
177183
),
178184
message,
179185
)
@@ -197,6 +203,7 @@ class AppRemoteMessagingRepositoryTest {
197203
),
198204
matchingRules = emptyList(),
199205
exclusionRules = emptyList(),
206+
surfaces = emptyList(),
200207
),
201208
)
202209

@@ -217,6 +224,7 @@ class AppRemoteMessagingRepositoryTest {
217224
),
218225
matchingRules = emptyList(),
219226
exclusionRules = emptyList(),
227+
surfaces = emptyList(),
220228
),
221229
message,
222230
)
@@ -238,6 +246,7 @@ class AppRemoteMessagingRepositoryTest {
238246
),
239247
matchingRules = emptyList(),
240248
exclusionRules = emptyList(),
249+
surfaces = emptyList(),
241250
),
242251
)
243252

@@ -256,6 +265,7 @@ class AppRemoteMessagingRepositoryTest {
256265
),
257266
matchingRules = emptyList(),
258267
exclusionRules = emptyList(),
268+
surfaces = emptyList(),
259269
),
260270
message,
261271
)
@@ -426,6 +436,7 @@ class AppRemoteMessagingRepositoryTest {
426436
),
427437
matchingRules = emptyList(),
428438
exclusionRules = emptyList(),
439+
surfaces = emptyList(),
429440
)
430441
}
431442
}

0 commit comments

Comments
 (0)