@imatis/react-native-notifications 4.1.2-imatis.7 → 4.2.4-imatis.21

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.
Files changed (46) hide show
  1. package/.buildkite/pipeline.yaml +39 -0
  2. package/.nvmrc +1 -0
  3. package/CHANGELOG.gren.md +384 -317
  4. package/CODEOWNERS +1 -1
  5. package/lib/android/.gradle/6.1.1/executionHistory/executionHistory.bin +0 -0
  6. package/lib/android/.gradle/6.1.1/executionHistory/executionHistory.lock +0 -0
  7. package/lib/android/.gradle/6.1.1/fileContent/fileContent.lock +0 -0
  8. package/lib/android/.gradle/6.1.1/fileHashes/fileHashes.bin +0 -0
  9. package/lib/android/.gradle/6.1.1/fileHashes/fileHashes.lock +0 -0
  10. package/lib/android/.gradle/6.1.1/fileHashes/resourceHashesCache.bin +0 -0
  11. package/lib/android/.gradle/6.1.1/javaCompile/classAnalysis.bin +0 -0
  12. package/lib/android/.gradle/6.1.1/javaCompile/jarAnalysis.bin +0 -0
  13. package/lib/android/.gradle/6.1.1/javaCompile/javaCompile.lock +0 -0
  14. package/lib/android/.gradle/6.1.1/javaCompile/taskHistory.bin +0 -0
  15. package/lib/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  16. package/lib/android/.gradle/buildOutputCleanup/cache.properties +1 -1
  17. package/lib/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  18. package/lib/android/.gradle/checksums/checksums.lock +0 -0
  19. package/lib/android/.gradle/checksums/md5-checksums.bin +0 -0
  20. package/lib/android/.gradle/checksums/sha1-checksums.bin +0 -0
  21. package/lib/android/app/build.gradle +3 -5
  22. package/lib/android/app/src/main/AndroidManifest.xml +2 -1
  23. package/lib/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java +17 -14
  24. package/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/NotificationIntentAdapter.java +21 -7
  25. package/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java +54 -24
  26. package/lib/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotificationProps.java +24 -0
  27. package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/AppLaunchHelperTest.java +117 -0
  28. package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/InitialNotificationHolderTest.java +59 -0
  29. package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/JsIOHelperTest.java +60 -0
  30. package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/notification/PushNotificationTest.java +381 -0
  31. package/lib/android/app/src/test/java/com/wix/reactnativenotifications/core/notificationdrawer/PushNotificationsDrawerTest.java +96 -0
  32. package/lib/android/app/src/test/resources/robolectric.properties +1 -0
  33. package/lib/android/build.gradle +1 -1
  34. package/lib/android/local.properties +2 -2
  35. package/lib/dist/commands/Commands.test.js +2 -0
  36. package/lib/dist/interfaces/NotificationCategory.d.ts +3 -2
  37. package/lib/dist/interfaces/NotificationPermissions.d.ts +2 -0
  38. package/lib/src/interfaces/NotificationCategory.ts +4 -2
  39. package/metro.config.js +0 -1
  40. package/package.json +10 -13
  41. package/react-native-notifications.podspec +6 -5
  42. package/react-native.config.js +8 -0
  43. package/android/app/src/reactNative59/reactNative59.iml +0 -11
  44. package/android/app/src/reactNative60/reactNative60.iml +0 -11
  45. package/lib/ios/RNNotifications.xcodeproj/project.xcworkspace/xcuserdata/troy.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  46. package/package-lock.json +0 -13507
package/CODEOWNERS CHANGED
@@ -1 +1 @@
1
- * @yogevbd
1
+ * @DanielEliraz
@@ -1,2 +1,2 @@
1
- #Mon Jul 12 10:27:56 ICT 2021
1
+ #Tue Mar 22 09:43:34 CET 2022
2
2
  gradle.version=6.1.1
