31
31
import static com .google .firebase .appdistribution .impl .FeedbackActivity .RELEASE_NAME_EXTRA_KEY ;
32
32
import static com .google .firebase .appdistribution .impl .FeedbackActivity .SCREENSHOT_URI_EXTRA_KEY ;
33
33
import static com .google .firebase .appdistribution .impl .TestUtils .assertTaskFailure ;
34
+ import static java .util .stream .Collectors .toList ;
34
35
import static org .junit .Assert .assertEquals ;
35
36
import static org .junit .Assert .assertFalse ;
36
37
import static org .junit .Assert .assertNotNull ;
37
38
import static org .junit .Assert .assertNull ;
38
39
import static org .junit .Assert .assertTrue ;
40
+ import static org .mockito .ArgumentMatchers .any ;
39
41
import static org .mockito .Mockito .doReturn ;
40
42
import static org .mockito .Mockito .never ;
41
43
import static org .mockito .Mockito .spy ;
53
55
import android .content .pm .PackageInfo ;
54
56
import android .net .Uri ;
55
57
import android .os .Bundle ;
58
+ import android .util .Log ;
56
59
import androidx .test .core .app .ApplicationProvider ;
57
60
import androidx .test .core .content .pm .ApplicationInfoBuilder ;
58
61
import androidx .test .core .content .pm .PackageInfoBuilder ;
74
77
import java .util .concurrent .ExecutorService ;
75
78
import java .util .concurrent .Executors ;
76
79
import java .util .concurrent .Future ;
80
+ import java .util .function .Predicate ;
81
+ import org .junit .After ;
77
82
import org .junit .Before ;
78
83
import org .junit .Test ;
79
84
import org .junit .runner .RunWith ;
80
- import org .mockito .ArgumentCaptor ;
81
85
import org .mockito .Mock ;
82
86
import org .mockito .MockitoAnnotations ;
83
87
import org .robolectric .Robolectric ;
84
88
import org .robolectric .RobolectricTestRunner ;
89
+ import org .robolectric .RuntimeEnvironment ;
90
+ import org .robolectric .android .controller .ActivityController ;
85
91
import org .robolectric .shadows .ShadowAlertDialog ;
92
+ import org .robolectric .shadows .ShadowLog ;
86
93
import org .robolectric .shadows .ShadowPackageManager ;
87
94
88
95
@ RunWith (RobolectricTestRunner .class )
@@ -122,6 +129,7 @@ public class FirebaseAppDistributionServiceImplTest {
122
129
.setDownloadUrl (TEST_URL );
123
130
124
131
private FirebaseAppDistributionImpl firebaseAppDistribution ;
132
+ private ActivityController <TestActivity > activityController ;
125
133
private TestActivity activity ;
126
134
private FirebaseApp firebaseApp ;
127
135
private ExecutorService taskExecutor = Executors .newSingleThreadExecutor ();
@@ -190,11 +198,19 @@ public void setup() throws FirebaseAppDistributionException {
190
198
packageInfo .setLongVersionCode (INSTALLED_VERSION_CODE );
191
199
shadowPackageManager .installPackage (packageInfo );
192
200
193
- activity = spy (Robolectric .buildActivity (TestActivity .class ).create ().get ());
201
+ activityController = Robolectric .buildActivity (TestActivity .class ).setup ();
202
+ activity = spy (activityController .get ());
194
203
TestUtils .mockForegroundActivity (mockLifecycleNotifier , activity );
195
204
when (mockScreenshotTaker .takeScreenshot ()).thenReturn (Tasks .forResult (TEST_SCREENSHOT_URI ));
196
205
}
197
206
207
+ @ After
208
+ public void tearDown () {
209
+ if (activityController != null ) {
210
+ activityController .close ();
211
+ }
212
+ }
213
+
198
214
@ Test
199
215
public void checkForNewRelease_whenCheckForNewReleaseFails_throwsError () {
200
216
when (mockNewReleaseFetcher .checkForNewRelease ())
@@ -638,15 +654,16 @@ public void startFeedback_signsInTesterAndStartsActivity() throws InterruptedExc
638
654
firebaseAppDistribution .startFeedback ("Some terms and conditions" );
639
655
TestUtils .awaitAsyncOperations (taskExecutor );
640
656
641
- ArgumentCaptor <Intent > argument = ArgumentCaptor .forClass (Intent .class );
642
- verify (activity ).startActivity (argument .capture ());
643
657
verify (mockTesterSignInManager ).signInTester ();
644
- assertThat (argument .getValue ().getStringExtra (RELEASE_NAME_EXTRA_KEY ))
645
- .isEqualTo ("release-name" );
646
- assertThat (argument .getValue ().getStringExtra (SCREENSHOT_URI_EXTRA_KEY ))
658
+ Intent expectedIntent = new Intent (activity , FeedbackActivity .class );
659
+ Intent actualIntent = shadowOf (RuntimeEnvironment .getApplication ()).getNextStartedActivity ();
660
+ assertEquals (expectedIntent .getComponent (), actualIntent .getComponent ());
661
+ assertThat (actualIntent .getStringExtra (RELEASE_NAME_EXTRA_KEY )).isEqualTo ("release-name" );
662
+ assertThat (actualIntent .getStringExtra (SCREENSHOT_URI_EXTRA_KEY ))
647
663
.isEqualTo (TEST_SCREENSHOT_URI .toString ());
648
- assertThat (argument . getValue () .getStringExtra (INFO_TEXT_EXTRA_KEY ))
664
+ assertThat (actualIntent .getStringExtra (INFO_TEXT_EXTRA_KEY ))
649
665
.isEqualTo ("Some terms and conditions" );
666
+ assertThat (firebaseAppDistribution .isFeedbackInProgress ()).isTrue ();
650
667
}
651
668
652
669
@ Test
@@ -659,13 +676,93 @@ public void startFeedback_screenshotFails_startActivityWithNoScreenshot()
659
676
firebaseAppDistribution .startFeedback ("Some terms and conditions" );
660
677
TestUtils .awaitAsyncOperations (taskExecutor );
661
678
662
- ArgumentCaptor <Intent > argument = ArgumentCaptor .forClass (Intent .class );
663
- verify (activity ).startActivity (argument .capture ());
664
679
verify (mockTesterSignInManager ).signInTester ();
665
- assertThat (argument .getValue ().getStringExtra (RELEASE_NAME_EXTRA_KEY ))
666
- .isEqualTo ("release-name" );
667
- assertThat (argument .getValue ().hasExtra (SCREENSHOT_URI_EXTRA_KEY )).isFalse ();
668
- assertThat (argument .getValue ().getStringExtra (INFO_TEXT_EXTRA_KEY ))
669
- .isEqualTo ("Some terms and conditions" );
680
+ Intent expectedIntent = new Intent (activity , FeedbackActivity .class );
681
+ Intent actualIntent = shadowOf (RuntimeEnvironment .getApplication ()).getNextStartedActivity ();
682
+ assertEquals (expectedIntent .getComponent (), actualIntent .getComponent ());
683
+ assertThat (actualIntent .getStringExtra (RELEASE_NAME_EXTRA_KEY )).isEqualTo ("release-name" );
684
+ assertThat (actualIntent .getStringExtra (SCREENSHOT_URI_EXTRA_KEY ))
685
+ .isEqualTo (TEST_SCREENSHOT_URI .toString ());
686
+ assertThat (actualIntent .getStringExtra (INFO_TEXT_EXTRA_KEY ))
687
+ .isEqualTo ("Some terms and conditions" );
688
+ assertThat (firebaseAppDistribution .isFeedbackInProgress ()).isTrue ();
689
+ }
690
+
691
+ @ Test
692
+ public void startFeedback_calledMultipleTimes_onlyStartsOnce () throws InterruptedException {
693
+ when (mockReleaseIdentifier .identifyRelease ()).thenReturn (Tasks .forResult ("release-name" ));
694
+
695
+ firebaseAppDistribution .startFeedback ("Some terms and conditions" );
696
+ firebaseAppDistribution .startFeedback ("Some other terms and conditions" );
697
+ TestUtils .awaitAsyncOperations (taskExecutor );
698
+
699
+ verify (activity , times (1 )).startActivity (any ());
700
+ }
701
+
702
+ @ Test
703
+ public void startFeedback_closingActivity_setsInProgressToFalse () throws InterruptedException {
704
+ when (mockReleaseIdentifier .identifyRelease ()).thenReturn (Tasks .forResult ("release-name" ));
705
+
706
+ firebaseAppDistribution .startFeedback ("Some terms and conditions" );
707
+ TestUtils .awaitAsyncOperations (taskExecutor );
708
+ // Simulate destroying the feedback activity
709
+ firebaseAppDistribution .onActivityDestroyed (new FeedbackActivity ());
710
+
711
+ assertThat (firebaseAppDistribution .isFeedbackInProgress ()).isFalse ();
712
+ }
713
+
714
+ @ Test
715
+ public void startFeedback_screenshotFails_logsAndSetsInProgressToFalse ()
716
+ throws InterruptedException {
717
+ when (mockReleaseIdentifier .identifyRelease ()).thenReturn (Tasks .forResult ("release-name" ));
718
+ FirebaseAppDistributionException exception =
719
+ new FirebaseAppDistributionException ("Error" , Status .UNKNOWN );
720
+ when (mockScreenshotTaker .takeScreenshot ()).thenReturn (Tasks .forException (exception ));
721
+
722
+ firebaseAppDistribution .startFeedback ("Some terms and conditions" );
723
+ TestUtils .awaitAsyncOperations (taskExecutor );
724
+
725
+ assertThat (firebaseAppDistribution .isFeedbackInProgress ()).isFalse ();
726
+ assertLoggedError ("Failed to launch feedback flow" , exception );
727
+ }
728
+
729
+ @ Test
730
+ public void startFeedback_signInTesterFails_logsAndSetsInProgressToFalse ()
731
+ throws InterruptedException {
732
+ when (mockReleaseIdentifier .identifyRelease ()).thenReturn (Tasks .forResult ("release-name" ));
733
+ FirebaseAppDistributionException exception =
734
+ new FirebaseAppDistributionException ("Error" , Status .UNKNOWN );
735
+ when (mockTesterSignInManager .signInTester ()).thenReturn (Tasks .forException (exception ));
736
+
737
+ firebaseAppDistribution .startFeedback ("Some terms and conditions" );
738
+ TestUtils .awaitAsyncOperations (taskExecutor );
739
+
740
+ assertThat (firebaseAppDistribution .isFeedbackInProgress ()).isFalse ();
741
+ assertLoggedError ("Failed to launch feedback flow" , exception );
742
+ }
743
+
744
+ @ Test
745
+ public void startFeedback_cantIdentifyRelease_logsAndSetsInProgressToFalse ()
746
+ throws InterruptedException {
747
+ FirebaseAppDistributionException exception =
748
+ new FirebaseAppDistributionException ("Error" , Status .UNKNOWN );
749
+ when (mockReleaseIdentifier .identifyRelease ()).thenReturn (Tasks .forException (exception ));
750
+
751
+ firebaseAppDistribution .startFeedback ("Some terms and conditions" );
752
+ TestUtils .awaitAsyncOperations (taskExecutor );
753
+
754
+ assertThat (firebaseAppDistribution .isFeedbackInProgress ()).isFalse ();
755
+ assertLoggedError ("Failed to launch feedback flow" , exception );
756
+ }
757
+
758
+ private static void assertLoggedError (String partialMessage , Throwable e ) {
759
+ Predicate <ShadowLog .LogItem > predicate =
760
+ log ->
761
+ log .type == Log .ERROR
762
+ && log .msg .contains (partialMessage )
763
+ && (e != null ? log .throwable == e : true );
764
+ List <ShadowLog .LogItem > matchingLogs =
765
+ ShadowLog .getLogs ().stream ().filter (predicate ).collect (toList ());
766
+ assertThat (matchingLogs ).hasSize (1 );
670
767
}
671
768
}
0 commit comments