|
58 | 58 | import com.google.android.gms.cloudmessaging.CloudMessage;
|
59 | 59 | import com.google.android.gms.cloudmessaging.Rpc;
|
60 | 60 | import com.google.common.collect.ImmutableSet;
|
61 |
| -import com.google.common.collect.Sets; |
62 | 61 | import com.google.firebase.FirebaseApp;
|
63 | 62 | import com.google.firebase.FirebaseOptions;
|
64 | 63 | import com.google.firebase.iid.FirebaseInstanceIdReceiver;
|
65 | 64 | import com.google.firebase.messaging.AnalyticsTestHelper.Analytics;
|
| 65 | +import com.google.firebase.messaging.Constants.MessagePayloadKeys; |
66 | 66 | import com.google.firebase.messaging.testing.AnalyticsValidator;
|
67 | 67 | import com.google.firebase.messaging.testing.Bundles;
|
68 | 68 | import com.google.firebase.messaging.testing.FakeConnectorComponent;
|
@@ -105,6 +105,8 @@ public class FirebaseMessagingServiceRoboTest {
|
105 | 105 | // blank activity
|
106 | 106 | public static class MyTestActivity extends Activity {}
|
107 | 107 |
|
| 108 | + public static class MySecondTestActivity extends Activity {} |
| 109 | + |
108 | 110 | private static final AnalyticsValidator analyticsValidator =
|
109 | 111 | FakeConnectorComponent.getAnalyticsValidator();
|
110 | 112 |
|
@@ -501,6 +503,43 @@ public void testNotification_clickAnalytics_recreateActivity() throws Exception
|
501 | 503 | }
|
502 | 504 | }
|
503 | 505 |
|
| 506 | + /** Test that a notification does not re-log events when the same notification is found. */ |
| 507 | + @Test |
| 508 | + public void notification_clickAnalytics_duplicateMessageId() throws Exception { |
| 509 | + FirebaseMessaging.getInstance(firebaseApp); // register activity lifecycle friends |
| 510 | + simulateNotificationMessageWithAnalytics(); |
| 511 | + |
| 512 | + PendingIntent clickPendingIntent = getSingleShownNotification().contentIntent; |
| 513 | + try (ActivityScenario<MyTestActivity> scenario = |
| 514 | + dispatchActivityIntentToActivity(clickPendingIntent)) { |
| 515 | + Intent secondActivityIntent = new Intent(); |
| 516 | + secondActivityIntent.putExtras(shadowOf(clickPendingIntent).getSavedIntent()); |
| 517 | + // Start another Activity with the same notification and check it doesn't log open again. |
| 518 | + try (ActivityScenario<MySecondTestActivity> secondScenario = |
| 519 | + ActivityScenario.launch(secondActivityIntent)) { |
| 520 | + List<AnalyticsValidator.LoggedEvent> events = analyticsValidator.getLoggedEvents(); |
| 521 | + assertThat(events).hasSize(2); |
| 522 | + AnalyticsValidator.LoggedEvent receiveEvent = events.get(0); |
| 523 | + assertThat(receiveEvent.getOrigin()).isEqualTo(Analytics.ORIGIN_FCM); |
| 524 | + assertThat(receiveEvent.getName()).isEqualTo(Analytics.EVENT_NOTIFICATION_RECEIVE); |
| 525 | + assertThat(receiveEvent.getParams()) |
| 526 | + .string(Analytics.PARAM_MESSAGE_ID) |
| 527 | + .isEqualTo("composer_key"); |
| 528 | + assertThat(receiveEvent.getParams()) |
| 529 | + .string(Analytics.PARAM_MESSAGE_NAME) |
| 530 | + .isEqualTo("composer_label"); |
| 531 | + assertThat(receiveEvent.getParams()) |
| 532 | + .integer(Analytics.PARAM_MESSAGE_TIME) |
| 533 | + .isEqualTo(1234567890); |
| 534 | + assertThat(receiveEvent.getParams()).doesNotContainKey(Analytics.PARAM_TOPIC); |
| 535 | + |
| 536 | + AnalyticsValidator.LoggedEvent openEvent = events.get(1); |
| 537 | + assertThat(openEvent.getOrigin()).isEqualTo(Analytics.ORIGIN_FCM); |
| 538 | + assertThat(openEvent.getName()).isEqualTo(Analytics.EVENT_NOTIFICATION_OPEN); |
| 539 | + } |
| 540 | + } |
| 541 | + } |
| 542 | + |
504 | 543 | /** Test that a notification logs the correct event on dismiss. */
|
505 | 544 | @Test
|
506 | 545 | public void testNotification_dismissAnalytics() throws Exception {
|
@@ -612,6 +651,7 @@ private void simulateNotificationMessageWithAnalytics() throws InterruptedExcept
|
612 | 651 | // Robo manifest doesn't have a default activity, so set click action so that we get a
|
613 | 652 | // click pending intent.
|
614 | 653 | builder.addData(DisplayNotificationRoboTest.KEY_CLICK_ACTION, "click_action");
|
| 654 | + builder.addData(MessagePayloadKeys.MSGID, "msg_id"); |
615 | 655 | AnalyticsTestHelper.addAnalyticsExtras(builder);
|
616 | 656 | startServiceViaReceiver(builder.buildIntent());
|
617 | 657 | }
|
@@ -766,43 +806,4 @@ private static Set<ServiceConnection> getBoundServiceConnections() {
|
766 | 806 | .getBoundServiceConnections();
|
767 | 807 | return ImmutableSet.copyOf(connList.toArray(new ServiceConnection[0]));
|
768 | 808 | }
|
769 |
| - |
770 |
| - /** |
771 |
| - * Calls handleIntent on {@link #service} in a background thread and connects any outgoing |
772 |
| - * bindService calls made in the meantime. |
773 |
| - * |
774 |
| - * <p>Returns a CountDownLatch that's finished when the call to handleIntent finishes. |
775 |
| - */ |
776 |
| - private CountDownLatch handleIntent(Intent intent, int time, TimeUnit unit) throws Exception { |
777 |
| - long timeoutAtMillis = System.currentTimeMillis() + unit.toMillis(time); |
778 |
| - |
779 |
| - // Connections that were active before we started |
780 |
| - Set<ServiceConnection> previousConnections = getBoundServiceConnections(); |
781 |
| - |
782 |
| - // Run the thing that will cause a bindService call in the background |
783 |
| - CountDownLatch finishedLatch = new CountDownLatch(1); |
784 |
| - executorService.execute( |
785 |
| - () -> { |
786 |
| - service.handleIntent(intent); |
787 |
| - finishedLatch.countDown(); |
788 |
| - }); |
789 |
| - |
790 |
| - // wait for the call to be made (service connection to appear) |
791 |
| - while (Sets.difference(getBoundServiceConnections(), previousConnections).isEmpty()) { |
792 |
| - assertWithMessage("timed out waiting for binder connection") |
793 |
| - .that(System.currentTimeMillis()) |
794 |
| - .isLessThan(timeoutAtMillis); |
795 |
| - |
796 |
| - TimeUnit.MILLISECONDS.sleep(50); |
797 |
| - } |
798 |
| - |
799 |
| - CountDownLatch flushLatch = new CountDownLatch(1); |
800 |
| - new Handler(Looper.getMainLooper()).post(flushLatch::countDown); |
801 |
| - shadowOf(Looper.getMainLooper()).idle(); |
802 |
| - |
803 |
| - long millisRemaining = Math.max(0, timeoutAtMillis - System.currentTimeMillis()); |
804 |
| - assertThat(flushLatch.await(millisRemaining, TimeUnit.MILLISECONDS)).isTrue(); |
805 |
| - |
806 |
| - return finishedLatch; |
807 |
| - } |
808 | 809 | }
|
0 commit comments