@@ -1,21 +1,19 @@
1
1
  import groovy.json.JsonSlurper
2
2
 
3
3
  apply plugin: 'com.android.library'
4
- apply plugin: 'kotlin-android'
5
- apply plugin: 'kotlin-android-extensions'
6
4
 
7
5
  def safeExtGet(prop, fallback) {
8
6
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
9
7
  }
10
8
 
11
- def DEFAULT_COMPILE_SDK_VERSION = 29
9
+ def DEFAULT_COMPILE_SDK_VERSION = 30
12
10
  def DEFAULT_MIN_SDK_VERSION = 21
13
11
  def DEFAULT_KOTLIN_VERSION = "1.3.61"
14
12
  def DEFAULT_KOTLIN_STDLIB_VERSION = "kotlin-stdlib-jdk8"
15
13
  def DEFAULT_FIREBASE_MESSAGING_VERSION = "21.1.0"
16
14
 
17
- def androidSdkVersion = safeExtGet('androidSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
18
- def androidMinSdkVersion = safeExtGet('androidMinSdkVersion', DEFAULT_MIN_SDK_VERSION)
15
+ def androidSdkVersion = safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
16
+ def androidMinSdkVersion = safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION)
19
17
  def androidTargetSdkVersion = safeExtGet('targetSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
20
18
  def kotlinVersion = safeExtGet('kotlinVersion', DEFAULT_KOTLIN_VERSION)
21
19
  def kotlinStdlib = safeExtGet('kotlinStdlib', DEFAULT_KOTLIN_STDLIB_VERSION)
@@ -11,7 +11,8 @@
11
11
  <service android:name=".core.ProxyService"/>
12
12
 
13
13
  <service
14
- android:name=".fcm.FcmInstanceIdListenerService">
14
+ android:name=".fcm.FcmInstanceIdListenerService"
15
+ android:exported="true">
15
16
  <intent-filter>
16
17
  <action android:name="com.google.firebase.MESSAGING_EVENT" />
17
18
  <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
@@ -2,6 +2,7 @@ package com.wix.reactnativenotifications;
2
2
 
3
3
  import android.app.Activity;
4
4
  import android.app.Application;
5
+ import android.content.Context;
5
6
  import android.content.Intent;
6
7
  import android.os.Bundle;
7
8
 
@@ -61,24 +62,13 @@ public class RNNotificationsPackage implements ReactPackage, AppLifecycleFacade.
61
62
  final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(mApplication.getApplicationContext());
62
63
  notificationsDrawer.onNewActivity(activity);
63
64
 
64
- Intent intent = activity.getIntent();
65
- if (NotificationIntentAdapter.canHandleIntent(intent)) {
66
- Bundle notificationData = intent.getExtras();
67
- final IPushNotification pushNotification = PushNotification.get(mApplication.getApplicationContext(), notificationData);
68
- if (pushNotification != null) {
69
- pushNotification.onOpened();
70
- }
71
- }
65
+ callOnOpenedIfNeed(activity);
72
66
  }
73
67
 
74
68
  @Override
75
69
  public void onActivityStarted(Activity activity) {
76
- Bundle bundle = activity.getIntent().getExtras();
77
- if (bundle != null) {
78
- PushNotificationProps props = new PushNotificationProps(bundle);
79
- if (props.isFirebaseBackgroundPayload()) {
80
- InitialNotificationHolder.getInstance().set(props);
81
- }
70
+ if (InitialNotificationHolder.getInstance().get() == null) {
71
+ callOnOpenedIfNeed(activity);
82
72
  }
83
73
  }
84
74
 
@@ -101,4 +91,17 @@ public class RNNotificationsPackage implements ReactPackage, AppLifecycleFacade.
101
91
  @Override
102
92
  public void onActivityDestroyed(Activity activity) {
103
93
  }
94
+
95
+ private void callOnOpenedIfNeed(Activity activity) {
96
+ Intent intent = activity.getIntent();
97
+ if (NotificationIntentAdapter.canHandleIntent(intent)) {
98
+ Context appContext = mApplication.getApplicationContext();
99
+ Bundle notificationData = NotificationIntentAdapter.cannotHandleTrampolineActivity(appContext) ?
100
+ NotificationIntentAdapter.extractPendingNotificationDataFromIntent(intent) : intent.getExtras();
101
+ final IPushNotification pushNotification = PushNotification.get(appContext, notificationData);
102
+ if (pushNotification != null) {
103
+ pushNotification.onOpened();
104
+ }
105
+ }
106
+ }
104
107
  }
