| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser; | 5 package org.chromium.chrome.browser; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.net.Uri; | 8 import android.net.Uri; |
| 9 import android.os.Environment; | 9 import android.os.Environment; |
| 10 import android.support.test.InstrumentationRegistry; |
| 10 import android.support.test.filters.MediumTest; | 11 import android.support.test.filters.MediumTest; |
| 11 | 12 |
| 13 import org.junit.After; |
| 14 import org.junit.Assert; |
| 15 import org.junit.Before; |
| 16 import org.junit.Rule; |
| 17 import org.junit.Test; |
| 18 import org.junit.runner.RunWith; |
| 19 |
| 12 import org.chromium.base.ThreadUtils; | 20 import org.chromium.base.ThreadUtils; |
| 21 import org.chromium.base.test.util.CommandLineFlags; |
| 13 import org.chromium.base.test.util.Feature; | 22 import org.chromium.base.test.util.Feature; |
| 14 import org.chromium.base.test.util.RetryOnFailure; | 23 import org.chromium.base.test.util.RetryOnFailure; |
| 15 import org.chromium.base.test.util.TestFileUtil; | 24 import org.chromium.base.test.util.TestFileUtil; |
| 16 import org.chromium.base.test.util.UrlUtils; | 25 import org.chromium.base.test.util.UrlUtils; |
| 17 import org.chromium.chrome.test.ChromeActivityTestCaseBase; | 26 import org.chromium.chrome.test.ChromeActivityTestRule; |
| 27 import org.chromium.chrome.test.ChromeJUnit4ClassRunner; |
| 18 import org.chromium.chrome.test.TestContentProvider; | 28 import org.chromium.chrome.test.TestContentProvider; |
| 19 import org.chromium.content.browser.test.util.Criteria; | 29 import org.chromium.content.browser.test.util.Criteria; |
| 20 import org.chromium.content.browser.test.util.CriteriaHelper; | 30 import org.chromium.content.browser.test.util.CriteriaHelper; |
| 21 import org.chromium.net.test.EmbeddedTestServer; | 31 import org.chromium.net.test.EmbeddedTestServer; |
| 22 | 32 |
| 23 import java.io.File; | 33 import java.io.File; |
| 24 import java.io.IOException; | 34 import java.io.IOException; |
| 25 import java.io.InputStream; | 35 import java.io.InputStream; |
| 26 import java.util.concurrent.Callable; | 36 import java.util.concurrent.Callable; |
| 27 | 37 |
| 28 /** Test suite for different Android URL schemes. */ | 38 /** Test suite for different Android URL schemes. */ |
| 39 @RunWith(ChromeJUnit4ClassRunner.class) |
| 29 @RetryOnFailure | 40 @RetryOnFailure |
| 30 public class UrlSchemeTest extends ChromeActivityTestCaseBase<ChromeActivity> { | 41 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, |
| 42 ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG}) |
| 43 public class UrlSchemeTest { |
| 44 @Rule |
| 45 public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = |
| 46 new ChromeActivityTestRule<>(ChromeActivity.class); |
| 47 |
| 31 private static final String SIMPLE_SRC = "simple.html"; | 48 private static final String SIMPLE_SRC = "simple.html"; |
| 32 private static final String SIMPLE_IMAGE = "google.png"; | 49 private static final String SIMPLE_IMAGE = "google.png"; |
| 33 | 50 |
| 34 private EmbeddedTestServer mTestServer; | 51 private EmbeddedTestServer mTestServer; |
| 35 | 52 |
| 36 public UrlSchemeTest() { | 53 @Before |
| 37 super(ChromeActivity.class); | 54 public void setUp() throws Exception { |
| 55 mActivityTestRule.startMainActivityFromLauncher(); |
| 56 TestContentProvider.resetResourceRequestCounts( |
| 57 InstrumentationRegistry.getInstrumentation().getTargetContext())
; |
| 58 TestContentProvider.setDataFilePath( |
| 59 InstrumentationRegistry.getInstrumentation().getTargetContext(), |
| 60 UrlUtils.getTestFilePath("")); |
| 61 mTestServer = EmbeddedTestServer.createAndStartServer( |
| 62 InstrumentationRegistry.getInstrumentation().getContext()); |
| 38 } | 63 } |
| 39 | 64 |
| 40 @Override | 65 @After |
| 41 public void setUp() throws Exception { | 66 public void tearDown() throws Exception { |
| 42 super.setUp(); | |
| 43 TestContentProvider.resetResourceRequestCounts(getInstrumentation().getT
argetContext()); | |
| 44 TestContentProvider.setDataFilePath(getInstrumentation().getTargetContex
t(), | |
| 45 UrlUtils.getTestFilePath("")); | |
| 46 mTestServer = EmbeddedTestServer.createAndStartServer(getInstrumentation
().getContext()); | |
| 47 } | |
| 48 | |
| 49 @Override | |
| 50 protected void tearDown() throws Exception { | |
| 51 mTestServer.stopAndDestroyServer(); | 67 mTestServer.stopAndDestroyServer(); |
| 52 super.tearDown(); | |
| 53 } | 68 } |
| 54 | 69 |
| 55 /** | 70 /** |
| 56 * Test that resource request count in the content provider works. | 71 * Test that resource request count in the content provider works. |
| 57 * This is to make sure that attempts to access the content provider | 72 * This is to make sure that attempts to access the content provider |
| 58 * will be detected. | 73 * will be detected. |
| 59 */ | 74 */ |
| 75 @Test |
| 60 @MediumTest | 76 @MediumTest |
| 61 @Feature({"Navigation"}) | 77 @Feature({"Navigation"}) |
| 62 public void testContentProviderResourceRequestCount() throws IOException { | 78 public void testContentProviderResourceRequestCount() throws IOException { |
| 63 String resource = SIMPLE_SRC; | 79 String resource = SIMPLE_SRC; |
| 64 ensureResourceRequestCountInContentProvider(resource, 0); | 80 ensureResourceRequestCountInContentProvider(resource, 0); |
| 65 // Make a request to the content provider. | 81 // Make a request to the content provider. |
| 66 Uri uri = Uri.parse(createContentUrl(resource)); | 82 Uri uri = Uri.parse(createContentUrl(resource)); |
| 67 Context context = getInstrumentation().getContext(); | 83 Context context = InstrumentationRegistry.getInstrumentation().getContex
t(); |
| 68 InputStream inputStream = null; | 84 InputStream inputStream = null; |
| 69 try { | 85 try { |
| 70 inputStream = context.getContentResolver().openInputStream(uri); | 86 inputStream = context.getContentResolver().openInputStream(uri); |
| 71 assertNotNull(inputStream); | 87 Assert.assertNotNull(inputStream); |
| 72 } finally { | 88 } finally { |
| 73 if (inputStream != null) inputStream.close(); | 89 if (inputStream != null) inputStream.close(); |
| 74 } | 90 } |
| 75 ensureResourceRequestCountInContentProvider(resource, 1); | 91 ensureResourceRequestCountInContentProvider(resource, 1); |
| 76 } | 92 } |
| 77 | 93 |
| 78 /** | 94 /** |
| 79 * Make sure content URL access works. | 95 * Make sure content URL access works. |
| 80 */ | 96 */ |
| 97 @Test |
| 81 @MediumTest | 98 @MediumTest |
| 82 @Feature({"Navigation"}) | 99 @Feature({"Navigation"}) |
| 83 public void testContentUrlAccess() throws InterruptedException { | 100 public void testContentUrlAccess() throws InterruptedException { |
| 84 String resource = SIMPLE_SRC; | 101 String resource = SIMPLE_SRC; |
| 85 loadUrl(createContentUrl(resource)); | 102 mActivityTestRule.loadUrl(createContentUrl(resource)); |
| 86 ensureResourceRequestCountInContentProviderNotLessThan(resource, 1); | 103 ensureResourceRequestCountInContentProviderNotLessThan(resource, 1); |
| 87 } | 104 } |
| 88 | 105 |
| 89 /** | 106 /** |
| 90 * Make sure a Content url *CANNOT* access the contents of an iframe that is
loaded as a | 107 * Make sure a Content url *CANNOT* access the contents of an iframe that is
loaded as a |
| 91 * content URL. | 108 * content URL. |
| 92 */ | 109 */ |
| 110 @Test |
| 93 @MediumTest | 111 @MediumTest |
| 94 @Feature({"Navigation"}) | 112 @Feature({"Navigation"}) |
| 95 public void testContentUrlIframeAccessFromContentUrl() throws Throwable { | 113 public void testContentUrlIframeAccessFromContentUrl() throws Throwable { |
| 96 final String resource = "page_with_iframe_as_content_url.html"; | 114 final String resource = "page_with_iframe_as_content_url.html"; |
| 97 final String iframe = "simple_iframe.html"; | 115 final String iframe = "simple_iframe.html"; |
| 98 final String iframeId = "iframe_test_id"; | 116 final String iframeId = "iframe_test_id"; |
| 99 | 117 |
| 100 final String script = "var ifrm = document.getElementById('" + iframeId
+ "');" | 118 final String script = "var ifrm = document.getElementById('" + iframeId
+ "');" |
| 101 + "try {" | 119 + "try {" |
| 102 + " var a = ifrm.contentWindow.document.body.textContent;" | 120 + " var a = ifrm.contentWindow.document.body.textContent;" |
| 103 + "} catch (e) {" | 121 + "} catch (e) {" |
| 104 + " document.title = 'fail';" | 122 + " document.title = 'fail';" |
| 105 + "}"; | 123 + "}"; |
| 106 | 124 |
| 107 loadUrl(createContentUrl(resource)); | 125 mActivityTestRule.loadUrl(createContentUrl(resource)); |
| 108 | 126 |
| 109 // Make sure iframe is really loaded by verifying the title | 127 // Make sure iframe is really loaded by verifying the title |
| 110 CriteriaHelper.pollUiThread(new Criteria() { | 128 CriteriaHelper.pollUiThread(new Criteria() { |
| 111 @Override | 129 @Override |
| 112 public boolean isSatisfied() { | 130 public boolean isSatisfied() { |
| 113 return getActivity().getActivityTab().getTitle().equals("iframe
loaded"); | 131 return mActivityTestRule.getActivity().getActivityTab().getTitle
().equals( |
| 132 "iframe loaded"); |
| 114 } | 133 } |
| 115 }); | 134 }); |
| 116 // Make sure that content provider was asked to provide the content. | 135 // Make sure that content provider was asked to provide the content. |
| 117 ensureResourceRequestCountInContentProviderNotLessThan(iframe, 1); | 136 ensureResourceRequestCountInContentProviderNotLessThan(iframe, 1); |
| 118 runJavaScriptCodeInCurrentTab(script); | 137 mActivityTestRule.runJavaScriptCodeInCurrentTab(script); |
| 119 | 138 |
| 120 // Make sure content access failed by verifying that title is set to fai
l. | 139 // Make sure content access failed by verifying that title is set to fai
l. |
| 121 CriteriaHelper.pollUiThread(new Criteria() { | 140 CriteriaHelper.pollUiThread(new Criteria() { |
| 122 @Override | 141 @Override |
| 123 public boolean isSatisfied() { | 142 public boolean isSatisfied() { |
| 124 return getActivity().getActivityTab().getTitle().equals("fail"); | 143 return mActivityTestRule.getActivity().getActivityTab().getTitle
().equals("fail"); |
| 125 } | 144 } |
| 126 }); | 145 }); |
| 127 } | 146 } |
| 128 | 147 |
| 129 /** | 148 /** |
| 130 * Test that a content URL is *ALLOWED* to access an image provided by a con
tent URL. | 149 * Test that a content URL is *ALLOWED* to access an image provided by a con
tent URL. |
| 131 */ | 150 */ |
| 151 @Test |
| 132 @MediumTest | 152 @MediumTest |
| 133 @Feature({"Navigation"}) | 153 @Feature({"Navigation"}) |
| 134 public void testContentUrlImageFromContentUrl() throws Throwable { | 154 public void testContentUrlImageFromContentUrl() throws Throwable { |
| 135 verifyImageLoadRules(createContentUrl(SIMPLE_SRC), "success", 1); | 155 verifyImageLoadRules(createContentUrl(SIMPLE_SRC), "success", 1); |
| 136 } | 156 } |
| 137 | 157 |
| 138 /** | 158 /** |
| 139 * Test that a HTTP URL is *NOT ALLOWED* to access an image provided by a co
ntent URL. | 159 * Test that a HTTP URL is *NOT ALLOWED* to access an image provided by a co
ntent URL. |
| 140 */ | 160 */ |
| 161 @Test |
| 141 @MediumTest | 162 @MediumTest |
| 142 @Feature({"Navigation"}) | 163 @Feature({"Navigation"}) |
| 143 public void testContentUrlImageFromHttpUrl() throws Throwable { | 164 public void testContentUrlImageFromHttpUrl() throws Throwable { |
| 144 final String main = mTestServer.getURL("/chrome/test/data/android/" + SI
MPLE_SRC); | 165 final String main = mTestServer.getURL("/chrome/test/data/android/" + SI
MPLE_SRC); |
| 145 verifyImageLoadRules(main, "error", 0); | 166 verifyImageLoadRules(main, "error", 0); |
| 146 } | 167 } |
| 147 | 168 |
| 148 private void verifyImageLoadRules(String url, final String expectedTitle, in
t expectedLoadCount) | 169 private void verifyImageLoadRules(String url, final String expectedTitle, in
t expectedLoadCount) |
| 149 throws Throwable { | 170 throws Throwable { |
| 150 final String resource = SIMPLE_IMAGE; | 171 final String resource = SIMPLE_IMAGE; |
| 151 final String script = "var img = new Image();" | 172 final String script = "var img = new Image();" |
| 152 + " img.onerror = function() { document.title = 'error' };" | 173 + " img.onerror = function() { document.title = 'error' };" |
| 153 + " img.onabort = function() { document.title = 'error' };" | 174 + " img.onabort = function() { document.title = 'error' };" |
| 154 + " img.onload = function() { document.title = 'success' };" | 175 + " img.onload = function() { document.title = 'success' };" |
| 155 + " img.src = '" + createContentUrl(resource) + "';" | 176 + " img.src = '" + createContentUrl(resource) + "';" |
| 156 + " document.body.appendChild(img);"; | 177 + " document.body.appendChild(img);"; |
| 157 loadUrl(url); | 178 mActivityTestRule.loadUrl(url); |
| 158 runJavaScriptCodeInCurrentTab(script); | 179 mActivityTestRule.runJavaScriptCodeInCurrentTab(script); |
| 159 | 180 |
| 160 CriteriaHelper.pollUiThread(new Criteria() { | 181 CriteriaHelper.pollUiThread(new Criteria() { |
| 161 @Override | 182 @Override |
| 162 public boolean isSatisfied() { | 183 public boolean isSatisfied() { |
| 163 return getActivity().getActivityTab().getTitle().equals(expected
Title); | 184 return mActivityTestRule.getActivity().getActivityTab().getTitle
().equals( |
| 185 expectedTitle); |
| 164 } | 186 } |
| 165 }); | 187 }); |
| 166 ensureResourceRequestCountInContentProviderNotLessThan(resource, expecte
dLoadCount); | 188 ensureResourceRequestCountInContentProviderNotLessThan(resource, expecte
dLoadCount); |
| 167 } | 189 } |
| 168 | 190 |
| 169 /** | 191 /** |
| 170 * Test that a content URL is not allowed within a data URL. | 192 * Test that a content URL is not allowed within a data URL. |
| 171 */ | 193 */ |
| 194 @Test |
| 172 @MediumTest | 195 @MediumTest |
| 173 @Feature({"Navigation"}) | 196 @Feature({"Navigation"}) |
| 174 public void testContentUrlFromData() throws InterruptedException { | 197 public void testContentUrlFromData() throws InterruptedException { |
| 175 final String target = SIMPLE_IMAGE; | 198 final String target = SIMPLE_IMAGE; |
| 176 loadUrl(UrlUtils.encodeHtmlDataUri( | 199 mActivityTestRule.loadUrl( |
| 177 "<img src=\"" + createContentUrl(target) + "\">")); | 200 UrlUtils.encodeHtmlDataUri("<img src=\"" + createContentUrl(targ
et) + "\">")); |
| 178 ensureResourceRequestCountInContentProvider(target, 0); | 201 ensureResourceRequestCountInContentProvider(target, 0); |
| 179 } | 202 } |
| 180 | 203 |
| 181 /** | 204 /** |
| 182 * Test that a content URL is not allowed within a local file. | 205 * Test that a content URL is not allowed within a local file. |
| 183 */ | 206 */ |
| 207 @Test |
| 184 @MediumTest | 208 @MediumTest |
| 185 @Feature({"Navigation"}) | 209 @Feature({"Navigation"}) |
| 186 public void testContentUrlFromFile() throws InterruptedException, IOExceptio
n { | 210 public void testContentUrlFromFile() throws InterruptedException, IOExceptio
n { |
| 187 final String target = SIMPLE_IMAGE; | 211 final String target = SIMPLE_IMAGE; |
| 188 final File file = new File(Environment.getExternalStorageDirectory(), ta
rget + ".html"); | 212 final File file = new File(Environment.getExternalStorageDirectory(), ta
rget + ".html"); |
| 189 try { | 213 try { |
| 190 TestFileUtil.createNewHtmlFile( | 214 TestFileUtil.createNewHtmlFile( |
| 191 file, target, "<img src=\"" + createContentUrl(target) + "\"
>"); | 215 file, target, "<img src=\"" + createContentUrl(target) + "\"
>"); |
| 192 loadUrl("file:///" + file.getAbsolutePath()); | 216 mActivityTestRule.loadUrl("file:///" + file.getAbsolutePath()); |
| 193 ensureResourceRequestCountInContentProvider(target, 0); | 217 ensureResourceRequestCountInContentProvider(target, 0); |
| 194 } finally { | 218 } finally { |
| 195 TestFileUtil.deleteFile(file); | 219 TestFileUtil.deleteFile(file); |
| 196 } | 220 } |
| 197 } | 221 } |
| 198 | 222 |
| 199 private String getTitleOnUiThread() { | 223 private String getTitleOnUiThread() { |
| 200 return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<String>
() { | 224 return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<String>
() { |
| 201 @Override | 225 @Override |
| 202 public String call() throws Exception { | 226 public String call() throws Exception { |
| 203 return getActivity().getActivityTab().getTitle(); | 227 return mActivityTestRule.getActivity().getActivityTab().getTitle
(); |
| 204 } | 228 } |
| 205 }); | 229 }); |
| 206 } | 230 } |
| 207 | 231 |
| 208 /** | 232 /** |
| 209 * Test that the browser can be navigated to a file URL. | 233 * Test that the browser can be navigated to a file URL. |
| 210 */ | 234 */ |
| 235 @Test |
| 211 @MediumTest | 236 @MediumTest |
| 212 @Feature({"Navigation"}) | 237 @Feature({"Navigation"}) |
| 213 public void testFileUrlNavigation() throws InterruptedException, IOException
{ | 238 public void testFileUrlNavigation() throws InterruptedException, IOException
{ |
| 214 final File file = new File(Environment.getExternalStorageDirectory(), | 239 final File file = new File(Environment.getExternalStorageDirectory(), |
| 215 "url_navigation_test.html"); | 240 "url_navigation_test.html"); |
| 216 | 241 |
| 217 try { | 242 try { |
| 218 TestFileUtil.createNewHtmlFile(file, "File", null); | 243 TestFileUtil.createNewHtmlFile(file, "File", null); |
| 219 loadUrl("file://" + file.getAbsolutePath()); | 244 mActivityTestRule.loadUrl("file://" + file.getAbsolutePath()); |
| 220 assertEquals("File", getTitleOnUiThread()); | 245 Assert.assertEquals("File", getTitleOnUiThread()); |
| 221 } finally { | 246 } finally { |
| 222 TestFileUtil.deleteFile(file); | 247 TestFileUtil.deleteFile(file); |
| 223 } | 248 } |
| 224 } | 249 } |
| 225 | 250 |
| 226 /** | 251 /** |
| 227 * Verifies the number of resource requests made to the content provider. | 252 * Verifies the number of resource requests made to the content provider. |
| 228 * @param resource Resource name | 253 * @param resource Resource name |
| 229 * @param expectedCount Expected resource requests count | 254 * @param expectedCount Expected resource requests count |
| 230 */ | 255 */ |
| 231 private void ensureResourceRequestCountInContentProvider(String resource, in
t expectedCount) { | 256 private void ensureResourceRequestCountInContentProvider(String resource, in
t expectedCount) { |
| 232 Context context = getInstrumentation().getTargetContext(); | 257 Context context = InstrumentationRegistry.getInstrumentation().getTarget
Context(); |
| 233 int actualCount = TestContentProvider.getResourceRequestCount(context, r
esource); | 258 int actualCount = TestContentProvider.getResourceRequestCount(context, r
esource); |
| 234 assertEquals(expectedCount, actualCount); | 259 Assert.assertEquals(expectedCount, actualCount); |
| 235 } | 260 } |
| 236 | 261 |
| 237 /** | 262 /** |
| 238 * Verifies the number of resource requests made to the content provider. | 263 * Verifies the number of resource requests made to the content provider. |
| 239 * @param resource Resource name | 264 * @param resource Resource name |
| 240 * @param expectedMinimalCount Expected minimal resource requests count | 265 * @param expectedMinimalCount Expected minimal resource requests count |
| 241 */ | 266 */ |
| 242 private void ensureResourceRequestCountInContentProviderNotLessThan( | 267 private void ensureResourceRequestCountInContentProviderNotLessThan( |
| 243 String resource, int expectedMinimalCount) { | 268 String resource, int expectedMinimalCount) { |
| 244 Context context = getInstrumentation().getTargetContext(); | 269 Context context = InstrumentationRegistry.getInstrumentation().getTarget
Context(); |
| 245 int actualCount = TestContentProvider.getResourceRequestCount(context, r
esource); | 270 int actualCount = TestContentProvider.getResourceRequestCount(context, r
esource); |
| 246 assertTrue("Minimal expected: " + expectedMinimalCount + ", actual: " +
actualCount, | 271 Assert.assertTrue("Minimal expected: " + expectedMinimalCount + ", actua
l: " + actualCount, |
| 247 actualCount >= expectedMinimalCount); | 272 actualCount >= expectedMinimalCount); |
| 248 } | 273 } |
| 249 | 274 |
| 250 private String createContentUrl(final String target) { | 275 private String createContentUrl(final String target) { |
| 251 return TestContentProvider.createContentUrl(target); | 276 return TestContentProvider.createContentUrl(target); |
| 252 } | 277 } |
| 253 | |
| 254 @Override | |
| 255 public void startMainActivity() throws InterruptedException { | |
| 256 startMainActivityFromLauncher(); | |
| 257 } | |
| 258 } | 278 } |
| OLD | NEW |