<!DOCTYPE html>
<title>Digital Credential tests.</title>
<link rel="help" href="https://wicg.github.io/digital-credentials/" />
<script src="/common/get-host-info.sub.js"></script>
<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>

<body>
  <iframe id="same-origin"></iframe>
  <iframe id="cross-origin" allow="digital-credentials-get"></iframe>
</body>
<script type="module">
  import { makeGetOptions, sendMessage, loadIframe } from "./support/helper.js";

  const iframeSameOrigin = document.querySelector("iframe#same-origin");
  const iframeCrossOrigin = document.querySelector("iframe#cross-origin");

  promise_setup(async () => {
    const hostInfo = get_host_info();
    await Promise.all([
      loadIframe(
        iframeCrossOrigin,
        `${hostInfo.HTTPS_REMOTE_ORIGIN}/digital-credentials/support/iframe.html`
      ),
      loadIframe(iframeSameOrigin, "/digital-credentials/support/iframe.html"),
    ]);
  });

  promise_test(async (t) => {
    const invalidData = [null, undefined, "", 123, true, false];
    for (const data of invalidData) {
      const options = {
        digital: {
          requests: [
            {
              data,
              protocol: "openid4vp",
            },
          ],
        },
      };
      await promise_rejects_js(
        t,
        TypeError,
        navigator.credentials.get(options)
      );
    }
  }, "Type conversion happens on the data member of the DigitalCredentialGetRequest object.");

  promise_test(async (t) => {
    iframeSameOrigin.focus();
    for (const global of [window, iframeSameOrigin.contentWindow]) {
      await promise_rejects_dom(
        t,
        "NotSupportedError",
        global.DOMException,
        global.navigator.credentials.get()
      );

      await promise_rejects_dom(
        t,
        "NotSupportedError",
        global.DOMException,
        global.navigator.credentials.get({})
      );

      await promise_rejects_dom(
        t,
        "NotSupportedError",
        global.DOMException,
        global.navigator.credentials.get({ x: "y" })
      );

      await promise_rejects_dom(
        t,
        "NotSupportedError",
        global.DOMException,
        global.navigator.credentials.get({ x: "y", y: "z" })
      );

      await promise_rejects_dom(
        t,
        "NotSupportedError",
        global.DOMException,
        global.navigator.credentials.get({ mediation: "required" })
      );

      const abortController = new AbortController();
      const { signal } = abortController;

      await promise_rejects_dom(
        t,
        "NotSupportedError",
        global.DOMException,
        global.navigator.credentials.get({ signal })
      );

      await promise_rejects_dom(
        t,
        "NotSupportedError",
        global.DOMException,
        global.navigator.credentials.get({ signal, mediation: "required" })
      );
    }
  }, "Calling navigator.credentials.get() without a digital member same origin.");

  promise_test(async (t) => {
    for (const request of [undefined, []]) {
      const options = makeGetOptions(request);
      await test_driver.bless("user activation");
      await promise_rejects_js(
        t,
        TypeError,
        navigator.credentials.get(options)
      );
    }
  }, "navigator.credentials.get() API rejects if there are no credential request.");

  promise_test(async (t) => {
    iframeSameOrigin.focus();
    const { contentWindow: iframeWindow } = iframeSameOrigin;
    for (const request of [undefined, []]) {
      const options = makeGetOptions(request);
      await test_driver.bless("user activation");
      await promise_rejects_js(
        t,
        iframeWindow.TypeError,
        iframeWindow.navigator.credentials.get(options)
      );
    }
  }, "navigator.credentials.get() API rejects if there are no credential request for same-origin iframe.");

  promise_test(async (t) => {
    iframeCrossOrigin.focus();
    for (const request of [undefined, []]) {
      const options = makeGetOptions(request);
      const result = await sendMessage(iframeCrossOrigin, {
        action: "get",
        options,
      });
      assert_equals(result.constructor, "TypeError");
    }
  }, "navigator.credentials.get() API rejects if there are no credential request in cross-origin iframe.");

  promise_test(async (t) => {
    const abortController = new AbortController();
    const { signal } = abortController;
    abortController.abort();
    for (const options of [{ signal }, { signal, ...makeGetOptions([]) }]) {
      await promise_rejects_dom(
        t,
        "AbortError",
        navigator.credentials.get(options)
      );
    }
  }, "navigator.credentials.get() promise is rejected if called with an aborted controller.");

  promise_test(async (t) => {
    iframeSameOrigin.focus();
    const { contentWindow: iframeWindow } = iframeSameOrigin;
    const abortController = new iframeWindow.AbortController();
    const { signal } = abortController;
    abortController.abort();
    for (const options of [{ signal }, { signal, ...makeGetOptions([]) }]) {
      await test_driver.bless("user activation");
      await promise_rejects_dom(
        t,
        "AbortError",
        iframeWindow.DOMException,
        iframeWindow.navigator.credentials.get(options)
      );
      assert_true(
        navigator.userActivation.isActive,
        "User activation is still active."
      );
    }
  }, "navigator.credentials.get() promise is rejected if called with an aborted controller in same-origin iframe.");

  promise_test(async (t) => {
    iframeCrossOrigin.focus();
    for (const options of [undefined, {}, makeGetOptions([])]) {
      const result = await sendMessage(iframeCrossOrigin, {
        abort: "before",
        action: "get",
        options,
      });
      assert_equals(result.constructor, "DOMException");
      assert_equals(result.name, "AbortError");
    }
  }, "navigator.credentials.get() promise is rejected if called with an aborted signal in cross-origin iframe.");

  promise_test(async (t) => {
    const abortController = new AbortController();
    const { signal } = abortController;
    const options = makeGetOptions("openid4vp");
    options.signal = signal;
    await test_driver.bless("user activation");
    const promise = promise_rejects_dom(
      t,
      "AbortError",
      DOMException,
      navigator.credentials.get(options)
    );
    abortController.abort();
    await promise;
  }, "navigator.credentials.get() promise is rejected if abort controller is aborted after call to get().");

  promise_test(async (t) => {
    iframeCrossOrigin.focus();
    const result = await sendMessage(iframeCrossOrigin, {
      abort: "after",
      action: "get",
      needsActivation: true,
      options: makeGetOptions("openid4vp"),
    });
    assert_equals(result.constructor, "DOMException");
    assert_equals(result.name, "AbortError");
  }, "navigator.credentials.get() promise is rejected if abort controller is aborted after call to get() in cross-origin iframe.");

  promise_test(async (t) => {
    /** @type sequence<CredentialMediationRequirement> */
    const disallowedMediations = ["conditional", "optional", "silent"];
    for (const mediation of disallowedMediations) {
      const options = makeGetOptions("default", mediation);
      await promise_rejects_js(
        t,
        TypeError,
        navigator.credentials.get(options)
      );
    }
  }, "Mediation is required to get a DigitalCredential.");
</script>
