<!doctype html>
<meta charset="utf8">
<link rel="help" href="https://w3c.github.io/payment-request/#user-accepts-the-payment-request-algorithm">
<title>
  User accepts the payment request algorithm
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
setup({ explicit_done: true, explicit_timeout: true });
const applePay = Object.freeze({
  supportedMethods: "https://apple.com/apple-pay",
  data: {
    version: 3,
    merchantIdentifier: "merchant.com.example",
    countryCode: "US",
    merchantCapabilities: ["supports3DS"],
    supportedNetworks: ["visa"],
  }
});
const basicCardMethod = Object.freeze({
  supportedMethods: "basic-card",
});
const validMethod = Object.freeze({
  supportedMethods: "this-is-just-for-testings-will-never-match",
});
const methods = Object.freeze([basicCardMethod, validMethod, applePay]);
const validAmount = Object.freeze({
  currency: "USD",
  value: "5.00",
});
const shippingOptions = [
  Object.freeze({
    id: "option1",
    label: "Option 1",
    amount: validAmount,
    selected: false,
  }),
  Object.freeze({
    id: "option 2",
    label: "Option 2",
    amount: validAmount,
    selected: true,
  }),
];

const detailsNoShippingOptions = Object.freeze({
  total: {
    label: "Total due",
    amount: validAmount,
  },
});

const detailsWithShippingOptions = Object.assign({}, detailsNoShippingOptions, {
  shippingOptions,
});

const optionsRequestNothing = Object.freeze({
  requestShipping: false,
  requestPayerEmail: false,
  requestPayerName: false,
  requestPayerPhone: false,
});

const optionsRequestEverything = Object.freeze({
  requestShipping: true,
  requestPayerEmail: true,
  requestPayerName: true,
  requestPayerPhone: true,
});

test(() => {
  // smoke test
  try {
    new PaymentRequest(methods, detailsNoShippingOptions);
  } catch (err) {
    done();
    throw err;
  }
}, "Must be able to construct a payment request (smoke test)");

function testAcceptRequestAlgorithm(
  button,
  details,
  options = {},
  expectedResponse = {}
) {
  button.disabled = true;
  promise_test(async t => {
    const request = new PaymentRequest(methods, details, options);
    const response = await request.show();
    assert_true(
      response instanceof PaymentResponse,
      "Expected an instance of PaymentResponse."
    );
    // Response [[calledComplete]] is false, so this shouldn't throw
    await response.complete("success");
    // For good measure, test that subsequent complete()
    for (const state of [undefined, "success", "fail", "unknown"]) {
      await promise_rejects(
        t,
        "InvalidStateError",
        response.complete(state),
        "Response [[calledComplete]] is true, so InvalidStateError"
      );
    }
    assert_equals(
      request.id,
      response.requestId,
      "Request and response ids must match."
    );
    assert_true(response.details instanceof Object, "Expected an object");
    assert_equals(
      response.shippingAddress,
      request.shippingAddress,
      "Request and response must reference same shippingAddress (or both null)."
    );
    assert_equals(
      response.shippingOption,
      request.shippingOption,
      "Request and response must be the same value (or both null)."
    );
    if (options.requestShipping === true) {
      assert_true(
        response.shippingAddress instanceof PaymentAddress,
        "Expected an instance of PaymentAddress."
      );
    }
    const expected = {
      methodName: "basic-card",
      payerEmail: options.requestPayerEmail
        ? expectedResponse.payerEmail
        : null,
      payerName: options.requestPayerName ? expectedResponse.payerName : null,
      payerPhone: options.requestPayerPhone
        ? expectedResponse.payerPhone
        : null,
    };
    for (const [attr, expectedValue] of Object.entries(expected)) {
      assert_equals(
        response[attr],
        expectedValue,
        `response.${attr} must be ${expectedValue}`
      );
    }
    await promise_rejects(
      t,
      "InvalidStateError",
      request.show(),
      "Request [[state]] is closed, so InvalidStateError"
    );
  }, button.textContent.trim());
}

</script>

<section>
  <h2 id="user-accepts-payment-request">User accepts payment request</h2>
  <p>
    Click on each button in sequence from top to bottom without refreshing the page.
    Each button will bring up the Payment Request UI window.
  </p>
  <p>
    When shown the payment sheet, please input a credit card and select Pay.
  </p>
  <ol>
    <li>
      <button onclick="
        const detailsWithId = Object.assign({}, detailsNoShippingOptions, { id: 'pass' });
        testAcceptRequestAlgorithm(this, detailsWithId, optionsRequestNothing);">
        User accepts payment request, but not shipping is requested.
      </button> Use any credit card to pay.
    </li>
    <li>
      <button onclick="
        const requestShipping = Object.assign({}, optionsRequestNothing, {requestShipping: true});
        const expectedValues = { shippingOption: 'option 2' };
        testAcceptRequestAlgorithm(this, detailsWithShippingOptions, requestShipping, expectedValues);">
        User accepts payment request, merchant requests shipping.
      </button> Select any shipping option, and use any credit card to pay.
    </li>
    <li>
      <button onclick="
        const requestPayerEmail = Object.assign({}, optionsRequestNothing, {requestPayerEmail: true});
        const expectValues = { payerEmail: 'wpt@w3.org' };
        testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerEmail, expectValues);">
        User accepts payment request, merchant requests email.
      </button>
      When prompted, please use "wpt@w3.org" as the email.
    </li>
    <li>
      <button onclick="
        const requestPayerPhone = Object.assign({}, optionsRequestNothing, {requestPayerPhone: true});
        const expectValues = { payerPhone: '+12345678910' };
        testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerPhone, expectValues);">
        User accepts payment request, merchant requests phone.
      </button>
      When prompted, please use "+12345678910" as the phone number.
    </li>
    <li>
      <button onclick="
        const requestPayerName = Object.assign({}, optionsRequestNothing, {requestPayerName: true});
        const expectValues = { payerName: 'web platform test' };
        testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerName, expectValues);">
        User accepts payment request, merchant requests payer's name.
      </button>
      When prompted, please use "web platform test" as the payer name.
    </li>
    <li>
      <button onclick="
        const expectValues = {
          payerEmail: 'wpt@w3.org',
          payerName: 'web platform test',
          payerPhone: '+12345678910',
          shippingOption: 'option 2',
        };
        testAcceptRequestAlgorithm(this, detailsWithShippingOptions, optionsRequestEverything, expectValues);">
        User accepts payment request, merchant requests everything.
      </button>
      When prompted, please use: "+12345678910" as the phone number, "web platform test" as the payer name, and "wpt@w3.org" as the email. Then press Pay.
    </li>
    <li>
      <button onclick="done()">Done</button>
    </li>
  </ol>
</section>
<small>
  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
</small>
