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 android.content.ContentResolver; 19 import android.content.Context; 20 import android.net.Uri; 21 import android.os.Looper; 22 import android.provider.DocumentsContract; 23 import android.support.annotation.Nullable; 24 import android.support.test.InstrumentationRegistry; 25 import com.android.documentsui.InspectorProvider; 26 import android.test.suitebuilder.annotation.MediumTest; 27 import com.android.documentsui.base.DocumentInfo; 28 import com.android.documentsui.inspector.InspectorController.DataSupplier; 29 import com.android.documentsui.testing.TestLoaderManager; 30 import java.util.concurrent.CountDownLatch; 31 import java.util.concurrent.TimeUnit; 32 import java.util.function.Consumer; 33 import junit.framework.TestCase; 34 import org.junit.Before; 35 import org.junit.Test; 36 37 /** 38 * This test relies the inspector providers test.txt file in inspector root. 39 */ 40 @MediumTest 41 public class DocumentLoaderTest extends TestCase { 42 43 private static final String TEST_DOC_NAME = "test.txt"; 44 private static final String DIR_TOP = "Top"; 45 private static final String NOT_DIRECTORY = "OpenInProviderTest"; 46 47 private Context mContext; 48 private TestLoaderManager mLoaderManager; 49 private DataSupplier mLoader; 50 private ContentResolver mResolver; 51 52 @Before setUp()53 public void setUp() throws Exception { 54 super.setUp(); 55 mContext = InstrumentationRegistry.getTargetContext(); 56 mResolver = mContext.getContentResolver(); 57 mLoaderManager = new TestLoaderManager(); 58 mLoader = new RuntimeDataSupplier(mContext, mLoaderManager); 59 60 if (Looper.myLooper() == null) { 61 Looper.prepare(); 62 } 63 } 64 65 /** 66 * Tests the loader using the Inspector Content provider. This test that we got valid info back 67 * from the loader. 68 * 69 * @throws Exception 70 */ 71 @Test testLoadsDocument()72 public void testLoadsDocument() throws Exception { 73 Uri validUri = DocumentsContract.buildDocumentUri( 74 InspectorProvider.AUTHORITY, TEST_DOC_NAME); 75 TestDocConsumer consumer = new TestDocConsumer(1); 76 mLoader.loadDocInfo(validUri, consumer); 77 78 // this is a test double that requires explicitly loading. @see TestLoaderManager 79 mLoaderManager.getLoader(0).startLoading(); 80 81 consumer.latch.await(1000, TimeUnit.MILLISECONDS); 82 83 assertNotNull(consumer.info); 84 assertEquals(consumer.info.displayName, TEST_DOC_NAME); 85 assertEquals(consumer.info.size, 0); 86 } 87 88 /** 89 * Test invalid uri, DocumentInfo returned should be null. 90 * 91 * @throws Exception 92 */ 93 @Test testInvalidInput()94 public void testInvalidInput() throws Exception { 95 Uri invalidUri = Uri.parse("content://poodles/chuckleberry/ham"); 96 TestDocConsumer consumer = new TestDocConsumer(1); 97 mLoader.loadDocInfo(invalidUri, consumer); 98 99 // this is a test double that requires explicitly loading. @see TestLoaderManager 100 mLoaderManager.getLoader(0).startLoading(); 101 102 consumer.latch.await(1000, TimeUnit.MILLISECONDS); 103 assertNull(consumer.info); 104 } 105 106 @Test testNonContentUri()107 public void testNonContentUri() { 108 109 Uri invalidUri = Uri.parse("http://poodles/chuckleberry/ham"); 110 TestDocConsumer consumer = new TestDocConsumer(1); 111 112 try { 113 mLoader.loadDocInfo(invalidUri, consumer); 114 115 // this is a test double that requires explicitly loading. @see TestLoaderManager 116 mLoaderManager.getLoader(0).startLoading(); 117 fail("Should have thrown exception."); 118 } catch (Exception expected) {} 119 } 120 121 @Test testDir_loadNumberOfChildren()122 public void testDir_loadNumberOfChildren() throws Exception { 123 Uri dirUri = DocumentsContract.buildDocumentUri( 124 InspectorProvider.AUTHORITY, DIR_TOP); 125 126 DocumentInfo info = DocumentInfo.fromUri(mResolver, dirUri); 127 128 TestDirConsumer consumer = new TestDirConsumer(1); 129 mLoader.loadDirCount(info, consumer); 130 mLoaderManager.getLoader(0).startLoading(); 131 132 consumer.latch.await(1000, TimeUnit.MILLISECONDS); 133 assertEquals(consumer.childCount, 4); 134 } 135 136 @Test testDir_notADirectory()137 public void testDir_notADirectory() throws Exception { 138 Uri uri = DocumentsContract.buildDocumentUri( 139 InspectorProvider.AUTHORITY, NOT_DIRECTORY); 140 141 DocumentInfo info = DocumentInfo.fromUri(mResolver, uri); 142 TestDirConsumer consumer = new TestDirConsumer(1); 143 144 try { 145 mLoader.loadDirCount(info, consumer); 146 mLoaderManager.getLoader(0).startLoading(); 147 fail("should have thrown exception"); 148 } catch (Exception expected) {} 149 } 150 151 /** 152 * Helper function for testing async processes. 153 */ 154 private static class TestDocConsumer implements Consumer<DocumentInfo> { 155 156 private DocumentInfo info; 157 private CountDownLatch latch; 158 TestDocConsumer(int expectedCount)159 public TestDocConsumer(int expectedCount) { 160 latch = new CountDownLatch(expectedCount); 161 } 162 163 @Nullable 164 @Override accept(DocumentInfo documentInfo)165 public void accept(DocumentInfo documentInfo) { 166 info = documentInfo; 167 latch.countDown(); 168 } 169 } 170 171 private static class TestDirConsumer implements Consumer<Integer> { 172 173 private int childCount; 174 private CountDownLatch latch; 175 TestDirConsumer(int expectedCount)176 public TestDirConsumer(int expectedCount) { 177 latch = new CountDownLatch(expectedCount); 178 } 179 180 @Override accept(Integer integer)181 public void accept(Integer integer) { 182 childCount = integer; 183 latch.countDown(); 184 } 185 } 186 }