Skip to content

Commit 090788b

Browse files
committed
Add tests
1 parent de52e94 commit 090788b

File tree

3 files changed

+118
-17
lines changed

3 files changed

+118
-17
lines changed

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ class FirebaseAppDistributionImpl implements FirebaseAppDistribution {
8787

8888
private TaskCompletionSource<Void> showSignInDialogTask = null;
8989
private TaskCompletionSource<Void> showUpdateDialogTask = null;
90-
9190
private AtomicBoolean feedbackInProgress = new AtomicBoolean(false);
9291

9392
@VisibleForTesting
@@ -379,6 +378,11 @@ private Task<Void> launchFeedbackActivity(
379378
});
380379
}
381380

381+
@VisibleForTesting
382+
boolean isFeedbackInProgress() {
383+
return feedbackInProgress.get();
384+
}
385+
382386
@VisibleForTesting
383387
void onActivityResumed(Activity activity) {
384388
if (awaitingSignInDialogConfirmation()) {

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionLifecycleNotifier.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ <T> Task<T> applyToForegroundActivityTask(SuccessContinuation<Activity, T> conti
161161
});
162162
}
163163

164-
private Task<Activity> getForegroundActivity() {
164+
Task<Activity> getForegroundActivity() {
165165
synchronized (lock) {
166166
if (currentActivity != null) {
167167
return Tasks.forResult(currentActivity);

firebase-appdistribution/src/test/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionServiceImplTest.java

Lines changed: 112 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@
3131
import static com.google.firebase.appdistribution.impl.FeedbackActivity.RELEASE_NAME_EXTRA_KEY;
3232
import static com.google.firebase.appdistribution.impl.FeedbackActivity.SCREENSHOT_URI_EXTRA_KEY;
3333
import static com.google.firebase.appdistribution.impl.TestUtils.assertTaskFailure;
34+
import static java.util.stream.Collectors.toList;
3435
import static org.junit.Assert.assertEquals;
3536
import static org.junit.Assert.assertFalse;
3637
import static org.junit.Assert.assertNotNull;
3738
import static org.junit.Assert.assertNull;
3839
import static org.junit.Assert.assertTrue;
40+
import static org.mockito.ArgumentMatchers.any;
3941
import static org.mockito.Mockito.doReturn;
4042
import static org.mockito.Mockito.never;
4143
import static org.mockito.Mockito.spy;
@@ -53,6 +55,7 @@
5355
import android.content.pm.PackageInfo;
5456
import android.net.Uri;
5557
import android.os.Bundle;
58+
import android.util.Log;
5659
import androidx.test.core.app.ApplicationProvider;
5760
import androidx.test.core.content.pm.ApplicationInfoBuilder;
5861
import androidx.test.core.content.pm.PackageInfoBuilder;
@@ -74,15 +77,19 @@
7477
import java.util.concurrent.ExecutorService;
7578
import java.util.concurrent.Executors;
7679
import java.util.concurrent.Future;
80+
import java.util.function.Predicate;
81+
import org.junit.After;
7782
import org.junit.Before;
7883
import org.junit.Test;
7984
import org.junit.runner.RunWith;
80-
import org.mockito.ArgumentCaptor;
8185
import org.mockito.Mock;
8286
import org.mockito.MockitoAnnotations;
8387
import org.robolectric.Robolectric;
8488
import org.robolectric.RobolectricTestRunner;
89+
import org.robolectric.RuntimeEnvironment;
90+
import org.robolectric.android.controller.ActivityController;
8591
import org.robolectric.shadows.ShadowAlertDialog;
92+
import org.robolectric.shadows.ShadowLog;
8693
import org.robolectric.shadows.ShadowPackageManager;
8794

8895
@RunWith(RobolectricTestRunner.class)
@@ -122,6 +129,7 @@ public class FirebaseAppDistributionServiceImplTest {
122129
.setDownloadUrl(TEST_URL);
123130

124131
private FirebaseAppDistributionImpl firebaseAppDistribution;
132+
private ActivityController<TestActivity> activityController;
125133
private TestActivity activity;
126134
private FirebaseApp firebaseApp;
127135
private ExecutorService taskExecutor = Executors.newSingleThreadExecutor();
@@ -190,11 +198,19 @@ public void setup() throws FirebaseAppDistributionException {
190198
packageInfo.setLongVersionCode(INSTALLED_VERSION_CODE);
191199
shadowPackageManager.installPackage(packageInfo);
192200

193-
activity = spy(Robolectric.buildActivity(TestActivity.class).create().get());
201+
activityController = Robolectric.buildActivity(TestActivity.class).setup();
202+
activity = spy(activityController.get());
194203
TestUtils.mockForegroundActivity(mockLifecycleNotifier, activity);
195204
when(mockScreenshotTaker.takeScreenshot()).thenReturn(Tasks.forResult(TEST_SCREENSHOT_URI));
196205
}
197206

207+
@After
208+
public void tearDown() {
209+
if (activityController != null) {
210+
activityController.close();
211+
}
212+
}
213+
198214
@Test
199215
public void checkForNewRelease_whenCheckForNewReleaseFails_throwsError() {
200216
when(mockNewReleaseFetcher.checkForNewRelease())
@@ -638,15 +654,16 @@ public void startFeedback_signsInTesterAndStartsActivity() throws InterruptedExc
638654
firebaseAppDistribution.startFeedback("Some terms and conditions");
639655
TestUtils.awaitAsyncOperations(taskExecutor);
640656

641-
ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);
642-
verify(activity).startActivity(argument.capture());
643657
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))
647663
.isEqualTo(TEST_SCREENSHOT_URI.toString());
648-
assertThat(argument.getValue().getStringExtra(INFO_TEXT_EXTRA_KEY))
664+
assertThat(actualIntent.getStringExtra(INFO_TEXT_EXTRA_KEY))
649665
.isEqualTo("Some terms and conditions");
666+
assertThat(firebaseAppDistribution.isFeedbackInProgress()).isTrue();
650667
}
651668

652669
@Test
@@ -659,13 +676,93 @@ public void startFeedback_screenshotFails_startActivityWithNoScreenshot()
659676
firebaseAppDistribution.startFeedback("Some terms and conditions");
660677
TestUtils.awaitAsyncOperations(taskExecutor);
661678

662-
ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);
663-
verify(activity).startActivity(argument.capture());
664679
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);
670767
}
671768
}

0 commit comments

Comments
 (0)