<!DOCTYPE html>
<title>Digital Credential API: get() user activation tests.</title>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.js" type="module"></script>
<body></body>
<script type="module">
  import { makeGetOptions } from "./support/helper.js";

  promise_test(async (t) => {
    assert_false(
      navigator.userActivation.isActive,
      "User activation should not be active",
    );
    const options = makeGetOptions();
    await promise_rejects_dom(
      t,
      "NotAllowedError",
      navigator.credentials.get(options),
    );
  }, "navigator.credentials.get() calling the API without user activation should reject with NotAllowedError.");

  promise_test(async (t) => {
    assert_false(
      navigator.userActivation.isActive,
      "User activation should not be active",
    );
    const options = makeGetOptions({ data: { val: BigInt(1) } });
    await promise_rejects_dom(
      t,
      "NotAllowedError",
      navigator.credentials.get(options),
    );
  }, "navigator.credentials.get() with non-serializable data and no user activation should reject with NotAllowedError.");

  promise_test(async (t) => {
    assert_false(
      navigator.userActivation.isActive,
      "User activation should not be active",
    );
    const options = makeGetOptions({ protocol: [] });
    await promise_rejects_js(t, TypeError, navigator.credentials.get(options));
    assert_false(
      navigator.userActivation.isActive,
      "User activation should not be active",
    );
  }, "navigator.credentials.get() with empty protocol array and no user activation needed should reject with TypeError.")

  promise_test(async (t) => {
    await test_driver.bless();
    assert_true(
      navigator.userActivation.isActive,
      "User activation should be active after test_driver.bless().",
    );
    const abort = new AbortController();
    const options = makeGetOptions({ signal: abort.signal });
    abort.abort();
    const promise = navigator.credentials.get(options);
    await promise_rejects_dom(t, "AbortError", promise);
    assert_true(
      navigator.userActivation.isActive,
      "User activation should not be consumed on early abort with navigator.credentials.get().",
    );
  }, "navigator.credentials.get() with early abort does not consume user activation.");

  promise_test(async (t) => {
    await test_driver.bless();
    assert_true(
      navigator.userActivation.isActive,
      "User activation should be active after test_driver.bless().",
    );
    const abort = new AbortController();
    const options = makeGetOptions({ signal: abort.signal });

    const promise = navigator.credentials.get(options);
    abort.abort();
    await promise_rejects_dom(t, "AbortError", promise);
    assert_false(
      navigator.userActivation.isActive,
      "User activation should be consumed after navigator.credentials.get().",
    );
  }, "navigator.credentials.get() with late abort consumes user activation.");
</script>
