Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 13 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /payment-method-manifest/pmm-supported-origins.https.window.html - WPT Dashboard Interop Dashboard
// META: title=Payment Method Manifest supported_origins validation
// META: script=/common/get-host-info.sub.js
// META: script=/common/utils.js
// META: script=/payment-method-manifest/resources/helpers.js
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: [
// Origin without an explicit port (uses default port 443).
// Origins with an explicit port (wptserve's HTTPS port).
get_host_info().HTTPS_ORIGIN,
get_host_info().HTTPS_REMOTE_ORIGIN,
get_host_info().HTTPS_NOTSAMESITE_ORIGIN,
],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 3);
// The spec does not speak to the supported_origins being fetched by the
// browser, but we can check whether or not the default_applications was
// fetched as a proxy for "payment method manifest was parsed as valid".
assert_equals(
logs.length, 3,
'Browser must perform 3 server requests (HEAD PMI, GET PMM, GET WAM)');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[0].method, 'HEAD', 'PMI request must use HEAD method');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
assert_equals(logs[1].method, 'GET', 'PMM request must use GET method');
assert_equals(logs[2].endpoint, 'web-app-manifest',
'Third request must hit WAM URL');
assert_equals(logs[2].method, 'GET', 'WAM request must use GET method');
}, 'Multiple valid HTTPS origins in supported_origins are allowed');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 3);
// The spec does not speak to the supported_origins being fetched by the
// browser, but we can check whether or not the default_applications was
// fetched as a proxy for "payment method manifest was parsed as valid".
assert_equals(
logs.length, 3,
'Browser must perform 3 server requests (HEAD PMI, GET PMM, GET WAM)');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[0].method, 'HEAD', 'PMI request must use HEAD method');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
assert_equals(logs[1].method, 'GET', 'PMM request must use GET method');
assert_equals(logs[2].endpoint, 'web-app-manifest',
'Third request must hit WAM URL');
assert_equals(logs[2].method, 'GET', 'WAM request must use GET method');
}, 'Omitting supported_origins is allowed');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: get_host_info().HTTPS_ORIGIN,
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The non-array supported_origins should cause payment method manifest
// validation to fail, so the default_applications should not be fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins is a string');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Non-array supported_origins must fail validation and prevent WAM fetch');
}, 'Non-array value for supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: '*',
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The wildcard supported_origins should cause payment method manifest
// validation to fail, so the default_applications should not be fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins is wildcard "*"');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Wildcard "*" supported_origins must fail validation and prevent WAM fetch');
}, 'Wildcard "*" for supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: null,
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The null supported_origins should cause payment method manifest validation
// to fail, so the default_applications should not be fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins is null');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Null supported_origins must fail validation and prevent WAM fetch');
}, 'Null value for supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: [],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The empty supported_origins list should cause payment method manifest
// validation to fail, so the default_applications should not be fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins is an empty array');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Empty supported_origins array must fail entire manifest validation and prevent WAM fetch');
}, 'Empty array for supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: [get_host_info().HTTPS_ORIGIN, 123],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The non-string item in the supported_origins should cause payment method
// manifest validation to fail, so the default_applications should not be
// fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins contains a non-string');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Non-string item in supported_origins must fail validation and prevent WAM fetch');
}, 'Non-string item in supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: ['/relative-origin'],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The relative URL in the supported_origins should cause payment method
// manifest validation to fail, so the default_applications should not be
// fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins contains a relative URL');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Relative URL in supported_origins must fail validation and prevent WAM fetch');
}, 'Relative URL in supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: [
get_host_info().HTTPS_ORIGIN,
get_host_info().HTTP_ORIGIN,
],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The non-HTTPS origin in the supported_origins should cause payment method
// manifest validation to fail, so the default_applications should not be
// fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins contains an HTTP origin');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Non-HTTPS origin in supported_origins must fail validation and prevent WAM fetch');
}, 'Non-HTTPS origin in supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: [get_host_info().HTTPS_ORIGIN_WITH_CREDS],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The inclusion of a username/password origin in the supported_origins should
// cause payment method manifest validation to fail, so the
// default_applications should not be fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins contains credentials');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Origin with username/password in supported_origins must fail validation and prevent WAM fetch');
}, 'Origin with username or password in supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: [`${get_host_info().HTTPS_ORIGIN}/webpay`],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The inclusion of an origin with a path in the supported_origins should
// cause payment method manifest validation to fail, so the
// default_applications should not be fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins contains a path');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Origin with non-empty path in supported_origins must fail validation and prevent WAM fetch');
}, 'Origin with path in supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: [`${get_host_info().HTTPS_ORIGIN}/?action=webpay`],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The inclusion of an origin with a query in the supported_origins should
// cause payment method manifest validation to fail, so the
// default_applications should not be fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins contains a query string');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Origin with query in supported_origins must fail validation and prevent WAM fetch');
}, 'Origin with query in supported_origins fails validation');
promise_test(async t => {
const testId = token();
const wamUrl = createWebAppManifestUrl(testId);
const pmmUrl = createPaymentMethodManifestUrl(testId, {
body: JSON.stringify({
default_applications: [wamUrl],
supported_origins: [`${get_host_info().HTTPS_ORIGIN}/#webpay`],
}),
});
const pmiUrl = createPaymentMethodIdentifierUrl(testId, {
link: `<${pmmUrl}>; rel="payment-method-manifest"`,
});
const request = new PaymentRequest(
[{supportedMethods: pmiUrl}],
{total: {label: 'Total', amount: {currency: 'USD', value: '1.00'}}});
try {
await request.canMakePayment();
} catch (err) {
// It is fine for this call to fail; server logs are still captured and
// inspected below.
}
const logs = await waitForServerAccessLogs(t, testId, 2);
// The inclusion of an origin with a fragment in the supported_origins should
// cause payment method manifest validation to fail, so the
// default_applications should not be fetched.
assert_equals(
logs.length, 2,
'Browser must issue only 2 server requests (HEAD PMI, GET PMM) when supported_origins contains a fragment');
assert_equals(logs[0].endpoint, 'payment-method-identifier',
'First request must hit PMI URL');
assert_equals(logs[1].endpoint, 'payment-method-manifest',
'Second request must hit PMM URL');
const wamLogs = logs.filter(l => l.endpoint === 'web-app-manifest');
assert_equals(
wamLogs.length, 0,
'Origin with fragment in supported_origins must fail validation and prevent WAM fetch');
}, 'Origin with fragment in supported_origins fails validation');