<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for the 'secure-payment-confirmation' payment method authentication - cross origin</title>
<link rel="help" href="https://w3c.github.io/secure-payment-confirmation#sctn-authentication">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="utils.sub.js"></script>

<!-- This test requires a non-empty body to workaround https://github.com/web-platform-tests/wpt/issues/34563 -->
<body><div>Non-empty body</div></body>

<script>
'use strict';

promise_test(async t => {
  // Make sure that we are testing calling SPC in a cross-origin iframe.
  assert_not_equals(window.location.hostname, '{{hosts[alt][]}}',
      'This test must not be run on the alt hostname.');

  const authenticator = await window.test_driver.add_virtual_authenticator(
      AUTHENTICATOR_OPTS);
  t.add_cleanup(() => {
    return window.test_driver.remove_virtual_authenticator(authenticator);
  });

  await window.test_driver.set_spc_transaction_mode('autoAccept');
  t.add_cleanup(() => {
    return window.test_driver.set_spc_transaction_mode('none');
  });

  const credential = await createCredential();

  const frame = document.createElement('iframe');
  frame.allow = 'payment';
  frame.src = 'https://{{hosts[alt][]}}:{{ports[https][0]}}' +
      '/secure-payment-confirmation/resources/iframe-authenticate.html';

  // Wait for the iframe to load.
  const readyPromise = new Promise(resolve => {
      window.addEventListener('message', function handler(evt) {
        if (evt.source === frame.contentWindow && evt.data.type == 'loaded') {
          window.removeEventListener('message', handler);

          resolve(evt.data);
        }
      });
  });
  document.body.appendChild(frame);
  await readyPromise;

  // Setup the result promise before triggering authentication, to avoid a
  // race.
  const resultPromise = new Promise(resolve => {
      window.addEventListener('message', function handler(evt) {
        if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') {
          // We're done with the child iframe now.
          document.body.removeChild(frame);
          window.removeEventListener('message', handler);

          resolve(evt.data);
        }
      });
  });

  const rpId = window.location.hostname;
  frame.contentWindow.postMessage([credential.rawId, rpId], '*');

  const result = await resultPromise;

  assert_not_own_property(result, 'error');

  assert_equals(result.id, credential.id);
  assert_equals(result.clientDataJSON.origin, 'https://{{hosts[alt][]}}:{{ports[https][0]}}');
  assert_equals(result.clientDataJSON.payment.topOrigin, window.location.origin);
  // The credential was created in this frame, and so we are the rp.
  assert_equals(result.clientDataJSON.payment.rpId, window.location.hostname);
  // The payeeOrigin should be unrelated to what the origin and topOrigin are.
  assert_equals(result.clientDataJSON.payment.payeeOrigin, 'https://merchant.com');
}, 'SPC authentication ceremony in cross-origin iframe');

promise_test(async t => {
  // Make sure that we are testing calling SPC in a cross-origin iframe.
  assert_not_equals(window.location.hostname, '{{hosts[alt][]}}',
      'This test must not be run on the alt hostname.');

  const authenticator = await window.test_driver.add_virtual_authenticator(
      AUTHENTICATOR_OPTS);
  t.add_cleanup(() => {
    return window.test_driver.remove_virtual_authenticator(authenticator);
  });

  await window.test_driver.set_spc_transaction_mode('autoAccept');
  t.add_cleanup(() => {
    return window.test_driver.set_spc_transaction_mode('none');
  });

  const credential = await createCredential();

  const frame = document.createElement('iframe');
  // This iframe does *not* have a payments permission specified on it, and so
  // should not allow SPC authentication.
  frame.src = 'https://{{hosts[alt][]}}:{{ports[https][0]}}' +
      '/secure-payment-confirmation/resources/iframe-authenticate.html';

  // Wait for the iframe to load.
  const readyPromise = new Promise(resolve => {
      window.addEventListener('message', function handler(evt) {
        if (evt.source === frame.contentWindow && evt.data.type == 'loaded') {
          window.removeEventListener('message', handler);

          resolve(evt.data);
        }
      });
  });
  document.body.appendChild(frame);
  await readyPromise;

  // Setup the result promise before triggering authentication, to avoid a
  // race.
  const resultPromise = new Promise(resolve => {
      window.addEventListener('message', function handler(evt) {
        if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') {
          // We're done with the child iframe now.
          document.body.removeChild(frame);
          window.removeEventListener('message', handler);

          resolve(evt.data);
        }
      });
  });

  const rpId = window.location.hostname;
  frame.contentWindow.postMessage([credential.rawId, rpId], '*');

  const result = await resultPromise;

  assert_own_property(result, 'error');
  assert_true(result.error instanceof DOMException);
  assert_equals(result.error.name, 'SecurityError');

  assert_not_own_property(result, 'id');
  assert_not_own_property(result, 'clientDataJSON');
}, 'SPC authentication ceremony in cross-origin iframe without payment permission');
</script>
