<!doctype html>
<html>
<meta name="timeout" content="long">
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script>
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
const COEP = '|header(cross-origin-embedder-policy,require-corp)';
const COEP_RO =
  '|header(cross-origin-embedder-policy-report-only,require-corp)';
const CORP_CROSS_ORIGIN =
  '|header(cross-origin-resource-policy,cross-origin)';
const FRAME_URL = `${ORIGIN}/common/blank.html?pipe=`;
const REMOTE_FRAME_URL = `${REMOTE_ORIGIN}/common/blank.html?pipe=`;

function checkCorpReport(report, contextUrl, blockedUrl, disposition) {
  assert_equals(report.type, 'coep');
  assert_equals(report.url, contextUrl);
  assert_equals(report.body.type, 'corp');
  assert_equals(report.body.blockedURL, blockedUrl);
  assert_equals(report.body.disposition, disposition);
  assert_equals(report.body.destination, 'iframe');
}

function checkCoepMismatchReport(report, contextUrl, blockedUrl, disposition) {
  assert_equals(report.type, 'coep');
  assert_equals(report.url, contextUrl);
  assert_equals(report.body.type, 'navigation');
  assert_equals(report.body.blockedURL, blockedUrl);
  assert_equals(report.body.disposition, disposition);
}

function loadFrame(document, url) {
  return new Promise((resolve, reject) => {
    const frame = document.createElement('iframe');
    frame.src = url;
    frame.onload = () => resolve(frame);
    frame.onerror = reject;
    document.body.appendChild(frame);
  });
}

// |parentSuffix| is a suffix for the parent frame URL.
// When |withEmptyFrame| is true, this function creates an empty frame
// between the parent and target frames.
// |targetUrl| is a URL for the target frame.
async function loadFrames(test, parentSuffix, withEmptyFrame, targetUrl) {
  const frame = await loadFrame(document, FRAME_URL + parentSuffix);
  test.add_cleanup(() => frame.remove());
  let parent;
  if (withEmptyFrame) {
    parent = frame.contentDocument.createElement('iframe');
    frame.contentDocument.body.appendChild(parent);
  } else {
    parent = frame;
  }
  // Here we don't need "await". This loading may or may not succeed, and
  // we're not interested in the result.
  loadFrame(parent.contentDocument, targetUrl);

  return parent;
}

async function observeReports(global) {
  const reports = [];
  const observer = new global.ReportingObserver((rs) => {
    for (const r of rs) {
      reports.push(r.toJSON());
    }
  });
  observer.observe();

  // Wait 5000ms for reports to settle.
  await new Promise(r => step_timeout(r, 5000));
  return reports;
}

// CASES is a list of test case. Each test case consists of:
//   parent: the suffix of the URL of the parent frame.
//   target: the suffix of the URL of the target frame.
//   reports: the expectation of reports to be made. Each report is one of:
//     'CORP': CORP violation
//     'CORP-RO' CORP violation (report only)
//     'NAV': COEP mismatch between the frames.
//     'NAV-RO': COEP mismatch between the frames (report only).
const CASES = [
  { parent: '', target: '', reports: [] },
  { parent: '', target: COEP, reports: [] },
  { parent: COEP, target: COEP, reports: ['CORP'] },
  { parent: COEP, target: '', reports: ['CORP'] },

  { parent: '', target: CORP_CROSS_ORIGIN, reports: [] },
  { parent: COEP, target: CORP_CROSS_ORIGIN, reports: ['NAV'] },

  { parent: '', target: COEP + CORP_CROSS_ORIGIN, reports: [] },
  { parent: COEP, target: COEP + CORP_CROSS_ORIGIN, reports: [] },

  { parent: COEP_RO, target: COEP, reports: ['CORP-RO'] },
  { parent: COEP_RO, target: '', reports: ['CORP-RO', 'NAV-RO'] },
  { parent: COEP_RO, target: CORP_CROSS_ORIGIN, reports: ['NAV-RO'] },
  { parent: COEP_RO, target: COEP + CORP_CROSS_ORIGIN, reports: [] },

  { parent: COEP, target: COEP_RO + CORP_CROSS_ORIGIN, reports: ['NAV'] },
];

for (const testcase of CASES) {
  for (const withEmptyFrame of [false, true]) {
    function desc(s) {
      return s === '' ? '(none)' : s;
    }
    // These tests are very slow, so they must be run in parallel using
    // async_test.
    async_test(t => {
      const targetUrl = REMOTE_FRAME_URL + testcase.target;
      loadFrames(t, testcase.parent, withEmptyFrame, targetUrl)
          .then(t.step_func(parent => {
        const contextUrl = parent.src ? parent.src : 'about:blank';
        observeReports(parent.contentWindow).then(t.step_func(reports => {
          assert_equals(reports.length, testcase.reports.length);
          for (let i = 0; i < reports.length; i += 1) {
            const report = reports[i];
            switch (testcase.reports[i]) {
              case 'CORP':
                checkCorpReport(report, contextUrl, targetUrl, 'enforce');
                break;
              case 'CORP-RO':
                checkCorpReport(report, contextUrl, targetUrl, 'reporting');
                break;
              case 'NAV':
                checkCoepMismatchReport(report, contextUrl, targetUrl, 'enforce');
                break;
              case 'NAV-RO':
                checkCoepMismatchReport(report, contextUrl, targetUrl, 'reporting');
                break;
              default:
                assert_unreached(
                  'Unexpected report expeaction: ' + testcase.reports[i]);
            }
          }
          t.done();
        })).catch(t.step_func(e => { throw e; }));
      })).catch(t.step_func(e => { throw e; }));
    }, `parent: ${desc(testcase.parent)}, target: ${desc(testcase.target)}, ` +
       `with empty frame: ${withEmptyFrame}`);
  }
}

</script>
</body></html>
