<!doctype html>
<meta charset="utf8">
<link rel="help" href="https://w3c.github.io/payment-request/#algorithms">
<title>
  Payment Request algorithms
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
setup({
  explicit_done: true,
  explicit_timeout: true,
});
const methods = [
  {
    supportedMethods: "basic-card",
  },
];
const shippingOptions = {
  shippingOptions: [
    {
      id: "fail",
      label: "Option 1",
      amount: {
        currency: "USD",
        value: "5.00",
      },
      selected: true,
    },
    {
      id: "pass",
      label: "Option 2",
      amount: {
        currency: "USD",
        value: "5.00",
      },
    },
  ],
};

const detailsNoShippingOptions = {
  total: {
    label: "Total due",
    amount: {
      currency: "USD",
      value: "1.0",
    },
  },
};

const detailsWithShippingOptions = Object.assign(
  {
    total: {
      label: "Total due",
      amount: {
        currency: "USD",
        value: "1.0",
      },
    },
  },
  shippingOptions
);

const options = {
  requestShipping: true,
};

function testFireEvent(button, details, eventName, expectRequestProps) {
  button.disabled = true;
  promise_test(async t => {
    new PaymentRequest(methods, detailsNoShippingOptions, options);
    const request = new PaymentRequest(methods, details, options);
    const handlerPromise = new Promise(resolve => {
      request[`on${eventName}`] = event => {
        // "prevent immediate propagation" flag is set.
        // This listener below won't fire!
        event.updateWith(details);
        resolve(event);
      };
    });
    // This listener should never fire because the
    // the event handler caused "prevent immediate propagation" to be set.
    request.addEventListener(
      eventName,
      t.unreached_func("Second event listener should never fire")
    );
    const response = await request.show();
    const event = await handlerPromise;
    assert_true(
      event instanceof window.PaymentRequestUpdateEvent,
      "Expected instances of PaymentRequestUpdateEvent"
    );
    await response.complete("success");
  }, button.textContent.trim());
}

async function runAbortTest(button) {
  button.disabled = true;
  const { textContent: testName } = button;
  promise_test(async t => {
    const request = new PaymentRequest(methods, detailsNoShippingOptions);
    // Await the user to abort
    await promise_rejects(t, "AbortError", request.show());
    // [[state]] is now closed
    await promise_rejects(t, "InvalidStateError", request.show());
  }, testName.trim());
}
</script>
<h2>
  Tests for "algorithms" section
</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>
<section>
  <h3 id="abort-algo">
    User aborts the payment request algorithm
  </h3>
  <link rel="help" href="https://w3c.github.io/payment-request/#user-aborts-the-payment-request-algorithm">
  <p>
    When presented with the payment sheet, abort the payment request (e.g., by hitting the esc key or pressing a UA provided button).
  </p>
  <ol>
    <li>
      <button onclick="runAbortTest(this);">
      If the user aborts, the UA must run the user aborts the payment request algorithm.
    </button>
    </li>
  </ol>
</section>

<section>
  <h3 id="shipping-address-changed-algo">Shipping address changed algorithm</h3>
  <link rel="help" href="https://www.w3.org/TR/payment-request/#shipping-address-changed-algorithm">
  <p>
    When prompted, please change or enter a new shipping address and then select Pay.
  </p>
  <ol>
    <li>
      <button onclick="testFireEvent(this, detailsWithShippingOptions, 'shippingaddresschange', {});">
      The shipping address changed algorithm runs when the user provides a new shipping address.
    </button>
    </li>
  </ol>
</section>

<section>
  <h3 id="shipping-option-changed-algo">Shipping option changed algorithm</h3>
  <link rel="help" href="https://w3c.github.io/payment-request/#shipping-option-changed-algorithm">
  <p>
    Finally, when prompted, please select "shipping option 2" and then select Pay.
  </p>
  <ol>
    <li>
      <button onclick="testFireEvent(this, detailsWithShippingOptions, 'shippingoptionchange', {}, 'pass'); done();">
      The shipping option changed algorithm runs when the user chooses a new shipping option.
    </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>
