Skip to content

Commit 42217ef

Browse files
committed
Added tests for NotificationChannelManager
1 parent a5b31f4 commit 42217ef

File tree

4 files changed

+239
-68
lines changed

4 files changed

+239
-68
lines changed

OneSignalSDK/onesignal/src/main/java/com/onesignal/NotificationChannelManager.java

Lines changed: 97 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
import org.json.JSONObject;
4242

4343
import java.math.BigInteger;
44+
import java.util.HashSet;
45+
import java.util.List;
46+
import java.util.Set;
4447

4548
class NotificationChannelManager {
4649

@@ -51,89 +54,90 @@ class NotificationChannelManager {
5154
private static final String DEFAULT_CHANNEL_ID = "fcm_fallback_notification_channel";
5255

5356
static String createNotificationChannel(Context context, JSONObject jsonPayload) {
54-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Build.VERSION.SDK_INT: " + Build.VERSION.SDK_INT);
5557
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
5658
return DEFAULT_CHANNEL_ID;
5759

58-
JSONObject payload = jsonPayload;
59-
6060
// To test with additional data
61-
// JSONObject customJson = null;
62-
// try {
63-
// customJson = new JSONObject(jsonPayload.optString("custom"));
64-
// } catch (JSONException e) {
65-
// e.printStackTrace();
66-
// }
67-
// JSONObject payload = customJson.optJSONObject("a");
61+
JSONObject customJson = null;
62+
try {
63+
customJson = new JSONObject(jsonPayload.optString("custom"));
64+
} catch (JSONException e) {
65+
e.printStackTrace();
66+
}
67+
jsonPayload = customJson.optJSONObject("a");
6868

6969
NotificationManager notificationManager =
70-
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
70+
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
7171

7272
// TODO: Check for oth_chnl key, if this existing and chanel is already registered use this id
7373
// to allow any channels created outside of the SDK.
7474

75-
if (!payload.has("chnl"))
75+
if (!jsonPayload.has("chnl"))
7676
return createDefaultChannel(notificationManager);
77-
77+
7878
try {
79-
JSONObject channelPayload = payload.getJSONObject("chnl");
80-
81-
String channel_id = channelPayload.optString("id", DEFAULT_CHANNEL_ID);
82-
// Ensure we don't try to use the system reserved id
83-
if (channel_id.equals(NotificationChannel.DEFAULT_CHANNEL_ID))
84-
channel_id = DEFAULT_CHANNEL_ID;
85-
86-
int importance = channelPayload.optInt("imp", NotificationManager.IMPORTANCE_DEFAULT);
87-
String channel_name = channelPayload.optString("nm", "Miscellaneous");
88-
89-
NotificationChannel channel = new NotificationChannel(channel_id, channel_name, importance);
90-
91-
if (channelPayload.has("grp")) {
92-
String group_id = channelPayload.optString("grp");
93-
CharSequence group_name = channelPayload.optString("grp_nm");
94-
notificationManager.createNotificationChannelGroup(new NotificationChannelGroup(group_id, group_name));
95-
channel.setGroup(group_id);
96-
}
97-
98-
channel.enableLights(channelPayload.optBoolean("lght", true));
99-
if (channelPayload.has("ledc")) {
100-
BigInteger ledColor = new BigInteger(channelPayload.optString("ledc"), 16);
101-
channel.setLightColor(ledColor.intValue());
102-
}
103-
104-
channel.enableVibration(channelPayload.optBoolean("vib", true));
105-
if (channelPayload.has("vib_pt")) {
106-
JSONArray json_vib_array = channelPayload.optJSONArray("vib_pt");
107-
long[] long_array = new long[json_vib_array.length()];
108-
for (int i = 0; i < json_vib_array.length(); i++)
109-
long_array[i] = json_vib_array.optLong(i);
110-
channel.setVibrationPattern(long_array);
111-
}
112-
113-
if (channelPayload.has("snd_nm")) {
114-
// Sound will only play if Importance is set to High or Urgent
115-
Uri uri = OSUtils.getSoundUri(context, channelPayload.optString("snd_nm", null));
116-
if (uri!= null)
117-
channel.setSound(uri, null);
118-
}
119-
else if (!channelPayload.optBoolean("snd", true))
120-
channel.setSound(null, null);
121-
// Setting sound to null makes it 'None' in the Settings.
122-
// Otherwise not calling setSound makes it the default notification sound.
123-
124-
channel.setLockscreenVisibility(channelPayload.optInt("lck", Notification.VISIBILITY_PUBLIC));
125-
channel.enableVibration(channelPayload.optBoolean("lght", true));
126-
channel.setShowBadge(channelPayload.optBoolean("bdg", true));
127-
channel.setBypassDnd(channelPayload.optBoolean("bdnd", false));
128-
129-
notificationManager.createNotificationChannel(channel);
130-
return channel_id;
79+
return createChannel(context, notificationManager, jsonPayload);
13180
} catch (JSONException e) {
132-
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Count not create notification channel due to JSON payload error!", e);
81+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Could not create notification channel due to JSON payload error!", e);
13382
}
13483

13584
return DEFAULT_CHANNEL_ID;
13685
}
86+
87+
@RequiresApi(api = Build.VERSION_CODES.O)
88+
private static String createChannel(Context context, NotificationManager notificationManager, JSONObject payload) throws JSONException {
89+
JSONObject channelPayload = payload.getJSONObject("chnl");
90+
91+
String channel_id = channelPayload.optString("id", DEFAULT_CHANNEL_ID);
92+
// Ensure we don't try to use the system reserved id
93+
if (channel_id.equals(NotificationChannel.DEFAULT_CHANNEL_ID))
94+
channel_id = DEFAULT_CHANNEL_ID;
95+
96+
int importance = channelPayload.optInt("imp", NotificationManager.IMPORTANCE_DEFAULT);
97+
String channel_name = channelPayload.optString("nm", "Miscellaneous");
98+
99+
NotificationChannel channel = new NotificationChannel(channel_id, channel_name, importance);
100+
101+
if (channelPayload.has("grp")) {
102+
String group_id = channelPayload.optString("grp");
103+
CharSequence group_name = channelPayload.optString("grp_nm");
104+
notificationManager.createNotificationChannelGroup(new NotificationChannelGroup(group_id, group_name));
105+
channel.setGroup(group_id);
106+
}
107+
108+
channel.enableLights(channelPayload.optBoolean("lght", true));
109+
if (channelPayload.has("ledc")) {
110+
BigInteger ledColor = new BigInteger(channelPayload.optString("ledc"), 16);
111+
channel.setLightColor(ledColor.intValue());
112+
}
113+
114+
channel.enableVibration(channelPayload.optBoolean("vib", true));
115+
if (channelPayload.has("vib_pt")) {
116+
JSONArray json_vib_array = channelPayload.optJSONArray("vib_pt");
117+
long[] long_array = new long[json_vib_array.length()];
118+
for (int i = 0; i < json_vib_array.length(); i++)
119+
long_array[i] = json_vib_array.optLong(i);
120+
channel.setVibrationPattern(long_array);
121+
}
122+
123+
if (channelPayload.has("snd_nm")) {
124+
// Sound will only play if Importance is set to High or Urgent
125+
Uri uri = OSUtils.getSoundUri(context, channelPayload.optString("snd_nm", null));
126+
if (uri!= null)
127+
channel.setSound(uri, null);
128+
}
129+
else if (!channelPayload.optBoolean("snd", true))
130+
channel.setSound(null, null);
131+
// Setting sound to null makes it 'None' in the Settings.
132+
// Otherwise not calling setSound makes it the default notification sound.
133+
134+
channel.setLockscreenVisibility(channelPayload.optInt("lck", Notification.VISIBILITY_PUBLIC));
135+
channel.setShowBadge(channelPayload.optBoolean("bdg", true));
136+
channel.setBypassDnd(channelPayload.optBoolean("bdnd", false));
137+
138+
notificationManager.createNotificationChannel(channel);
139+
return channel_id;
140+
}
137141

138142
@RequiresApi(api = Build.VERSION_CODES.O)
139143
private static String createDefaultChannel(NotificationManager notificationManager) {
@@ -151,7 +155,32 @@ private static String createDefaultChannel(NotificationManager notificationManag
151155
// TODO: 1. Check JSONObject for a chnl_lst key.
152156
// 2. Create a set of new channels.
153157
// 3. Remove any other 'OS_' not defined in this payload
154-
private static void processChannelList(JSONObject payload) {
155-
158+
static void processChannelList(Context context, JSONObject payload) {
159+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
160+
return;
161+
162+
if (!payload.has("chnl_lst"))
163+
return;
164+
165+
NotificationManager notificationManager =
166+
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
167+
168+
Set<String> sycnedChannelSet = new HashSet<>();
169+
JSONArray chnlList = payload.optJSONArray("chnl_lst");
170+
int jsonArraySize = chnlList.length();
171+
for (int i = 0; i < jsonArraySize; i++) {
172+
try {
173+
sycnedChannelSet.add(createChannel(context, notificationManager, payload));
174+
} catch (JSONException e) {
175+
OneSignal.Log(OneSignal.LOG_LEVEL.ERROR, "Could not create notification channel due to JSON payload error!", e);
176+
}
177+
}
178+
179+
List<NotificationChannel> existingChannels = notificationManager.getNotificationChannels();
180+
for(NotificationChannel existingChannel : existingChannels) {
181+
String id = existingChannel.getId();
182+
if (id.startsWith("OS_") && !sycnedChannelSet.contains(id))
183+
notificationManager.deleteNotificationChannel(id);
184+
}
156185
}
157186
}

OneSignalSDK/unittest/src/test/java/com/onesignal/OneSignalPackagePrivateHelper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ public static class NotificationGenerationJob extends com.onesignal.Notification
9090
}
9191
}
9292

93+
public static String NotificationChannelManager_createNotificationChannel(Context context, JSONObject payload) {
94+
return NotificationChannelManager.createNotificationChannel(context, payload);
95+
}
96+
9397
// public interface BundleCompat<T> extends com.onesignal.BundleCompat {}
9498

9599

OneSignalSDK/unittest/src/test/java/com/onesignal/ShadowRoboNotificationManager.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727

2828
package com.onesignal;
2929

30+
import android.app.NotificationChannel;
3031
import android.app.Notification;
32+
import android.app.NotificationChannelGroup;
3133
import android.app.NotificationManager;
3234

3335
import org.robolectric.annotation.Implements;
@@ -90,4 +92,14 @@ public void notify(String tag, int id, Notification notification) {
9092
super.notify(tag, id, notification);
9193
}
9294

95+
public static NotificationChannel lastChannel;
96+
public void createNotificationChannel(NotificationChannel channel) {
97+
lastChannel = channel;
98+
}
99+
100+
public static NotificationChannelGroup lastChannelGroup;
101+
public void createNotificationChannelGroup(NotificationChannelGroup group) {
102+
lastChannelGroup = group;
103+
}
104+
93105
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package com.test.onesignal;
2+
3+
import android.app.Notification;
4+
import android.app.NotificationChannel;
5+
import android.app.NotificationChannelGroup;
6+
import android.app.NotificationManager;
7+
8+
import com.onesignal.ShadowOSUtils;
9+
import com.onesignal.ShadowRoboNotificationManager;
10+
import com.onesignal.example.BlankActivity;
11+
12+
import org.json.JSONArray;
13+
import org.json.JSONObject;
14+
import org.junit.Before;
15+
import org.junit.BeforeClass;
16+
import org.junit.Test;
17+
import org.junit.runner.RunWith;
18+
import org.robolectric.Robolectric;
19+
import org.robolectric.RobolectricTestRunner;
20+
import org.robolectric.android.controller.ActivityController;
21+
import org.robolectric.annotation.Config;
22+
import org.robolectric.shadows.ShadowLog;
23+
24+
import static com.onesignal.OneSignalPackagePrivateHelper.NotificationChannelManager_createNotificationChannel;
25+
import static org.junit.Assert.assertFalse;
26+
import static junit.framework.TestCase.assertTrue;
27+
import static org.junit.Assert.assertArrayEquals;
28+
import static org.junit.Assert.assertEquals;
29+
import static org.junit.Assert.assertNotNull;
30+
31+
@Config(packageName = "com.onesignal.example",
32+
shadows = {
33+
ShadowOSUtils.class,
34+
ShadowRoboNotificationManager.class},
35+
instrumentedPackages = {"com.onesignal"},
36+
sdk = 10000)
37+
@RunWith(RobolectricTestRunner.class)
38+
public class NotificationChannelManagerRunner {
39+
40+
private BlankActivity blankActivity;
41+
42+
@BeforeClass // Runs only once, before any tests
43+
public static void setUpClass() throws Exception {
44+
ShadowLog.stream = System.out;
45+
}
46+
47+
@Before
48+
public void beforeEachTest() throws Exception {
49+
ActivityController<BlankActivity> blankActivityController = Robolectric.buildActivity(BlankActivity.class).create();
50+
blankActivity = blankActivityController.get();
51+
}
52+
53+
@Test
54+
public void createNotificationChannelShouldReturnDefaultChannelWithEmptyPayload() throws Exception {
55+
JSONObject payload = new JSONObject();
56+
57+
String ret = NotificationChannelManager_createNotificationChannel(blankActivity, payload);
58+
59+
assertEquals("fcm_fallback_notification_channel", ret);
60+
NotificationChannel lastChannel = ShadowRoboNotificationManager.lastChannel;
61+
assertEquals("fcm_fallback_notification_channel", lastChannel.getId());
62+
assertNotNull(lastChannel.getSound());
63+
assertTrue(lastChannel.shouldShowLights());
64+
assertTrue(lastChannel.shouldVibrate());
65+
}
66+
67+
@Test
68+
public void createNotificationChannelCreateBasicChannel() throws Exception {
69+
JSONObject payload = new JSONObject();
70+
JSONObject chnl = new JSONObject();
71+
chnl.put("id", "test_id");
72+
payload.put("chnl", chnl);
73+
74+
String ret = NotificationChannelManager_createNotificationChannel(blankActivity, payload);
75+
76+
NotificationChannel channel = ShadowRoboNotificationManager.lastChannel;
77+
assertEquals("test_id", ret);
78+
assertEquals("test_id", ShadowRoboNotificationManager.lastChannel.getId());
79+
assertNotNull(channel.getSound());
80+
assertTrue(channel.shouldShowLights());
81+
assertTrue(channel.shouldVibrate());
82+
}
83+
84+
@Test
85+
public void createNotificationChannelWithALlOptionsl() throws Exception {
86+
JSONObject payload = new JSONObject();
87+
JSONObject chnl = new JSONObject();
88+
89+
chnl.put("id", "test_id");
90+
chnl.put("nm", "Test Name");
91+
chnl.put("grp", "grp_id");
92+
chnl.put("grp_nm", "Group Name");
93+
chnl.put("imp", NotificationManager.IMPORTANCE_MAX);
94+
chnl.put("lght", false);
95+
chnl.put("ledc", "FFFF0000");
96+
chnl.put("vib", false);
97+
chnl.put("vib_pt", new JSONArray("[1,2,3,4]"));
98+
chnl.put("snd_nm", "notification");
99+
chnl.put("lck", Notification.VISIBILITY_SECRET);
100+
chnl.put("bdg", true);
101+
chnl.put("bdnd", true);
102+
103+
payload.put("chnl", chnl);
104+
105+
String ret = NotificationChannelManager_createNotificationChannel(blankActivity, payload);
106+
107+
NotificationChannel channel = ShadowRoboNotificationManager.lastChannel;
108+
assertEquals("test_id", ret);
109+
assertEquals("test_id", ShadowRoboNotificationManager.lastChannel.getId());
110+
assertEquals("Test Name", channel.getName());
111+
assertEquals("grp_id", channel.getGroup());
112+
NotificationChannelGroup group = ShadowRoboNotificationManager.lastChannelGroup;
113+
assertEquals("grp_id", group.getId());
114+
assertEquals("Group Name", group.getName());
115+
assertNotNull(channel.getSound());
116+
assertFalse(channel.shouldShowLights());
117+
assertEquals(-65536, channel.getLightColor());
118+
assertTrue(channel.shouldVibrate()); // Setting a pattern enables vibration
119+
assertArrayEquals(new long[]{1,2,3,4}, channel.getVibrationPattern());
120+
assertEquals(NotificationManager.IMPORTANCE_MAX, channel.getImportance());
121+
assertEquals("content://settings/system/notification_sound", channel.getSound().toString());
122+
assertEquals(Notification.VISIBILITY_SECRET, channel.getLockscreenVisibility());
123+
assertTrue(channel.canShowBadge());
124+
assertTrue(channel.canBypassDnd());
125+
}
126+
}

0 commit comments

Comments
 (0)