Skip to content

Commit fbb2c67

Browse files
committed
Simpler way to customize open action and misc fixes
* Now supports application meta-tag 'com.onesignal.NotificationOpened.DEFAULT' with the value 'DISABLE' to turn off the launching of the main Activity. - No longer need to create a BroadcastReceiver just to have your NotificationOpenedHandler fire in your Application class. * Fixed issue with deleteTag not working when the value is a number. * Added a number of checks around tag methods to make them consistent to what the REST API supports. * Fixed location warning. * Reverted back to Robolectric 3.0 as custom shadows in 3.1 were not working.
1 parent fdee97d commit fbb2c67

File tree

11 files changed

+380
-40
lines changed

11 files changed

+380
-40
lines changed

OneSignalSDK.jar

1.75 KB
Binary file not shown.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,7 @@ public static void resetRunnables() {
3737
public static void SyncService_onTaskRemoved() {
3838
SyncService.onTaskRemoved();
3939
}
40+
41+
42+
public class NotificationTable extends OneSignalDbContract.NotificationTable { }
4043
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.onesignal;
2+
3+
import android.util.Log;
4+
5+
import org.robolectric.annotation.Implements;
6+
7+
import java.util.HashSet;
8+
import java.util.Set;
9+
10+
@Implements(OneSignal.class)
11+
public class ShadowOneSignal {
12+
13+
public static String messages = "";
14+
15+
static void Log(final OneSignal.LOG_LEVEL level, String message, Throwable throwable) {
16+
messages += message;
17+
Log.e("", message, throwable);
18+
}
19+
}

OneSignalSDK/app/src/test/java/com/onesignal/ShadowPushRegistratorADM.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@
3333
public class ShadowPushRegistratorADM {
3434
public static boolean testNoClass = true;
3535

36-
public void __constructor__() throws ClassNotFoundException {
37-
if (testNoClass)
38-
throw new ClassNotFoundException();
39-
}
36+
// TODO: Does not compile in Robolectric 3.0, try 3.1 once it releases.
37+
// public void __constructor__() throws ClassNotFoundException {
38+
// if (testNoClass)
39+
// throw new ClassNotFoundException();
40+
// }
4041
}

OneSignalSDK/app/src/test/java/com/test/onesignal/CustomRobolectricTestRunner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public CustomRobolectricTestRunner(Class<?> klass) throws InitializationError {
3838
}
3939

4040
@Override
41-
public InstrumentationConfiguration createClassLoaderConfig(Config config) {
41+
public InstrumentationConfiguration createClassLoaderConfig() {
4242
return InstrumentationConfiguration.newBuilder().addInstrumentedPackage("com.onesignal").build();
4343
}
4444
}

OneSignalSDK/app/src/test/java/com/test/onesignal/GenerateNotificationRunner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import com.onesignal.ShadowRoboNotificationManager;
4545
import com.onesignal.ShadowRoboNotificationManager.PostedNotification;
4646
import com.onesignal.example.BlankActivity;
47-
import com.onesignal.OneSignalDbContract.NotificationTable;
47+
import com.onesignal.OneSignalPackagePrivateHelper.NotificationTable;
4848

4949
import junit.framework.Assert;
5050

OneSignalSDK/app/src/test/java/com/test/onesignal/MainOneSignalClassRunner.java

Lines changed: 217 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
import android.app.Activity;
3131
import android.app.Service;
3232
import android.content.Context;
33+
import android.content.Intent;
34+
import android.content.SharedPreferences;
35+
import android.content.pm.ActivityInfo;
36+
import android.content.pm.ResolveInfo;
3337
import android.net.ConnectivityManager;
3438
import android.os.Bundle;
3539

@@ -38,6 +42,7 @@
3842
import com.onesignal.OneSignal;
3943
import com.onesignal.ShadowLocationGMS;
4044
import com.onesignal.ShadowOSUtils;
45+
import com.onesignal.ShadowOneSignal;
4146
import com.onesignal.ShadowOneSignalRestClient;
4247
import com.onesignal.OneSignalPackagePrivateHelper;
4348
import com.onesignal.ShadowPushRegistratorADM;
@@ -58,6 +63,7 @@
5863
import org.robolectric.RuntimeEnvironment;
5964
import org.robolectric.Shadows;
6065
import org.robolectric.annotation.Config;
66+
import org.robolectric.shadows.ShadowApplication;
6167
import org.robolectric.shadows.ShadowConnectivityManager;
6268
import org.robolectric.shadows.ShadowLog;
6369
import org.robolectric.shadows.ShadowSystemClock;
@@ -67,7 +73,7 @@
6773

6874
@Config(packageName = "com.onesignal.example",
6975
constants = BuildConfig.class,
70-
shadows = {ShadowOneSignalRestClient.class, ShadowPushRegistratorGPS.class, ShadowPushRegistratorADM.class, ShadowOSUtils.class, ShadowLocationGMS.class},
76+
shadows = {ShadowOneSignalRestClient.class, ShadowPushRegistratorGPS.class, ShadowPushRegistratorADM.class, ShadowOSUtils.class},
7177
sdk = 21)
7278

7379
@RunWith(CustomRobolectricTestRunner.class)
@@ -117,6 +123,7 @@ public void beforeEachTest() throws Exception {
117123

118124
ShadowPushRegistratorGPS.fail = false;
119125
notificationOpenedMessage = null;
126+
lastGetTags = null;
120127
}
121128

122129
@Test
@@ -222,6 +229,41 @@ public void notificationOpened(String message, JSONObject additionalData, boolea
222229
threadWait();
223230
}
224231

232+
@Test
233+
public void testOpeningLauncherActivity() throws Exception {
234+
AddLauncherIntentFilter();
235+
236+
// From app launching normally
237+
Assert.assertNotNull(Shadows.shadowOf(blankActivity).getNextStartedActivity());
238+
239+
OneSignal.handleNotificationOpened(blankActivity, new JSONArray("[{ \"alert\": \"Test Msg\", \"custom\": { \"i\": \"UUID\" } }]"), false);
240+
241+
Assert.assertNotNull(Shadows.shadowOf(blankActivity).getNextStartedActivity());
242+
Assert.assertNull(Shadows.shadowOf(blankActivity).getNextStartedActivity());
243+
}
244+
245+
@Test
246+
public void testDisableOpeningLauncherActivityOnNotifiOpen() throws Exception {
247+
ShadowApplication.getInstance().getAppManifest().getApplicationMetaData().put("com.onesignal.NotificationOpened.DEFAULT", "DISABLE");
248+
RuntimeEnvironment.getRobolectricPackageManager().addManifest(ShadowApplication.getInstance().getAppManifest(), ShadowApplication.getInstance().getResourceLoader());
249+
AddLauncherIntentFilter();
250+
251+
// From app launching normally
252+
Assert.assertNotNull(Shadows.shadowOf(blankActivity).getNextStartedActivity());
253+
OneSignal.init(blankActivity, "123456789", ONESIGNAL_APP_ID, new OneSignal.NotificationOpenedHandler() {
254+
@Override
255+
public void notificationOpened(String message, JSONObject additionalData, boolean isActive) {
256+
notificationOpenedMessage = message;
257+
}
258+
});
259+
Assert.assertNull(notificationOpenedMessage);
260+
261+
OneSignal.handleNotificationOpened(blankActivity, new JSONArray("[{ \"alert\": \"Test Msg\", \"custom\": { \"i\": \"UUID\" } }]"), false);
262+
263+
Assert.assertNull(Shadows.shadowOf(blankActivity).getNextStartedActivity());
264+
Assert.assertEquals("Test Msg", notificationOpenedMessage);
265+
}
266+
225267
@Test
226268
public void testNotificationReceivedWhenAppInFocus() throws Exception {
227269
OneSignal.init(blankActivity, "123456789", ONESIGNAL_APP_ID, new OneSignal.NotificationOpenedHandler() {
@@ -505,7 +547,6 @@ public void shouldSendTagsWithRequestBatching() throws Exception {
505547
@Override
506548
public void tagsAvailable(JSONObject tags) {
507549
lastGetTags = tags;
508-
System.out.println("tags: " + tags);
509550
}
510551
});
511552
threadAndTaskWait();
@@ -517,6 +558,62 @@ public void tagsAvailable(JSONObject tags) {
517558
Assert.assertEquals(2, ShadowOneSignalRestClient.networkCallCount);
518559
}
519560

561+
@Test
562+
public void testOldIntValues() throws Exception {
563+
final SharedPreferences prefs = blankActivity.getSharedPreferences(OneSignal.class.getSimpleName(), Context.MODE_PRIVATE);
564+
SharedPreferences.Editor editor = prefs.edit();
565+
editor.putString("ONESIGNAL_USERSTATE_SYNCVALYES_CURRENT_STATE", "{\"tags\": {\"int\": 123}}");
566+
editor.putString("ONESIGNAL_USERSTATE_SYNCVALYES_TOSYNC_STATE", "{\"tags\": {\"int\": 123}}");
567+
editor.commit();
568+
569+
OneSignalInit();
570+
threadAndTaskWait();
571+
System.out.println("Saved state: " + prefs.getString("ONESIGNAL_USERSTATE_SYNCVALYES_CURRENT_STATE", null));
572+
System.out.println("Deleting tag");
573+
OneSignal.deleteTag("int");
574+
threadAndTaskWait();
575+
576+
lastGetTags = null;
577+
OneSignal.getTags(new OneSignal.GetTagsHandler() {
578+
@Override
579+
public void tagsAvailable(JSONObject tags) {
580+
System.out.println("tags: " + tags);
581+
lastGetTags = tags;
582+
}
583+
});
584+
585+
final SharedPreferences prefs2 = blankActivity.getSharedPreferences(OneSignal.class.getSimpleName(), Context.MODE_PRIVATE);
586+
System.out.println("Saved state: " + prefs2.getString("ONESIGNAL_USERSTATE_SYNCVALYES_CURRENT_STATE", null));
587+
588+
System.out.println("lastGetTags: " + lastGetTags);
589+
Assert.assertNull(lastGetTags);
590+
}
591+
592+
@Test
593+
public void testSendTagNonStringValues() throws Exception {
594+
OneSignalInit();
595+
OneSignal.sendTags("{\"int\": 122, \"bool\": true, \"null\": null, \"array\": [123], \"object\": {}}");
596+
OneSignal.getTags(new OneSignal.GetTagsHandler() {
597+
@Override
598+
public void tagsAvailable(JSONObject tags) {
599+
lastGetTags = tags;
600+
}
601+
});
602+
603+
System.out.println(lastGetTags);
604+
605+
Assert.assertEquals(String.class, lastGetTags.get("int").getClass());
606+
Assert.assertEquals("122", lastGetTags.get("int"));
607+
Assert.assertEquals(String.class, lastGetTags.get("bool").getClass());
608+
Assert.assertEquals("true", lastGetTags.get("bool"));
609+
610+
// null should be the same as a blank string.
611+
Assert.assertFalse(lastGetTags.has("null"));
612+
613+
Assert.assertFalse(lastGetTags.has("array"));
614+
Assert.assertFalse(lastGetTags.has("object"));
615+
}
616+
520617
@Test
521618
public void shouldSaveToSyncIfKilledBeforeDelayedCompare() throws Exception {
522619
OneSignalInit();
@@ -559,8 +656,95 @@ public void shouldNotCrashIfOnTaskRemovedIsCalledBeforeInitIsDone() {
559656
OneSignalPackagePrivateHelper.SyncService_onTaskRemoved();
560657
}
561658

659+
@Test
660+
public void testMethodCallsBeforeInit() throws Exception {
661+
OneSignal.sendTag("key", "value");
662+
OneSignal.sendTags("{\"key\": \"value\"}");
663+
OneSignal.deleteTag("key");
664+
OneSignal.deleteTags("[\"key1\", \"key2\"]");
665+
OneSignal.setSubscription(false);
666+
OneSignal.enableVibrate(false);
667+
OneSignal.enableSound(false);
668+
OneSignal.promptLocation();
669+
OneSignal.postNotification("{}", new OneSignal.PostNotificationResponseHandler() {
670+
@Override
671+
public void onSuccess(JSONObject response) {
672+
}
673+
674+
@Override
675+
public void onFailure(JSONObject response) {
676+
}
677+
});
678+
OneSignalInit();
679+
threadAndTaskWait();
680+
}
681+
682+
// ####### DeleteTags Tests ######
683+
@Test
684+
public void testDeleteTags() throws Exception {
685+
OneSignalInit();
686+
OneSignal.sendTags("{\"str\": \"str1\", \"int\": 122, \"bool\": true}");
687+
OneSignal.deleteTag("int");
688+
OneSignal.getTags(new OneSignal.GetTagsHandler() {
689+
@Override
690+
public void tagsAvailable(JSONObject tags) {
691+
lastGetTags = tags;
692+
}
693+
});
694+
695+
System.out.println("lastGetTags: " + lastGetTags);
696+
Assert.assertFalse(lastGetTags.has("int"));
697+
lastGetTags = null;
698+
699+
// Makes sure they get sent
700+
OneSignal.sendTags("{\"str\": \"str1\", \"int\": 122, \"bool\": true}");
701+
threadAndTaskWait();
702+
Assert.assertEquals("str1", ShadowOneSignalRestClient.lastPost.getJSONObject("tags").get("str"));
703+
704+
OneSignal.deleteTag("int");
705+
706+
OneSignal.getTags(new OneSignal.GetTagsHandler() {
707+
@Override
708+
public void tagsAvailable(JSONObject tags) {
709+
lastGetTags = tags;
710+
}
711+
});
712+
713+
System.out.println("lastGetTags: " + lastGetTags);
714+
Assert.assertFalse(lastGetTags.has("int"));
715+
716+
// After the success response it should not store a "" string when saving to storage.
717+
threadAndTaskWait();
718+
719+
final SharedPreferences prefs = blankActivity.getSharedPreferences(OneSignal.class.getSimpleName(), Context.MODE_PRIVATE);
720+
String syncValues = prefs.getString("ONESIGNAL_USERSTATE_SYNCVALYES_CURRENT_STATE", null);
721+
Assert.assertFalse(new JSONObject(syncValues).has("tags"));
722+
}
723+
724+
@Test
725+
public void testOmitDeletesOfNonExistingKeys() throws Exception {
726+
OneSignalInit();
727+
OneSignal.deleteTag("this_key_does_not_exist");
728+
threadAndTaskWait();
729+
730+
Assert.assertFalse(ShadowOneSignalRestClient.lastPost.has("tags"));
731+
}
732+
733+
562734
// ####### GetTags Tests ########
563735

736+
public void testGetTagsWithNoTagsShouldBeNull() throws Exception {
737+
OneSignalInit();
738+
OneSignal.getTags(new OneSignal.GetTagsHandler() {
739+
@Override
740+
public void tagsAvailable(JSONObject tags) {
741+
lastGetTags = tags;
742+
}
743+
});
744+
745+
Assert.assertNull(lastGetTags);
746+
}
747+
564748
@Test
565749
public void shouldGetTags() throws Exception {
566750
OneSignalInit();
@@ -642,6 +826,7 @@ public void shouldNotDoubleCountFocusTime() throws Exception {
642826
// ####### Unit Test Location ########
643827

644828
@Test
829+
@Config(shadows = {ShadowLocationGMS.class})
645830
public void shouldUpdateAllLocationFieldsWhenAnyFieldsChange() throws Exception {
646831
OneSignalInit();
647832
threadAndTaskWait();
@@ -663,6 +848,22 @@ public void shouldUpdateAllLocationFieldsWhenAnyFieldsChange() throws Exception
663848
Assert.assertEquals(0.0, ShadowOneSignalRestClient.lastPost.getDouble("loc_type"));
664849
}
665850

851+
@Test
852+
@Config(shadows = {ShadowOneSignal.class})
853+
public void testLocationTimeout() throws Exception {
854+
//ShadowApplication.getInstance().grantPermissions(new String[]{"android.permission.YOUR_PERMISSION"});
855+
856+
OneSignalInit();
857+
threadAndTaskWait();
858+
859+
Class klass = Class.forName("com.onesignal.LocationGMS");
860+
klass.getDeclaredMethod("startFallBackThread").invoke(null);
861+
klass.getDeclaredMethod("fireFailedComplete").invoke(null);
862+
threadAndTaskWait();
863+
864+
Assert.assertFalse(ShadowOneSignal.messages.contains("GoogleApiClient timedout"));
865+
}
866+
666867
// ####### Unit test helper methods ########
667868

668869
private static void threadWait() {
@@ -685,4 +886,18 @@ private void OneSignalInit() {
685886
private void OneSignalInitWithBadProjectNum() {
686887
OneSignal.init(blankActivity, "NOT A VALID Google project number", ONESIGNAL_APP_ID);
687888
}
889+
890+
// For some reason Roboelctric does not automatically add this when it reads the AndroidManifest.xml
891+
// Also it seems it has to be done in the test itself instead of the setup process.
892+
private static void AddLauncherIntentFilter() {
893+
Intent launchIntent = new Intent(Intent.ACTION_MAIN);
894+
launchIntent.setPackage("com.onesignal.example");
895+
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
896+
ResolveInfo resolveInfo = new ResolveInfo();
897+
resolveInfo.activityInfo = new ActivityInfo();
898+
resolveInfo.activityInfo.packageName = "com.onesignal.example";
899+
resolveInfo.activityInfo.name = "MainActivity";
900+
901+
RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(launchIntent, resolveInfo);
902+
}
688903
}

0 commit comments

Comments
 (0)