@aws-amplify/rtn-push-notification 1.0.1-push-notification-dryrun.7810
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AmplifyRTNPushNotification.podspec +36 -0
- package/LICENSE +201 -0
- package/android/build.gradle +76 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/android/gradle.properties +23 -0
- package/android/gradlew +234 -0
- package/android/gradlew.bat +89 -0
- package/android/src/main/AndroidManifest.xml +22 -0
- package/android/src/main/kotlin/com/amazonaws/amplify/rtnpushnotification/PushNotificationAWSPinpointUtils.kt +159 -0
- package/android/src/main/kotlin/com/amazonaws/amplify/rtnpushnotification/PushNotificationEventManager.kt +49 -0
- package/android/src/main/kotlin/com/amazonaws/amplify/rtnpushnotification/PushNotificationFirebaseMessagingService.kt +74 -0
- package/android/src/main/kotlin/com/amazonaws/amplify/rtnpushnotification/PushNotificationHeadlessTaskService.kt +28 -0
- package/android/src/main/kotlin/com/amazonaws/amplify/rtnpushnotification/PushNotificationLaunchActivity.kt +27 -0
- package/android/src/main/kotlin/com/amazonaws/amplify/rtnpushnotification/PushNotificationModule.kt +188 -0
- package/android/src/main/kotlin/com/amazonaws/amplify/rtnpushnotification/PushNotificationPackage.kt +22 -0
- package/android/src/test/kotlin/PushNotificationAWSPinpointUtilsTest.kt +326 -0
- package/android/src/test/kotlin/PushNotificationEventManagerTest.kt +45 -0
- package/android/src/test/kotlin/PushNotificationFirebaseMessagingServiceTest.kt +92 -0
- package/android/src/test/kotlin/PushNotificationLaunchActivityTest.kt +45 -0
- package/android/src/test/kotlin/PushNotificationModuleTest.kt +201 -0
- package/ios/AmplifyPushNotification.h +17 -0
- package/ios/AmplifyPushNotification.m +21 -0
- package/ios/AmplifyPushNotificationAppDelegateHelper.swift +31 -0
- package/ios/AmplifyRTNEventManager.swift +73 -0
- package/ios/AmplifyRTNPushNotification-Bridging-Header.h +7 -0
- package/ios/AmplifyRTNPushNotification.m +26 -0
- package/ios/AmplifyRTNPushNotification.swift +121 -0
- package/ios/AmplifyRTNPushNotification.xcworkspace/contents.xcworkspacedata +28 -0
- package/ios/AmplifyRTNPushNotification.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/AmplifyRTNPushNotificationManager.swift +258 -0
- package/lib/.tsbuildinfo +3 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -0
- package/lib/types.d.ts +18 -0
- package/lib/types.js +5 -0
- package/lib/types.js.map +1 -0
- package/lib-esm/.tsbuildinfo +3 -0
- package/lib-esm/index.d.ts +3 -0
- package/lib-esm/index.js +5 -0
- package/lib-esm/index.js.map +1 -0
- package/lib-esm/types.d.ts +18 -0
- package/lib-esm/types.js +3 -0
- package/lib-esm/types.js.map +1 -0
- package/package.json +48 -0
- package/src/index.ts +10 -0
- package/src/types.ts +23 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import android.content.ComponentName
|
|
5
|
+
import android.content.Context
|
|
6
|
+
import android.content.Intent
|
|
7
|
+
import android.content.IntentFilter
|
|
8
|
+
import android.os.Bundle
|
|
9
|
+
import com.amazonaws.amplify.rtnpushnotification.*
|
|
10
|
+
import com.amplifyframework.annotations.InternalAmplifyApi
|
|
11
|
+
import com.amplifyframework.notifications.pushnotifications.NotificationContentProvider
|
|
12
|
+
import com.amplifyframework.notifications.pushnotifications.NotificationPayload
|
|
13
|
+
import com.amplifyframework.pushnotifications.pinpoint.PushNotificationsConstants
|
|
14
|
+
import com.amplifyframework.pushnotifications.pinpoint.PushNotificationsUtils
|
|
15
|
+
import com.amplifyframework.pushnotifications.pinpoint.permissions.PermissionRequestResult
|
|
16
|
+
import com.facebook.react.bridge.Arguments
|
|
17
|
+
import com.facebook.react.bridge.WritableMap
|
|
18
|
+
import io.mockk.*
|
|
19
|
+
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
20
|
+
import kotlinx.coroutines.test.runTest
|
|
21
|
+
import kotlinx.serialization.encodeToString
|
|
22
|
+
import kotlinx.serialization.json.Json
|
|
23
|
+
import org.junit.Assert.*
|
|
24
|
+
import org.junit.Before
|
|
25
|
+
import org.junit.Test
|
|
26
|
+
import org.junit.runner.RunWith
|
|
27
|
+
import org.robolectric.RobolectricTestRunner
|
|
28
|
+
import org.robolectric.RuntimeEnvironment
|
|
29
|
+
import org.robolectric.Shadows.shadowOf
|
|
30
|
+
import kotlin.random.Random
|
|
31
|
+
import com.amplifyframework.pushnotifications.pinpoint.permissions.PushNotificationPermission as CommonPushNotificationPermission
|
|
32
|
+
|
|
33
|
+
@InternalAmplifyApi
|
|
34
|
+
@ExperimentalCoroutinesApi
|
|
35
|
+
@RunWith(RobolectricTestRunner::class)
|
|
36
|
+
class PushNotificationAWSPinpointUtilsTest {
|
|
37
|
+
private object TestConst {
|
|
38
|
+
const val ADHOC_KEY = "foo"
|
|
39
|
+
const val ADHOC_VAL = "bar"
|
|
40
|
+
const val BODY = "body"
|
|
41
|
+
const val CAMPAIGN_ID = "campaign-id"
|
|
42
|
+
const val CAMPAIGN_ACTIVITY_ID = "campaign-activity-id"
|
|
43
|
+
const val DEEPLINK_URL = "deeplink://url"
|
|
44
|
+
const val IMAGE_URL = "http://image.fakeurl/avocado.png"
|
|
45
|
+
const val JOURNEY_ID = "journey-id"
|
|
46
|
+
const val JOURNEY_ACTIVITY_ID = "journey-id"
|
|
47
|
+
const val RANDOM_INT = 123
|
|
48
|
+
const val TITLE = "title"
|
|
49
|
+
const val URL = "https://goto.fakeurl"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private fun getTestPayload(data: Map<String, String> = mapOf()): NotificationPayload {
|
|
53
|
+
return NotificationPayload.Builder(
|
|
54
|
+
NotificationContentProvider.FCM(
|
|
55
|
+
mapOf(PushNotificationsConstants.PINPOINT_PREFIX to "").plus(data)
|
|
56
|
+
)
|
|
57
|
+
).build()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private val launchIntentFilter = IntentFilter(Intent.ACTION_MAIN).apply {
|
|
61
|
+
addCategory(Intent.CATEGORY_LAUNCHER)
|
|
62
|
+
}
|
|
63
|
+
private val mockMap = mockk<WritableMap>()
|
|
64
|
+
private lateinit var context: Context
|
|
65
|
+
|
|
66
|
+
@Before
|
|
67
|
+
fun setup() {
|
|
68
|
+
context = RuntimeEnvironment.getApplication().applicationContext
|
|
69
|
+
mockkConstructor(CommonPushNotificationPermission::class)
|
|
70
|
+
mockkConstructor(PushNotificationsUtils::class)
|
|
71
|
+
mockkObject(Random)
|
|
72
|
+
mockkStatic(Arguments::class)
|
|
73
|
+
justRun {
|
|
74
|
+
mockMap.putMap(any(), any())
|
|
75
|
+
mockMap.putString(any(), any())
|
|
76
|
+
anyConstructed<PushNotificationsUtils>().showNotification(any(), any(), any())
|
|
77
|
+
}
|
|
78
|
+
every { Random.nextInt() } returns TestConst.RANDOM_INT
|
|
79
|
+
every { anyConstructed<PushNotificationsUtils>().areNotificationsEnabled() } returns true
|
|
80
|
+
every { Arguments.createMap() } returns mockMap
|
|
81
|
+
val component = ComponentName(context.packageName, "TestMainActivity")
|
|
82
|
+
shadowOf(context.packageManager).apply {
|
|
83
|
+
addActivityIfNotPresent(component)
|
|
84
|
+
addIntentFilterForActivity(component, launchIntentFilter)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Test
|
|
89
|
+
fun `returns permission status`() {
|
|
90
|
+
every {
|
|
91
|
+
anyConstructed<CommonPushNotificationPermission>().hasRequiredPermission
|
|
92
|
+
} returns true
|
|
93
|
+
assertTrue(PushNotificationPermission(context).hasRequiredPermission)
|
|
94
|
+
|
|
95
|
+
every {
|
|
96
|
+
anyConstructed<CommonPushNotificationPermission>().hasRequiredPermission
|
|
97
|
+
} returns false
|
|
98
|
+
assertFalse(PushNotificationPermission(context).hasRequiredPermission)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@Test
|
|
102
|
+
fun `requests permission`() = runTest {
|
|
103
|
+
coEvery {
|
|
104
|
+
anyConstructed<CommonPushNotificationPermission>().requestPermission()
|
|
105
|
+
} returns PermissionRequestResult.Granted
|
|
106
|
+
assertTrue(PushNotificationPermission(context).requestPermission())
|
|
107
|
+
|
|
108
|
+
coEvery {
|
|
109
|
+
anyConstructed<CommonPushNotificationPermission>().requestPermission()
|
|
110
|
+
} returns PermissionRequestResult.NotGranted(
|
|
111
|
+
true
|
|
112
|
+
)
|
|
113
|
+
assertFalse(PushNotificationPermission(context).requestPermission())
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@Test
|
|
117
|
+
fun `shows notification if enabled`() {
|
|
118
|
+
PushNotificationUtils(context).showNotification(getTestPayload())
|
|
119
|
+
verify {
|
|
120
|
+
anyConstructed<PushNotificationsUtils>().showNotification(
|
|
121
|
+
TestConst.RANDOM_INT,
|
|
122
|
+
any(),
|
|
123
|
+
PushNotificationLaunchActivity::class.java
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@Test
|
|
129
|
+
fun `does not show notification if not enabled`() {
|
|
130
|
+
every { anyConstructed<PushNotificationsUtils>().areNotificationsEnabled() } returns false
|
|
131
|
+
PushNotificationUtils(context).showNotification(getTestPayload())
|
|
132
|
+
verify(exactly = 0) {
|
|
133
|
+
anyConstructed<PushNotificationsUtils>().showNotification(
|
|
134
|
+
any(), any(), any()
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@Test
|
|
140
|
+
fun `does not show notification if explicitly silent`() {
|
|
141
|
+
PushNotificationUtils(context).showNotification(
|
|
142
|
+
getTestPayload(
|
|
143
|
+
mapOf(
|
|
144
|
+
PushNotificationsConstants.PINPOINT_NOTIFICATION_SILENTPUSH to "1"
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
)
|
|
148
|
+
verify(exactly = 0) {
|
|
149
|
+
anyConstructed<PushNotificationsUtils>().showNotification(
|
|
150
|
+
any(), any(), any()
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@Test
|
|
156
|
+
fun `builds a notificationId based on campaign attributes`() {
|
|
157
|
+
PushNotificationUtils(context).showNotification(
|
|
158
|
+
getTestPayload(
|
|
159
|
+
mapOf(
|
|
160
|
+
PushNotificationsConstants.PINPOINT_CAMPAIGN_CAMPAIGN_ID to TestConst.CAMPAIGN_ID,
|
|
161
|
+
PushNotificationsConstants.PINPOINT_CAMPAIGN_CAMPAIGN_ACTIVITY_ID to TestConst.CAMPAIGN_ACTIVITY_ID
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
verify {
|
|
166
|
+
anyConstructed<PushNotificationsUtils>().showNotification(
|
|
167
|
+
"${TestConst.CAMPAIGN_ID}:${TestConst.CAMPAIGN_ACTIVITY_ID}".hashCode(),
|
|
168
|
+
any(),
|
|
169
|
+
any()
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@Test
|
|
175
|
+
fun `builds a notificationId based on journey attributes`() {
|
|
176
|
+
PushNotificationUtils(context).showNotification(
|
|
177
|
+
getTestPayload(
|
|
178
|
+
mapOf(
|
|
179
|
+
PushNotificationsConstants.PINPOINT_PREFIX to Json.encodeToString(
|
|
180
|
+
mapOf(
|
|
181
|
+
PushNotificationsConstants.JOURNEY to mapOf(
|
|
182
|
+
PushNotificationsConstants.JOURNEY_ID to TestConst.JOURNEY_ID,
|
|
183
|
+
PushNotificationsConstants.JOURNEY_ACTIVITY_ID to TestConst.JOURNEY_ACTIVITY_ID
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
)
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
verify {
|
|
191
|
+
anyConstructed<PushNotificationsUtils>().showNotification(
|
|
192
|
+
"${TestConst.JOURNEY_ID}:${TestConst.JOURNEY_ACTIVITY_ID}".hashCode(), any(), any()
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
@Test
|
|
198
|
+
fun `builds a random notificationId if only campaign id is present`() {
|
|
199
|
+
PushNotificationUtils(context).showNotification(
|
|
200
|
+
getTestPayload(
|
|
201
|
+
mapOf(
|
|
202
|
+
PushNotificationsConstants.PINPOINT_CAMPAIGN_CAMPAIGN_ID to TestConst.CAMPAIGN_ID
|
|
203
|
+
)
|
|
204
|
+
)
|
|
205
|
+
)
|
|
206
|
+
verify {
|
|
207
|
+
anyConstructed<PushNotificationsUtils>().showNotification(
|
|
208
|
+
TestConst.RANDOM_INT, any(), any()
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@Test
|
|
214
|
+
fun `returns if app is in foreground`() {
|
|
215
|
+
every { anyConstructed<PushNotificationsUtils>().isAppInForeground() } returns true
|
|
216
|
+
assertTrue(PushNotificationUtils(context).isAppInForeground())
|
|
217
|
+
every { anyConstructed<PushNotificationsUtils>().isAppInForeground() } returns false
|
|
218
|
+
assertFalse(PushNotificationUtils(context).isAppInForeground())
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
@Test
|
|
222
|
+
fun `can create a payload from bundle`() {
|
|
223
|
+
val bundle = Bundle().apply {
|
|
224
|
+
putString(PushNotificationsConstants.PINPOINT_NOTIFICATION_TITLE, TestConst.TITLE)
|
|
225
|
+
putString(PushNotificationsConstants.PINPOINT_NOTIFICATION_BODY, TestConst.BODY)
|
|
226
|
+
}
|
|
227
|
+
val payload = bundle.getNotificationPayload()
|
|
228
|
+
assertEquals(
|
|
229
|
+
TestConst.TITLE,
|
|
230
|
+
payload?.rawData?.get(PushNotificationsConstants.PINPOINT_NOTIFICATION_TITLE)
|
|
231
|
+
)
|
|
232
|
+
assertEquals(
|
|
233
|
+
TestConst.BODY,
|
|
234
|
+
payload?.rawData?.get(PushNotificationsConstants.PINPOINT_NOTIFICATION_BODY)
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
@Test
|
|
239
|
+
fun `can create a writable map from payload`() {
|
|
240
|
+
val payload = NotificationPayload.Builder(
|
|
241
|
+
NotificationContentProvider.FCM(
|
|
242
|
+
mapOf(
|
|
243
|
+
PushNotificationsConstants.PINPOINT_NOTIFICATION_TITLE to TestConst.TITLE,
|
|
244
|
+
PushNotificationsConstants.PINPOINT_NOTIFICATION_BODY to TestConst.BODY,
|
|
245
|
+
PushNotificationsConstants.PINPOINT_NOTIFICATION_IMAGEURL to TestConst.IMAGE_URL,
|
|
246
|
+
TestConst.ADHOC_KEY to TestConst.ADHOC_VAL
|
|
247
|
+
)
|
|
248
|
+
)
|
|
249
|
+
).build()
|
|
250
|
+
payload.toWritableMap()
|
|
251
|
+
verify {
|
|
252
|
+
mockMap.putString("title", TestConst.TITLE)
|
|
253
|
+
mockMap.putString("body", TestConst.BODY)
|
|
254
|
+
mockMap.putString("imageUrl", TestConst.IMAGE_URL)
|
|
255
|
+
mockMap.putString(
|
|
256
|
+
"channelId",
|
|
257
|
+
PushNotificationsConstants.DEFAULT_NOTIFICATION_CHANNEL_ID
|
|
258
|
+
)
|
|
259
|
+
mockMap.putString(TestConst.ADHOC_KEY, TestConst.ADHOC_VAL)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
@Test
|
|
264
|
+
fun `writable map from payload can contain url action`() {
|
|
265
|
+
val payload = NotificationPayload.Builder(
|
|
266
|
+
NotificationContentProvider.FCM(mapOf(PushNotificationsConstants.PINPOINT_URL to TestConst.URL))
|
|
267
|
+
).build()
|
|
268
|
+
payload.toWritableMap()
|
|
269
|
+
verify {
|
|
270
|
+
mockMap.putString(PushNotificationsConstants.URL, TestConst.URL)
|
|
271
|
+
mockMap.putMap("action", mockMap)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
@Test
|
|
276
|
+
fun `writable map from payload can contain deeplink action`() {
|
|
277
|
+
val payload = NotificationPayload.Builder(
|
|
278
|
+
NotificationContentProvider.FCM(mapOf(PushNotificationsConstants.PINPOINT_DEEPLINK to TestConst.DEEPLINK_URL))
|
|
279
|
+
).build()
|
|
280
|
+
payload.toWritableMap()
|
|
281
|
+
verify {
|
|
282
|
+
mockMap.putString(
|
|
283
|
+
PushNotificationsConstants.PINPOINT_DEEPLINK,
|
|
284
|
+
TestConst.DEEPLINK_URL
|
|
285
|
+
)
|
|
286
|
+
mockMap.putMap("action", mockMap)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@Test
|
|
291
|
+
fun `writable map from payload always has rawData`() {
|
|
292
|
+
val payload = NotificationPayload.Builder(
|
|
293
|
+
NotificationContentProvider.FCM(emptyMap())
|
|
294
|
+
).build()
|
|
295
|
+
payload.toWritableMap()
|
|
296
|
+
verify(exactly = 0) {
|
|
297
|
+
mockMap.putString(any(), any())
|
|
298
|
+
mockMap.putMap("action", any())
|
|
299
|
+
}
|
|
300
|
+
verify { mockMap.putMap("rawData", mockMap) }
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
@Test
|
|
304
|
+
fun `processes payload`() {
|
|
305
|
+
val payload = getTestPayload()
|
|
306
|
+
assertNotNull(payload.getProcessedIntent(context))
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
@Test
|
|
310
|
+
fun `adds url action and starts launch activity`() {
|
|
311
|
+
val payload =
|
|
312
|
+
getTestPayload(mapOf(PushNotificationsConstants.PINPOINT_URL to TestConst.URL))
|
|
313
|
+
val intent = payload.getProcessedIntent(context)
|
|
314
|
+
assertEquals(Intent.ACTION_VIEW, intent?.action)
|
|
315
|
+
assertEquals(TestConst.URL, intent?.data.toString())
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
@Test
|
|
319
|
+
fun `adds deeplink action and starts launch activity`() {
|
|
320
|
+
val payload =
|
|
321
|
+
getTestPayload(mapOf(PushNotificationsConstants.PINPOINT_DEEPLINK to TestConst.DEEPLINK_URL))
|
|
322
|
+
val intent = payload.getProcessedIntent(context)
|
|
323
|
+
assertEquals(Intent.ACTION_VIEW, intent?.action)
|
|
324
|
+
assertEquals(TestConst.DEEPLINK_URL, intent?.data.toString())
|
|
325
|
+
}
|
|
326
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import com.amazonaws.amplify.rtnpushnotification.PushNotificationEventManager
|
|
5
|
+
import com.amazonaws.amplify.rtnpushnotification.PushNotificationEventType
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.bridge.WritableMap
|
|
8
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
|
9
|
+
import io.mockk.*
|
|
10
|
+
import org.junit.Before
|
|
11
|
+
import org.junit.Test
|
|
12
|
+
|
|
13
|
+
class PushNotificationEventManagerTest {
|
|
14
|
+
private val mockContext = mockk<ReactApplicationContext>()
|
|
15
|
+
private val mockEmitter = mockk<RCTDeviceEventEmitter>()
|
|
16
|
+
private val mockMap = mockk<WritableMap>()
|
|
17
|
+
|
|
18
|
+
@Before
|
|
19
|
+
fun setup() {
|
|
20
|
+
justRun { mockEmitter.emit(any(), any()) }
|
|
21
|
+
every { mockContext.getJSModule(RCTDeviceEventEmitter::class.java) } returns mockEmitter
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Test
|
|
25
|
+
fun `queues events and sends when initialized`() {
|
|
26
|
+
PushNotificationEventManager.sendEvent(
|
|
27
|
+
PushNotificationEventType.NOTIFICATION_OPENED, mockMap
|
|
28
|
+
)
|
|
29
|
+
PushNotificationEventManager.sendEvent(
|
|
30
|
+
PushNotificationEventType.NOTIFICATION_OPENED, mockMap
|
|
31
|
+
)
|
|
32
|
+
verify(exactly = 0) {
|
|
33
|
+
mockEmitter.emit(
|
|
34
|
+
PushNotificationEventType.NOTIFICATION_OPENED.value, mockMap
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
PushNotificationEventManager.init(mockContext)
|
|
39
|
+
verify(exactly = 2) {
|
|
40
|
+
mockEmitter.emit(
|
|
41
|
+
PushNotificationEventType.NOTIFICATION_OPENED.value, mockMap
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import android.content.Intent
|
|
5
|
+
import android.os.Bundle
|
|
6
|
+
import com.amazonaws.amplify.rtnpushnotification.*
|
|
7
|
+
import com.amplifyframework.annotations.InternalAmplifyApi
|
|
8
|
+
import com.amplifyframework.notifications.pushnotifications.NotificationContentProvider
|
|
9
|
+
import com.amplifyframework.notifications.pushnotifications.NotificationPayload
|
|
10
|
+
import com.facebook.react.HeadlessJsTaskService
|
|
11
|
+
import com.facebook.react.bridge.Arguments
|
|
12
|
+
import com.facebook.react.bridge.WritableMap
|
|
13
|
+
import io.mockk.*
|
|
14
|
+
import org.junit.Before
|
|
15
|
+
import org.junit.Test
|
|
16
|
+
import org.junit.runner.RunWith
|
|
17
|
+
import org.robolectric.Robolectric.buildService
|
|
18
|
+
import org.robolectric.RobolectricTestRunner
|
|
19
|
+
import org.robolectric.RuntimeEnvironment
|
|
20
|
+
import org.robolectric.android.controller.ServiceController
|
|
21
|
+
|
|
22
|
+
@InternalAmplifyApi
|
|
23
|
+
@RunWith(RobolectricTestRunner::class)
|
|
24
|
+
class PushNotificationFirebaseMessagingServiceTest {
|
|
25
|
+
private object TestConst {
|
|
26
|
+
const val TOKEN = "foo-bar"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private val mockMap = mockk<WritableMap>()
|
|
30
|
+
private val testPayload = NotificationPayload.Builder(
|
|
31
|
+
NotificationContentProvider.FCM(
|
|
32
|
+
content = mapOf()
|
|
33
|
+
)
|
|
34
|
+
).build()
|
|
35
|
+
private lateinit var controller: ServiceController<PushNotificationFirebaseMessagingService>
|
|
36
|
+
|
|
37
|
+
@Before
|
|
38
|
+
fun setup() {
|
|
39
|
+
mockkConstructor(PushNotificationUtils::class)
|
|
40
|
+
mockkObject(PushNotificationEventManager)
|
|
41
|
+
mockkStatic(Arguments::class)
|
|
42
|
+
mockkStatic(Bundle::getNotificationPayload)
|
|
43
|
+
mockkStatic(HeadlessJsTaskService::class)
|
|
44
|
+
mockkStatic(NotificationPayload::toWritableMap)
|
|
45
|
+
justRun {
|
|
46
|
+
PushNotificationEventManager.sendEvent(any(), any())
|
|
47
|
+
mockMap.putString(any(), any())
|
|
48
|
+
HeadlessJsTaskService.acquireWakeLockNow(any())
|
|
49
|
+
anyConstructed<PushNotificationUtils>().showNotification(any())
|
|
50
|
+
}
|
|
51
|
+
every { any<NotificationPayload>().toWritableMap() } returns mockMap
|
|
52
|
+
every { Arguments.createMap() } returns mockMap
|
|
53
|
+
every { any<Bundle>().getNotificationPayload() } returns testPayload
|
|
54
|
+
controller = buildService(PushNotificationFirebaseMessagingService::class.java, Intent())
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@Test
|
|
58
|
+
fun `sends token received event on new token`() {
|
|
59
|
+
controller.create().get().onNewToken(TestConst.TOKEN)
|
|
60
|
+
|
|
61
|
+
verify {
|
|
62
|
+
PushNotificationEventManager.sendEvent(
|
|
63
|
+
PushNotificationEventType.TOKEN_RECEIVED,
|
|
64
|
+
mockMap
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@Test
|
|
70
|
+
fun `handles message in foreground`() {
|
|
71
|
+
every { anyConstructed<PushNotificationUtils>().isAppInForeground() } returns true
|
|
72
|
+
controller.create().get().handleIntent(Intent())
|
|
73
|
+
|
|
74
|
+
verify {
|
|
75
|
+
PushNotificationEventManager.sendEvent(
|
|
76
|
+
PushNotificationEventType.FOREGROUND_MESSAGE_RECEIVED,
|
|
77
|
+
mockMap
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@Test
|
|
83
|
+
fun `handles message in background`() {
|
|
84
|
+
every { anyConstructed<PushNotificationUtils>().isAppInForeground() } returns false
|
|
85
|
+
controller.create().get().handleIntent(Intent())
|
|
86
|
+
|
|
87
|
+
verify {
|
|
88
|
+
anyConstructed<PushNotificationUtils>().showNotification(testPayload)
|
|
89
|
+
HeadlessJsTaskService.acquireWakeLockNow(RuntimeEnvironment.getApplication().baseContext)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import android.content.Intent
|
|
5
|
+
import com.amazonaws.amplify.rtnpushnotification.PushNotificationLaunchActivity
|
|
6
|
+
import com.amazonaws.amplify.rtnpushnotification.getProcessedIntent
|
|
7
|
+
import com.amplifyframework.annotations.InternalAmplifyApi
|
|
8
|
+
import com.amplifyframework.notifications.pushnotifications.NotificationPayload
|
|
9
|
+
import io.mockk.*
|
|
10
|
+
import org.junit.Assert.assertEquals
|
|
11
|
+
import org.junit.Before
|
|
12
|
+
import org.junit.Test
|
|
13
|
+
import org.junit.runner.RunWith
|
|
14
|
+
import org.robolectric.Robolectric.buildActivity
|
|
15
|
+
import org.robolectric.RobolectricTestRunner
|
|
16
|
+
import org.robolectric.Shadows.shadowOf
|
|
17
|
+
|
|
18
|
+
@InternalAmplifyApi
|
|
19
|
+
@RunWith(RobolectricTestRunner::class)
|
|
20
|
+
class PushNotificationLaunchActivityTest {
|
|
21
|
+
private object TestConst {
|
|
22
|
+
const val EXTRAS_KEY = "foo"
|
|
23
|
+
const val EXTRAS_VAL = "bar"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Before
|
|
27
|
+
fun setup() {
|
|
28
|
+
mockkStatic(NotificationPayload::getProcessedIntent)
|
|
29
|
+
every { any<NotificationPayload>().getProcessedIntent(any()) } returns Intent()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Test
|
|
33
|
+
fun `adds launch intent with extras and starts launch activity`() {
|
|
34
|
+
val intent = Intent().apply {
|
|
35
|
+
putExtra(TestConst.EXTRAS_KEY, TestConst.EXTRAS_VAL)
|
|
36
|
+
}
|
|
37
|
+
buildActivity(PushNotificationLaunchActivity::class.java, intent).use {
|
|
38
|
+
val activity = it.setup().get()
|
|
39
|
+
val notificationIntent = shadowOf(activity).nextStartedActivity
|
|
40
|
+
|
|
41
|
+
assertEquals(TestConst.EXTRAS_VAL, notificationIntent.extras?.get(TestConst.EXTRAS_KEY))
|
|
42
|
+
it.pause().stop().destroy()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|