OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.webapk.lib.client; |
| 6 |
| 7 import static org.junit.Assert.assertEquals; |
| 8 import static org.junit.Assert.assertFalse; |
| 9 import static org.junit.Assert.assertNull; |
| 10 import static org.junit.Assert.assertTrue; |
| 11 import static org.mockito.Mockito.mock; |
| 12 import static org.mockito.Mockito.when; |
| 13 |
| 14 import android.content.Context; |
| 15 import android.content.Intent; |
| 16 import android.content.pm.ActivityInfo; |
| 17 import android.content.pm.PackageInfo; |
| 18 import android.content.pm.PackageManager; |
| 19 import android.content.pm.PackageManager.NameNotFoundException; |
| 20 import android.content.pm.ResolveInfo; |
| 21 import android.content.pm.Signature; |
| 22 |
| 23 import org.chromium.testing.local.LocalRobolectricTestRunner; |
| 24 import org.junit.Assert; |
| 25 import org.junit.Before; |
| 26 import org.junit.Test; |
| 27 import org.junit.runner.RunWith; |
| 28 import org.robolectric.Robolectric; |
| 29 import org.robolectric.annotation.Config; |
| 30 import org.robolectric.res.builder.RobolectricPackageManager; |
| 31 |
| 32 import java.net.URISyntaxException; |
| 33 import java.util.ArrayList; |
| 34 import java.util.List; |
| 35 |
| 36 /** |
| 37 * Unit tests for {@link org.chromium.webapk.lib.client.WebApkValidator}. |
| 38 */ |
| 39 @RunWith(LocalRobolectricTestRunner.class) |
| 40 @Config(manifest = Config.NONE) |
| 41 public class WebApkValidatorTest { |
| 42 private static final String WEBAPK_PACKAGE_NAME = "org.chromium.webapk.foo"; |
| 43 private static final String INVALID_WEBAPK_PACKAGE_NAME = "invalid.org.chrom
ium.webapk.foo"; |
| 44 private static final String URL_OF_WEBAPK = "https://www.foo.com"; |
| 45 private static final String URL_WITHOUT_WEBAPK = "https://www.other.com"; |
| 46 |
| 47 private static final byte[] EXPECTED_SIGNATURE = new byte[] { |
| 48 48, -126, 3, -121, 48, -126, 2, 111, -96, 3, 2, 1, 2, 2, 4, 20, -104, -6
6, -126, 48, 13, |
| 49 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 48, 116, 49, 11, 48, 9
, 6, 3, 85, 4, |
| 50 6, 19, 2, 67, 65, 49, 16, 48, 14, 6, 3, 85, 4, 8, 19, 7, 79, 110, 116, 9
7, 114, 105, |
| 51 111, 49, 17, 48, 15, 6, 3, 85, 4, 7, 19, 8, 87, 97, 116, 101, 114, 108,
111, 111, 49, |
| 52 17, 48, 15, 6, 3, 85, 4, 10, 19, 8, 67, 104, 114, 111, 109, 105, 117, 10
9, 49, 17, 48}; |
| 53 |
| 54 private static final byte[] SIGNATURE_1 = new byte[] { |
| 55 13, 52, 51, 48, 51, 48, 51, 49, 53, 49, 54, 52, 52, 90, 48, 116, 49, 11,
48, 9, 6, 3, |
| 56 85, 4, 6, 19, 2, 67, 65, 49, 16, 48, 14, 6, 3, 85, 4, 8, 19, 7, 79, 110,
116, 97, 114}; |
| 57 |
| 58 private static final byte[] SIGNATURE_2 = new byte[] { |
| 59 49, 17, 48, 15, 6, 3, 85, 4, 10, 19, 8, 67, 104, 114, 111, 109, 105, 117
, 109, 49, 17, |
| 60 48, 15, 6, 3, 85, 4, 11, 19, 8, 67, 104, 114, 111, 109, 105, 117, 109, 4
9, 26, 48, 24}; |
| 61 |
| 62 private Context mContext; |
| 63 private PackageManager mPackageManager; |
| 64 private PackageInfo mWebApkPackageInfo; |
| 65 private PackageInfo mInvalidWebApkPackageInfo; |
| 66 |
| 67 @Before |
| 68 public void setUp() { |
| 69 mContext = mock(Context.class); |
| 70 mPackageManager = mock(PackageManager.class); |
| 71 when(mContext.getPackageManager()).thenReturn(mPackageManager); |
| 72 WebApkValidator.initWithBrowserHostSignature(EXPECTED_SIGNATURE); |
| 73 } |
| 74 |
| 75 /** |
| 76 * Tests {@link WebApkValidator.queryWebApkPackage()} returns a WebAPK's pac
kage name if the |
| 77 * WebAPK can handle the given URL. |
| 78 */ |
| 79 @Test |
| 80 public void testQueryWebApkPackageReturnsWebApkPackageNameIfTheURLCanBeHandl
ed() { |
| 81 try { |
| 82 Intent intent = Intent.parseUri(URL_OF_WEBAPK, Intent.URI_INTENT_SCH
EME); |
| 83 intent.addCategory(Intent.CATEGORY_BROWSABLE); |
| 84 |
| 85 ResolveInfo info = newResolveInfo(WEBAPK_PACKAGE_NAME); |
| 86 RobolectricPackageManager packageManager = |
| 87 (RobolectricPackageManager) Robolectric.application.getPacka
geManager(); |
| 88 packageManager.addResolveInfoForIntent(intent, info); |
| 89 |
| 90 assertEquals(WEBAPK_PACKAGE_NAME, |
| 91 WebApkValidator.queryWebApkPackage(Robolectric.application,
URL_OF_WEBAPK)); |
| 92 } catch (URISyntaxException e) { |
| 93 Assert.fail("URI is invalid."); |
| 94 } |
| 95 } |
| 96 |
| 97 /** |
| 98 * Tests {@link WebApkValidator.queryWebApkPackage()} returns null for a non
-browsable Intent. |
| 99 */ |
| 100 @Test |
| 101 public void testQueryWebApkPackageReturnsNullForNonBrowsableIntent() { |
| 102 try { |
| 103 Intent intent = Intent.parseUri(URL_OF_WEBAPK, Intent.URI_INTENT_SCH
EME); |
| 104 |
| 105 ResolveInfo info = newResolveInfo(WEBAPK_PACKAGE_NAME); |
| 106 RobolectricPackageManager packageManager = |
| 107 (RobolectricPackageManager) Robolectric.application.getPacka
geManager(); |
| 108 packageManager.addResolveInfoForIntent(intent, info); |
| 109 |
| 110 assertNull(WebApkValidator.queryWebApkPackage( |
| 111 Robolectric.application, URL_OF_WEBAPK)); |
| 112 } catch (URISyntaxException e) { |
| 113 Assert.fail("URI is invalid."); |
| 114 } |
| 115 } |
| 116 |
| 117 /** |
| 118 * Tests {@link WebApkValidator.queryWebApkPackage()} returns null if no Web
APK handles |
| 119 * the given URL. |
| 120 */ |
| 121 @Test |
| 122 public void testQueryWebApkPackageReturnsNullWhenNoWebApkHandlesTheURL() { |
| 123 try { |
| 124 Intent intent = Intent.parseUri(URL_OF_WEBAPK, Intent.URI_INTENT_SCH
EME); |
| 125 intent.addCategory(Intent.CATEGORY_BROWSABLE); |
| 126 |
| 127 ResolveInfo info = newResolveInfo(WEBAPK_PACKAGE_NAME); |
| 128 RobolectricPackageManager packageManager = |
| 129 (RobolectricPackageManager) Robolectric.application.getPacka
geManager(); |
| 130 packageManager.addResolveInfoForIntent(intent, info); |
| 131 |
| 132 assertNull(WebApkValidator.queryWebApkPackage( |
| 133 Robolectric.application, URL_WITHOUT_WEBAPK)); |
| 134 } catch (URISyntaxException e) { |
| 135 Assert.fail("URI is invalid."); |
| 136 } |
| 137 } |
| 138 |
| 139 /** |
| 140 * Tests {@link WebApkValidator.findWebApkPackage()} returns a WebAPK's pack
age name when there |
| 141 * are ResolveInfos corresponds to a WebAPK. |
| 142 */ |
| 143 @Test |
| 144 public void testFindWebApkPackageReturnsWebApkPackageName() { |
| 145 List<ResolveInfo> infos = new ArrayList<ResolveInfo>(); |
| 146 infos.add(newResolveInfo(WEBAPK_PACKAGE_NAME)); |
| 147 assertEquals(WEBAPK_PACKAGE_NAME, WebApkValidator.findWebApkPackage(info
s)); |
| 148 } |
| 149 |
| 150 /** |
| 151 * Tests {@link WebApkValidator.findWebApkPackage()} returns null when there
isn't any |
| 152 * ResolveInfos corresponds to a WebAPK. |
| 153 */ |
| 154 @Test |
| 155 public void testFindWebApkPackageReturnsNullWhenNoResolveInfosCorrespondingT
oWebApk() { |
| 156 List<ResolveInfo> infos = new ArrayList<ResolveInfo>(); |
| 157 infos.add(newResolveInfo("com.google.android")); |
| 158 assertNull(WebApkValidator.findWebApkPackage(infos)); |
| 159 } |
| 160 /** |
| 161 * Tests {@link WebApkValidator.IsValidWebApk} returns false for a package t
hat doesn't start |
| 162 * with {@link WebApkConstants.WEBAPK_PACKAGE_PREFIX}. |
| 163 */ |
| 164 @Test |
| 165 public void testIsValidWebApkReturnsFalseForInvalidPackageName() { |
| 166 assertFalse(WebApkValidator.isValidWebApk(Robolectric.application.getApp
licationContext(), |
| 167 INVALID_WEBAPK_PACKAGE_NAME)); |
| 168 } |
| 169 |
| 170 /** |
| 171 * Tests {@link WebApkValidator.IsValidWebApk} returns true if the WebAPK ha
s the expected |
| 172 * signature. |
| 173 */ |
| 174 @Test |
| 175 public void testIsValidWebApkReturnsTrueForValidWebApk() throws NameNotFound
Exception { |
| 176 mWebApkPackageInfo = mock(PackageInfo.class); |
| 177 when(mPackageManager.getPackageInfo(WEBAPK_PACKAGE_NAME, PackageManager.
GET_SIGNATURES)) |
| 178 .thenReturn(mWebApkPackageInfo); |
| 179 mWebApkPackageInfo.signatures = new Signature[] {new Signature(EXPECTED_
SIGNATURE)}; |
| 180 |
| 181 assertTrue(WebApkValidator.isValidWebApk(mContext, WEBAPK_PACKAGE_NAME))
; |
| 182 } |
| 183 |
| 184 /** |
| 185 * Tests {@link WebApkValidator.IsValidWebApk} returns true if a WebAPK has
multiple |
| 186 * signatures and one matches the expected signature. |
| 187 */ |
| 188 @Test |
| 189 public void testIsValidWebApkReturnsTrueForWebApkWithMultipleSignaturesAndOn
eMatched() |
| 190 throws NameNotFoundException { |
| 191 mWebApkPackageInfo = mock(PackageInfo.class); |
| 192 when(mPackageManager.getPackageInfo(WEBAPK_PACKAGE_NAME, PackageManager.
GET_SIGNATURES)) |
| 193 .thenReturn(mWebApkPackageInfo); |
| 194 mWebApkPackageInfo.signatures = new Signature[] {new Signature(SIGNATURE
_1), |
| 195 new Signature(SIGNATURE_2), new Signature(EXPECTED_SIGNATURE)}; |
| 196 |
| 197 assertTrue(WebApkValidator.isValidWebApk(mContext, WEBAPK_PACKAGE_NAME))
; |
| 198 } |
| 199 |
| 200 /** |
| 201 * Tests {@link WebApkValidator.IsValidWebApk} returns false if a WebAPK has
multiple |
| 202 * signatures but none of them matches the expected signature. |
| 203 */ |
| 204 @Test |
| 205 public void testIsValidWebApkReturnsFalseForWebApkWithMultipleSignaturesWith
outAnyMatched() |
| 206 throws NameNotFoundException { |
| 207 mWebApkPackageInfo = mock(PackageInfo.class); |
| 208 when(mPackageManager.getPackageInfo(WEBAPK_PACKAGE_NAME, PackageManager.
GET_SIGNATURES)) |
| 209 .thenReturn(mWebApkPackageInfo); |
| 210 mWebApkPackageInfo.signatures = new Signature[] {new Signature(SIGNATURE
_1), |
| 211 new Signature(SIGNATURE_2)}; |
| 212 |
| 213 assertFalse(WebApkValidator.isValidWebApk(mContext, WEBAPK_PACKAGE_NAME)
); |
| 214 } |
| 215 |
| 216 private static ResolveInfo newResolveInfo(String packageName) { |
| 217 ActivityInfo activityInfo = new ActivityInfo(); |
| 218 activityInfo.packageName = packageName; |
| 219 ResolveInfo resolveInfo = new ResolveInfo(); |
| 220 resolveInfo.activityInfo = activityInfo; |
| 221 return resolveInfo; |
| 222 } |
| 223 } |
OLD | NEW |