Commit 806e5e85 authored by Rouslan Solomakhin's avatar Rouslan Solomakhin Committed by Commit Bot

[Payments] Integration test for Android payment app finder.

This patch adds an integration test for the Android payment app finder
using the real parser and downloader instead of mocks.

This patch adds payment app manifest files in
components/test/data/payments/<hostname>.com/. Because the embedded test
server uses HTTP, but payment manifests must use HTTPS, a
URLSubstituteParser wraps the PaymentManifestParser to replace
https://<hostname>.com with the test server URLs, e.g.,
http://127.0.0.1:12345/components/test/data/payments/<hostname>.com.

Because integration tests should not depend on the state of locally
installed applications, a MockPackageManagerDelegate is used to simulate
installed native Android apps in memory.

Bug: 620173
Change-Id: I8184a84f9f9daa05b5cc8da6e343378b62333b1a
Reviewed-on: https://chromium-review.googlesource.com/571943
Commit-Queue: Rouslan Solomakhin <rouslan@chromium.org>
Reviewed-by: default avatarGanggui Tang <gogerald@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488729}
parent 7e7585ae
......@@ -11,6 +11,7 @@ import android.content.res.Resources;
import android.text.TextUtils;
import org.chromium.base.Log;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.UrlConstants;
import org.chromium.chrome.browser.payments.PaymentAppFactory.PaymentAppCreatedCallback;
......@@ -25,7 +26,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
......@@ -39,14 +39,14 @@ import javax.annotation.Nullable;
* app.
*/
public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
private static final String TAG = "cr_PaymentAppFinder";
private static final String TAG = "PaymentAppFinder";
/** The maximum number of payment method manifests to download. */
private static final int MAX_NUMBER_OF_MANIFESTS = 10;
/** The name of the intent for the service to check whether an app is ready to pay. */
/* package */ static final String ACTION_IS_READY_TO_PAY =
"org.chromium.intent.action.IS_READY_TO_PAY";
"org.chromium.intent.action.IS_READY_TO_PAY";
/**
* Meta data name of an app's supported payment method names.
......@@ -60,6 +60,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
/* package */ static final String META_DATA_NAME_OF_DEFAULT_PAYMENT_METHOD_NAME =
"org.chromium.default_payment_method_name";
private static boolean sAllowHttpForTest;
private final WebContents mWebContents;
private final Set<String> mNonUriPaymentMethods;
private final Set<URI> mUriPaymentMethods;
......@@ -129,7 +131,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
assert !TextUtils.isEmpty(method);
if (supportedNonUriPaymentMethods.contains(method)) {
mNonUriPaymentMethods.add(method);
} else if (method.startsWith(UrlConstants.HTTPS_URL_PREFIX)) {
} else if (method.startsWith(UrlConstants.HTTPS_URL_PREFIX)
|| (sAllowHttpForTest && method.startsWith("http://127.0.0.1:"))) {
URI uri;
try {
// Don't use java.net.URL, because it performs a synchronous DNS lookup in
......@@ -140,7 +143,10 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
}
if (uri.isAbsolute()) {
assert UrlConstants.HTTPS_SCHEME.equals(uri.getScheme());
assert UrlConstants.HTTPS_SCHEME.equals(uri.getScheme())
|| (sAllowHttpForTest
&& UrlConstants.HTTP_SCHEME.equals(uri.getScheme())
&& "127.0.0.1".equals(uri.getHost()));
mUriPaymentMethods.add(uri);
}
}
......@@ -192,7 +198,7 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
mPendingApps.put(uriMethodName, new HashSet<>(supportedApps));
if (mManifestVerifiers.size() == MAX_NUMBER_OF_MANIFESTS) {
Log.d(TAG, "Reached maximum number of allowed payment app manifests.");
Log.e(TAG, "Reached maximum number of allowed payment app manifests.");
break;
}
}
......@@ -271,9 +277,7 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
if (app == null) {
CharSequence label = mPackageManagerDelegate.getAppLabel(resolveInfo);
if (TextUtils.isEmpty(label)) {
Log.d(TAG,
String.format(Locale.getDefault(), "Skipping '%s' because of empty label.",
packageName));
Log.e(TAG, "Skipping \"%s\" because of empty label.", packageName);
return;
}
app = new AndroidPaymentApp(mWebContents, packageName, resolveInfo.activityInfo.name,
......@@ -338,4 +342,9 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
mCallback.onAllPaymentAppsCreated();
}
}
@VisibleForTesting
public static void allowHttpForTest() {
sAllowHttpForTest = true;
}
}
\ No newline at end of file
......@@ -22,7 +22,7 @@ import java.util.List;
import javax.annotation.Nullable;
/** Abstraction of Android's package manager to enable unit testing. */
/** Abstraction of Android's package manager to enable testing. */
public class PackageManagerDelegate {
/**
* Retrieves package information of an installed application.
......
......@@ -39,7 +39,7 @@ import java.util.Set;
public class PaymentManifestVerifier
implements ManifestDownloadCallback, ManifestParseCallback,
PaymentManifestWebDataService.PaymentManifestWebDataServiceCallback {
private static final String TAG = "cr_PaymentManifest";
private static final String TAG = "PaymentManifest";
/** Interface for the callback to invoke when finished verification. */
public interface ManifestVerifyCallback {
......@@ -125,7 +125,8 @@ public class PaymentManifestVerifier
* Builds the manifest verifier.
*
* @param methodName The name of the payment method name that apps offer to handle.
* Must be an absolute URI with HTTPS scheme.
* Must be an absolute URI with HTTPS scheme, but HTTP localhost
* is allowed in testing.
* @param matchingApps The identifying information for the native Android payment apps
* that offer to handle this payment method.
* @param webDataService The web data service to cache manifest.
......@@ -139,7 +140,9 @@ public class PaymentManifestVerifier
PaymentManifestParser parser, PackageManagerDelegate packageManagerDelegate,
ManifestVerifyCallback callback) {
assert methodName.isAbsolute();
assert UrlConstants.HTTPS_SCHEME.equals(methodName.getScheme());
assert UrlConstants.HTTPS_SCHEME.equals(methodName.getScheme())
|| ("127.0.0.1".equals(methodName.getHost())
&& UrlConstants.HTTP_SCHEME.equals(methodName.getScheme()));
assert !matchingApps.isEmpty();
mMethodName = methodName;
......@@ -161,7 +164,7 @@ public class PaymentManifestVerifier
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
// Intentionally ignore.
Log.d(TAG, "Unable to generate SHA-256 hashes.");
Log.e(TAG, "Unable to generate SHA-256 hashes.");
}
mMessageDigest = md;
......@@ -335,7 +338,7 @@ public class PaymentManifestVerifier
}
mSupportedAppParsedManifests.add(manifest);
// Do not verify payment app if it has already been verified by cached manifest.
// Verify payment apps only if they have not already been verified by the cached manifest.
if (mIsManifestCacheStaleOrUnusable) {
Set<String> verifiedAppPackageNames = verifyAppWithWebAppManifest(manifest);
for (String packageName : verifiedAppPackageNames) {
......@@ -361,18 +364,42 @@ public class PaymentManifestVerifier
mSupportedAppPackageNames.toArray(new String[mSupportedAppPackageNames.size()]));
// Cache supported apps' parsed manifests.
for (int i = 0; i < mSupportedAppParsedManifests.size(); i++) {
mWebDataService.addPaymentWebAppManifest(mSupportedAppParsedManifests.get(i));
}
mWebDataService.addPaymentWebAppManifest(flattenListOfArrays(mSupportedAppParsedManifests));
mCallback.onVerifyFinished(this);
}
/**
* Flattens a list of arrays into a single array.
*
* @param listOfLists A lists of arrays to flatten.
* @return The single array result.
*/
private static WebAppManifestSection[] flattenListOfArrays(
List<WebAppManifestSection[]> listOfLists) {
int totalNumberOfItems = 0;
for (int i = 0; i < listOfLists.size(); i++) {
totalNumberOfItems += listOfLists.get(i).length;
}
WebAppManifestSection[] flattenedList = new WebAppManifestSection[totalNumberOfItems];
for (int i = 0, k = 0; i < listOfLists.size(); i++) {
for (int j = 0; j < listOfLists.get(i).length; j++, k++) {
assert k < flattenedList.length;
flattenedList[k] = listOfLists.get(i)[j];
}
}
return flattenedList;
}
/**
* @return The set of package names of payment apps that match the manifest. Could be empty,
* but never null.
*/
private Set<String> verifyAppWithWebAppManifest(WebAppManifestSection[] manifest) {
assert manifest.length > 0;
List<Set<String>> sectionsFingerprints = new ArrayList<>();
for (int i = 0; i < manifest.length; i++) {
WebAppManifestSection section = manifest[i];
......@@ -387,16 +414,43 @@ public class PaymentManifestVerifier
for (int i = 0; i < manifest.length; i++) {
WebAppManifestSection section = manifest[i];
AppInfo appInfo = mMatchingApps.get(section.id);
if (appInfo != null && appInfo.version >= section.minVersion
&& appInfo.sha256CertFingerprints != null
&& appInfo.sha256CertFingerprints.equals(sectionsFingerprints.get(i))) {
packageNames.add(section.id);
if (appInfo == null) continue;
if (appInfo.version < section.minVersion) {
Log.e(TAG, "\"%s\" version is %d, but at least %d is required.", section.id,
appInfo.version, section.minVersion);
continue;
}
if (appInfo.sha256CertFingerprints == null) {
Log.e(TAG, "Unable to determine fingerprints of \"%s\".", section.id);
continue;
}
if (!appInfo.sha256CertFingerprints.equals(sectionsFingerprints.get(i))) {
Log.e(TAG,
"\"%s\" fingerprints don't match the manifest. Expected %s, but found %s.",
section.id, setToString(sectionsFingerprints.get(i)),
setToString(appInfo.sha256CertFingerprints));
continue;
}
packageNames.add(section.id);
}
return packageNames;
}
private static String setToString(Set<String> set) {
StringBuilder result = new StringBuilder("[");
for (String item : set) {
result.append(' ');
result.append(item);
}
result.append(" ]");
return result.toString();
}
@Override
public void onManifestDownloadFailure() {
if (mAtLeastOneManifestFailedToDownloadOrParse) return;
......@@ -414,4 +468,4 @@ public class PaymentManifestVerifier
if (mIsManifestCacheStaleOrUnusable) mCallback.onInvalidManifest(mMethodName);
mCallback.onVerifyFinished(this);
}
}
}
\ No newline at end of file
......@@ -1531,7 +1531,9 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/physicalweb/MockPwsClient.java",
"javatests/src/org/chromium/chrome/browser/physicalweb/UrlManagerTest.java",
"javatests/src/org/chromium/chrome/browser/policy/CombinedPolicyProviderTest.java",
"javatests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinderTest.java",
"javatests/src/org/chromium/chrome/browser/payments/CurrencyFormatterTest.java",
"javatests/src/org/chromium/chrome/browser/payments/MockPackageManagerDelegate.java",
"javatests/src/org/chromium/chrome/browser/payments/PaymentManifestDownloaderTest.java",
"javatests/src/org/chromium/chrome/browser/payments/PaymentManifestParserTest.java",
"javatests/src/org/chromium/chrome/browser/payments/PaymentRequestAbortTest.java",
......
// Copyright 2017 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.chrome.browser.payments;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.payments.PaymentAppFactory.PaymentAppCreatedCallback;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.components.payments.PaymentManifestDownloader;
import org.chromium.components.payments.PaymentManifestParser;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.WebContents;
import org.chromium.net.test.EmbeddedTestServer;
import org.chromium.payments.mojom.WebAppManifestSection;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/** An integration test for the Android payment app finder. */
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({
ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
ChromeActivityTestRule.DISABLE_NETWORK_PREDICTION_FLAG,
})
@MediumTest
public class AndroidPaymentAppFinderTest implements PaymentAppCreatedCallback {
@Rule
public ChromeActivityTestRule<ChromeActivity> mRule =
new ChromeActivityTestRule<>(ChromeActivity.class);
/**
* Wrapper around a payment manifest parser that substitutes web app manifest URIs to point to
* the test server.
*/
private static class URLSubstituteParser extends PaymentManifestParser {
private URI mTestServerUri;
/** @param uri The URI of the test server. */
public void setTestServerUri(URI uri) {
assert mTestServerUri == null : "Test server URI should be set only once";
mTestServerUri = uri;
}
@Override
public void parsePaymentMethodManifest(
String content, final ManifestParseCallback callback) {
super.parsePaymentMethodManifest(content, new ManifestParseCallback() {
@Override
public void onPaymentMethodManifestParseSuccess(URI[] webAppManifestUris) {
URI[] localhostWebAppManifestUris = new URI[webAppManifestUris.length];
for (int i = 0; i < webAppManifestUris.length; i++) {
try {
localhostWebAppManifestUris[i] = new URI(
webAppManifestUris[i]
.toString()
.replaceAll("https://alicepay.com",
mTestServerUri.toString() + "/alicepay.com")
.replaceAll("https://bobpay.com",
mTestServerUri.toString() + "/bobpay.com")
.replaceAll("https://charliepay.com",
mTestServerUri.toString() + "/charliepay.com")
.replaceAll("https://davepay.com",
mTestServerUri.toString() + "/davepay.com")
.replaceAll("https://evepay.com",
mTestServerUri.toString() + "/evepay.com"));
} catch (URISyntaxException e) {
assert false : "URI should be valid";
}
}
callback.onPaymentMethodManifestParseSuccess(localhostWebAppManifestUris);
}
@Override
public void onWebAppManifestParseSuccess(WebAppManifestSection[] manifest) {
assert false : "Web app manifest parsing callback should not be triggered.";
}
@Override
public void onManifestParseFailure() {
callback.onManifestParseFailure();
}
});
}
}
private final URLSubstituteParser mParser = new URLSubstituteParser();
/** Simulates a package manager in memory. */
private final MockPackageManagerDelegate mPackageManager = new MockPackageManagerDelegate();
/** A downloader that allows HTTP URLs. */
private final PaymentManifestDownloader mDownloader = new PaymentManifestDownloader() {
@Override
public void initialize(WebContents webContents) {
super.initialize(webContents);
allowHttpForTest();
}
};
private EmbeddedTestServer mServer;
private List<PaymentApp> mPaymentApps;
private boolean mAllPaymentAppsCreated;
// PaymentAppCreatedCallback
@Override
public void onPaymentAppCreated(PaymentApp paymentApp) {
mPaymentApps.add(paymentApp);
}
// PaymentAppCreatedCallback
@Override
public void onAllPaymentAppsCreated() {
mAllPaymentAppsCreated = true;
}
@Before
public void setUp() throws Throwable {
mRule.startMainActivityOnBlankPage();
mPackageManager.reset();
mServer = EmbeddedTestServer.createAndStartServer(
InstrumentationRegistry.getInstrumentation().getContext());
mParser.setTestServerUri(new URI(mServer.getURL("/components/test/data/payments")));
AndroidPaymentAppFinder.allowHttpForTest();
mPaymentApps = new ArrayList<>();
mAllPaymentAppsCreated = false;
}
@After
public void tearDown() throws Throwable {
if (mServer != null) mServer.stopAndDestroyServer();
}
/** Absence of installed apps should result in no payment apps. */
@Test
@Feature({"Payments"})
public void testNoApps() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add("basic-card");
methods.add(mServer.getURL("/components/test/data/payments/alicepay.com/webpay"));
methods.add(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
methods.add(mServer.getURL("/components/test/data/payments/charliepay.com/webpay"));
methods.add(mServer.getURL("/components/test/data/payments/davepay.com/webpay"));
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
}
/**
* Payment apps without metadata or without default payment method name in metadata should be
* filtered out.
*/
@Test
@Feature({"Payments"})
public void testBadMetadata() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add("basic-card");
mPackageManager.installPaymentApp(
"BobPay", "com.bobpay", null /* no metadata */, "01020304050607080900");
mPackageManager.installPaymentApp("AlicePay", "com.alicepay",
"" /* no default payment method name in metadata */, "ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
}
/** Payment apps without a human-readable name should be filtered out. */
@Test
@Feature({"Payments"})
public void testEmptyLabel() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add("basic-card");
mPackageManager.installPaymentApp(
"" /* empty label */, "com.bobpay", "basic-card", "01020304050607080900");
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
}
/** Invalid and relative URIs cannot be used as payment method names. */
@Test
@Feature({"Payments"})
public void testInvalidPaymentMethodNames() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add("https://"); // Invalid URI.
methods.add("../index.html"); // Relative URI.
mPackageManager.installPaymentApp(
"BobPay", "com.bobpay", "https://", "01020304050607080900");
mPackageManager.installPaymentApp(
"AlicePay", "com.alicepay", "../index.html", "ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
}
/** Non-URL payment method names are hard-coded to those defined in W3C. */
@Test
@Feature({"Payments"})
public void testTwoAppsWithIncorrectMethodNames() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add("basic-card");
methods.add("incorrect-method-name"); // Even if merchant supports it, Chrome filters out
// unknown non-URL method names.
mPackageManager.installPaymentApp(
"BobPay", "com.bobpay", "incorrect-method-name", "01020304050607080900");
mPackageManager.installPaymentApp(
"AlicePay", "com.alicepay", "incorrect-method-name", "ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
}
/**
* Test "basic-card" payment method with a payment app that supports IS_READY_TO_PAY service.
* Another non-payment app also supports IS_READY_TO_PAY service, but it should be filtered
* out, because it's not a payment app.
*/
@Test
@Feature({"Payments"})
public void testOneBasicCardAppWithAFewIsReadyToPayServices() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add("basic-card");
mPackageManager.installPaymentApp(
"BobPay", "com.bobpay", "basic-card", "01020304050607080900");
mPackageManager.addIsReadyToPayService("com.bobpay");
mPackageManager.addIsReadyToPayService("com.alicepay");
findApps(methods);
Assert.assertEquals("1 app should match the query", 1, mPaymentApps.size());
Assert.assertEquals("com.bobpay", mPaymentApps.get(0).getAppIdentifier());
}
/**
* Test BobPay with https://bobpay.com/webpay payment method name, which the payment app
* supports through the "default_applications" directive in the
* https://bobpay.com/payment-manifest.json file. BobPay has the correct signature that
* matches the fingerprint in https://bobpay.com/app.json.
*/
@Test
@Feature({"Payments"})
public void testOneUrlMethodNameApp() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
"01020304050607080900");
findApps(methods);
Assert.assertEquals("1 app should match the query", 1, mPaymentApps.size());
Assert.assertEquals("com.bobpay", mPaymentApps.get(0).getAppIdentifier());
}
/**
* Test BobPay with an incorrect signature and https://bobpay.com/webpay payment method name.
*/
@Test
@Feature({"Payments"})
public void testOneUrlMethodNameAppWithWrongSignature() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
"AA" /* incorrect signature */);
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
}
/** A payment app whose package info cannot be retrieved should be filtered out. */
@Test
@Feature({"Payments"})
public void testOneAppWithoutPackageInfo() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
null /* no package info*/);
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
}
/** Unsigned payment app should be filtered out. */
@Test
@Feature({"Payments"})
public void testOneAppWithoutSignatures() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
"" /* no signatures */);
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
}
/**
* If two payment apps both support "basic-card" payment method name, then they both should be
* found.
*/
@Test
@Feature({"Payments"})
public void testTwoBasicCardApps() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add("basic-card");
mPackageManager.installPaymentApp(
"BobPay", "com.bobpay", "basic-card", "01020304050607080900");
mPackageManager.installPaymentApp(
"AlicePay", "com.alicepay", "basic-card", "ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertEquals("2 apps should match the query", 2, mPaymentApps.size());
Set<String> appIdentifiers = new HashSet<>();
appIdentifiers.add(mPaymentApps.get(0).getAppIdentifier());
appIdentifiers.add(mPaymentApps.get(1).getAppIdentifier());
Assert.assertTrue(appIdentifiers.contains("com.bobpay"));
Assert.assertTrue(appIdentifiers.contains("com.alicepay"));
}
/**
* Test https://davepay.com/webpay payment method, the "default_applications" of which
* supports two different package names: one for production and one for development version
* of the payment app. Both of these apps should be found. Repeated lookups should continue
* finding the two apps.
*/
@Test
@Feature({"Payments"})
public void testTwoUrlMethodNameAppsWithSameMethodName() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/davepay.com/webpay"));
mPackageManager.installPaymentApp("DavePay", "com.davepay.prod",
mServer.getURL("/components/test/data/payments/davepay.com/webpay"),
"44444444442222222222");
mPackageManager.installPaymentApp("DavePay Dev", "com.davepay.dev",
mServer.getURL("/components/test/data/payments/davepay.com/webpay"),
"44444444441111111111");
findApps(methods);
Assert.assertEquals("2 apps should match the query", 2, mPaymentApps.size());
Set<String> appIdentifiers = new HashSet<>();
appIdentifiers.add(mPaymentApps.get(0).getAppIdentifier());
appIdentifiers.add(mPaymentApps.get(1).getAppIdentifier());
Assert.assertTrue(appIdentifiers.contains("com.davepay.prod"));
Assert.assertTrue(appIdentifiers.contains("com.davepay.dev"));
mPaymentApps.clear();
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertEquals("2 apps should match the query again", 2, mPaymentApps.size());
appIdentifiers.clear();
appIdentifiers.add(mPaymentApps.get(0).getAppIdentifier());
appIdentifiers.add(mPaymentApps.get(1).getAppIdentifier());
Assert.assertTrue(appIdentifiers.contains("com.davepay.prod"));
Assert.assertTrue(appIdentifiers.contains("com.davepay.dev"));
}
/**
* If the merchant supports https://bobpay.com/webpay and https://alicepay.com/webpay payment
* method names and the user has an app for each of those, then both apps should be found.
* Repeated lookups should succeed.
*/
@Test
@Feature({"Payments"})
public void testTwoUrlMethodNameAppsWithDifferentMethodNames() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
methods.add(mServer.getURL("/components/test/data/payments/alicepay.com/webpay"));
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
"01020304050607080900");
mPackageManager.installPaymentApp("AlicePay", "com.alicepay",
mServer.getURL("/components/test/data/payments/alicepay.com/webpay"),
"ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertEquals("2 apps should match the query", 2, mPaymentApps.size());
Set<String> appIdentifiers = new HashSet<>();
appIdentifiers.add(mPaymentApps.get(0).getAppIdentifier());
appIdentifiers.add(mPaymentApps.get(1).getAppIdentifier());
Assert.assertTrue(appIdentifiers.contains("com.bobpay"));
Assert.assertTrue(appIdentifiers.contains("com.alicepay"));
mPaymentApps.clear();
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertEquals("2 apps should match the query again", 2, mPaymentApps.size());
appIdentifiers.clear();
appIdentifiers.add(mPaymentApps.get(0).getAppIdentifier());
appIdentifiers.add(mPaymentApps.get(1).getAppIdentifier());
Assert.assertTrue(appIdentifiers.contains("com.bobpay"));
Assert.assertTrue(appIdentifiers.contains("com.alicepay"));
}
/**
* If the merchant supports a couple of payment methods, one of which does not have a valid
* manifest, then all apps that support the invalid manifest should be filtered out. Repeated
* calls should continue finding only the payment app for the valid manifest.
*/
@Test
@Feature({"Payments"})
public void testOneValidManifestAndOneInvalidManifestWithPaymentAppsForBoth() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
methods.add(mServer.getURL("/components/test/data/payments/not-valid.com/webpay"));
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
"01020304050607080900");
mPackageManager.installPaymentApp("NotValid", "com.not-valid",
mServer.getURL("/components/test/data/payments/not-valid.com/webpay"),
"ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertEquals("1 app should match the query", 1, mPaymentApps.size());
Assert.assertEquals("com.bobpay", mPaymentApps.get(0).getAppIdentifier());
mPaymentApps.clear();
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertEquals("1 app should match the query again", 1, mPaymentApps.size());
Assert.assertEquals("com.bobpay", mPaymentApps.get(0).getAppIdentifier());
}
/**
* Repeated lookups of payment apps for URL method names should continue finding the same
* payment apps.
*/
@Test
@Feature({"Payments"})
public void testTwoUrlMethodNameAppsTwice() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
methods.add(mServer.getURL("/components/test/data/payments/alicepay.com/webpay"));
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
"01020304050607080900");
mPackageManager.installPaymentApp("AlicePay", "com.alicepay",
mServer.getURL("/components/test/data/payments/alicepay.com/webpay"),
"ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertEquals("2 apps should match the query", 2, mPaymentApps.size());
Set<String> appIdentifiers = new HashSet<>();
appIdentifiers.add(mPaymentApps.get(0).getAppIdentifier());
appIdentifiers.add(mPaymentApps.get(1).getAppIdentifier());
Assert.assertTrue(appIdentifiers.contains("com.bobpay"));
Assert.assertTrue(appIdentifiers.contains("com.alicepay"));
mPaymentApps.clear();
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertEquals("2 apps should still match the query", 2, mPaymentApps.size());
appIdentifiers.clear();
appIdentifiers.add(mPaymentApps.get(0).getAppIdentifier());
appIdentifiers.add(mPaymentApps.get(1).getAppIdentifier());
Assert.assertTrue(appIdentifiers.contains("com.bobpay"));
Assert.assertTrue(appIdentifiers.contains("com.alicepay"));
}
/**
* Test CharliePay Dev with https://charliepay.com/webpay payment method, which supports both
* dev and prod versions of the app through multiple web app manifests. Repeated app look ups
* should be successful.
*/
@Test
@Feature({"Payments"})
public void testCharliePayDev() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/charliepay.com/webpay"));
mPackageManager.installPaymentApp("CharliePay", "com.charliepay.dev",
mServer.getURL("/components/test/data/payments/charliepay.com/webpay"),
"33333333333111111111");
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
"01020304050607080900");
mPackageManager.installPaymentApp("AlicePay", "com.alicepay",
mServer.getURL("/components/test/data/payments/alicepay.com/webpay"),
"ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertEquals("1 app should match the query", 1, mPaymentApps.size());
Assert.assertEquals("com.charliepay.dev", mPaymentApps.get(0).getAppIdentifier());
mPaymentApps.clear();
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertEquals("1 app should match the query again", 1, mPaymentApps.size());
Assert.assertEquals("com.charliepay.dev", mPaymentApps.get(0).getAppIdentifier());
}
/**
* Test DavePay Dev with https://davepay.com/webpay payment method, which supports both
* dev and prod versions of the app through multiple sections of "related_applications" entry
* in the same web app manifest. Repeated app look ups should be successful.
*/
@Test
@Feature({"Payments"})
public void testDavePayDev() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/davepay.com/webpay"));
mPackageManager.installPaymentApp("DavePay", "com.davepay.dev",
mServer.getURL("/components/test/data/payments/davepay.com/webpay"),
"44444444441111111111");
mPackageManager.installPaymentApp("BobPay", "com.bobpay",
mServer.getURL("/components/test/data/payments/bobpay.com/webpay"),
"01020304050607080900");
mPackageManager.installPaymentApp("AlicePay", "com.alicepay",
mServer.getURL("/components/test/data/payments/alicepay.com/webpay"),
"ABCDEFABCDEFABCDEFAB");
findApps(methods);
Assert.assertEquals("1 app should match the query", 1, mPaymentApps.size());
Assert.assertEquals("com.davepay.dev", mPaymentApps.get(0).getAppIdentifier());
mPaymentApps.clear();
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertEquals("1 app should match the query again", 1, mPaymentApps.size());
Assert.assertEquals("com.davepay.dev", mPaymentApps.get(0).getAppIdentifier());
}
/**
* Test a valid installation of EvePay with 55555555551111111111 signature and
* https://evepay.com/webpay payment method, which supports a couple of different signatures
* (with the same package name) through different web app manifests. Repeated app look ups
* should be successful.
*/
@Test
@Feature({"Payments"})
public void testValidEvePay1() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/evepay.com/webpay"));
mPackageManager.installPaymentApp("EvePay", "com.evepay",
mServer.getURL("/components/test/data/payments/evepay.com/webpay"),
"55555555551111111111");
findApps(methods);
Assert.assertEquals("1 app should match the query", 1, mPaymentApps.size());
Assert.assertEquals("com.evepay", mPaymentApps.get(0).getAppIdentifier());
mPaymentApps.clear();
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertEquals("1 app should match the query again", 1, mPaymentApps.size());
Assert.assertEquals("com.evepay", mPaymentApps.get(0).getAppIdentifier());
}
/**
* Test a valid installation of EvePay with 55555555552222222222 signature and
* https://evepay.com/webpay payment method, which supports a couple of different signatures
* (with the same package name) through different web app manifests. Repeated app look ups
* should be successful.
*/
@Test
@Feature({"Payments"})
public void testValidEvePay2() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/evepay.com/webpay"));
mPackageManager.installPaymentApp("EvePay", "com.evepay",
mServer.getURL("/components/test/data/payments/evepay.com/webpay"),
"55555555552222222222");
findApps(methods);
Assert.assertEquals("1 app should match the query", 1, mPaymentApps.size());
Assert.assertEquals("com.evepay", mPaymentApps.get(0).getAppIdentifier());
mPaymentApps.clear();
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertEquals("1 app should match the query again", 1, mPaymentApps.size());
Assert.assertEquals("com.evepay", mPaymentApps.get(0).getAppIdentifier());
}
/**
* Test an invalid installation of EvePay with https://evepay.com/webpay payment method, which
* supports several different signatures (with the same package name) through different web app
* manifests. Repeated app look ups should find no payment apps.
*/
@Test
@Feature({"Payments"})
public void testInvalidEvePay() throws Throwable {
Set<String> methods = new HashSet<>();
methods.add(mServer.getURL("/components/test/data/payments/evepay.com/webpay"));
mPackageManager.installPaymentApp("EvePay", "com.evepay",
mServer.getURL("/components/test/data/payments/evepay.com/webpay"), "55");
findApps(methods);
Assert.assertTrue("No apps should match the query", mPaymentApps.isEmpty());
mAllPaymentAppsCreated = false;
findApps(methods);
Assert.assertTrue("No apps should match the query again", mPaymentApps.isEmpty());
}
private void findApps(final Set<String> methodNames) throws Throwable {
mRule.runOnUiThread(new Runnable() {
@Override
public void run() {
AndroidPaymentAppFinder.find(
mRule.getActivity().getCurrentContentViewCore().getWebContents(),
methodNames, new PaymentManifestWebDataService(), mDownloader, mParser,
mPackageManager, AndroidPaymentAppFinderTest.this);
}
});
CriteriaHelper.pollInstrumentationThread(new Criteria() {
@Override
public boolean isSatisfied() {
return mAllPaymentAppsCreated;
}
});
}
}
\ No newline at end of file
// Copyright 2017 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.chrome.browser.payments;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** Simulates a package manager in memory. */
class MockPackageManagerDelegate extends PackageManagerDelegate {
private final List<ResolveInfo> mActivities = new ArrayList<>();
private final Map<String, PackageInfo> mPackages = new HashMap<>();
private final Map<ResolveInfo, CharSequence> mLabels = new HashMap<>();
private final List<ResolveInfo> mServices = new ArrayList<>();
/**
* Simulates an installed payment app.
*
* @param label The user visible name of the app.
* @param packageName The identifying package name.
* @param defaultPaymentMethodName The name of the default payment method name for this app.
* If null, then this app will not have metadata. If empty,
* then the default payment method name will not be set.
* @param signature The signature of the app. The SHA256 hash of this
* signature is called "fingerprint" and should be present in
* the app's web app manifest. If null, then this app will
* not have package info. If empty, then this app will not
* have any signatures.
*/
public void installPaymentApp(CharSequence label, String packageName,
String defaultPaymentMethodName, String signature) {
ResolveInfo paymentApp = new ResolveInfo();
paymentApp.activityInfo = new ActivityInfo();
paymentApp.activityInfo.packageName = packageName;
paymentApp.activityInfo.name = packageName + ".WebPaymentActivity";
paymentApp.activityInfo.applicationInfo = new ApplicationInfo();
if (defaultPaymentMethodName != null) {
Bundle metaData = new Bundle();
if (!defaultPaymentMethodName.isEmpty()) {
metaData.putString(
AndroidPaymentAppFinder.META_DATA_NAME_OF_DEFAULT_PAYMENT_METHOD_NAME,
defaultPaymentMethodName);
}
paymentApp.activityInfo.metaData = metaData;
}
mActivities.add(paymentApp);
if (signature != null) {
PackageInfo packageInfo = new PackageInfo();
packageInfo.versionCode = 10;
if (signature.isEmpty()) {
packageInfo.signatures = new Signature[0];
} else {
packageInfo.signatures = new Signature[1];
packageInfo.signatures[0] = new Signature(signature);
}
mPackages.put(packageName, packageInfo);
}
mLabels.put(paymentApp, label);
}
/**
* Simulates an IS_READY_TO_PAY service in a payment app.
*
* @param packageName The identifying package name.
*/
public void addIsReadyToPayService(String packageName) {
ResolveInfo service = new ResolveInfo();
service.serviceInfo = new ServiceInfo();
service.serviceInfo.packageName = packageName;
service.serviceInfo.name = packageName + ".IsReadyToPayService";
mServices.add(service);
}
/** Resets the package manager to the state of no installed apps. */
public void reset() {
mActivities.clear();
mPackages.clear();
mLabels.clear();
}
@Override
public List<ResolveInfo> getActivitiesThatCanRespondToIntentWithMetaData(Intent intent) {
return mActivities;
}
@Override
public List<ResolveInfo> getActivitiesThatCanRespondToIntent(Intent intent) {
return getActivitiesThatCanRespondToIntentWithMetaData(intent);
}
@Override
public List<ResolveInfo> getServicesThatCanRespondToIntent(Intent intent) {
return mServices;
}
@Override
public PackageInfo getPackageInfoWithSignatures(String packageName) {
return mPackages.get(packageName);
}
@Override
public CharSequence getAppLabel(ResolveInfo resolveInfo) {
return mLabels.get(resolveInfo);
}
@Override
public Drawable getAppIcon(ResolveInfo resolveInfo) {
return null;
}
}
\ No newline at end of file
......@@ -41,12 +41,12 @@ public class PaymentManifestDownloaderTest implements ManifestDownloadCallback {
public ChromeActivityTestRule<ChromeActivity> mRule =
new ChromeActivityTestRule<>(ChromeActivity.class);
private static final String PAYMENT_METHOD_MANIFEST = "{\n"
+ " \"default_applications\": [\"app.json\"],\n"
private static final String EXPECTED_PAYMENT_METHOD_MANIFEST = "{\n"
+ " \"default_applications\": [\"https://bobpay.com/app.json\"],\n"
+ " \"supported_origins\": [\"https://alicepay.com\"]\n"
+ "}\n";
private static final String WEB_APP_MANIFEST = "{\n"
private static final String EXPECTED_WEB_APP_MANIFEST = "{\n"
+ " \"name\": \"BobPay\",\n"
+ " \"related_applications\": [{\n"
+ " \"platform\": \"play\",\n"
......@@ -54,8 +54,9 @@ public class PaymentManifestDownloaderTest implements ManifestDownloadCallback {
+ " \"min_version\": \"1\",\n"
+ " \"fingerprints\": [{\n"
+ " \"type\": \"sha256_cert\",\n"
+ " \"value\": \"59:5C:88:65:FF:C4:E8:20:CF:F7:3E:C8:64:D0"
+ ":95:F0:06:19:2E:A6:7B:20:04:D1:03:07:92:E2:A5:31:67:66\"\n"
+ " \"value\": \"9A:89:C6:8C:4C:5E:28:B8:C4:A5:56:76:73:D4:62:"
+ "FF:F5:15:DB:46:11:6F:99:00:62:4D:09:C4:74:F5:93:FB\",\n"
+ " \"comment\": \"This fingperint is SHA256 of '01020304050607080900'\"\n"
+ " }]\n"
+ " }]\n"
+ "}\n";
......@@ -124,7 +125,8 @@ public class PaymentManifestDownloaderTest implements ManifestDownloadCallback {
@Test
@Feature({"Payments"})
public void testDownloadWebAppManifest() throws Throwable {
final URI uri = new URI(mServer.getURL("/components/test/data/payments/app.json"));
final URI uri =
new URI(mServer.getURL("/components/test/data/payments/bobpay.com/app.json"));
mRule.runOnUiThread(new Runnable() {
@Override
public void run() {
......@@ -140,7 +142,7 @@ public class PaymentManifestDownloaderTest implements ManifestDownloadCallback {
Assert.assertTrue(
"Web app manifest should have been downloaded.", mDownloadWebAppManifestSuccess);
Assert.assertEquals(WEB_APP_MANIFEST, mWebAppManifest);
Assert.assertEquals(EXPECTED_WEB_APP_MANIFEST, mWebAppManifest);
}
@Test
......@@ -166,7 +168,7 @@ public class PaymentManifestDownloaderTest implements ManifestDownloadCallback {
@Test
@Feature({"Payments"})
public void testDownloadPaymentMethodManifest() throws Throwable {
final URI uri = new URI(mServer.getURL("/components/test/data/payments/webpay"));
final URI uri = new URI(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
mRule.runOnUiThread(new Runnable() {
@Override
public void run() {
......@@ -182,7 +184,7 @@ public class PaymentManifestDownloaderTest implements ManifestDownloadCallback {
Assert.assertTrue("Payment method manifest should have been downloaded.",
mDownloadPaymentMethodManifestSuccess);
Assert.assertEquals(PAYMENT_METHOD_MANIFEST, mPaymentMethodManifest);
Assert.assertEquals(EXPECTED_PAYMENT_METHOD_MANIFEST, mPaymentMethodManifest);
}
@Test
......@@ -211,9 +213,10 @@ public class PaymentManifestDownloaderTest implements ManifestDownloadCallback {
public void testSeveralDownloadsAtOnce() throws Throwable {
final URI paymentMethodUri1 = new URI(mServer.getURL("/no-such-payment-method-name"));
final URI paymentMethodUri2 =
new URI(mServer.getURL("/components/test/data/payments/webpay"));
new URI(mServer.getURL("/components/test/data/payments/bobpay.com/webpay"));
final URI webAppUri1 = new URI(mServer.getURL("/no-such-app.json"));
final URI webAppUri2 = new URI(mServer.getURL("/components/test/data/payments/app.json"));
final URI webAppUri2 =
new URI(mServer.getURL("/components/test/data/payments/bobpay.com/app.json"));
mRule.runOnUiThread(new Runnable() {
@Override
public void run() {
......@@ -233,7 +236,7 @@ public class PaymentManifestDownloaderTest implements ManifestDownloadCallback {
}
});
Assert.assertEquals(PAYMENT_METHOD_MANIFEST, mPaymentMethodManifest);
Assert.assertEquals(WEB_APP_MANIFEST, mWebAppManifest);
Assert.assertEquals(EXPECTED_PAYMENT_METHOD_MANIFEST, mPaymentMethodManifest);
Assert.assertEquals(EXPECTED_WEB_APP_MANIFEST, mWebAppManifest);
}
}
......@@ -175,7 +175,8 @@ void PaymentManifestDownloader::InitiateDownload(
bool PaymentManifestDownloader::IsValidManifestUrl(const GURL& url) {
return url.is_valid() &&
(url.SchemeIs(url::kHttpsScheme) ||
(url.SchemeIs(url::kHttpScheme) && allow_http_for_test_));
(allow_http_for_test_ && url.SchemeIs(url::kHttpScheme) &&
url.host() == "127.0.0.1"));
}
} // namespace payments
......@@ -118,98 +118,96 @@ source_set("unit_tests") {
]
}
bundle_data("payments_test_bundle_data") {
testonly = true
if (is_ios) {
bundle_data("payments_test_bundle_data") {
testonly = true
sources = [
"//components/test/data/payments/abort.js",
"//components/test/data/payments/alicepay_bobpay_charliepay_and_cards.js",
"//components/test/data/payments/app.json",
"//components/test/data/payments/blob_url.js",
"//components/test/data/payments/bobpay.js",
"//components/test/data/payments/bobpay_and_basic_card_with_basic_card_modifiers.js",
"//components/test/data/payments/bobpay_and_basic_card_with_modifiers.js",
"//components/test/data/payments/bobpay_and_cards.js",
"//components/test/data/payments/bobpay_ui_skip.js",
"//components/test/data/payments/bobpay_ui_skip_preload.js",
"//components/test/data/payments/can_make_payment_metrics.js",
"//components/test/data/payments/can_make_payment_query.js",
"//components/test/data/payments/can_make_payment_query_bobpay.js",
"//components/test/data/payments/can_make_payment_query_cc.js",
"//components/test/data/payments/contact_details.js",
"//components/test/data/payments/contact_details_and_free_shipping.js",
"//components/test/data/payments/debit.js",
"//components/test/data/payments/dynamic_shipping.js",
"//components/test/data/payments/email.js",
"//components/test/data/payments/email_and_free_shipping.js",
"//components/test/data/payments/email_and_phone.js",
"//components/test/data/payments/extra_shipping_options.js",
"//components/test/data/payments/fail_complete.js",
"//components/test/data/payments/free_shipping.js",
"//components/test/data/payments/initiated.js",
"//components/test/data/payments/initiated_test.html",
"//components/test/data/payments/long_id.js",
"//components/test/data/payments/metrics.js",
"//components/test/data/payments/modifier.js",
"//components/test/data/payments/multiple_show.js",
"//components/test/data/payments/name.js",
"//components/test/data/payments/name_and_free_shipping.js",
"//components/test/data/payments/no_shipping.js",
"//components/test/data/payments/payment-manifest.json",
"//components/test/data/payments/payment_method_identifier.js",
"//components/test/data/payments/payment_request.html",
"//components/test/data/payments/payment_request.js",
"//components/test/data/payments/payment_request_abort_test.html",
"//components/test/data/payments/payment_request_alicepay_bobpay_charliepay_and_cards_test.html",
"//components/test/data/payments/payment_request_blob_url_test.html",
"//components/test/data/payments/payment_request_bobpay_and_basic_card_with_basic_card_modifiers_test.html",
"//components/test/data/payments/payment_request_bobpay_and_basic_card_with_modifiers_test.html",
"//components/test/data/payments/payment_request_bobpay_and_cards_test.html",
"//components/test/data/payments/payment_request_bobpay_test.html",
"//components/test/data/payments/payment_request_bobpay_ui_skip_preload_test.html",
"//components/test/data/payments/payment_request_bobpay_ui_skip_test.html",
"//components/test/data/payments/payment_request_can_make_payment_metrics_test.html",
"//components/test/data/payments/payment_request_can_make_payment_query_bobpay_test.html",
"//components/test/data/payments/payment_request_can_make_payment_query_cc_test.html",
"//components/test/data/payments/payment_request_can_make_payment_query_test.html",
"//components/test/data/payments/payment_request_contact_details_and_free_shipping_test.html",
"//components/test/data/payments/payment_request_contact_details_test.html",
"//components/test/data/payments/payment_request_debit_test.html",
"//components/test/data/payments/payment_request_dynamic_shipping_test.html",
"//components/test/data/payments/payment_request_email_and_free_shipping_test.html",
"//components/test/data/payments/payment_request_email_and_phone_test.html",
"//components/test/data/payments/payment_request_email_test.html",
"//components/test/data/payments/payment_request_extra_shipping_options_test.html",
"//components/test/data/payments/payment_request_fail_complete_test.html",
"//components/test/data/payments/payment_request_free_shipping_test.html",
"//components/test/data/payments/payment_request_id.js",
"//components/test/data/payments/payment_request_id_test.html",
"//components/test/data/payments/payment_request_iframe.html",
"//components/test/data/payments/payment_request_long_id_test.html",
"//components/test/data/payments/payment_request_main.html",
"//components/test/data/payments/payment_request_metrics_test.html",
"//components/test/data/payments/payment_request_modifier_test.html",
"//components/test/data/payments/payment_request_multiple_requests.html",
"//components/test/data/payments/payment_request_multiple_show_test.html",
"//components/test/data/payments/payment_request_name_and_free_shipping_test.html",
"//components/test/data/payments/payment_request_name_test.html",
"//components/test/data/payments/payment_request_no_shipping_test.html",
"//components/test/data/payments/payment_request_payment_method_identifier_test.html",
"//components/test/data/payments/payment_request_phone_and_free_shipping_test.html",
"//components/test/data/payments/payment_request_phone_test.html",
"//components/test/data/payments/payment_request_shipping_address_change_test.html",
"//components/test/data/payments/payment_request_show_twice_test.html",
"//components/test/data/payments/phone.js",
"//components/test/data/payments/phone_and_free_shipping.js",
"//components/test/data/payments/shipping_address_change.js",
"//components/test/data/payments/show_twice.js",
"//components/test/data/payments/style.css",
"//components/test/data/payments/util.js",
"//components/test/data/payments/webpay",
"//components/test/data/payments/webpay.mock-http-headers",
]
outputs = [
"{{bundle_resources_dir}}/" +
"{{source_root_relative_dir}}/{{source_file_part}}",
]
sources = [
"//components/test/data/payments/abort.js",
"//components/test/data/payments/alicepay_bobpay_charliepay_and_cards.js",
"//components/test/data/payments/blob_url.js",
"//components/test/data/payments/bobpay.js",
"//components/test/data/payments/bobpay_and_basic_card_with_basic_card_modifiers.js",
"//components/test/data/payments/bobpay_and_basic_card_with_modifiers.js",
"//components/test/data/payments/bobpay_and_cards.js",
"//components/test/data/payments/bobpay_ui_skip.js",
"//components/test/data/payments/bobpay_ui_skip_preload.js",
"//components/test/data/payments/can_make_payment_metrics.js",
"//components/test/data/payments/can_make_payment_query.js",
"//components/test/data/payments/can_make_payment_query_bobpay.js",
"//components/test/data/payments/can_make_payment_query_cc.js",
"//components/test/data/payments/contact_details.js",
"//components/test/data/payments/contact_details_and_free_shipping.js",
"//components/test/data/payments/debit.js",
"//components/test/data/payments/dynamic_shipping.js",
"//components/test/data/payments/email.js",
"//components/test/data/payments/email_and_free_shipping.js",
"//components/test/data/payments/email_and_phone.js",
"//components/test/data/payments/extra_shipping_options.js",
"//components/test/data/payments/fail_complete.js",
"//components/test/data/payments/free_shipping.js",
"//components/test/data/payments/initiated.js",
"//components/test/data/payments/initiated_test.html",
"//components/test/data/payments/long_id.js",
"//components/test/data/payments/metrics.js",
"//components/test/data/payments/modifier.js",
"//components/test/data/payments/multiple_show.js",
"//components/test/data/payments/name.js",
"//components/test/data/payments/name_and_free_shipping.js",
"//components/test/data/payments/no_shipping.js",
"//components/test/data/payments/payment_method_identifier.js",
"//components/test/data/payments/payment_request.html",
"//components/test/data/payments/payment_request.js",
"//components/test/data/payments/payment_request_abort_test.html",
"//components/test/data/payments/payment_request_alicepay_bobpay_charliepay_and_cards_test.html",
"//components/test/data/payments/payment_request_blob_url_test.html",
"//components/test/data/payments/payment_request_bobpay_and_basic_card_with_basic_card_modifiers_test.html",
"//components/test/data/payments/payment_request_bobpay_and_basic_card_with_modifiers_test.html",
"//components/test/data/payments/payment_request_bobpay_and_cards_test.html",
"//components/test/data/payments/payment_request_bobpay_test.html",
"//components/test/data/payments/payment_request_bobpay_ui_skip_preload_test.html",
"//components/test/data/payments/payment_request_bobpay_ui_skip_test.html",
"//components/test/data/payments/payment_request_can_make_payment_metrics_test.html",
"//components/test/data/payments/payment_request_can_make_payment_query_bobpay_test.html",
"//components/test/data/payments/payment_request_can_make_payment_query_cc_test.html",
"//components/test/data/payments/payment_request_can_make_payment_query_test.html",
"//components/test/data/payments/payment_request_contact_details_and_free_shipping_test.html",
"//components/test/data/payments/payment_request_contact_details_test.html",
"//components/test/data/payments/payment_request_debit_test.html",
"//components/test/data/payments/payment_request_dynamic_shipping_test.html",
"//components/test/data/payments/payment_request_email_and_free_shipping_test.html",
"//components/test/data/payments/payment_request_email_and_phone_test.html",
"//components/test/data/payments/payment_request_email_test.html",
"//components/test/data/payments/payment_request_extra_shipping_options_test.html",
"//components/test/data/payments/payment_request_fail_complete_test.html",
"//components/test/data/payments/payment_request_free_shipping_test.html",
"//components/test/data/payments/payment_request_id.js",
"//components/test/data/payments/payment_request_id_test.html",
"//components/test/data/payments/payment_request_iframe.html",
"//components/test/data/payments/payment_request_long_id_test.html",
"//components/test/data/payments/payment_request_main.html",
"//components/test/data/payments/payment_request_metrics_test.html",
"//components/test/data/payments/payment_request_modifier_test.html",
"//components/test/data/payments/payment_request_multiple_requests.html",
"//components/test/data/payments/payment_request_multiple_show_test.html",
"//components/test/data/payments/payment_request_name_and_free_shipping_test.html",
"//components/test/data/payments/payment_request_name_test.html",
"//components/test/data/payments/payment_request_no_shipping_test.html",
"//components/test/data/payments/payment_request_payment_method_identifier_test.html",
"//components/test/data/payments/payment_request_phone_and_free_shipping_test.html",
"//components/test/data/payments/payment_request_phone_test.html",
"//components/test/data/payments/payment_request_shipping_address_change_test.html",
"//components/test/data/payments/payment_request_show_twice_test.html",
"//components/test/data/payments/phone.js",
"//components/test/data/payments/phone_and_free_shipping.js",
"//components/test/data/payments/shipping_address_change.js",
"//components/test/data/payments/show_twice.js",
"//components/test/data/payments/style.css",
"//components/test/data/payments/util.js",
]
outputs = [
"{{bundle_resources_dir}}/" +
"{{source_root_relative_dir}}/{{source_file_part}}",
]
}
}
{
"name": "AlicePay",
"related_applications": [{
"platform": "play",
"id": "com.alicepay",
"min_version": "1",
"fingerprints": [{
"type": "sha256_cert",
"value": "C2:16:F6:8A:50:30:CC:C7:A8:C4:58:FE:29:E6:3B:5C:B9:2D:89:BB:8A:9E:CD:FC:B0:B9:27:77:1E:2E:93:FD",
"comment": "This fingperint is SHA256 of 'ABCDEFABCDEFABCDEFAB'"
}]
}]
}
{
"default_applications": ["https://alicepay.com/app.json"],
"supported_origins": "*"
}
......@@ -6,7 +6,8 @@
"min_version": "1",
"fingerprints": [{
"type": "sha256_cert",
"value": "59:5C:88:65:FF:C4:E8:20:CF:F7:3E:C8:64:D0:95:F0:06:19:2E:A6:7B:20:04:D1:03:07:92:E2:A5:31:67:66"
"value": "9A:89:C6:8C:4C:5E:28:B8:C4:A5:56:76:73:D4:62:FF:F5:15:DB:46:11:6F:99:00:62:4D:09:C4:74:F5:93:FB",
"comment": "This fingperint is SHA256 of '01020304050607080900'"
}]
}]
}
{
"default_applications": ["app.json"],
"default_applications": ["https://bobpay.com/app.json"],
"supported_origins": ["https://alicepay.com"]
}
HTTP/1.1 200 OK
Link: <payment-manifest.json>; rel="payment-method-manifest"
{
"name": "CharliePay Dev",
"related_applications": [{
"platform": "play",
"id": "com.charliepay.dev",
"min_version": "1",
"fingerprints": [{
"type": "sha256_cert",
"value": "15:A8:F5:AE:6D:33:EB:E0:15:22:31:9B:A0:07:3B:7F:44:FB:85:9C:1D:F6:B7:5E:75:1A:A1:A3:3A:13:8D:86",
"comment": "This fingperint is SHA256 of '33333333333111111111'"
}]
}]
}
{
"default_applications": ["https://charliepay.com/dev.json", "https://charliepay.com/prod.json"]
}
{
"name": "CharliePay",
"related_applications": [{
"platform": "play",
"id": "com.charliepay.prod",
"min_version": "1",
"fingerprints": [{
"type": "sha256_cert",
"value": "AA:BB:CC:DD:EE:FF:E0:D3:A0:E9:3C:D9:9D:40:5B:30:65:4D:39:9C:5B:C7:00:A6:39:2E:B7:85:37:28:E0:2B",
"comment": "This fingerprint is not used in tests, so it does not correspond to any signature."
}]
}]
}
HTTP/1.1 200 OK
Link: <payment-manifest.json>; rel="payment-method-manifest"
{
"name": "DavePay",
"related_applications": [{
"platform": "play",
"id": "com.davepay.prod",
"min_version": "1",
"fingerprints": [{
"type": "sha256_cert",
"value": "C9:F0:AC:53:A0:CE:E0:D3:A0:E9:3C:D9:9D:40:5B:30:65:4D:39:9C:5B:C7:00:A6:39:2E:B7:85:37:28:E0:2B",
"comment": "This fingperint is SHA256 of '44444444442222222222'"
}]
}, {
"platform": "play",
"id": "com.davepay.dev",
"min_version": "1",
"fingerprints": [{
"type": "sha256_cert",
"value": "BB:65:66:5C:BD:75:04:92:99:85:B1:1D:2D:32:11:DC:B5:66:B8:74:25:D7:AB:D1:EC:3C:56:EE:72:D9:25:81",
"comment": "This fingperint is SHA256 of '44444444441111111111'"
}]
}]
}
{
"default_applications": ["https://davepay.com/app.json"]
}
HTTP/1.1 200 OK
Link: <payment-manifest.json>; rel="payment-method-manifest"
{
"name": "EvePay",
"related_applications": [{
"platform": "play",
"id": "com.evepay",
"min_version": "1",
"fingerprints": [{
"type": "sha256_cert",
"value": "74:2C:5F:7D:3E:A0:CE:D7:C9:5A:5C:07:55:FD:8C:59:9B:B0:1E:1B:F2:6E:3E:32:3F:23:AB:04:42:2A:75:E3",
"comment": "This fingperint is SHA256 of '55555555551111111111'"
}]
}]
}
{
"name": "EvePay",
"related_applications": [{
"platform": "play",
"id": "com.evepay",
"min_version": "1",
"fingerprints": [{
"type": "sha256_cert",
"value": "70:00:B7:67:09:84:E5:36:15:02:AF:99:ED:AE:B4:04:EE:AB:65:B2:A6:20:B6:38:75:06:2A:26:FB:12:B4:B9",
"comment": "This fingperint is SHA256 of '55555555552222222222'"
}]
}]
}
{
"default_applications": ["https://evepay.com/app1.json", "https://evepay.com/app2.json"]
}
HTTP/1.1 200 OK
Link: <payment-manifest.json>; rel="payment-method-manifest"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment