<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for the 'secure-payment-confirmation' payment method enrollment - cross origin</title>
<link rel="help" href="https://w3c.github.io/secure-payment-confirmation#client-extension-processing-registration">
<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 enrolling an SPC credential 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);
  });

  const frame = document.createElement('iframe');
  frame.allow = 'payment';
  frame.src = 'https://{{hosts[alt][]}}:{{ports[https][0]}}' +
      '/secure-payment-confirmation/resources/iframe-enroll.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;

  const resultPromise = new Promise(resolve => {
      window.addEventListener('message', function handler(evt) {
        if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') {
          window.removeEventListener('message', handler);
          document.body.removeChild(frame);
          resolve(evt.data);
        }
      });
  });
  frame.contentWindow.postMessage({ userActivation: true }, '*');
  const result = await resultPromise;

  // Because we specified the 'payment' permission and the iframe had a user
  // activation, the enrollment should work.
  assert_equals(result.error, null);
  assert_own_property(result, 'id');
  assert_own_property(result, 'rawId');
}, 'SPC enrollment in cross-origin iframe');

promise_test(async t => {
  // Make sure that we are testing enrolling an SPC credential 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);
  });

  const frame = document.createElement('iframe');
  frame.allow = 'payment';
  frame.src = 'https://{{hosts[alt][]}}:{{ports[https][0]}}' +
      '/secure-payment-confirmation/resources/iframe-enroll.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;

  const resultPromise = new Promise(resolve => {
      window.addEventListener('message', function handler(evt) {
        if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') {
          window.removeEventListener('message', handler);
          document.body.removeChild(frame);
          resolve(evt.data);
        }
      });
  });
  frame.contentWindow.postMessage({ userActivation: false }, '*');
  const result = await resultPromise;

  // Without a user activation, we expect a NotAllowedError.
  assert_true(result.error instanceof DOMException);
  assert_equals(result.error.name, 'NotAllowedError');
  assert_not_own_property(result, 'id');
  assert_not_own_property(result, 'rawId');
}, 'SPC enrollment in cross-origin iframe fails without user activation');

promise_test(async t => {
  // Make sure that we are testing enrolling an SPC credential 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);
  });

  const frame = document.createElement('iframe');
  // This iframe does *not* have a payments permission specified on it, and so
  // should not allow SPC credential creation.
  frame.src = 'https://{{hosts[alt][]}}:{{ports[https][0]}}' +
      '/secure-payment-confirmation/resources/iframe-enroll.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;

  const resultPromise = new Promise(resolve => {
      window.addEventListener('message', function handler(evt) {
        if (evt.source === frame.contentWindow && evt.data.type == 'spc_result') {
          window.removeEventListener('message', handler);
          document.body.removeChild(frame);
          resolve(evt.data);
        }
      });
  });
  frame.contentWindow.postMessage({ userActivation: true }, '*');
  const result = await resultPromise;

  // Because we didn't specify the 'payment' permission, the enrollment should
  // result in an error.
  assert_own_property(result, 'error');
  assert_true(result.error instanceof DOMException);
  assert_equals(result.error.name, 'NotSupportedError');
  assert_not_own_property(result, 'id');
  assert_not_own_property(result, 'rawId');
}, 'SPC enrollment in cross-origin iframe without payment permission');
</script>
