
<!DOCTYPE html>
<meta charset="utf-8"/>
<title>Web Locks API: Partitioned WebLocks</title>

<!-- Pull in get_host_info() -->
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="resources/helpers.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>

const { HTTPS_ORIGIN, HTTPS_NOTSAMESITE_ORIGIN } = get_host_info();
// Map of lock_id => function that releases a lock.
const held = new Map();
let next_lock_id = 1;

// How this test works:
// Step 1 (top-frame): request an exclusive web-lock and store its id
// and release for clean-up.
// Step 2 (top-frame): open a pop-up window and load a not-same-site
// ./web-locks/resources/partitioned-parent.html
// Step 3 (pop-up): load a same-site iframe inside the pop-up.
// Step 4 (pop-up): send a web-lock request to the same-site iframe.
// Step 5 (iframe): process the web-lock request and message the result
// back to the pop-up.
// Step 6 (pop-up): intercept the result message from the iframe and
// send it to the top-frame.
// Step 7 (top-frame): add cleanup hook.
// Step 8 (top-frame): ensure that the same-site iframe's web-lock
// request succeeds since it and the top-level site are successfully
// partitioned and each can hold an exclusive lock.

async function third_party_test(t) {
  let target_url = HTTPS_ORIGIN + '/web-locks/resources/iframe.html';
  target_url = new URL(
    `/web-locks/resources/partitioned-parent.html?target=${encodeURIComponent(target_url)}`,
    HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname);

  // Step 1.
  let lock_id = next_lock_id++;
  let [ promise, release ] = makePromiseAndResolveFunc();
  let released = navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
        lock => {
          if (lock === null) {
            assert_true(false)
            return;
          }
          return promise;
        });
  held.set(lock_id, { release, released });

  // Step 2.
  const w = window.open(target_url);
  const result = await new Promise(resolve => window.onmessage = resolve);

  // Step 7.
  t.add_cleanup(() => {
    w.close();
    let released = [];
    for(let i = 1; i < next_lock_id; i++){
      let h = held.get(i);
      h.release();
      released.push(h.released);
    }
    return Promise.allSettled(released);
  });

  // Step 8.
  // When 3rd party storage partitioning is enabled, the iframe should be able
  // to acquire a lock with the same name as one exclusively held by the opener
  // of its top window, even when that opener has the same origin.
  assert_equals(result.data.failed, undefined,
      'The 1p iframe failed to acquire the lock');
}

promise_test(t => {
  return third_party_test(t);
}, 'WebLocks of an iframe under a 3rd-party site are partitioned');


// Optional Test: Checking for partitioned web locks in an A->B->A
// (nested-iframe with cross-site ancestor chain) scenario.
//
// How this test works:
// Nested Step 1 (top frame): request an exclusive web-lock and
// store its id and release for clean-up.
// Nested Step 2 (top frame): open a pop-up window and load a
// same-site /web-locks/resources/partitioned-parent.html.
// Nested Step 3 (pop-up): load a not-same-site "parent" iframe (A->B)
// (/web-locks/resources/iframe-parent.html) inside the pop-up.
// Nested Step 4 (pop-up): send a web-lock request to the parent iframe.
// Nested Step 5 (parent iframe): load a "child" iframe (A->B->A)
// (/web-locks/resources/iframe.html) that is same-site with the
// pop-up inside the "parent" iframe.
// Nested Step 6 (parent iframe): pass on the web-lock request message to
// the "child" iframe.
// Nested Step 7 (child iframe): process the web-lock request and message
// the result to the parent iframe.
// Nested Step 8 (parent iframe): intercept the result message from the
// child iframe and send it to the pop-up.
// Nested Step 9 (pop-up): intercept the result message from the parent
// iframe and send it to the top frame.
// Nested Step 10 (top frame): add cleanup hook
// Nested Step 11 (top frame): ensure that the same-site iframe's web-lock
// request succeeds since it and the top-level are successfully
// partitioned and each can hold an exclusive lock.

// Map of lock_id => function that releases a lock.
const held_2 = new Map();
let next_lock_id_2 = 1;

async function nested_iframe_test(t) {
  // Create innermost child iframe (leaf).
  let leaf_url = HTTPS_ORIGIN + '/web-locks/resources/iframe.html';
  // Wrap the child iframe in its cross-origin parent (middle).
  let middle_url = new URL(
    `/web-locks/resources/iframe-parent.html?target=${encodeURIComponent(leaf_url)}`,
    HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname);
  // Embed the parent iframe in the top-level site (top).
  let top_url = new URL(
    `/web-locks/resources/partitioned-parent.html?target=${encodeURIComponent(middle_url)}`,
    HTTPS_ORIGIN + self.location.pathname);

  // Nested Step 1.
  // Request the weblock for the top-level site.
  let lock_id = next_lock_id_2++;
  let [ promise, release ] = makePromiseAndResolveFunc();
  let released = navigator.locks.request('testLock', {mode: 'exclusive', ifAvailable: true},
        lock => {
          if (lock === null) {
            assert_true(false)
            return;
          }
          return promise;
        }).catch(error => alert(error.message));
  held_2.set(lock_id, { release, released });

  // Nested Step 2.
  // Open the nested iframes. The script in the innermost child iframe
  // will attempt to obtain the same weblock as above.
  const w = window.open(top_url);
  const result = await new Promise(resolve => window.onmessage = resolve);

  // Nested Step 10.
  t.add_cleanup(() => {
    w.close();
    let released = [];
    for(let i = 1; i < next_lock_id; i++){
      let h = held_2.get(i);
      h.release();
      released.push(h.released);
    }
    return Promise.allSettled(released);
  });

  // Nested Step 11.
  // With third-party storage partitioning enabled, the same-site iframe
  // should be able to acquire the lock as it has a cross-site ancestor
  // and is partitioned separately from the top-level site.
  assert_equals(result.data.failed, undefined,
      'The 1p iframe failed to acquire the lock');
}

promise_test(t => {
  return nested_iframe_test(t);
}, 'WebLocks of a nested iframe with a cross-site ancestor are partitioned');
</script>
</body>
