<!DOCTYPE html>
<!-- Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
<meta charset="utf-8">
<title>Tests for PaymentRequest.canMakePayment() method</title>
<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const basicCard = Object.freeze({ supportedMethods: "basic-card" });
const defaultMethods = Object.freeze([basicCard]);
const defaultDetails = Object.freeze({
  total: {
    label: "Total",
    amount: {
      currency: "USD",
      value: "1.00",
    },
  },
});

promise_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  try {
    assert_true(
      await request.canMakePayment(),
      `canMakePaymentPromise should be true`
    );
    assert_true(
      await request.canMakePayment(),
      `canMakePaymentPromise should be true`
    );
  } catch (err) {
    assert_equals(
      err.name,
      "NotAllowedError",
      "if it throws, then it must be a NotAllowedError."
    );
  }
}, `If request.[[state]] is "created", then return a promise that resolves to true for known method.`);

promise_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  const acceptPromise = request.show(); // Sets state to "interactive"
  const canMakePaymentPromise = request.canMakePayment();
  try {
    const result = await canMakePaymentPromise;
    assert_true(
      false,
      `canMakePaymentPromise should have thrown InvalidStateError`
    );
  } catch (err) {
    await promise_rejects(t, "InvalidStateError", canMakePaymentPromise);
  } finally {
    await request.abort();
    await promise_rejects(t, "AbortError", acceptPromise);
  }
  // The state should be "closed"
  await promise_rejects(t, "InvalidStateError", request.canMakePayment());
}, `If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException.`);

promise_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  const acceptPromise = request.show(); // The state is now "interactive"
  acceptPromise.catch(() => {}); // no-op, just to silence unhandled rejection in devtools.
  await request.abort(); // The state is now "closed"
  await promise_rejects(t, "InvalidStateError", request.canMakePayment());
  try {
    const result = await request.canMakePayment();
    assert_true(
      false,
      `should have thrown InvalidStateError, but instead returned "${result}"`
    );
  } catch (err) {
    assert_equals(
      err.name,
      "InvalidStateError",
      "must be an InvalidStateError."
    );
  }
}, `If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.`);

promise_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  assert_true(await request.canMakePayment(), "basic-card should be supported");
}, `If payment method identifier and serialized parts are supported, resolve promise with true.`);

promise_test(async t => {
  const unsupportedMethods = [
    "this-is-not-supported",
    "https://not.supported",
    "e",
    "n6jzof05mk2g4lhxr-u-q-w1-c-i-pa-ty-bdvs9-ho-ae7-p-md8-s-wq3-h-qd-e-q-sa",
    "a-b-q-n-s-pw0",
    "m-u",
    "s-l5",
    "k9-f",
    "m-l",
    "u4-n-t",
    "i488jh6-g18-fck-yb-v7-i",
    "x-x-t-t-c34-o",
    "https://wpt",
    "https://wpt.fyi/",
    "https://wpt.fyi/payment",
    "https://wpt.fyi/payment-request",
    "https://wpt.fyi/payment-request?",
    "https://wpt.fyi/payment-request?this=is",
    "https://wpt.fyi/payment-request?this=is&totally",
    "https://wpt.fyi:443/payment-request?this=is&totally",
    "https://wpt.fyi:443/payment-request?this=is&totally#fine",
    "https://:@wpt.fyi:443/payment-request?this=is&totally#👍",
    " \thttps://wpt\n ",
    "https://xn--c1yn36f",
    "https://點看",
  ];
  for (const method of unsupportedMethods) {
    try {
      const request = new PaymentRequest(
        [{ supportedMethods: method }],
        defaultDetails
      );
      assert_false(
        await request.canMakePayment(),
        `method "${method}" must not be supported`
      );
    } catch (err) {
      assert_true(
        false,
        `Unexpected exception testing method ${method}, expected false. See error console.`
      );
    }
  }
}, `If payment method identifier is unknown, resolve promise with false.`);

promise_test(async t => {
  // This test might never actually hit its assertion, but that's allowed.
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  for (let i = 0; i < 1000; i++) {
    try {
      await request.canMakePayment();
    } catch (err) {
      assert_equals(
        err.name,
        "NotAllowedError",
        "if it throws, then it must be a NotAllowedError."
      );
      break;
    }
  }
  for (let i = 0; i < 1000; i++) {
    try {
      await new PaymentRequest(defaultMethods, defaultDetails).canMakePayment();
    } catch (err) {
      assert_equals(
        err.name,
        "NotAllowedError",
        "if it throws, then it must be a NotAllowedError."
      );
      break;
    }
  }
}, `Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.`);
</script>
