chromium/third_party/blink/web_tests/wpt_internal/fenced_frame/content-shared-storage-get.https.html

<!DOCTYPE html>
<title>Test sharedStorage.get() in a fenced frame with network revocation.</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/utils.js"></script>

<body>
<script>

promise_setup(async () => {
  // Set sharedStorage value for HTTPS_ORIGIN
  await sharedStorage.set('test', 'apple');

  // Set sharedStorage value for HTTPS_REMOTE_ORIGIN.
  let init_iframe = await attachIFrameContext(
                  {origin: get_host_info().HTTPS_REMOTE_ORIGIN});
  await init_iframe.execute(async () => {
      await sharedStorage.set('test', 'banana');
  });
});

promise_test(async (t) => {
  const fencedframe = await attachFencedFrameContext(
    {origin: get_host_info().HTTPS_ORIGIN});

  await fencedframe.execute(async () => {
    await window.fence.disableUntrustedNetwork();
    let get_result = await sharedStorage.get('test');
    assert_equals(get_result, 'apple');
  });
}, 'Test sharedStorage.get() succeeds in a fenced frame with network ' +
   'revocation.');

promise_test(async (t) => {
  const fencedframe = await attachFencedFrameContext(
    {origin: get_host_info().HTTPS_ORIGIN});

  await fencedframe.execute(async () => {
    try {
      await sharedStorage.get('test');
      assert_unreached('Calling get() without revoking network should throw.');
    } catch (e) {
      assert_equals(e.name, 'OperationError');
      assert_equals(e.message, 'sharedStorage.get() is not allowed in a ' +
        'fenced frame until network access for it and all descendent frames ' +
        'has been revoked with window.fence.disableUntrustedNetwork()');
    }
  });
}, 'Test that sharedStorage.get() in a fenced frame rejects when network is ' +
   'not revoked.');

promise_test(async (t) => {
  const fencedframe = await attachFencedFrameContext(
    {origin: get_host_info().HTTPS_REMOTE_ORIGIN});

  await fencedframe.execute(async () => {
    await window.fence.disableUntrustedNetwork();
    let get_result = await sharedStorage.get('test');
    assert_equals(get_result, 'banana');
  });
}, 'Test that sharedStorage.get() can only fetch keys for its own origin ' +
   'when network is revoked.');

promise_test(async (t) => {
    // First, try get() in a top-level document.
    try {
      await sharedStorage.get('test');
      assert_unreached('Call to get() in top-level document should throw.');
    } catch (e) {
      assert_equals(e.name, 'OperationError');
      assert_equals(e.message, 'Cannot call get() outside of a fenced frame.')
    }

    const samesite_iframe = await attachIFrameContext(
      {origin: get_host_info().HTTPS_ORIGIN});

    // Then, try get() in an iframe.
    await samesite_iframe.execute(async () => {
      try {
        await sharedStorage.get('test');
        assert_unreached('Call to get() outside a fenced frame should throw.');
      } catch (e) {
        assert_equals(e.name, 'OperationError');
        assert_equals(e.message, 'Cannot call get() outside of a fenced frame.')
      }
    });
}, 'Test that sharedStorage.get() rejects outside of a fenced frame.');

promise_test(async (t) => {
  const fencedframe = await attachFencedFrameContext(
    {origin: get_host_info().HTTPS_ORIGIN});

  const destination_url = new URL('resources/dummy.html', location.href);

  await fencedframe.execute(async (destination_url) => {
    const nested_frame = await attachFencedFrameContext(
      {origin: get_host_info().HTTPS_ORIGIN})

    // Note that we do *not* await, because we need to operate in the top frame
    // while the nested frame still hasn't disabled network access.
    let disable_network_promise = window.fence.disableUntrustedNetwork();

    let timeout_promise = new Promise(
        resolve => setTimeout(() => {resolve('timeout')}, 1000));
    const result =
        await Promise.race([disable_network_promise, timeout_promise]);
    assert_equals(result, 'timeout',
        "The disableUntrustedNetwork() promise should not resolve.");

    // Even though disableUntrustedNetwork() has not resolved, network calls
    // should not succeed.
    try {
      const response_failure = await fetch(destination_url);
      assert_unreached('The fetch should throw an exception.');
    } catch (e) {
      assert_equals(e.name, 'TypeError');
      assert_equals(e.message, 'Failed to fetch');
    }

    // Network calls in the nested fenced frame should still succeed, since
    // their network hasn't been cut off yet.
    await nested_frame.execute(async (destination_url) => {
      await fetch(destination_url);
    }, [destination_url]);

    try {
      await sharedStorage.get('test');
      assert_unreached('sharedStorage.get() is not allowed in a fenced frame ' +
        'until network access for it and all descendent frames has been ' +
        'revoked with window.fence.disableUntrustedNetwork()');
    } catch (e) {
      assert_equals(e.name, 'OperationError');
      assert_equals(e.message, 'sharedStorage.get() is not allowed in a ' +
        'fenced frame until network access for it and all descendent frames ' +
        'has been revoked with window.fence.disableUntrustedNetwork()');
    }
  }, [destination_url]);
}, 'sharedStorage.get() fails in a top-level fenced frame with network ' +
   'disabled because a nested fenced frame has not disabled network yet.');

</script>
</body>