• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.integrationtests.axt;
2 
3 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
4 import static androidx.test.espresso.intent.Intents.getIntents;
5 import static androidx.test.espresso.intent.Intents.intending;
6 import static androidx.test.espresso.intent.matcher.ComponentNameMatchers.hasClassName;
7 import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction;
8 import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
9 import static androidx.test.ext.truth.content.IntentCorrespondences.action;
10 import static androidx.test.ext.truth.content.IntentCorrespondences.all;
11 import static androidx.test.ext.truth.content.IntentCorrespondences.data;
12 import static androidx.test.ext.truth.content.IntentSubject.assertThat;
13 import static com.google.common.truth.Truth.assertThat;
14 import static org.junit.Assert.assertThrows;
15 
16 import android.app.Activity;
17 import android.app.Instrumentation.ActivityResult;
18 import android.content.ActivityNotFoundException;
19 import android.content.Intent;
20 import android.net.Uri;
21 import android.os.Bundle;
22 import androidx.test.core.app.ActivityScenario;
23 import androidx.test.espresso.intent.Intents;
24 import androidx.test.ext.junit.runners.AndroidJUnit4;
25 import com.google.common.collect.Iterables;
26 import org.junit.After;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 
31 /** Integration tests for using androidx.test's espresso intents API on Robolectric. */
32 @RunWith(AndroidJUnit4.class)
33 public class IntentsTest {
34 
35   @Before
setUp()36   public void setUp() {
37     Intents.init();
38   }
39 
40   @After
tearDown()41   public void tearDown() {
42     Intents.release();
43   }
44 
45   @Test
testNoIntents()46   public void testNoIntents() {
47     Intents.assertNoUnverifiedIntents();
48   }
49 
50   @Test
testIntendedFailEmpty()51   public void testIntendedFailEmpty() {
52     assertThrows(
53         AssertionError.class, () -> Intents.intended(org.hamcrest.Matchers.any(Intent.class)));
54   }
55 
56   @Test
testIntendedSuccess()57   public void testIntendedSuccess() {
58     Intent i = new Intent();
59     i.setAction(Intent.ACTION_VIEW);
60     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
61     getApplicationContext().startActivity(i);
62     Intents.intended(hasAction(Intent.ACTION_VIEW));
63   }
64 
65   @Test
testIntendedNotMatching()66   public void testIntendedNotMatching() {
67     Intent i = new Intent();
68     i.setAction(Intent.ACTION_VIEW);
69     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
70     getApplicationContext().startActivity(i);
71     assertThrows(
72         AssertionError.class,
73         () -> Intents.intended(hasAction(Intent.ACTION_AIRPLANE_MODE_CHANGED)));
74   }
75 
76   /**
77    * Variant of testIntendedSuccess that uses truth APIs.
78    *
79    * <p>In this form the test verifies that only a single intent was sent.
80    */
81   @Test
testIntendedSuccess_truth()82   public void testIntendedSuccess_truth() {
83     Intent i = new Intent();
84     i.setAction(Intent.ACTION_VIEW);
85     i.putExtra("ignoreextra", "");
86     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
87     getApplicationContext().startActivity(i);
88     assertThat(Iterables.getOnlyElement(getIntents())).hasAction(Intent.ACTION_VIEW);
89   }
90 
91   /**
92    * Variant of testIntendedSuccess that uses truth APIs.
93    *
94    * <p>This is a more flexible/lenient variant of {@link #testIntendedSuccess_truth} that handles
95    * cases where other intents might have been sent.
96    */
97   @Test
testIntendedSuccess_truthCorrespondence()98   public void testIntendedSuccess_truthCorrespondence() {
99     Intent i = new Intent();
100     i.setAction(Intent.ACTION_VIEW);
101     i.putExtra("ignoreextra", "");
102     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
103     getApplicationContext().startActivity(i);
104     Intent alsoSentIntentButDontCare = new Intent(Intent.ACTION_MAIN);
105     alsoSentIntentButDontCare.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
106 
107     getApplicationContext().startActivity(alsoSentIntentButDontCare);
108     assertThat(getIntents())
109         .comparingElementsUsing(action())
110         .contains(new Intent(Intent.ACTION_VIEW));
111   }
112 
113   /** Variant of testIntendedSuccess_truthCorrespondence that uses chained Correspondences. */
114   @Test
testIntendedSuccess_truthChainedCorrespondence()115   public void testIntendedSuccess_truthChainedCorrespondence() {
116     Intent i = new Intent();
117     i.setAction(Intent.ACTION_VIEW);
118     i.putExtra("ignoreextra", "");
119     i.setData(Uri.parse("http://robolectric.org"));
120     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
121     getApplicationContext().startActivity(i);
122     Intent alsoSentIntentButNotMatching = new Intent(Intent.ACTION_VIEW);
123     alsoSentIntentButNotMatching.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
124     getApplicationContext().startActivity(alsoSentIntentButNotMatching);
125 
126     Intent expectedIntent =
127         new Intent(Intent.ACTION_VIEW).setData(Uri.parse("http://robolectric.org"));
128     assertThat(getIntents()).comparingElementsUsing(all(action(), data())).contains(expectedIntent);
129   }
130 
131   /**
132    * Activity that captures calls to {@link Activity#onActivityResult(int, int, Intent)}
133    *
134    * @noinspection NewClassNamingConvention
135    */
136   public static class ResultCapturingActivity extends Activity {
137 
138     private ActivityResult activityResult;
139 
140     @Override
onCreate(Bundle savedInstanceState)141     protected void onCreate(Bundle savedInstanceState) {
142       super.onCreate(savedInstanceState);
143     }
144 
145     @Override
onStart()146     protected void onStart() {
147       super.onStart();
148     }
149 
150     @Override
onResume()151     protected void onResume() {
152       super.onResume();
153     }
154 
155     @Override
onDestroy()156     protected void onDestroy() {
157       super.onDestroy();
158     }
159 
160     @Override
onPause()161     protected void onPause() {
162       super.onPause();
163     }
164 
165     @Override
onActivityResult(int requestCode, int resultCode, Intent data)166     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
167       super.onActivityResult(requestCode, resultCode, data);
168       activityResult = new ActivityResult(resultCode, data);
169     }
170   }
171 
172   /**
173    * Dummy activity whose calls we intent to we're stubbing out.
174    *
175    * @noinspection NewClassNamingConvention
176    */
177   public static class DummyActivity extends Activity {}
178 
179   @Test
intending_callsOnActivityResult()180   public void intending_callsOnActivityResult() {
181     intending(hasComponent(hasClassName(DummyActivity.class.getName())))
182         .respondWith(new ActivityResult(Activity.RESULT_OK, new Intent().putExtra("key", 123)));
183 
184     try (ActivityScenario<ResultCapturingActivity> activityScenario =
185         ActivityScenario.launch(ResultCapturingActivity.class)) {
186       activityScenario.onActivity(
187           activity ->
188               activity.startActivityForResult(new Intent(activity, DummyActivity.class), 0));
189 
190       activityScenario.onActivity(
191           activity -> {
192             assertThat(activity.activityResult.getResultCode()).isEqualTo(Activity.RESULT_OK);
193             assertThat(activity.activityResult.getResultData()).extras().containsKey("key");
194           });
195     }
196   }
197 
198   @Test
browserIntentNotResolved()199   public void browserIntentNotResolved() {
200     Intent browserIntent = new Intent(Intent.ACTION_VIEW);
201     browserIntent.setData(Uri.parse("http://www.robolectric.org"));
202     browserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
203 
204     Intents.intending(hasAction(Intent.ACTION_VIEW))
205         .respondWithFunction(
206             intent -> {
207               throw new ActivityNotFoundException();
208             });
209 
210     assertThrows(
211         ActivityNotFoundException.class,
212         () -> getApplicationContext().startActivity(browserIntent));
213   }
214 }
215