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
17package android.support.v4.app;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertNotNull;
22import static org.junit.Assert.assertTrue;
23
24import android.annotation.TargetApi;
25import android.content.Intent;
26import android.net.Uri;
27import android.os.Bundle;
28import android.support.test.filters.SdkSuppress;
29import android.support.test.filters.SmallTest;
30import android.support.test.runner.AndroidJUnit4;
31import android.support.v4.BaseInstrumentationTestCase;
32
33import org.junit.Test;
34import org.junit.runner.RunWith;
35
36import java.util.HashMap;
37import java.util.Map;
38
39@RunWith(AndroidJUnit4.class)
40@SmallTest
41public class RemoteInputTest extends BaseInstrumentationTestCase<TestSupportActivity> {
42    private static final String RESULT_KEY = "result_key";  // value doesn't matter
43    private static final String MIME_TYPE = "mimeType";  // value doesn't matter
44
45    public RemoteInputTest() {
46        super(TestSupportActivity.class);
47    }
48
49    @Test
50    public void testRemoteInputBuilder_setDataOnly() throws Throwable {
51        RemoteInput input = newDataOnlyRemoteInput();
52
53        assertTrue(input.isDataOnly());
54        assertFalse(input.getAllowFreeFormInput());
55        assertTrue(input.getChoices() == null || input.getChoices().length == 0);
56        assertEquals(1, input.getAllowedDataTypes().size());
57        assertTrue(input.getAllowedDataTypes().contains(MIME_TYPE));
58    }
59
60    @Test
61    public void testRemoteInputBuilder_setTextOnly() throws Throwable {
62        RemoteInput input = newTextRemoteInput();
63
64        assertFalse(input.isDataOnly());
65        assertTrue(input.getAllowFreeFormInput());
66        assertTrue(input.getChoices() == null || input.getChoices().length == 0);
67        assertTrue(input.getAllowedDataTypes() == null || input.getAllowedDataTypes().isEmpty());
68    }
69
70    @Test
71    public void testRemoteInputBuilder_setChoicesOnly() throws Throwable {
72        RemoteInput input = newChoicesOnlyRemoteInput();
73
74        assertFalse(input.isDataOnly());
75        assertFalse(input.getAllowFreeFormInput());
76        assertTrue(input.getChoices() != null && input.getChoices().length > 0);
77        assertTrue(input.getAllowedDataTypes() == null || input.getAllowedDataTypes().isEmpty());
78    }
79
80    @Test
81    public void testRemoteInputBuilder_setDataAndTextAndChoices() throws Throwable {
82        CharSequence[] choices = new CharSequence[2];
83        choices[0] = "first";
84        choices[1] = "second";
85        RemoteInput input =
86                new RemoteInput.Builder(RESULT_KEY)
87                .setChoices(choices)
88                .setAllowDataType(MIME_TYPE, true)
89                .build();
90
91        assertFalse(input.isDataOnly());
92        assertTrue(input.getAllowFreeFormInput());
93        assertTrue(input.getChoices() != null && input.getChoices().length > 0);
94        assertEquals(1, input.getAllowedDataTypes().size());
95        assertTrue(input.getAllowedDataTypes().contains(MIME_TYPE));
96    }
97
98    @SdkSuppress(minSdkVersion = 17)
99    @TargetApi(17)
100    @Test
101    public void testRemoteInputBuilder_addAndGetDataResultsFromIntent() throws Throwable {
102        Uri uri = Uri.parse("Some Uri");
103        RemoteInput input = newDataOnlyRemoteInput();
104        Intent intent = new Intent();
105        Map<String, Uri> putResults = new HashMap<>();
106        putResults.put(MIME_TYPE, uri);
107        RemoteInput.addDataResultToIntent(input, intent, putResults);
108
109        verifyIntentHasDataResults(intent, uri);
110    }
111
112    @SdkSuppress(minSdkVersion = 17)
113    @TargetApi(17)
114    @Test
115    public void testRemoteInputBuilder_addAndGetTextResultsFromIntent() throws Throwable {
116        CharSequence charSequence = "value doesn't matter";
117        RemoteInput input = newTextRemoteInput();
118        Intent intent = new Intent();
119        Bundle putResults = new Bundle();
120        putResults.putCharSequence(input.getResultKey(), charSequence);
121        RemoteInput[] arr = new RemoteInput[1];
122        arr[0] = input;
123        RemoteInput.addResultsToIntent(arr, intent, putResults);
124
125        verifyIntentHasTextResults(intent, charSequence);
126    }
127
128    @SdkSuppress(minSdkVersion = 17)
129    @TargetApi(17)
130    @Test
131    public void testRemoteInputBuilder_addAndGetDataAndTextResultsFromIntentDataFirst()
132            throws Throwable {
133        CharSequence charSequence = "value doesn't matter";
134        Uri uri = Uri.parse("Some Uri");
135        RemoteInput input =
136                new RemoteInput.Builder(RESULT_KEY)
137                .setAllowDataType(MIME_TYPE, true)
138                .build();
139        Intent intent = new Intent();
140
141        Map<String, Uri> dataResults = new HashMap<>();
142        dataResults.put(MIME_TYPE, uri);
143        RemoteInput.addDataResultToIntent(input, intent, dataResults);
144
145        Bundle textResults = new Bundle();
146        textResults.putCharSequence(input.getResultKey(), charSequence);
147        RemoteInput[] arr = new RemoteInput[1];
148        arr[0] = input;
149        RemoteInput.addResultsToIntent(arr, intent, textResults);
150
151        verifyIntentHasTextResults(intent, charSequence);
152        verifyIntentHasDataResults(intent, uri);
153    }
154
155    @SdkSuppress(minSdkVersion = 17)
156    @TargetApi(17)
157    @Test
158    public void testRemoteInputBuilder_addAndGetDataAndTextResultsFromIntentTextFirst()
159            throws Throwable {
160        CharSequence charSequence = "value doesn't matter";
161        Uri uri = Uri.parse("Some Uri");
162        RemoteInput input =
163                new RemoteInput.Builder(RESULT_KEY)
164                .setAllowDataType(MIME_TYPE, true)
165                .build();
166        Intent intent = new Intent();
167
168        Bundle textResults = new Bundle();
169        textResults.putCharSequence(input.getResultKey(), charSequence);
170        RemoteInput[] arr = new RemoteInput[1];
171        arr[0] = input;
172        RemoteInput.addResultsToIntent(arr, intent, textResults);
173
174        Map<String, Uri> dataResults = new HashMap<>();
175        dataResults.put(MIME_TYPE, uri);
176        RemoteInput.addDataResultToIntent(input, intent, dataResults);
177
178        verifyIntentHasTextResults(intent, charSequence);
179        verifyIntentHasDataResults(intent, uri);
180    }
181
182    private static void verifyIntentHasTextResults(Intent intent, CharSequence expected) {
183        Bundle getResults = RemoteInput.getResultsFromIntent(intent);
184        assertNotNull(getResults);
185        assertTrue(getResults.containsKey(RESULT_KEY));
186        assertEquals(expected, getResults.getCharSequence(RESULT_KEY, "default"));
187    }
188
189    private static void verifyIntentHasDataResults(Intent intent, Uri expectedUri) {
190        Map<String, Uri> getResults = RemoteInput.getDataResultsFromIntent(intent, RESULT_KEY);
191        assertNotNull(getResults);
192        assertEquals(1, getResults.size());
193        assertTrue(getResults.containsKey(MIME_TYPE));
194        assertEquals(expectedUri, getResults.get(MIME_TYPE));
195    }
196
197    private static RemoteInput newTextRemoteInput() {
198        return new RemoteInput.Builder(RESULT_KEY).build();  // allowFreeForm defaults to true
199    }
200
201    private static RemoteInput newChoicesOnlyRemoteInput() {
202        CharSequence[] choices = new CharSequence[2];
203        choices[0] = "first";
204        choices[1] = "second";
205        return new RemoteInput.Builder(RESULT_KEY)
206            .setAllowFreeFormInput(false)
207            .setChoices(choices)
208            .build();
209    }
210
211    private static RemoteInput newDataOnlyRemoteInput() {
212        return new RemoteInput.Builder(RESULT_KEY)
213            .setAllowFreeFormInput(false)
214            .setAllowDataType(MIME_TYPE, true)
215            .build();
216    }
217}
218