Skip to content

Commit 5ff5f54

Browse files
committed
Refactored code and added unit tests for firebase messaging service.
1 parent 1d11848 commit 5ff5f54

File tree

4 files changed

+261
-7
lines changed

4 files changed

+261
-7
lines changed

android/src/main/java/com/azure/reactnative/notificationhub/NotificationChannelBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ public class NotificationChannelBuilder {
1212
private boolean mEnableLights = true;
1313
private boolean mEnableVibration = true;
1414

15-
public NotificationChannelBuilder() {
15+
public static class Factory {
16+
public static NotificationChannelBuilder create() {
17+
return new NotificationChannelBuilder();
18+
}
19+
}
20+
21+
private NotificationChannelBuilder() {
1622
}
1723

1824
public NotificationChannel build() {

android/src/main/java/com/azure/reactnative/notificationhub/ReactNativeFirebaseMessagingService.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class ReactNativeFirebaseMessagingService extends FirebaseMessagingServic
2424
public static void createNotificationChannel(Context context) {
2525
if (notificationChannelID == null) {
2626
NotificationHubUtil notificationHubUtil = NotificationHubUtil.getInstance();
27-
NotificationChannelBuilder builder = new NotificationChannelBuilder();
27+
NotificationChannelBuilder builder = NotificationChannelBuilder.Factory.create();
2828
if (notificationHubUtil.hasChannelImportance(context)) {
2929
builder.setImportance(notificationHubUtil.getChannelImportance(context));
3030
}
@@ -52,6 +52,18 @@ public static void createNotificationChannel(Context context) {
5252
}
5353
}
5454

55+
public static void deleteNotificationChannel(Context context) {
56+
if (notificationChannelID != null) {
57+
final String channelToDeleteID = notificationChannelID;
58+
notificationChannelID = null;
59+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
60+
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
61+
Context.NOTIFICATION_SERVICE);
62+
notificationManager.deleteNotificationChannel(channelToDeleteID);
63+
}
64+
}
65+
}
66+
5567
@Override
5668
public void onNewToken(String token) {
5769
Log.i(TAG, "Refreshing FCM Registration Token");

sample/android/app/src/test/java/com/reactnativeazurenotificationhubsample/NotificationHubUtilTest.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
import static com.azure.reactnative.notificationhub.ReactNativeNotificationsHandler.RESOURCE_DEF_TYPE_RAW;
3737
import static com.azure.reactnative.notificationhub.ReactNativeNotificationsHandler.RESOURCE_NAME_LAUNCHER;
3838
import static com.azure.reactnative.notificationhub.ReactNativeNotificationsHandler.RESOURCE_NAME_NOTIFICATION;
39-
import static org.mockito.ArgumentMatchers.anyBoolean;
40-
import static org.mockito.ArgumentMatchers.anyInt;
4139
import static org.mockito.ArgumentMatchers.anyString;
4240
import static org.mockito.ArgumentMatchers.eq;
4341
import static org.mockito.Mockito.reset;
@@ -48,13 +46,10 @@
4846
import static org.powermock.api.mockito.PowerMockito.when;
4947

5048
import org.junit.runner.RunWith;
51-
import org.mockito.ArgumentCaptor;
5249
import org.mockito.Mock;
53-
import org.mockito.Mockito;
5450
import org.powermock.api.mockito.PowerMockito;
5551
import org.powermock.core.classloader.annotations.PrepareForTest;
5652
import org.powermock.modules.junit4.PowerMockRunner;
57-
import org.powermock.reflect.Whitebox;
5853

5954
import com.azure.reactnative.notificationhub.NotificationHubUtil;
6055
import com.azure.reactnative.notificationhub.ReactNativeNotificationHubModule;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
package com.reactnativeazurenotificationhubsample;
2+
3+
import android.app.NotificationChannel;
4+
import android.app.NotificationManager;
5+
import android.content.Context;
6+
import android.content.Intent;
7+
import android.os.Build;
8+
import android.os.Bundle;
9+
import android.util.Log;
10+
11+
import com.azure.reactnative.notificationhub.NotificationChannelBuilder;
12+
import com.azure.reactnative.notificationhub.NotificationHubUtil;
13+
import com.azure.reactnative.notificationhub.ReactNativeFirebaseMessagingService;
14+
import com.azure.reactnative.notificationhub.ReactNativeNotificationsHandler;
15+
import com.azure.reactnative.notificationhub.ReactNativeRegistrationIntentService;
16+
import com.facebook.react.bridge.ReactApplicationContext;
17+
import com.google.firebase.messaging.FirebaseMessagingService;
18+
import com.google.firebase.messaging.RemoteMessage;
19+
20+
import org.junit.Before;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.mockito.Mock;
24+
import org.powermock.api.mockito.PowerMockito;
25+
import org.powermock.core.classloader.annotations.PrepareForTest;
26+
import org.powermock.modules.junit4.PowerMockRunner;
27+
import org.powermock.reflect.Whitebox;
28+
29+
import static com.azure.reactnative.notificationhub.ReactNativeNotificationsHandler.KEY_REMOTE_NOTIFICATION_COLDSTART;
30+
import static com.azure.reactnative.notificationhub.ReactNativeNotificationsHandler.KEY_REMOTE_NOTIFICATION_FOREGROUND;
31+
import static com.azure.reactnative.notificationhub.ReactNativeNotificationsHandler.KEY_REMOTE_NOTIFICATION_USER_INTERACTION;
32+
import static org.mockito.ArgumentMatchers.any;
33+
import static org.mockito.ArgumentMatchers.anyBoolean;
34+
import static org.mockito.ArgumentMatchers.anyInt;
35+
import static org.mockito.ArgumentMatchers.eq;
36+
import static org.mockito.Mockito.reset;
37+
import static org.mockito.Mockito.times;
38+
import static org.mockito.Mockito.verify;
39+
import static org.powermock.api.mockito.PowerMockito.verifyStatic;
40+
import static org.powermock.api.mockito.PowerMockito.when;
41+
import static org.powermock.api.support.membermodification.MemberMatcher.methodsDeclaredIn;
42+
43+
/**
44+
* Unit tests for ReactNativeNotificationHubModule.
45+
*/
46+
@RunWith(PowerMockRunner.class)
47+
@PrepareForTest({
48+
NotificationHubUtil.class,
49+
ReactNativeNotificationsHandler.class,
50+
NotificationChannelBuilder.Factory.class,
51+
NotificationHubUtil.IntentFactory.class,
52+
Build.VERSION.class,
53+
FirebaseMessagingService.class,
54+
RemoteMessage.class,
55+
Log.class
56+
})
57+
public class ReactNativeFirebaseMessagingServiceTest {
58+
@Mock
59+
ReactApplicationContext mReactApplicationContext;
60+
61+
@Mock
62+
NotificationHubUtil mHubUtil;
63+
64+
@Mock
65+
NotificationManager mNotificationManager;
66+
67+
ReactNativeFirebaseMessagingService mMessagingService;
68+
69+
@Before
70+
public void setUp() {
71+
// Reset mocks
72+
reset(mHubUtil);
73+
reset(mReactApplicationContext);
74+
75+
// Prepare mock objects
76+
PowerMockito.mockStatic(NotificationHubUtil.class);
77+
when(NotificationHubUtil.getInstance()).thenReturn(mHubUtil);
78+
PowerMockito.mockStatic(ReactNativeNotificationsHandler.class);
79+
PowerMockito.mockStatic(NotificationChannelBuilder.Factory.class);
80+
PowerMockito.mockStatic(NotificationHubUtil.IntentFactory.class);
81+
PowerMockito.suppress(methodsDeclaredIn(FirebaseMessagingService.class));
82+
PowerMockito.mockStatic(Log.class);
83+
when(mReactApplicationContext.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(
84+
mNotificationManager);
85+
86+
// Reset channel
87+
ReactNativeFirebaseMessagingService.deleteNotificationChannel(mReactApplicationContext);
88+
reset(mNotificationManager);
89+
when(mReactApplicationContext.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(
90+
mNotificationManager);
91+
92+
mMessagingService = new ReactNativeFirebaseMessagingService();
93+
94+
}
95+
96+
@Test
97+
public void testCreateNotificationChannelBelowVersionO() {
98+
final int sdkVersion = Build.VERSION_CODES.LOLLIPOP;
99+
100+
NotificationChannelBuilder builder = PowerMockito.mock(NotificationChannelBuilder.class);
101+
when(NotificationChannelBuilder.Factory.create()).thenReturn(builder);
102+
when(mHubUtil.hasChannelImportance(mReactApplicationContext)).thenReturn(false);
103+
when(mHubUtil.hasChannelShowBadge(mReactApplicationContext)).thenReturn(false);
104+
when(mHubUtil.hasChannelEnableLights(mReactApplicationContext)).thenReturn(false);
105+
when(mHubUtil.hasChannelEnableVibration(mReactApplicationContext)).thenReturn(false);
106+
Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", sdkVersion);
107+
108+
ReactNativeFirebaseMessagingService.createNotificationChannel(mReactApplicationContext);
109+
110+
verify(builder, times(0)).setImportance(anyInt());
111+
verify(builder, times(0)).setShowBadge(anyBoolean());
112+
verify(builder, times(0)).enableLights(anyBoolean());
113+
verify(builder, times(0)).enableVibration(anyBoolean());
114+
verify(builder, times(0)).build();
115+
verify(mNotificationManager, times(0)).createNotificationChannel(
116+
any(NotificationChannel.class));
117+
}
118+
119+
@Test
120+
public void testCreateNotificationChannel() {
121+
final int channelImportance = 1;
122+
final boolean channelShowBadge = true;
123+
final boolean channelEnableLights = true;
124+
final boolean channelEnableVibration = true;
125+
final int sdkVersion = Build.VERSION_CODES.O;
126+
127+
NotificationChannelBuilder builder = PowerMockito.mock(NotificationChannelBuilder.class);
128+
when(NotificationChannelBuilder.Factory.create()).thenReturn(builder);
129+
NotificationChannel channel = PowerMockito.mock(NotificationChannel.class);
130+
when(channel.getId()).thenReturn(ReactNativeNotificationsHandler.NOTIFICATION_CHANNEL_ID);
131+
when(builder.build()).thenReturn(channel);
132+
when(mHubUtil.hasChannelImportance(mReactApplicationContext)).thenReturn(true);
133+
when(mHubUtil.getChannelImportance(mReactApplicationContext)).thenReturn(channelImportance);
134+
when(mHubUtil.hasChannelShowBadge(mReactApplicationContext)).thenReturn(true);
135+
when(mHubUtil.getChannelShowBadge(mReactApplicationContext)).thenReturn(channelShowBadge);
136+
when(mHubUtil.hasChannelEnableLights(mReactApplicationContext)).thenReturn(true);
137+
when(mHubUtil.getChannelEnableLights(mReactApplicationContext)).thenReturn(channelEnableLights);
138+
when(mHubUtil.hasChannelEnableVibration(mReactApplicationContext)).thenReturn(true);
139+
when(mHubUtil.getChannelEnableVibration(mReactApplicationContext)).thenReturn(channelEnableVibration);
140+
Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", sdkVersion);
141+
142+
ReactNativeFirebaseMessagingService.createNotificationChannel(mReactApplicationContext);
143+
144+
verify(mHubUtil, times(1)).hasChannelImportance(mReactApplicationContext);
145+
verify(builder, times(1)).setImportance(channelImportance);
146+
verify(mHubUtil, times(1)).hasChannelShowBadge(mReactApplicationContext);
147+
verify(builder, times(1)).setShowBadge(channelShowBadge);
148+
verify(mHubUtil, times(1)).hasChannelEnableLights(mReactApplicationContext);
149+
verify(builder, times(1)).enableLights(channelEnableLights);
150+
verify(mHubUtil, times(1)).hasChannelEnableVibration(mReactApplicationContext);
151+
verify(builder, times(1)).enableVibration(channelEnableVibration);
152+
verify(builder, times(1)).build();
153+
verify(mNotificationManager, times(1)).createNotificationChannel(
154+
any(NotificationChannel.class));
155+
}
156+
157+
@Test
158+
public void testDeleteNotificationChannel() {
159+
final int sdkVersion = Build.VERSION_CODES.O;
160+
161+
Whitebox.setInternalState(Build.VERSION.class, "SDK_INT", sdkVersion);
162+
163+
// Prepare channel
164+
NotificationChannelBuilder builder = PowerMockito.mock(NotificationChannelBuilder.class);
165+
when(NotificationChannelBuilder.Factory.create()).thenReturn(builder);
166+
NotificationChannel channel = PowerMockito.mock(NotificationChannel.class);
167+
when(channel.getId()).thenReturn(ReactNativeNotificationsHandler.NOTIFICATION_CHANNEL_ID);
168+
when(builder.build()).thenReturn(channel);
169+
ReactNativeFirebaseMessagingService.createNotificationChannel(mReactApplicationContext);
170+
171+
ReactNativeFirebaseMessagingService.deleteNotificationChannel(mReactApplicationContext);
172+
173+
verify(mNotificationManager, times(1)).deleteNotificationChannel(
174+
ReactNativeNotificationsHandler.NOTIFICATION_CHANNEL_ID);
175+
}
176+
177+
@Test
178+
public void testOnNewToken() {
179+
final String token = "Token";
180+
181+
mMessagingService.onNewToken(token);
182+
183+
verifyStatic(NotificationHubUtil.IntentFactory.class);
184+
NotificationHubUtil.IntentFactory.createIntent(
185+
any(), eq(ReactNativeRegistrationIntentService.class));
186+
}
187+
188+
@Test
189+
public void testOnMessageReceivedForeground() {
190+
RemoteMessage remoteMessage = PowerMockito.mock(RemoteMessage.class);
191+
Intent intent = PowerMockito.mock(Intent.class);
192+
Bundle bundle = PowerMockito.mock(Bundle.class);
193+
when(remoteMessage.toIntent()).thenReturn(intent);
194+
when(intent.getExtras()).thenReturn(bundle);
195+
when(mHubUtil.getAppIsForeground()).thenReturn(true);
196+
197+
// Prepare channel
198+
NotificationChannelBuilder builder = PowerMockito.mock(NotificationChannelBuilder.class);
199+
when(NotificationChannelBuilder.Factory.create()).thenReturn(builder);
200+
NotificationChannel channel = PowerMockito.mock(NotificationChannel.class);
201+
when(channel.getId()).thenReturn(ReactNativeNotificationsHandler.NOTIFICATION_CHANNEL_ID);
202+
when(builder.build()).thenReturn(channel);
203+
ReactNativeFirebaseMessagingService.createNotificationChannel(mReactApplicationContext);
204+
205+
mMessagingService.onMessageReceived(remoteMessage);
206+
207+
verify(bundle, times(1)).putBoolean(
208+
KEY_REMOTE_NOTIFICATION_FOREGROUND, true);
209+
verify(bundle, times(1)).putBoolean(
210+
KEY_REMOTE_NOTIFICATION_USER_INTERACTION, false);
211+
verify(bundle, times(1)).putBoolean(
212+
KEY_REMOTE_NOTIFICATION_COLDSTART, false);
213+
PowerMockito.verifyStatic(ReactNativeNotificationsHandler.class);
214+
ReactNativeNotificationsHandler.sendBroadcast(any(), eq(bundle), eq((long)0));
215+
}
216+
217+
@Test
218+
public void testOnMessageReceivedBackground() {
219+
RemoteMessage remoteMessage = PowerMockito.mock(RemoteMessage.class);
220+
Intent intent = PowerMockito.mock(Intent.class);
221+
Bundle bundle = PowerMockito.mock(Bundle.class);
222+
when(remoteMessage.toIntent()).thenReturn(intent);
223+
when(intent.getExtras()).thenReturn(bundle);
224+
when(mHubUtil.getAppIsForeground()).thenReturn(false);
225+
226+
// Prepare channel
227+
NotificationChannelBuilder builder = PowerMockito.mock(NotificationChannelBuilder.class);
228+
when(NotificationChannelBuilder.Factory.create()).thenReturn(builder);
229+
NotificationChannel channel = PowerMockito.mock(NotificationChannel.class);
230+
when(channel.getId()).thenReturn(ReactNativeNotificationsHandler.NOTIFICATION_CHANNEL_ID);
231+
when(builder.build()).thenReturn(channel);
232+
ReactNativeFirebaseMessagingService.createNotificationChannel(mReactApplicationContext);
233+
234+
mMessagingService.onMessageReceived(remoteMessage);
235+
236+
PowerMockito.verifyStatic(ReactNativeNotificationsHandler.class);
237+
ReactNativeNotificationsHandler.sendNotification(any(), eq(bundle), any());
238+
PowerMockito.verifyStatic(ReactNativeNotificationsHandler.class);
239+
ReactNativeNotificationsHandler.sendBroadcast(any(), eq(bundle), eq((long)0));
240+
}
241+
}

0 commit comments

Comments
 (0)