@@ -1,6 +1,8 @@
1
1
  package com.wix.reactnativenotifications.core;
2
2
 
3
+ import android.annotation.SuppressLint;
3
4
  import android.app.PendingIntent;
5
+ import android.app.TaskStackBuilder;
4
6
  import android.content.Context;
5
7
  import android.content.Intent;
6
8
  import android.os.Bundle;
@@ -10,9 +12,23 @@ import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
10
12
  public class NotificationIntentAdapter {
11
13
  private static final String PUSH_NOTIFICATION_EXTRA_NAME = "pushNotification";
12
14
 
13
- public static PendingIntent createPendingNotificationIntent(Context appContext, Intent intent, PushNotificationProps notification) {
14
- intent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
15
- return PendingIntent.getService(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT);
15
+ @SuppressLint("UnspecifiedImmutableFlag")
16
+ public static PendingIntent createPendingNotificationIntent(Context appContext, PushNotificationProps notification) {
17
+ if (cannotHandleTrampolineActivity(appContext)) {
18
+ Intent mainActivityIntent = appContext.getPackageManager().getLaunchIntentForPackage(appContext.getPackageName());
19
+ mainActivityIntent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
20
+ TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(appContext);
21
+ taskStackBuilder.addNextIntentWithParentStack(mainActivityIntent);
22
+ return taskStackBuilder.getPendingIntent((int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
23
+ } else {
24
+ Intent intent = new Intent(appContext, ProxyService.class);
25
+ intent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, notification.asBundle());
26
+ return PendingIntent.getService(appContext, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_ONE_SHOT);
27
+ }
28
+ }
29
+
30
+ public static boolean cannotHandleTrampolineActivity(Context appContext) {
31
+ return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R && appContext.getApplicationInfo().targetSdkVersion >= 31;
16
32
  }
17
33
 
18
34
  public static Bundle extractPendingNotificationDataFromIntent(Intent intent) {
@@ -22,11 +38,9 @@ public class NotificationIntentAdapter {
22
38
  public static boolean canHandleIntent(Intent intent) {
23
39
  if (intent != null) {
24
40
  Bundle notificationData = intent.getExtras();
25
- if (notificationData != null &&
41
+ return notificationData != null &&
26
42
  (intent.hasExtra(PUSH_NOTIFICATION_EXTRA_NAME) ||
27
- notificationData.getString("google.message_id", null) != null)) {
28
- return true;
29
- }
43
+ notificationData.getString("google.message_id", null) != null);
30
44
  }
31
45
 
32
46
  return false;
@@ -9,6 +9,8 @@ import android.content.Context;
9
9
  import android.content.Intent;
10
10
  import android.graphics.Color;
11
11
  import android.media.AudioAttributes;
12
+ import android.media.AudioManager;
13
+ import android.media.MediaPlayer;
12
14
  import android.net.Uri;
13
15
  import android.os.Build;
14
16
  import android.os.Bundle;
@@ -23,7 +25,6 @@ import com.wix.reactnativenotifications.core.AppLifecycleFacadeHolder;
23
25
  import com.wix.reactnativenotifications.core.InitialNotificationHolder;
24
26
  import com.wix.reactnativenotifications.core.JsIOHelper;
25
27
  import com.wix.reactnativenotifications.core.NotificationIntentAdapter;
26
- import com.wix.reactnativenotifications.core.ProxyService;
27
28
 
28
29
  import static com.wix.reactnativenotifications.Defs.NOTIFICATION_OPENED_EVENT_NAME;
29
30
  import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_EVENT_NAME;
@@ -65,14 +66,14 @@ public class PushNotification implements IPushNotification {
65
66
  mAppLaunchHelper = appLaunchHelper;
66
67
  mJsIOHelper = JsIOHelper;
67
68
  mNotificationProps = createProps(bundle);
68
- initDefaultChannel(context);
69
+ //initDefaultChannel(context);
69
70
  }
70
71
 
71
72
  @Override
72
73
  public void onReceived() throws InvalidNotificationException {
73
74
  if (!mAppLifecycleFacade.isAppVisible()) {
74
- notifyReceivedBackgroundToJS();
75
75
  postNotification(null);
76
+ notifyReceivedBackgroundToJS();
76
77
  } else {
77
78
  notifyReceivedToJS();
78
79
  }
@@ -94,15 +95,22 @@ public class PushNotification implements IPushNotification {
94
95
  }
95
96
 
96
97
  protected int postNotification(Integer notificationId) {
97
- final PendingIntent pendingIntent = getCTAPendingIntent();
98
+ final PendingIntent pendingIntent = NotificationIntentAdapter.createPendingNotificationIntent(mContext, mNotificationProps);;
98
99
  final Notification notification = buildNotification(pendingIntent);
100
+
99
101
  if (mNotificationProps.getGuid().equals("-1")) {
100
102
  cancelAllNotifications();
101
103
  return -1;
102
104
  }
105
+
103
106
  if (mNotificationProps.getTitle() == null || mNotificationProps.getTitle().isEmpty()) {
104
107
  return -1;
105
108
  }
109
+
110
+ if (mNotificationProps.isDataOnlyPushNotification()) {
111
+ return -1;
112
+ }
113
+
106
114
  return postNotification(notification, notificationId);
107
115
  }
108
116
 
@@ -151,12 +159,6 @@ public class PushNotification implements IPushNotification {
151
159
  return mAppVisibilityListener;
152
160
  }
153
161
 
154
- protected PendingIntent getCTAPendingIntent() {
155
- final Intent cta = new Intent(mContext, ProxyService.class);
156
- cta.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
157
- return NotificationIntentAdapter.createPendingNotificationIntent(mContext, cta, mNotificationProps);
158
- }
159
-
160
162
  protected Notification buildNotification(PendingIntent intent) {
161
163
  return getNotificationBuilder(intent).build();
162
164
  }
@@ -164,11 +166,15 @@ public class PushNotification implements IPushNotification {
164
166
  protected Notification.Builder getNotificationBuilder(PendingIntent intent) {
165
167
  Uri soundUri = null;
166
168
  String sound = mNotificationProps.getSound();
167
- if (sound != null) {
169
+ if (sound != null && sound != "") {
168
170
  sound = sound.toLowerCase();
169
171
  int soundResourceId = getAppResourceId(sound, "raw");
170
172
  if (soundResourceId == 0) {
171
- soundResourceId = getAppResourceId(sound.substring(0, sound.lastIndexOf('.')), "raw");
173
+ String[] soundSplited = sound.split("\\.");
174
+ if (soundSplited.length > 0) {
175
+ String soundName = soundSplited[0];
176
+ soundResourceId = getAppResourceId(soundName, "raw");
177
+ }
172
178
  }
173
179
  soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"+ mContext.getPackageName() + "/" + soundResourceId);
174
180
  }
@@ -180,7 +186,8 @@ public class PushNotification implements IPushNotification {
180
186
  .setContentIntent(intent)
181
187
  .setDefaults(Notification.DEFAULT_VIBRATE)
182
188
  .setAutoCancel(true)
183
- .setPriority(Notification.PRIORITY_HIGH);
189
+ .setPriority(Notification.PRIORITY_HIGH)
190
+ .setOngoing(mNotificationProps.getOngoing());
184
191
 
185
192
  if (soundUri != null) {
186
193
  notification.setSound(soundUri);
@@ -191,14 +198,10 @@ public class PushNotification implements IPushNotification {
191
198
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
192
199
  final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
193
200
  String channelId = mNotificationProps.getChannelId();
194
- channelId = channelId != null ? channelId : DEFAULT_CHANNEL_ID;
201
+ channelId = channelId != null ? channelId : DEFAULT_CHANNEL_ID + sound;
195
202
  NotificationChannel channel = notificationManager.getNotificationChannel(channelId);
196
- if (channel != null && soundUri != null) {
197
- AudioAttributes audioAttributes = new AudioAttributes.Builder()
198
- .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
199
- .setUsage(AudioAttributes.USAGE_NOTIFICATION)
200
- .build();
201
- channel.setSound(soundUri, audioAttributes);
203
+ if (channel == null && soundUri != null) {
204
+ initDefaultChannel(mContext, channelId, soundUri);
202
205
  }
203
206
  notification.setChannelId(channelId);
204
207
  }
@@ -211,6 +214,24 @@ public class PushNotification implements IPushNotification {
211
214
  Log.d(LOGTAG, e.getMessage());
212
215
  }
213
216
 
217
+ if(mNotificationProps.getCriticalAlert()){
218
+ try {
219
+ MediaPlayer mMediaPlayer = new MediaPlayer();
220
+ mMediaPlayer.setDataSource(mContext.getApplicationContext(), soundUri);
221
+ mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
222
+
223
+ mMediaPlayer.prepare();
224
+ mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
225
+ public void onPrepared(MediaPlayer arg0) {
226
+ mMediaPlayer.seekTo(0);
227
+ mMediaPlayer.start();
228
+ }
229
+ });
230
+ } catch (Exception e) {
231
+ Log.d(LOGTAG, e.getMessage());
232
+ }
233
+ }
234
+
214
235
  return notification;
215
236
  }
216
237
 
@@ -264,8 +285,10 @@ public class PushNotification implements IPushNotification {
264
285
  }
265
286
 
266
287
  protected void launchOrResumeApp() {
267
- final Intent intent = mAppLaunchHelper.getLaunchIntent(mContext);
268
- mContext.startActivity(intent);
288
+ if (!NotificationIntentAdapter.cannotHandleTrampolineActivity(mContext)) {
289
+ final Intent intent = mAppLaunchHelper.getLaunchIntent(mContext);
290
+ mContext.startActivity(intent);
291
+ }
269
292
  }
270
293
 
271
294
  private int getAppResourceId(String resName, String resType) {
@@ -277,9 +300,9 @@ public class PushNotification implements IPushNotification {
277
300
  notificationManager.cancelAll();
278
301
  }
279
302
 
280
- private void initDefaultChannel(Context context) {
303
+ private void initDefaultChannel(Context context, String channelId, Uri soundUri) {
281
304
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
282
- NotificationChannel defaultChannel = new NotificationChannel(DEFAULT_CHANNEL_ID,
305
+ NotificationChannel defaultChannel = new NotificationChannel(channelId,
283
306
  DEFAULT_CHANNEL_NAME,
284
307
  NotificationManager.IMPORTANCE_HIGH);
285
308
  defaultChannel.setDescription(DEFAULT_CHANNEL_NAME);
@@ -289,6 +312,13 @@ public class PushNotification implements IPushNotification {
289
312
  defaultChannel.enableVibration(true);
290
313
  defaultChannel.setShowBadge(true);
291
314
  defaultChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
315
+ if (soundUri != null) {
316
+ AudioAttributes audioAttributes = new AudioAttributes.Builder()
317
+ .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
318
+ .setUsage(AudioAttributes.USAGE_NOTIFICATION)
319
+ .build();
320
+ defaultChannel.setSound(soundUri, audioAttributes);
321
+ }
292
322
  final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
293
323
  notificationManager.createNotificationChannel(defaultChannel);
294
324
  }
@@ -37,6 +37,30 @@ public class PushNotificationProps {
37
37
  public boolean isFirebaseBackgroundPayload() {
38
38
  return mBundle.containsKey("google.message_id");
39
39
  }
40
+
41
+ public boolean isDataOnlyPushNotification() {
42
+ return getTitle() == null && getBody() == null;
43
+ }
44
+
45
+ public Boolean getCriticalAlert() {
46
+ String val = mBundle.getString("criticalalert");
47
+ if(val != null && !val.isEmpty()){
48
+ return val.toLowerCase().equals("true");
49
+ }
50
+ return false;
51
+ }
52
+
53
+ public Double getCriticalAlertVolume() {
54
+ String val = mBundle.getString("criticalalertvolume");
55
+ if(val != null && !val.isEmpty()){
56
+ return Double.parseDouble(val);
57
+ }
58
+ return 0.0;
59
+ }
60
+
61
+ public Boolean getOngoing() {
62
+ return mBundle.getBoolean("ongoing");
63
+ }
40
64
 
41
65
  @Override
42
66
  public String toString() {
@@ -0,0 +1,117 @@
1
+ package com.wix.reactnativenotifications.core;
2
+
3
+ import android.app.Activity;
4
+ import android.content.ComponentName;
5
+ import android.content.Context;
6
+ import android.content.Intent;
7
+ import android.content.pm.PackageManager;
8
+
9
+ import org.junit.Before;
10
+ import org.junit.Test;
11
+ import org.junit.runner.RunWith;
12
+ import org.mockito.Mock;
13
+ import org.mockito.MockitoAnnotations;
14
+ import org.robolectric.RobolectricTestRunner;
15
+
16
+ import static org.junit.Assert.assertEquals;
17
+ import static org.junit.Assert.assertFalse;
18
+ import static org.junit.Assert.assertNotNull;
19
+ import static org.junit.Assert.assertTrue;
20
+ import static org.mockito.ArgumentMatchers.eq;
21
+ import static org.mockito.Mockito.mock;
22
+ import static org.mockito.Mockito.when;
23
+
24
+ @RunWith(RobolectricTestRunner.class)
25
+ public class AppLaunchHelperTest {
26
+
27
+ private static final String LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME = "launchedFromNotification";
28
+
29
+ static class ActivityMock extends Activity {
30
+ }
31
+
32
+ private final String APP_PACKAGE_NAME = "the.package";
33
+ private final String APP_MAIN_ACTIVITY_NAME = ActivityMock.class.getName();
34
+
35
+ @Mock private Context mContext;
36
+ @Mock private PackageManager mPackageManager;
37
+
38
+
39
+ @Before
40
+ public void setup() throws Exception {
41
+ MockitoAnnotations.initMocks(this);
42
+ when(mContext.getApplicationContext()).thenReturn(mContext);
43
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
44
+ when(mContext.getPackageName()).thenReturn(APP_PACKAGE_NAME);
45
+
46
+ // Set-up the intent (mock) returned by the SDK for getLaunchIntentForPackage()
47
+ Intent intent = mock(Intent.class);
48
+ when(intent.getComponent()).thenReturn(new ComponentName(APP_PACKAGE_NAME, APP_MAIN_ACTIVITY_NAME));
49
+ when(mPackageManager.getLaunchIntentForPackage(eq(APP_PACKAGE_NAME))).thenReturn(intent);
50
+ }
51
+
52
+ @Test
53
+ public void getLaunchIntent__returnsCustomIntentWithNotifFlagExtra() throws Exception {
54
+ final AppLaunchHelper uut = getUUT();
55
+ Intent intent = uut.getLaunchIntent(mContext);
56
+
57
+ assertNotNull(intent);
58
+ assertEquals(APP_PACKAGE_NAME, intent.getComponent().getPackageName());
59
+ assertEquals(APP_MAIN_ACTIVITY_NAME, intent.getComponent().getClassName());
60
+ assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, intent.getFlags());
61
+ assertTrue(intent.getBooleanExtra(LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME, false));
62
+ }
63
+
64
+ @Test
65
+ public void isLaunchIntentsActivity_activityIsMainLauncherActivity_returnTrue() throws Exception {
66
+ Activity activity = getActivityMock(APP_MAIN_ACTIVITY_NAME);
67
+
68
+ final AppLaunchHelper uut = getUUT();
69
+ boolean result = uut.isLaunchIntentsActivity(activity);
70
+
71
+ assertTrue(result);
72
+ }
73
+
74
+ @Test
75
+ public void isLaunchIntentsActivity_activityIsNotMainActivity_returnFalse() throws Exception {
76
+ Activity activity = getActivityMock("other.activity");
77
+
78
+ final AppLaunchHelper uut = getUUT();
79
+ boolean result = uut.isLaunchIntentsActivity(activity);
80
+
81
+ assertFalse(result);
82
+ }
83
+
84
+ @Test
85
+ public void isLaunchIntentOfNotification_hasFlagInBundle_returnTrue() throws Exception {
86
+ Intent intent = mock(Intent.class);
87
+ when(intent.getBooleanExtra(eq(LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME), eq(false))).thenReturn(true);
88
+
89
+ final AppLaunchHelper uut = getUUT();
90
+ boolean result = uut.isLaunchIntentOfNotification(intent);
91
+
92
+ assertTrue(result);
93
+ }
94
+
95
+ @Test
96
+ public void isLaunchIntentOfNotification_noFlagInBundle_returnFalse() throws Exception {
97
+ Intent intent = mock(Intent.class);
98
+
99
+ final AppLaunchHelper uut = getUUT();
100
+ boolean result = uut.isLaunchIntentOfNotification(intent);
101
+
102
+ assertFalse(result);
103
+ }
104
+
105
+ protected Activity getActivityMock(String activityClassName) {
106
+ Activity activity = mock(Activity.class);
107
+ when(activity.getPackageManager()).thenReturn(mPackageManager);
108
+ when(activity.getPackageName()).thenReturn(APP_PACKAGE_NAME);
109
+ when(activity.getComponentName()).thenReturn(new ComponentName(APP_PACKAGE_NAME, activityClassName));
110
+ when(activity.getLocalClassName()).thenReturn(activityClassName);
111
+ return activity;
112
+ }
113
+
114
+ private AppLaunchHelper getUUT() {
115
+ return new AppLaunchHelper();
116
+ }
117
+ }
@@ -0,0 +1,59 @@
1
+ package com.wix.reactnativenotifications.core;
2
+
3
+ import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
4
+
5
+ import org.junit.Test;
6
+ import org.junit.runner.RunWith;
7
+ import org.mockito.junit.MockitoJUnitRunner;
8
+
9
+ import static org.junit.Assert.*;
10
+ import static org.mockito.Mockito.mock;
11
+
12
+ @RunWith(MockitoJUnitRunner.class)
13
+ public class InitialNotificationHolderTest {
14
+
15
+ @Test
16
+ public void initialState() throws Exception {
17
+ final InitialNotificationHolder uut = createUUT();
18
+ assertNull(uut.get());
19
+ }
20
+
21
+ @Test
22
+ public void setsInitialNotification() throws Exception {
23
+ PushNotificationProps props = mock(PushNotificationProps.class);
24
+ final InitialNotificationHolder uut = createUUT();
25
+ uut.set(props);
26
+ assertEquals(props, uut.get());
27
+ }
28
+
29
+ @Test
30
+ public void clearsInitialNotification() throws Exception {
31
+ PushNotificationProps props = mock(PushNotificationProps.class);
32
+ final InitialNotificationHolder uut = createUUT();
33
+ uut.set(props);
34
+ uut.clear();
35
+ assertNull(uut.get());
36
+ }
37
+
38
+ @Test
39
+ public void replacesInitialNotification() throws Exception {
40
+ PushNotificationProps props1 = mock(PushNotificationProps.class);
41
+ PushNotificationProps props2 = mock(PushNotificationProps.class);
42
+ final InitialNotificationHolder uut = createUUT();
43
+ uut.set(props1);
44
+ uut.set(props2);
45
+ assertNotEquals(props1, props2);
46
+ assertEquals(props2, uut.get());
47
+ }
48
+
49
+ @Test
50
+ public void isALazySingleton() throws Exception {
51
+ final InitialNotificationHolder instance = InitialNotificationHolder.getInstance();
52
+ assertNotNull(instance);
53
+ assertEquals(instance, InitialNotificationHolder.getInstance());
54
+ }
55
+
56
+ private InitialNotificationHolder createUUT() {
57
+ return new InitialNotificationHolder();
58
+ }
59
+ }
@@ -0,0 +1,60 @@
1
+ package com.wix.reactnativenotifications.core;
2
+
3
+ import android.os.Bundle;
4
+
5
+ import com.facebook.react.bridge.ReactContext;
6
+ import com.facebook.react.bridge.WritableMap;
7
+ import com.facebook.react.modules.core.DeviceEventManagerModule;
8
+
9
+ import org.junit.Before;
10
+ import org.junit.Test;
11
+ import org.junit.runner.RunWith;
12
+ import org.mockito.Mock;
13
+ import org.mockito.junit.MockitoJUnitRunner;
14
+
15
+ import static org.junit.Assert.assertFalse;
16
+ import static org.junit.Assert.assertTrue;
17
+ import static org.mockito.ArgumentMatchers.any;
18
+ import static org.mockito.ArgumentMatchers.anyString;
19
+ import static org.mockito.Mockito.mock;
20
+ import static org.mockito.Mockito.never;
21
+ import static org.mockito.Mockito.verify;
22
+ import static org.mockito.Mockito.when;
23
+
24
+ @RunWith(MockitoJUnitRunner.class)
25
+ public class JsIOHelperTest {
26
+
27
+ @Mock DeviceEventManagerModule.RCTDeviceEventEmitter mRCTDeviceEventEmitter;
28
+ @Mock ReactContext mReactContext;
29
+
30
+ @Before
31
+ public void setup() throws Exception {
32
+ when(mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)).thenReturn(mRCTDeviceEventEmitter);
33
+ }
34
+
35
+ @Test
36
+ public void sendEventToJS_hasReactContext_emitsEventToJs() throws Exception {
37
+ WritableMap data = mock(WritableMap.class);
38
+
39
+ final JsIOHelper uut = createUUT();
40
+ boolean result = uut.sendEventToJS("my-event", data, mReactContext);
41
+
42
+ assertTrue(result);
43
+ verify(mRCTDeviceEventEmitter).emit("my-event", data);
44
+ }
45
+
46
+ @Test
47
+ public void sendEventToJS_noReactContext_returnsFalse() throws Exception {
48
+ WritableMap data = mock(WritableMap.class);
49
+
50
+ final JsIOHelper uut = createUUT();
51
+ boolean result = uut.sendEventToJS("my-event", data, null);
52
+
53
+ assertFalse(result);
54
+ verify(mRCTDeviceEventEmitter, never()).emit(anyString(), any(WritableMap.class));
55
+ }
56
+
57
+ private JsIOHelper createUUT() {
58
+ return new JsIOHelper();
59
+ }
60
+ }