<!doctype html>
<meta charset="utf8">
<link rel="help" href="https://www.w3.org/TR/payment-request/#updatewith()-method">
<link rel="help" href="https://github.com/w3c/payment-request/pull/591">
<title>
  PaymentRequestUpdateEvent.updateWith() needs to be called immediately
</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 validMethod = Object.freeze({ supportedMethods: "basic-card" });
const validMethods = Object.freeze([validMethod, applePay]);
const validAmount = Object.freeze({ currency: "USD", value: "5.00" });
const validTotal = Object.freeze({
  label: "label",
  amount: validAmount,
});
const validShippingOptionA = Object.freeze({
  id: "a-shipping-option",
  label: "A shipping option",
  amount: validAmount,
  selected: true,
});
const validShippingOptionB = Object.freeze({
  id: "b-shipping-option",
  label: "B shipping option",
  amount: validAmount,
});
const validDetails = Object.freeze({
  total: validTotal,
  shippingOptions: [validShippingOptionA, validShippingOptionB],
});
const validOptions = Object.freeze({
  requestShipping: true,
});

function testImmediateUpdate({ textContent: testName }) {
  promise_test(async t => {
    const request = new PaymentRequest(
      validMethods,
      validDetails,
      validOptions
    );
    const eventPromise = new Promise((resolve, reject) => {
      request.addEventListener(
        "shippingaddresschange",
        ev => {
          // Forces updateWith() to be run in the next event loop tick so that
          // [[waitForUpdate]] is already true when it runs.
          t.step_timeout(() => {
            try {
              ev.updateWith(validDetails);
              resolve(); // This is bad.
            } catch (err) {
              reject(err); // this is good.
            }
          });
        },
        { once: true }
      );
    });
    const acceptPromise = request.show();
    await promise_rejects_dom(
      t,
      "InvalidStateError",
      eventPromise,
      "The event loop already spun, so [[waitForUpdate]] is now true"
    );
    const response = await acceptPromise;
    await response.complete();
  }, testName.trim());
}

function testSubsequentUpdateWithCalls({ textContent: testName }) {
  promise_test(async t => {
    const request = new PaymentRequest(
      validMethods,
      validDetails,
      validOptions
    );
    const eventPromise = new Promise((resolve, reject) => {
      request.addEventListener("shippingaddresschange", async ev => {
        const p = Promise.resolve(validDetails);
        ev.updateWith(p);
        await p;
        try {
          ev.updateWith(validDetails);
          resolve(); // this is bad, we should never get to here.
        } catch (err) {
          reject(err); // this is good!
        }
      });
    });
    const responsePromise = request.show();
    await promise_rejects_dom(
      t,
      "InvalidStateError",
      eventPromise,
      "Expected eventPromise to have rejected, because updateWith() was a called twice"
    );
    const response = await responsePromise;
    await response.complete();
  }, testName.trim());
}

function testRecycleEvents({ textContent: testName }) {
  promise_test(async t => {
    const request = new PaymentRequest(
      validMethods,
      validDetails,
      validOptions
    );

    // Register both listeners.
    const addressChangedPromise = new Promise(resolve => {
      request.addEventListener("shippingaddresschange", resolve, {
        once: true,
      });
    });

    const optionChangedPromise = new Promise(resolve => {
      request.addEventListener("shippingoptionchange", resolve, {
        once: true,
      });
    });

    const responsePromise = request.show();

    // Let's wait for the address to change.
    const addressChangeEvent = await addressChangedPromise;

    // Sets [[waitingForUpdate]] to true.
    addressChangeEvent.updateWith(validDetails);

    // Let's wait for the shippingOption.
    const optionChangeEvent = await optionChangedPromise;

    // Here, we try to be sneaky, and reuse the addressChangeEvent to perform the update.
    // However, addressChangeEvent [[waitingForUpdate]] is true, so it throws.
    assert_throws_dom(
      "InvalidStateError",
      () => {
        addressChangeEvent.updateWith(validDetails);
      },
      "addressChangeEvent [[waitingForUpdate]] is true, so it must throw"
    );

    // But optionChangeEvent is still usable tho, so...
    optionChangeEvent.updateWith(validDetails);

    assert_throws_dom(
      "InvalidStateError",
      () => {
        optionChangeEvent.updateWith(validDetails);
      },
      "optionChangeEvent [[waitingForUpdate]] is true, so it must throw"
    );

    const response = await responsePromise;
    await response.complete();
  }, testName.trim());
}
</script>
<h2>updateWith() method</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 the payment sheet is shown, select a different shipping address once. Then pay.
</p>
<ol>
  <li id="test-0">
    <button onclick="testImmediateUpdate(this);">
      updateWith() must be called immediately, otherwise must throw an InvalidStateError.
    </button>
  </li>
  <li id="test-1">
    <button onclick="testSubsequentUpdateWithCalls(this);">
      Once the event has performed an update, subsequent calls to updateWith() must throw InvalidStateError.
    </button>
  </li>
  <li id="test-2">
    <button onclick="testRecycleEvents(this);">
      Recycling events must not be possible.
    </button> When the payment sheet is shown, select a different shipping address once, then change shipping option once. Then pay.
  </li>
  <li>
    <button onclick="done();">Done!</button>
  </li>
</ol>
<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>
