Index: chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java |
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..27ba022405a8878d8811ae781e4911bf0c98dae7 |
--- /dev/null |
+++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkValidatorTest.java |
@@ -0,0 +1,223 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.webapk.lib.client; |
+ |
+import static org.junit.Assert.assertEquals; |
+import static org.junit.Assert.assertFalse; |
+import static org.junit.Assert.assertNull; |
+import static org.junit.Assert.assertTrue; |
+import static org.mockito.Mockito.mock; |
+import static org.mockito.Mockito.when; |
+ |
+import android.content.Context; |
+import android.content.Intent; |
+import android.content.pm.ActivityInfo; |
+import android.content.pm.PackageInfo; |
+import android.content.pm.PackageManager; |
+import android.content.pm.PackageManager.NameNotFoundException; |
+import android.content.pm.ResolveInfo; |
+import android.content.pm.Signature; |
+ |
+import org.chromium.testing.local.LocalRobolectricTestRunner; |
+import org.junit.Assert; |
+import org.junit.Before; |
+import org.junit.Test; |
+import org.junit.runner.RunWith; |
+import org.robolectric.Robolectric; |
+import org.robolectric.annotation.Config; |
+import org.robolectric.res.builder.RobolectricPackageManager; |
+ |
+import java.net.URISyntaxException; |
+import java.util.ArrayList; |
+import java.util.List; |
+ |
+/** |
+ * Unit tests for {@link org.chromium.webapk.lib.client.WebApkValidator}. |
+ */ |
+@RunWith(LocalRobolectricTestRunner.class) |
+@Config(manifest = Config.NONE) |
+public class WebApkValidatorTest { |
+ private static final String WEBAPK_PACKAGE_NAME = "org.chromium.webapk.foo"; |
+ private static final String INVALID_WEBAPK_PACKAGE_NAME = "invalid.org.chromium.webapk.foo"; |
+ private static final String URL_OF_WEBAPK = "https://www.foo.com"; |
+ private static final String URL_WITHOUT_WEBAPK = "https://www.other.com"; |
+ |
+ private static final byte[] EXPECTED_SIGNATURE = new byte[] { |
+ 48, -126, 3, -121, 48, -126, 2, 111, -96, 3, 2, 1, 2, 2, 4, 20, -104, -66, -126, 48, 13, |
+ 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 48, 116, 49, 11, 48, 9, 6, 3, 85, 4, |
+ 6, 19, 2, 67, 65, 49, 16, 48, 14, 6, 3, 85, 4, 8, 19, 7, 79, 110, 116, 97, 114, 105, |
+ 111, 49, 17, 48, 15, 6, 3, 85, 4, 7, 19, 8, 87, 97, 116, 101, 114, 108, 111, 111, 49, |
+ 17, 48, 15, 6, 3, 85, 4, 10, 19, 8, 67, 104, 114, 111, 109, 105, 117, 109, 49, 17, 48}; |
+ |
+ private static final byte[] SIGNATURE_1 = new byte[] { |
+ 13, 52, 51, 48, 51, 48, 51, 49, 53, 49, 54, 52, 52, 90, 48, 116, 49, 11, 48, 9, 6, 3, |
+ 85, 4, 6, 19, 2, 67, 65, 49, 16, 48, 14, 6, 3, 85, 4, 8, 19, 7, 79, 110, 116, 97, 114}; |
+ |
+ private static final byte[] SIGNATURE_2 = new byte[] { |
+ 49, 17, 48, 15, 6, 3, 85, 4, 10, 19, 8, 67, 104, 114, 111, 109, 105, 117, 109, 49, 17, |
+ 48, 15, 6, 3, 85, 4, 11, 19, 8, 67, 104, 114, 111, 109, 105, 117, 109, 49, 26, 48, 24}; |
+ |
+ private Context mContext; |
+ private PackageManager mPackageManager; |
+ private PackageInfo mWebApkPackageInfo; |
+ private PackageInfo mInvalidWebApkPackageInfo; |
+ |
+ @Before |
+ public void setUp() { |
+ mContext = mock(Context.class); |
+ mPackageManager = mock(PackageManager.class); |
+ when(mContext.getPackageManager()).thenReturn(mPackageManager); |
+ WebApkValidator.initWithBrowserHostSignature(EXPECTED_SIGNATURE); |
+ } |
+ |
+ /** |
+ * Tests {@link WebApkValidator.queryWebApkPackage()} returns a WebAPK's package name if the |
+ * WebAPK can handle the given URL. |
+ */ |
+ @Test |
+ public void testQueryWebApkPackageReturnsWebApkPackageNameIfTheURLCanBeHandled() { |
+ try { |
+ Intent intent = Intent.parseUri(URL_OF_WEBAPK, Intent.URI_INTENT_SCHEME); |
+ intent.addCategory(Intent.CATEGORY_BROWSABLE); |
+ |
+ ResolveInfo info = newResolveInfo(WEBAPK_PACKAGE_NAME); |
+ RobolectricPackageManager packageManager = |
+ (RobolectricPackageManager) Robolectric.application.getPackageManager(); |
+ packageManager.addResolveInfoForIntent(intent, info); |
+ |
+ assertEquals(WEBAPK_PACKAGE_NAME, |
+ WebApkValidator.queryWebApkPackage(Robolectric.application, URL_OF_WEBAPK)); |
+ } catch (URISyntaxException e) { |
+ Assert.fail("URI is invalid."); |
+ } |
+ } |
+ |
+ /** |
+ * Tests {@link WebApkValidator.queryWebApkPackage()} returns null for a non-browsable Intent. |
+ */ |
+ @Test |
+ public void testQueryWebApkPackageReturnsNullForNonBrowsableIntent() { |
+ try { |
+ Intent intent = Intent.parseUri(URL_OF_WEBAPK, Intent.URI_INTENT_SCHEME); |
+ |
+ ResolveInfo info = newResolveInfo(WEBAPK_PACKAGE_NAME); |
+ RobolectricPackageManager packageManager = |
+ (RobolectricPackageManager) Robolectric.application.getPackageManager(); |
+ packageManager.addResolveInfoForIntent(intent, info); |
+ |
+ assertNull(WebApkValidator.queryWebApkPackage( |
+ Robolectric.application, URL_OF_WEBAPK)); |
+ } catch (URISyntaxException e) { |
+ Assert.fail("URI is invalid."); |
+ } |
+ } |
+ |
+ /** |
+ * Tests {@link WebApkValidator.queryWebApkPackage()} returns null if no WebAPK handles |
+ * the given URL. |
+ */ |
+ @Test |
+ public void testQueryWebApkPackageReturnsNullWhenNoWebApkHandlesTheURL() { |
+ try { |
+ Intent intent = Intent.parseUri(URL_OF_WEBAPK, Intent.URI_INTENT_SCHEME); |
+ intent.addCategory(Intent.CATEGORY_BROWSABLE); |
+ |
+ ResolveInfo info = newResolveInfo(WEBAPK_PACKAGE_NAME); |
+ RobolectricPackageManager packageManager = |
+ (RobolectricPackageManager) Robolectric.application.getPackageManager(); |
+ packageManager.addResolveInfoForIntent(intent, info); |
+ |
+ assertNull(WebApkValidator.queryWebApkPackage( |
+ Robolectric.application, URL_WITHOUT_WEBAPK)); |
+ } catch (URISyntaxException e) { |
+ Assert.fail("URI is invalid."); |
+ } |
+ } |
+ |
+ /** |
+ * Tests {@link WebApkValidator.findWebApkPackage()} returns a WebAPK's package name when there |
+ * are ResolveInfos corresponds to a WebAPK. |
+ */ |
+ @Test |
+ public void testFindWebApkPackageReturnsWebApkPackageName() { |
+ List<ResolveInfo> infos = new ArrayList<ResolveInfo>(); |
+ infos.add(newResolveInfo(WEBAPK_PACKAGE_NAME)); |
+ assertEquals(WEBAPK_PACKAGE_NAME, WebApkValidator.findWebApkPackage(infos)); |
+ } |
+ |
+ /** |
+ * Tests {@link WebApkValidator.findWebApkPackage()} returns null when there isn't any |
+ * ResolveInfos corresponds to a WebAPK. |
+ */ |
+ @Test |
+ public void testFindWebApkPackageReturnsNullWhenNoResolveInfosCorrespondingToWebApk() { |
+ List<ResolveInfo> infos = new ArrayList<ResolveInfo>(); |
+ infos.add(newResolveInfo("com.google.android")); |
+ assertNull(WebApkValidator.findWebApkPackage(infos)); |
+ } |
+ /** |
+ * Tests {@link WebApkValidator.IsValidWebApk} returns false for a package that doesn't start |
+ * with {@link WebApkConstants.WEBAPK_PACKAGE_PREFIX}. |
+ */ |
+ @Test |
+ public void testIsValidWebApkReturnsFalseForInvalidPackageName() { |
+ assertFalse(WebApkValidator.isValidWebApk(Robolectric.application.getApplicationContext(), |
+ INVALID_WEBAPK_PACKAGE_NAME)); |
+ } |
+ |
+ /** |
+ * Tests {@link WebApkValidator.IsValidWebApk} returns true if the WebAPK has the expected |
+ * signature. |
+ */ |
+ @Test |
+ public void testIsValidWebApkReturnsTrueForValidWebApk() throws NameNotFoundException { |
+ mWebApkPackageInfo = mock(PackageInfo.class); |
+ when(mPackageManager.getPackageInfo(WEBAPK_PACKAGE_NAME, PackageManager.GET_SIGNATURES)) |
+ .thenReturn(mWebApkPackageInfo); |
+ mWebApkPackageInfo.signatures = new Signature[] {new Signature(EXPECTED_SIGNATURE)}; |
+ |
+ assertTrue(WebApkValidator.isValidWebApk(mContext, WEBAPK_PACKAGE_NAME)); |
+ } |
+ |
+ /** |
+ * Tests {@link WebApkValidator.IsValidWebApk} returns true if a WebAPK has multiple |
+ * signatures and one matches the expected signature. |
+ */ |
+ @Test |
+ public void testIsValidWebApkReturnsTrueForWebApkWithMultipleSignaturesAndOneMatched() |
+ throws NameNotFoundException { |
+ mWebApkPackageInfo = mock(PackageInfo.class); |
+ when(mPackageManager.getPackageInfo(WEBAPK_PACKAGE_NAME, PackageManager.GET_SIGNATURES)) |
+ .thenReturn(mWebApkPackageInfo); |
+ mWebApkPackageInfo.signatures = new Signature[] {new Signature(SIGNATURE_1), |
+ new Signature(SIGNATURE_2), new Signature(EXPECTED_SIGNATURE)}; |
+ |
+ assertTrue(WebApkValidator.isValidWebApk(mContext, WEBAPK_PACKAGE_NAME)); |
+ } |
+ |
+ /** |
+ * Tests {@link WebApkValidator.IsValidWebApk} returns false if a WebAPK has multiple |
+ * signatures but none of them matches the expected signature. |
+ */ |
+ @Test |
+ public void testIsValidWebApkReturnsFalseForWebApkWithMultipleSignaturesWithoutAnyMatched() |
+ throws NameNotFoundException { |
+ mWebApkPackageInfo = mock(PackageInfo.class); |
+ when(mPackageManager.getPackageInfo(WEBAPK_PACKAGE_NAME, PackageManager.GET_SIGNATURES)) |
+ .thenReturn(mWebApkPackageInfo); |
+ mWebApkPackageInfo.signatures = new Signature[] {new Signature(SIGNATURE_1), |
+ new Signature(SIGNATURE_2)}; |
+ |
+ assertFalse(WebApkValidator.isValidWebApk(mContext, WEBAPK_PACKAGE_NAME)); |
+ } |
+ |
+ private static ResolveInfo newResolveInfo(String packageName) { |
+ ActivityInfo activityInfo = new ActivityInfo(); |
+ activityInfo.packageName = packageName; |
+ ResolveInfo resolveInfo = new ResolveInfo(); |
+ resolveInfo.activityInfo = activityInfo; |
+ return resolveInfo; |
+ } |
+} |