1 /*
2  * Copyright (C) 2017 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 com.android.documentsui.inspector;
17 
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.when;
20 
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.media.ExifInterface;
24 import android.net.Uri;
25 import android.os.Bundle;
26 import android.os.Looper;
27 import android.provider.DocumentsContract;
28 import android.test.suitebuilder.annotation.MediumTest;
29 
30 import androidx.test.rule.provider.ProviderTestRule;
31 
32 import com.android.documentsui.InspectorProvider;
33 import com.android.documentsui.base.DocumentInfo;
34 import com.android.documentsui.base.UserId;
35 import com.android.documentsui.inspector.InspectorController.DataSupplier;
36 import com.android.documentsui.testing.LatchedConsumer;
37 import com.android.documentsui.testing.TestSupportLoaderManager;
38 
39 import junit.framework.TestCase;
40 
41 import org.junit.Before;
42 import org.junit.Rule;
43 import org.junit.Test;
44 
45 import java.util.concurrent.TimeUnit;
46 
47 /**
48  * This test relies the inspector providers test.txt file in inspector root.
49  */
50 @MediumTest
51 public class DocumentLoaderTest extends TestCase {
52 
53     private static final String TEST_DOC_NAME = "test.txt";
54     private static final String DIR_TOP = "Top";
55     private static final String NOT_DIRECTORY = "OpenInProviderTest";
56 
57     private Context mContext;
58     private UserId mUserId;
59     private TestSupportLoaderManager mLoaderManager;
60     private DataSupplier mLoader;
61     private ContentResolver mResolver;
62 
63     @Rule
64     private ProviderTestRule mProviderTestRule = new ProviderTestRule.Builder(
65             InspectorProvider.class, InspectorProvider.AUTHORITY).build();
66 
67     @Before
setUp()68     public void setUp() throws Exception {
69         super.setUp();
70 
71         mContext = prepareContentResolverSource();
72         mUserId = UserId.DEFAULT_USER;
73         mResolver = mContext.getContentResolver();
74         mLoaderManager = new TestSupportLoaderManager();
75         mLoader = new RuntimeDataSupplier(mContext, mLoaderManager);
76 
77         if (Looper.myLooper() == null) {
78             Looper.prepare();
79         }
80     }
81 
prepareContentResolverSource()82     protected Context prepareContentResolverSource() {
83         ContentResolver contentResolver = mProviderTestRule.getResolver();
84         Context context = mock(Context.class);
85         // inject ContentResolver
86         when(context.getContentResolver()).thenReturn(contentResolver);
87         // inject ContentResolver and prevent CursorLoader.loadInBackground from
88         // NullPointerException
89         when(context.getApplicationContext()).thenReturn(context);
90         return context;
91 
92     }
93 
94     /**
95      * Tests the loader using the Inspector Content provider. This test that we got valid info back
96      * from the loader.
97      */
98     @Test
testLoadsDocument()99     public void testLoadsDocument() throws Exception {
100         Uri validUri = DocumentsContract.buildDocumentUri(
101                 InspectorProvider.AUTHORITY, TEST_DOC_NAME);
102         LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1);
103         mLoader.loadDocInfo(validUri, mUserId, consumer);
104 
105         // this is a test double that requires explicitly loading. @see TestLoaderManager
106         mLoaderManager.getLoader(0).startLoading();
107 
108         consumer.assertCalled(1000, TimeUnit.MILLISECONDS);
109 
110         assertNotNull(consumer.getValue());
111         assertEquals(consumer.getValue().displayName, TEST_DOC_NAME);
112         assertEquals(consumer.getValue().size, 0);
113     }
114 
115     /**
116      * Test invalid uri, DocumentInfo returned should be null.
117      */
118     @Test
testInvalidInput()119     public void testInvalidInput() throws Exception {
120         Uri invalidUri = Uri.parse("content://poodles/chuckleberry/ham");
121         LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1);
122         mLoader.loadDocInfo(invalidUri, mUserId, consumer);
123 
124         // this is a test double that requires explicitly loading. @see TestLoaderManager
125         mLoaderManager.getLoader(0).startLoading();
126 
127         consumer.assertCalled(1000, TimeUnit.MILLISECONDS);
128         assertNull(consumer.getValue());
129     }
130 
131     @Test
testNonContentUri()132     public void testNonContentUri() {
133 
134         Uri invalidUri = Uri.parse("http://poodles/chuckleberry/ham");
135         LatchedConsumer<DocumentInfo> consumer = new LatchedConsumer<>(1);
136 
137         try {
138             mLoader.loadDocInfo(invalidUri, mUserId, consumer);
139 
140             // this is a test double that requires explicitly loading. @see TestLoaderManager
141             mLoaderManager.getLoader(0).startLoading();
142             fail("Should have thrown exception.");
143         } catch (Exception expected) {
144         }
145     }
146 
147     @Test
testDir_loadNumberOfChildren()148     public void testDir_loadNumberOfChildren() throws Exception {
149         Uri dirUri = DocumentsContract.buildDocumentUri(
150                 InspectorProvider.AUTHORITY, DIR_TOP);
151 
152         DocumentInfo info = DocumentInfo.fromUri(mResolver, dirUri, mUserId);
153 
154         LatchedConsumer<Integer> consumer = new LatchedConsumer<>(1);
155         mLoader.loadDirCount(info, consumer);
156         mLoaderManager.getLoader(0).startLoading();
157 
158         consumer.assertCalled(1000, TimeUnit.MILLISECONDS);
159         assertEquals(consumer.getValue().intValue(), 4);
160     }
161 
162     @Test
testDir_notADirectory()163     public void testDir_notADirectory() throws Exception {
164         Uri uri = DocumentsContract.buildDocumentUri(
165                 InspectorProvider.AUTHORITY, NOT_DIRECTORY);
166 
167         DocumentInfo info = DocumentInfo.fromUri(mResolver, uri, mUserId);
168         LatchedConsumer<Integer> consumer = new LatchedConsumer<>(1);
169 
170         try {
171             mLoader.loadDirCount(info, consumer);
172             mLoaderManager.getLoader(0).startLoading();
173             fail("should have thrown exception");
174         } catch (Exception expected) {
175         }
176     }
177 
178     @Test
testLoadMetadata()179     public void testLoadMetadata() throws Exception {
180         Uri uri = DocumentsContract.buildDocumentUri(
181                 InspectorProvider.AUTHORITY, InspectorProvider.TEST_JPEG);
182         LatchedConsumer<Bundle> consumer = new LatchedConsumer<>(1);
183 
184         mLoader.getDocumentMetadata(uri, mUserId, consumer);
185         mLoaderManager.getLoader(0).startLoading();
186 
187         consumer.assertCalled(100, TimeUnit.MILLISECONDS);
188         assertNotNull(consumer.getValue());
189         assertEquals(consumer.getValue().getInt(ExifInterface.TAG_IMAGE_WIDTH),
190                 InspectorProvider.TEST_JPEG_WIDTH);
191         assertEquals(consumer.getValue().getInt(ExifInterface.TAG_IMAGE_LENGTH),
192                 InspectorProvider.TEST_JPEG_HEIGHT);
193     }
194 
195     @Test
testLoadMetadata_Unsupported()196     public void testLoadMetadata_Unsupported() throws Exception {
197         Uri uri = DocumentsContract.buildDocumentUri(
198                 InspectorProvider.AUTHORITY, InspectorProvider.INVALID_JPEG);
199         LatchedConsumer<Bundle> consumer = new LatchedConsumer<>(1);
200 
201         mLoader.getDocumentMetadata(uri, mUserId, consumer);
202         mLoaderManager.getLoader(0).startLoading();
203 
204         consumer.assertCalled(100, TimeUnit.MILLISECONDS);
205         assertNull(consumer.getValue());
206     }
207 }
208