diff --git a/parse/build.gradle b/parse/build.gradle index 9921801c4..b362f628a 100644 --- a/parse/build.gradle +++ b/parse/build.gradle @@ -81,7 +81,7 @@ tasks.withType(Test) { jacoco.includeNoLocationClasses = true jacoco.excludes = ['jdk.internal.*'] testLogging { - events "passed", "skipped", "failed", "standardOut", "standardError" + events "failed" } } diff --git a/parse/src/main/java/com/parse/ParseCommandCache.java b/parse/src/main/java/com/parse/ParseCommandCache.java index 2fc7dfe50..5d09a1823 100644 --- a/parse/src/main/java/com/parse/ParseCommandCache.java +++ b/parse/src/main/java/com/parse/ParseCommandCache.java @@ -144,7 +144,9 @@ public static int getPendingCount() { public void onDestroy() { // TODO (grantland): pause #6484855 - notifier.removeListener(listener); + if (notifier != null) { + notifier.removeListener(listener); + } } // Set the maximum number of times to retry before assuming disconnection. diff --git a/parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java b/parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java index e94b30a98..ff9eeba91 100644 --- a/parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java +++ b/parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java @@ -426,18 +426,17 @@ protected NotificationCompat.Builder getNotification(Context context, Intent int Intent deleteIntent = getDeleteIntent(extras, packageName); + int pendingIntentFlags = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.R + ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE + : PendingIntent.FLAG_UPDATE_CURRENT; + PendingIntent pContentIntent = PendingIntent.getBroadcast( - context, - contentIntentRequestCode, - contentIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + context, contentIntentRequestCode, contentIntent, pendingIntentFlags); PendingIntent pDeleteIntent = PendingIntent.getBroadcast( - context, - deleteIntentRequestCode, - deleteIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + context, deleteIntentRequestCode, deleteIntent, pendingIntentFlags); String channelId = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { diff --git a/parse/src/test/java/com/parse/ParsePushBroadcastReceiverTest.java b/parse/src/test/java/com/parse/ParsePushBroadcastReceiverTest.java new file mode 100644 index 000000000..61ed5e49d --- /dev/null +++ b/parse/src/test/java/com/parse/ParsePushBroadcastReceiverTest.java @@ -0,0 +1,174 @@ +package com.parse; + +import static androidx.core.app.NotificationCompat.EXTRA_TEXT; +import static androidx.core.app.NotificationCompat.EXTRA_TITLE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.content.Intent; +import androidx.core.app.NotificationCompat; +import java.util.HashMap; +import java.util.Map; +import org.json.JSONObject; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class ParsePushBroadcastReceiverTest extends ResetPluginsParseTest { + + @Before + public void setUp() throws Exception { + super.setUp(); + + Parse.Configuration configuration = + new Parse.Configuration.Builder(RuntimeEnvironment.application) + .applicationId(BuildConfig.LIBRARY_PACKAGE_NAME) + .server("https://api.parse.com/1") + .build(); + + ParsePlugins plugins = mock(ParsePlugins.class); + when(plugins.configuration()).thenReturn(configuration); + when(plugins.applicationContext()).thenReturn(RuntimeEnvironment.application); + Parse.initialize(configuration, plugins); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + ParseCorePlugins.getInstance().reset(); + ParsePlugins.reset(); + Parse.destroy(); + } + + @Test + public void testBuildNotification() { + final ParsePushBroadcastReceiver broadcastReceiver = new ParsePushBroadcastReceiver(); + final Map map = new HashMap(); + map.put("alert", "alert"); + map.put("title", "title"); + + final String notificationPayload = new JSONObject(map).toString(); + + final Intent intent = new Intent(); + intent.putExtra(ParsePushBroadcastReceiver.KEY_PUSH_DATA, notificationPayload); + + final NotificationCompat.Builder notification = + broadcastReceiver.getNotification( + RuntimeEnvironment.getApplication().getApplicationContext(), intent); + + assertNotNull(notification); + } + + @Test + public void testBuildNotificationReturnsNullOnInvalidPayload() { + final ParsePushBroadcastReceiver broadcastReceiver = new ParsePushBroadcastReceiver(); + final Intent intent = new Intent(); + intent.putExtra(ParsePushBroadcastReceiver.KEY_PUSH_DATA, "{\"json\": broken json}"); + + final NotificationCompat.Builder notification = + broadcastReceiver.getNotification( + RuntimeEnvironment.getApplication().getApplicationContext(), intent); + + assertNull(notification); + } + + @Test + public void testBuildNotificationReturnsNullOnMissingTitleAndAlert() { + final ParsePushBroadcastReceiver broadcastReceiver = new ParsePushBroadcastReceiver(); + final Map map = new HashMap(); + + final String notificationPayload = new JSONObject(map).toString(); + + final Intent intent = new Intent(); + intent.putExtra(ParsePushBroadcastReceiver.KEY_PUSH_DATA, notificationPayload); + + final NotificationCompat.Builder notification = + broadcastReceiver.getNotification( + RuntimeEnvironment.getApplication().getApplicationContext(), intent); + + assertNull(notification); + } + + @Test + public void testNotificationBuilderWhenAlertNotProvidedSetFallback() { + final ParsePushBroadcastReceiver broadcastReceiver = new ParsePushBroadcastReceiver(); + final Map map = new HashMap(); + map.put("title", "title"); + + final String notificationPayload = new JSONObject(map).toString(); + + final Intent intent = new Intent(); + intent.putExtra(ParsePushBroadcastReceiver.KEY_PUSH_DATA, notificationPayload); + + final NotificationCompat.Builder notification = + broadcastReceiver.getNotification( + RuntimeEnvironment.getApplication().getApplicationContext(), intent); + + assertNotNull(notification); + assertEquals("Notification received.", notification.build().extras.getString(EXTRA_TEXT)); + } + + @Test + public void testNotificationBuilderWhenAlertIsSetWhenProvided() { + final ParsePushBroadcastReceiver broadcastReceiver = new ParsePushBroadcastReceiver(); + final Map map = new HashMap(); + map.put("alert", "This is an alert"); + + final String notificationPayload = new JSONObject(map).toString(); + + final Intent intent = new Intent(); + intent.putExtra(ParsePushBroadcastReceiver.KEY_PUSH_DATA, notificationPayload); + + final NotificationCompat.Builder notification = + broadcastReceiver.getNotification( + RuntimeEnvironment.getApplication().getApplicationContext(), intent); + + assertNotNull(notification); + assertEquals("This is an alert", notification.build().extras.getString(EXTRA_TEXT)); + } + + @Test + public void testNotificationBuilderWhenTitleNotProvidedSetFallback() { + final ParsePushBroadcastReceiver broadcastReceiver = new ParsePushBroadcastReceiver(); + final Map map = new HashMap(); + map.put("alert", "alert"); + + final String notificationPayload = new JSONObject(map).toString(); + + final Intent intent = new Intent(); + intent.putExtra(ParsePushBroadcastReceiver.KEY_PUSH_DATA, notificationPayload); + + final NotificationCompat.Builder notification = + broadcastReceiver.getNotification( + RuntimeEnvironment.getApplication().getApplicationContext(), intent); + + assertNotNull(notification); + assertEquals("com.parse.test", notification.build().extras.getString(EXTRA_TITLE)); + } + + @Test + public void testNotificationBuilderWhenTitleIsSetWhenProvided() { + final ParsePushBroadcastReceiver broadcastReceiver = new ParsePushBroadcastReceiver(); + final Map map = new HashMap(); + map.put("title", "Application name"); + + final String notificationPayload = new JSONObject(map).toString(); + + final Intent intent = new Intent(); + intent.putExtra(ParsePushBroadcastReceiver.KEY_PUSH_DATA, notificationPayload); + + final NotificationCompat.Builder notification = + broadcastReceiver.getNotification( + RuntimeEnvironment.getApplication().getApplicationContext(), intent); + + assertNotNull(notification); + assertEquals("Application name", notification.build().extras.getString(EXTRA_TITLE)); + } +}