Skip to content

Commit

Permalink
fix: missing pending intents mutability for Android 12+ (#1139)
Browse files Browse the repository at this point in the history
  • Loading branch information
azlekov authored Nov 16, 2021
1 parent 8d9691e commit fbe8d87
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 10 deletions.
2 changes: 1 addition & 1 deletion parse/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
events "failed"
}
}

Expand Down
4 changes: 3 additions & 1 deletion parse/src/main/java/com/parse/ParseCommandCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
15 changes: 7 additions & 8 deletions parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
174 changes: 174 additions & 0 deletions parse/src/test/java/com/parse/ParsePushBroadcastReceiverTest.java
Original file line number Diff line number Diff line change
@@ -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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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));
}
}

0 comments on commit fbe8d87

Please sign in to comment.