<!DOCTYPE html>
<!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
<!--  Copyright (C) 2017 Apple Inc. All rights reserved.  -->
<!-- FIXME: Upstream this test to web-platform-tests/payment-request/. -->
<meta charset="utf-8">
<title>Test for PaymentRequest.show() method</title>
<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
<script src="/js-test-resources/ui-helper.js"></script>
<script src="/resources/payment-request.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
'use strict';
const applePay = Object.freeze({
    supportedMethods: "https://apple.com/apple-pay",
    data: {
        version: 2,
        merchantIdentifier: '',
        merchantCapabilities: ['supports3DS'],
        supportedNetworks: ['visa', 'masterCard'],
        countryCode: 'US',
    },
});
const defaultMethods = Object.freeze([applePay]);
const defaultDetails = Object.freeze({
  total: {
    label: "Total",
    amount: {
      currency: "USD",
      value: "1.00",
    },
  },
});

test(() => {
  try {
    new PaymentRequest(defaultMethods, defaultDetails);
  } catch (err) {
    done();
    throw err;
  }
}, "Must be possible to construct a payment request");


user_activation_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  const acceptPromise = request.show(); // Sets state to "interactive"
  await promise_rejects_dom(t, "SecurityError", request.show());
  await request.abort();
  await promise_rejects_dom(t, "AbortError", acceptPromise);
}, `Throws if the promise [[state]] is not "created"`);

user_activation_test(async t => {
  const request1 = new PaymentRequest(defaultMethods, defaultDetails);
  const request2 = new PaymentRequest(defaultMethods, defaultDetails);
  const acceptPromise1 = request1.show();
  const acceptPromise2 = request2.show();
  await promise_rejects_dom(t, "SecurityError", acceptPromise2);
  await request1.abort();
  await promise_rejects_dom(t, "AbortError", acceptPromise1);
}, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`);

user_activation_test(async t => {
  const request = new PaymentRequest(
    [{ supportedMethods: "this-is-not-supported" }],
    defaultDetails);
  const acceptPromise = request.show();
  await promise_rejects_dom(t, "NotSupportedError", acceptPromise);
}, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`);

user_activation_test(async t => {
  const request = new PaymentRequest(
    [{ supportedMethods: "https://apple.com/apple-pay" }],
    defaultDetails);
  const acceptPromise = request.show();
  await promise_rejects_js(t, TypeError, acceptPromise);
}, `If data conversion results in an error, then return a promise rejected with a "TypeError" DOMException.`);

user_activation_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  const acceptPromise = request.show(); // Sets state to "interactive"
  internals.mockPaymentCoordinator.cancelPayment();
  await promise_rejects_dom(t, "AbortError", acceptPromise);
}, `If the user aborts the payment request algorithm, then return a promise rejected with an "AbortError" DOMException.`);

user_activation_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  const acceptPromise = request.show(new Promise(resolve => {
    window.setTimeout(() => {
      internals.mockPaymentCoordinator.cancelPayment();
      window.setTimeout(() => resolve(defaultDetails));
    });
  })); // Sets state to "interactive"
  await promise_rejects_dom(t, "AbortError", acceptPromise);
}, `If the user aborts the payment request algorithm while details are updating, then reject the accept promise with an "AbortError" when the details settle.`);

user_activation_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  const expectedLabel = "Updated Total";
  const expectedAmount = "2.00";
  const details = {
      total: {
          label: expectedLabel,
          amount: {
              currency: "USD",
              value: expectedAmount,
          },
      },
  };
  const acceptPromise = request.show(details);
  internals.mockPaymentCoordinator.changePaymentMethod({ type: 'credit' });
  internals.mockPaymentCoordinator.acceptPayment();
  const result = await acceptPromise;
  assert_equals(internals.mockPaymentCoordinator.total.label, expectedLabel);
  assert_equals(internals.mockPaymentCoordinator.total.amount, expectedAmount);
  result.complete("success");
}, `A request is updated when show()'s detail promise resolves.`);

user_activation_test(async t => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  const expectedLabel = "Updated Total";
  const expectedAmount = "2.00";

  var shippingAddressChanged = false;
  const shippingAddressChangedPromise = new Promise((resolve) => {
    request.onshippingaddresschange = (event) => {
      shippingAddressChanged = true;
      event.updateWith({});
      resolve();
    };
  });

  const detailsPromise = new Promise((resolve) => {
    const details = {
      total: {
        label: expectedLabel,
        amount: {
          currency: "USD",
          value: expectedAmount,
        },
      },
    };

    request.onmerchantvalidation = (event) => {
      const sessionPromise = new Promise((resolve) => resolve({ }));
      event.complete(sessionPromise);
      sessionPromise.then(() => window.setTimeout(() => {
        assert_equals(shippingAddressChanged, false, "shippingaddresschange does not fire before the details promise resolves.");
        resolve(details);
      }));
    };
  });

  request.show(detailsPromise).catch(() => {});
  await shippingAddressChangedPromise;
}, `Change events do not occur until show()'s detail promise resolves.`);
</script>
