Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: content/public/android/junit/src/org/chromium/content/browser/installedapp/InstalledAppProviderTest.java

Issue 2706403014: Add Android implementation of navigator.getInstalledRelatedApps. (Closed)
Patch Set: Rebase. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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.content.browser.installedapp;
6
7 import android.content.pm.ApplicationInfo;
8 import android.content.pm.PackageManager;
9 import android.content.pm.PackageManager.NameNotFoundException;
10 import android.content.res.AssetManager;
11 import android.content.res.Resources;
12 import android.os.Bundle;
13
14 import org.junit.Assert;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.junit.runner.RunWith;
18
19 import org.robolectric.RuntimeEnvironment;
20 import org.robolectric.annotation.Config;
21 import org.robolectric.res.builder.DefaultPackageManager;
22
23 import org.chromium.base.test.util.Feature;
24 import org.chromium.installedapp.mojom.InstalledAppProvider;
25 import org.chromium.installedapp.mojom.RelatedApplication;
26 import org.chromium.testing.local.LocalRobolectricTestRunner;
27
28 import java.net.URI;
29 import java.net.URISyntaxException;
30 import java.util.HashMap;
31
32 /**
33 * Ensure that the InstalledAppProvider returns the correct apps.
34 */
35 @RunWith(LocalRobolectricTestRunner.class)
36 @Config(manifest = Config.NONE)
37 public class InstalledAppProviderTest {
38 private static final String ASSET_STATEMENTS_KEY =
39 InstalledAppProviderImpl.ASSET_STATEMENTS_KEY;
40 private static final String RELATION_HANDLE_ALL_URLS =
41 "delegate_permission/common.handle_all_urls";
42 private static final String NAMESPACE_WEB =
43 InstalledAppProviderImpl.ASSET_STATEMENT_NAMESPACE_WEB;
44 private static final String PLATFORM_ANDROID =
45 InstalledAppProviderImpl.RELATED_APP_PLATFORM_ANDROID;
46 private static final String PLATFORM_OTHER = "itunes";
47 // Note: Android package name and origin deliberately unrelated (there is no requirement that
48 // they be the same).
49 private static final String PACKAGE_NAME_1 = "com.app1.package";
50 private static final String PACKAGE_NAME_2 = "com.app2.package";
51 private static final String PACKAGE_NAME_3 = "com.app3.package";
52 private static final String URL_UNRELATED = "https://appstore.example.com/ap p1";
53 private static final String ORIGIN = "https://example.com:8000";
54 private static final String URL_ON_ORIGIN =
55 "https://example.com:8000/path/to/page.html?key=value#fragment";
56 private static final String ORIGIN_SYNTAX_ERROR = "https:{";
57 private static final String ORIGIN_MISSING_SCHEME = "path/only";
58 private static final String ORIGIN_MISSING_HOST = "file:///path/piece";
59 private static final String ORIGIN_MISSING_PORT = "http://example.com";
60 private static final String ORIGIN_DIFFERENT_SCHEME = "http://example.com:80 00";
61 private static final String ORIGIN_DIFFERENT_HOST = "https://example.org:800 0";
62 private static final String ORIGIN_DIFFERENT_PORT = "https://example.com:800 1";
63
64 private FakePackageManager mPackageManager;
65 private FakeFrameUrlDelegate mFrameUrlDelegate;
66 private InstalledAppProviderImpl mInstalledAppProvider;
67
68 /**
69 * FakePackageManager allows for the "installation" of Android package names and setting up
70 * Resources for installed packages.
71 */
72 private static class FakePackageManager extends DefaultPackageManager {
73 private final HashMap<String, Bundle> mMetaDataMap;
74 private final HashMap<String, Resources> mResourceMap;
75
76 public FakePackageManager() {
77 super();
78 mMetaDataMap = new HashMap<String, Bundle>();
79 mResourceMap = new HashMap<String, Resources>();
80 }
81
82 @Override
83 public ApplicationInfo getApplicationInfo(String packageName, int flags)
84 throws NameNotFoundException {
85 if (packageName == null) throw new NullPointerException();
86
87 Bundle metaData = mMetaDataMap.get(packageName);
88 if (metaData == null) throw new NameNotFoundException(packageName);
89
90 // Create an application with this metadata (but only if |flags| all ows). Doing it this
91 // way (rather than simply storing the ApplicationInfo in a map) ens ures that the
92 // |flags| is set correctly.
93 ApplicationInfo appInfo = new ApplicationInfo();
94 appInfo.packageName = packageName;
95 if ((flags & PackageManager.GET_META_DATA) != 0) {
96 appInfo.metaData = metaData;
97 }
98 return appInfo;
99 }
100
101 @Override
102 public Resources getResourcesForApplication(ApplicationInfo app)
103 throws NameNotFoundException {
104 if (app == null) throw new NullPointerException();
105
106 Resources result = mResourceMap.get(app.packageName);
107 if (result == null) throw new NameNotFoundException(app.packageName) ;
108
109 return result;
110 }
111
112 public void setMetaDataAndResourcesForTest(
113 String packageName, Bundle metaData, Resources resources) {
114 mMetaDataMap.put(packageName, metaData);
115 mResourceMap.put(packageName, resources);
116 }
117 }
118
119 /**
120 * Fakes the Resources object, allowing lookup of a single String value.
121 *
122 * Note: The real Resources object defines a mapping to many values. This fa ke object only
123 * allows a single value in the mapping, and it must be a String (which is a ll that is required
124 * for these tests).
125 */
126 private static class FakeResources extends Resources {
127 private final int mId;
128 private final String mValue;
129
130 // Do not warn about deprecated call to Resources(); the documentation s ays code is not
131 // supposed to create its own Resources object, but we are using it to f ake out the
132 // Resources, and there is no other way to do that.
133 @SuppressWarnings("deprecation")
134 public FakeResources(int identifier, String value) {
135 super(new AssetManager(), null, null);
136 mId = identifier;
137 mValue = value;
138 }
139
140 @Override
141 public int getIdentifier(String name, String defType, String defPackage) {
142 if (name == null) throw new NullPointerException();
143
144 // There is *no guarantee* (in the Digital Asset Links spec) about w hat the string
145 // resource should be called ("asset_statements" is just an example) . Therefore,
146 // getIdentifier cannot be used to get the asset statements string. Always fail the
147 // lookup here, to ensure the implementation isn't relying on any pa rticular hard-coded
148 // string.
149 return 0;
150 }
151
152 @Override
153 public String getString(int id) {
154 if (id != mId) {
155 throw new Resources.NotFoundException("id 0x" + Integer.toHexStr ing(id));
156 }
157
158 return mValue;
159 }
160 }
161
162 private static final class FakeFrameUrlDelegate
163 implements InstalledAppProviderImpl.FrameUrlDelegate {
164 private URI mFrameUrl;
165
166 public FakeFrameUrlDelegate(String frameUrl) {
167 setFrameUrl(frameUrl);
168 }
169
170 public void setFrameUrl(String frameUrl) {
171 if (frameUrl == null) {
172 mFrameUrl = null;
173 return;
174 }
175
176 try {
177 mFrameUrl = new URI(frameUrl);
178 } catch (URISyntaxException e) {
179 throw new AssertionError(e);
180 }
181 }
182
183 @Override
184 public URI getUrl() {
185 return mFrameUrl;
186 }
187 }
188
189 /**
190 * Creates a metaData bundle with a single resource-id key.
191 */
192 private static Bundle createMetaData(String metaDataName, int metaDataResour ceId) {
193 Bundle metaData = new Bundle();
194 metaData.putInt(metaDataName, metaDataResourceId);
195 return metaData;
196 }
197
198 /**
199 * Sets a resource with a single key-value pair in an Android package's mani fest.
200 *
201 * The value is always a string.
202 */
203 private void setStringResource(String packageName, String key, String value) {
204 int identifier = 0x1234;
205 Bundle metaData = createMetaData(key, identifier);
206 FakeResources resources = new FakeResources(identifier, value);
207 mPackageManager.setMetaDataAndResourcesForTest(packageName, metaData, re sources);
208 }
209
210 /**
211 * Creates a valid Android asset statement string.
212 */
213 private String createAssetStatement(String platform, String relation, String url) {
214 return String.format(
215 "{\"relation\": [\"%s\"], \"target\": {\"namespace\": \"%s\", \" site\": \"%s\"}}",
216 relation, platform, url);
217 }
218
219 /**
220 * Sets an asset statement to an Android package's manifest (in the fake pac kage manager).
221 *
222 * Only one asset statement can be set for a given package (if this is calle d twice on the same
223 * package, overwrites the previous asset statement).
224 *
225 * This corresponds to a Statement List in the Digital Asset Links spec v1.
226 */
227 private void setAssetStatement(
228 String packageName, String platform, String relation, String url) {
229 String statements = "[" + createAssetStatement(platform, relation, url) + "]";
230 setStringResource(packageName, ASSET_STATEMENTS_KEY, statements);
231 }
232
233 /**
234 * Creates a RelatedApplication to put in the web app manifest.
235 */
236 private RelatedApplication createRelatedApplication(String platform, String id, String url) {
237 RelatedApplication application = new RelatedApplication();
238 application.platform = platform;
239 application.id = id;
240 application.url = url;
241 return application;
242 }
243
244 /**
245 * Calls filterInstalledApps with the given inputs, and tests that the expec ted result is
246 * returned.
247 */
248 private void verifyInstalledApps(RelatedApplication[] manifestRelatedApps,
249 final RelatedApplication[] expectedInstalledRelatedApps) {
250 mInstalledAppProvider.filterInstalledApps(
251 manifestRelatedApps, new InstalledAppProvider.FilterInstalledApp sResponse() {
252 @Override
253 public void call(RelatedApplication[] installedRelatedApps) {
254 Assert.assertEquals(
255 expectedInstalledRelatedApps.length, installedRe latedApps.length);
256
257 for (int i = 0; i < installedRelatedApps.length; i++) {
258 Assert.assertEquals(
259 expectedInstalledRelatedApps[i], installedRe latedApps[i]);
260 }
261 }
262 });
263 }
264
265 @Before
266 public void setUp() {
267 mPackageManager = new FakePackageManager();
268 RuntimeEnvironment.setRobolectricPackageManager(mPackageManager);
269 mFrameUrlDelegate = new FakeFrameUrlDelegate(URL_ON_ORIGIN);
270 mInstalledAppProvider =
271 new InstalledAppProviderImpl(mFrameUrlDelegate, RuntimeEnvironme nt.application);
272 }
273
274 /**
275 * Origin of the page using the API is missing certain parts of the URI.
276 */
277 @Test
278 @Feature({"InstalledApp"})
279 public void testOriginMissingParts() {
280 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
281 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
282 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
283 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
284
285 mFrameUrlDelegate.setFrameUrl(ORIGIN_MISSING_SCHEME);
286 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
287
288 mFrameUrlDelegate.setFrameUrl(ORIGIN_MISSING_HOST);
289 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
290 }
291
292 /**
293 * No related Android apps.
294 *
295 * An Android app relates to the web app, but not mutual.
296 */
297 @Test
298 @Feature({"InstalledApp"})
299 public void testNoRelatedApps() {
300 // The web manifest has no related apps.
301 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {};
302
303 // One Android app is installed named |PACKAGE_NAME_1|. It has a related web app with origin
304 // |ORIGIN|.
305 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
306
307 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
308 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
309 }
310
311 /**
312 * One related Android app with no id (package name).
313 *
314 * An Android app relates to the web app, but not mutual.
315 */
316 @Test
317 @Feature({"InstalledApp"})
318 public void testOneRelatedAppNoId() {
319 RelatedApplication manifestRelatedApps[] =
320 new RelatedApplication[] {createRelatedApplication(PLATFORM_ANDR OID, null, null)};
321
322 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
323
324 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
325 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
326 }
327
328 /**
329 * One related app (from a non-Android platform).
330 *
331 * An Android app with the same id relates to the web app. This should be ig nored since the
332 * manifest doesn't mention the Android app.
333 */
334 @Test
335 @Feature({"InstalledApp"})
336 public void testOneRelatedNonAndroidApp() {
337 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
338 createRelatedApplication(PLATFORM_OTHER, PACKAGE_NAME_1, null)};
339
340 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
341
342 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
343 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
344 }
345
346 /**
347 * One related Android app; Android app is not installed.
348 *
349 * Another Android app relates to the web app, but not mutual.
350 */
351 @Test
352 @Feature({"InstalledApp"})
353 public void testOneRelatedAppNotInstalled() {
354 // The web manifest has a related Android app named |PACKAGE_NAME_1|.
355 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
356 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
357
358 // One Android app is installed named |PACKAGE_NAME_2|. It has a related web app with origin
359 // |ORIGIN|.
360 setAssetStatement(PACKAGE_NAME_2, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
361
362 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
363 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
364 }
365
366 /**
367 * Android app manifest has an asset_statements key, but the resource it lin ks to is missing.
368 */
369 @Test
370 @Feature({"InstalledApp"})
371 public void testOneRelatedAppBrokenAssetStatementsResource() {
372 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
373 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
374
375 Bundle metaData = createMetaData(ASSET_STATEMENTS_KEY, 0x1234);
376 String statements =
377 "[" + createAssetStatement(NAMESPACE_WEB, RELATION_HANDLE_ALL_UR LS, ORIGIN) + "]";
378 FakeResources resources = new FakeResources(0x4321, statements);
379 mPackageManager.setMetaDataAndResourcesForTest(PACKAGE_NAME_1, metaData, resources);
380 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
381 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
382 }
383
384 /**
385 * One related Android app; Android app is not mutually related (has no asse t_statements).
386 */
387 @Test
388 @Feature({"InstalledApp"})
389 public void testOneRelatedAppNoAssetStatements() {
390 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
391 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
392
393 setStringResource(PACKAGE_NAME_1, null, null);
394 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
395 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
396 }
397
398 /**
399 * One related Android app; Android app is related to other origins.
400 *
401 * Tests three cases:
402 * - The Android app is related to a web app with a different scheme.
403 * - The Android app is related to a web app with a different host.
404 * - The Android app is related to a web app with a different port.
405 */
406 @Test
407 @Feature({"InstalledApp"})
408 public void testOneRelatedAppRelatedToDifferentOrigins() {
409 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
410 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
411
412 setAssetStatement(
413 PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_ DIFFERENT_SCHEME);
414 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
415 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
416
417 setAssetStatement(
418 PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_ DIFFERENT_HOST);
419 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
420
421 setAssetStatement(
422 PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_ DIFFERENT_PORT);
423 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
424 }
425
426 /**
427 * One related Android app; Android app is installed and mutually related.
428 */
429 @Test
430 @Feature({"InstalledApp"})
431 public void testOneInstalledRelatedApp() {
432 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
433 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
434
435 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
436
437 RelatedApplication[] expectedInstalledRelatedApps = manifestRelatedApps;
438 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
439 }
440
441 /**
442 * Change the frame URL and ensure the app relates to the new URL, not the o ld one.
443 *
444 * This simulates navigating the frame while keeping the same Mojo service o pen.
445 */
446 @Test
447 @Feature({"InstalledApp"})
448 public void testDynamicallyChangingUrl() {
449 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
450 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
451
452 setAssetStatement(
453 PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_ DIFFERENT_SCHEME);
454
455 // Should be empty, since Android app does not relate to this frame's or igin.
456 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
457 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
458
459 // Simulate a navigation to a different origin.
460 mFrameUrlDelegate.setFrameUrl(ORIGIN_DIFFERENT_SCHEME);
461
462 // Now the result should include the Android app that relates to the new origin.
463 expectedInstalledRelatedApps = manifestRelatedApps;
464 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
465
466 // Simulate the native RenderFrameHost disappearing.
467 mFrameUrlDelegate.setFrameUrl(null);
468
469 expectedInstalledRelatedApps = new RelatedApplication[] {};
470 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
471 }
472
473 /**
474 * One related Android app (installed and mutually related), with a non-null URL field.
475 */
476 @Test
477 @Feature({"InstalledApp"})
478 public void testInstalledRelatedAppWithUrl() {
479 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
480 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, URL_U NRELATED)};
481
482 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
483
484 RelatedApplication[] expectedInstalledRelatedApps = manifestRelatedApps;
485 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
486 }
487
488 /**
489 * One related Android app; Android app is related to multiple origins.
490 */
491 @Test
492 @Feature({"InstalledApp"})
493 public void testMultipleAssetStatements() {
494 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
495 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
496
497 // Create an asset_statements field with multiple statements. The second one matches the web
498 // app.
499 String statements = "["
500 + createAssetStatement(
501 NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_DIFFER ENT_HOST)
502 + ", " + createAssetStatement(NAMESPACE_WEB, RELATION_HANDLE_ALL _URLS, ORIGIN)
503 + "]";
504 setStringResource(PACKAGE_NAME_1, ASSET_STATEMENTS_KEY, statements);
505
506 RelatedApplication[] expectedInstalledRelatedApps = manifestRelatedApps;
507 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
508 }
509
510 /**
511 * A JSON syntax error in the Android app's asset statement.
512 */
513 @Test
514 @Feature({"InstalledApp"})
515 public void testAssetStatementSyntaxError() {
516 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
517 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
518
519 String statements = "[{\"target\" {}}]";
520 setStringResource(PACKAGE_NAME_1, ASSET_STATEMENTS_KEY, statements);
521
522 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
523 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
524 }
525
526 /**
527 * The Android app's asset statement is not an array.
528 */
529 @Test
530 @Feature({"InstalledApp"})
531 public void testAssetStatementNotArray() {
532 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
533 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
534
535 String statement = createAssetStatement(NAMESPACE_WEB, RELATION_HANDLE_A LL_URLS, ORIGIN);
536 setStringResource(PACKAGE_NAME_1, ASSET_STATEMENTS_KEY, statement);
537
538 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
539 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
540 }
541
542 /**
543 * The Android app's asset statement array contains non-objects.
544 */
545 @Test
546 @Feature({"InstalledApp"})
547 public void testAssetStatementArrayNoObjects() {
548 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
549 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
550
551 String statements = "["
552 + createAssetStatement(NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN) + ", 4]";
553 setStringResource(PACKAGE_NAME_1, ASSET_STATEMENTS_KEY, statements);
554
555 // Expect it to ignore the integer and successfully parse the valid obje ct.
556 RelatedApplication[] expectedInstalledRelatedApps = manifestRelatedApps;
557 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
558 }
559
560 /**
561 * Android app has no "relation" in the asset statement.
562 *
563 * Currently, the relation string (in the Android package's asset statement) is ignored, so the
564 * app is still returned as "installed".
565 */
566 @Test
567 @Feature({"InstalledApp"})
568 public void testAssetStatementNoRelation() {
569 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
570 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
571
572 String statements = String.format(
573 "[{\"target\": {\"namespace\": \"%s\", \"site\": \"%s\"}}]", NAM ESPACE_WEB, ORIGIN);
574 setStringResource(PACKAGE_NAME_1, ASSET_STATEMENTS_KEY, statements);
575
576 // TODO(mgiuca): [Spec issue] Should we require a specific relation stri ng, rather than any
577 // or no relation?
578 RelatedApplication[] expectedInstalledRelatedApps = manifestRelatedApps;
579 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
580 }
581
582 /**
583 * Android app is related with a non-standard relation.
584 *
585 * Currently, the relation string (in the Android package's asset statement) is ignored, so any
586 * will do. Is this desirable, or do we want to require a specific relation string?
587 */
588 @Test
589 @Feature({"InstalledApp"})
590 public void testAssetStatementNonStandardRelation() {
591 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
592 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
593
594 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, "nonstandard/relation", ORIGIN);
595
596 // TODO(mgiuca): [Spec issue] Should we require a specific relation stri ng, rather than any
597 // or no relation?
598 RelatedApplication[] expectedInstalledRelatedApps = manifestRelatedApps;
599 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
600 }
601
602 /**
603 * Android app has no "target" in the asset statement.
604 */
605 @Test
606 @Feature({"InstalledApp"})
607 public void testAssetStatementNoTarget() {
608 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
609 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
610
611 String statements = String.format("[{\"relation\": [\"%s\"]}]", RELATION _HANDLE_ALL_URLS);
612 setStringResource(PACKAGE_NAME_1, ASSET_STATEMENTS_KEY, statements);
613
614 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
615 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
616 }
617
618 /**
619 * Android app has no "namespace" in the asset statement.
620 */
621 @Test
622 @Feature({"InstalledApp"})
623 public void testAssetStatementNoNamespace() {
624 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
625 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
626
627 String statements =
628 String.format("[{\"relation\": [\"%s\"], \"target\": {\"site\": \"%s\"}}]",
629 RELATION_HANDLE_ALL_URLS, ORIGIN);
630 setStringResource(PACKAGE_NAME_1, ASSET_STATEMENTS_KEY, statements);
631
632 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
633 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
634 }
635
636 /**
637 * Android app is related, but not to the web namespace.
638 */
639 @Test
640 @Feature({"InstalledApp"})
641 public void testNonWebAssetStatement() {
642 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
643 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
644
645 setAssetStatement(PACKAGE_NAME_1, "play", RELATION_HANDLE_ALL_URLS, ORIG IN);
646
647 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
648 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
649 }
650
651 /**
652 * Android app has no "site" in the asset statement.
653 */
654 @Test
655 @Feature({"InstalledApp"})
656 public void testAssetStatementNoSite() {
657 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
658 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
659
660 String statements =
661 String.format("[{\"relation\": [\"%s\"], \"target\": {\"namespac e\": \"%s\"}}]",
662 RELATION_HANDLE_ALL_URLS, NAMESPACE_WEB);
663 setStringResource(PACKAGE_NAME_1, ASSET_STATEMENTS_KEY, statements);
664
665 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
666 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
667 }
668
669 /**
670 * Android app has a syntax error in the "site" field of the asset statement .
671 */
672 @Test
673 @Feature({"InstalledApp"})
674 public void testAssetStatementSiteSyntaxError() {
675 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
676 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
677
678 setAssetStatement(
679 PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_ SYNTAX_ERROR);
680
681 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
682 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
683 }
684
685 /**
686 * Android app has a "site" field missing certain parts of the URI (scheme, host, port).
687 */
688 @Test
689 @Feature({"InstalledApp"})
690 public void testAssetStatementSiteMissingParts() {
691 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
692 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
693
694 setAssetStatement(
695 PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_ MISSING_SCHEME);
696 RelatedApplication[] expectedInstalledRelatedApps = new RelatedApplicati on[] {};
697 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
698
699 setAssetStatement(
700 PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_ MISSING_HOST);
701 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
702
703 setAssetStatement(
704 PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URLS, ORIGIN_ MISSING_PORT);
705 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
706 }
707
708 /**
709 * One related Android app; Android app is related with a path part in the " site" field.
710 *
711 * The path part shouldn't really be there (according to the Digital Asset L inks spec), but if
712 * it is, we are lenient and just ignore it (matching only the origin).
713 */
714 @Test
715 @Feature({"InstalledApp"})
716 public void testAssetStatementSiteHasPath() {
717 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
718 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
719
720 String site = ORIGIN + "/path";
721 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, site);
722
723 RelatedApplication[] expectedInstalledRelatedApps = manifestRelatedApps;
724 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
725 }
726
727 /**
728 * One related Android app; Android app is installed and mutually related.
729 *
730 * Another Android app relates to the web app, but not mutual.
731 */
732 @Test
733 @Feature({"InstalledApp"})
734 public void testExtraInstalledApp() {
735 RelatedApplication manifestRelatedApps[] = new RelatedApplication[] {
736 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) };
737
738 setAssetStatement(PACKAGE_NAME_1, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
739 setAssetStatement(PACKAGE_NAME_2, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
740
741 RelatedApplication[] expectedInstalledRelatedApps = manifestRelatedApps;
742 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
743 }
744
745 /**
746 * Two related Android apps; Android apps both installed and mutually relate d.
747 *
748 * Web app also related to an app with the same name on another platform, an d another Android
749 * app which is not installed.
750 */
751 @Test
752 @Feature({"InstalledApp"})
753 public void testMultipleInstalledRelatedApps() {
754 RelatedApplication[] manifestRelatedApps = new RelatedApplication[] {
755 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_1, null) ,
756 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_2, null) ,
757 createRelatedApplication(PLATFORM_OTHER, PACKAGE_NAME_2, null),
758 createRelatedApplication(PLATFORM_ANDROID, PACKAGE_NAME_3, null) };
759
760 setAssetStatement(PACKAGE_NAME_2, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
761 setAssetStatement(PACKAGE_NAME_3, NAMESPACE_WEB, RELATION_HANDLE_ALL_URL S, ORIGIN);
762
763 RelatedApplication[] expectedInstalledRelatedApps =
764 new RelatedApplication[] {manifestRelatedApps[1], manifestRelate dApps[3]};
765 verifyInstalledApps(manifestRelatedApps, expectedInstalledRelatedApps);
766 }
767 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698