1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.app.cts;
17 
18 import static org.mockito.Mockito.*;
19 
20 import android.app.Activity;
21 import android.app.Fragment;
22 import android.app.PendingIntent;
23 import android.app.stubs.FragmentResultActivity;
24 import android.app.stubs.FragmentTestActivity;
25 import android.app.stubs.R;
26 import android.content.Intent;
27 import android.content.IntentSender;
28 import android.test.ActivityInstrumentationTestCase2;
29 
30 import androidx.test.filters.SmallTest;
31 
32 import org.mockito.ArgumentCaptor;
33 
34 import java.util.concurrent.TimeUnit;
35 
36 /**
37  * Tests Fragment's startActivityForResult and startIntentSenderForResult.
38  */
39 public class FragmentReceiveResultTest extends
40         ActivityInstrumentationTestCase2<FragmentTestActivity> {
41 
42     private FragmentTestActivity mActivity;
43     private Fragment mFragment;
44 
FragmentReceiveResultTest()45     public FragmentReceiveResultTest() {
46         super(FragmentTestActivity.class);
47     }
48 
49     @Override
setUp()50     protected void setUp() throws Exception {
51         super.setUp();
52         mActivity = getActivity();
53         mFragment = attachTestFragment();
54     }
55 
56     @SmallTest
testStartActivityForResultOk()57     public void testStartActivityForResultOk() {
58         startActivityForResult(10, Activity.RESULT_OK, "content 10");
59 
60         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
61         asyncVerifyOnce(mFragment)
62                 .onActivityResult(eq(10), eq(Activity.RESULT_OK), captor.capture());
63         final String data = captor.getValue()
64                 .getStringExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT);
65         assertEquals("content 10", data);
66     }
67 
68     @SmallTest
testStartActivityForResultCanceled()69     public void testStartActivityForResultCanceled() {
70         startActivityForResult(20, Activity.RESULT_CANCELED, "content 20");
71 
72         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
73         asyncVerifyOnce(mFragment)
74                 .onActivityResult(eq(20), eq(Activity.RESULT_CANCELED), captor.capture());
75         final String data = captor.getValue()
76                 .getStringExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT);
77         assertEquals("content 20", data);
78     }
79 
80     @SmallTest
testStartIntentSenderForResultOk()81     public void testStartIntentSenderForResultOk() {
82         startIntentSenderForResult(30, Activity.RESULT_OK, "content 30");
83 
84         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
85         asyncVerifyOnce(mFragment)
86                 .onActivityResult(eq(30), eq(Activity.RESULT_OK), captor.capture());
87         final String data = captor.getValue()
88                 .getStringExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT);
89         assertEquals("content 30", data);
90     }
91 
92     @SmallTest
testStartIntentSenderForResultCanceled()93     public void testStartIntentSenderForResultCanceled() {
94         startIntentSenderForResult(40, Activity.RESULT_CANCELED, "content 40");
95 
96         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
97         asyncVerifyOnce(mFragment)
98                 .onActivityResult(eq(40), eq(Activity.RESULT_CANCELED), captor.capture());
99         final String data = captor.getValue()
100                 .getStringExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT);
101         assertEquals("content 40", data);
102     }
103 
attachTestFragment()104     private Fragment attachTestFragment() {
105         final Fragment fragment = spy(new Fragment());
106         getInstrumentation().waitForIdleSync();
107         getInstrumentation().runOnMainSync(new Runnable() {
108             @Override
109             public void run() {
110                 mActivity.getFragmentManager().beginTransaction()
111                         .add(R.id.content, fragment)
112                         .addToBackStack(null)
113                         .commitAllowingStateLoss();
114                 mActivity.getFragmentManager().executePendingTransactions();
115             }
116         });
117         getInstrumentation().waitForIdleSync();
118         return fragment;
119     }
120 
startActivityForResult(final int requestCode, final int resultCode, final String content)121     private void startActivityForResult(final int requestCode, final int resultCode,
122             final String content) {
123         getInstrumentation().runOnMainSync(new Runnable() {
124             @Override
125             public void run() {
126                 Intent intent = new Intent(mActivity, FragmentResultActivity.class);
127                 intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CODE, resultCode);
128                 intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT, content);
129 
130                 mFragment.startActivityForResult(intent, requestCode);
131             }
132         });
133         getInstrumentation().waitForIdleSync();
134     }
135 
asyncVerifyOnce(T mock)136     private static <T> T asyncVerifyOnce(T mock) {
137         return verify(mock, timeout(TimeUnit.SECONDS.toMillis(10)).times(1));
138     }
139 
startIntentSenderForResult(final int requestCode, final int resultCode, final String content)140     private void startIntentSenderForResult(final int requestCode, final int resultCode,
141             final String content) {
142         getInstrumentation().runOnMainSync(new Runnable() {
143             @Override
144             public void run() {
145                 Intent intent = new Intent(mActivity, FragmentResultActivity.class);
146                 intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CODE, resultCode);
147                 intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CONTENT, content);
148 
149                 PendingIntent pendingIntent = PendingIntent.getActivity(mActivity,
150                         requestCode, intent, PendingIntent.FLAG_IMMUTABLE);
151 
152                 try {
153                     mFragment.startIntentSenderForResult(pendingIntent.getIntentSender(),
154                             requestCode, null, 0, 0, 0, null);
155                 } catch (IntentSender.SendIntentException e) {
156                     fail("IntentSender failed");
157                 }
158             }
159         });
160         getInstrumentation().waitForIdleSync();
161     }
162 
163 }
164