<!DOCTYPE html>
<title>CSP for subresource WebBundle (blocked cases)</title>
<link
  rel="help"
  href="https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md"
/>
<meta
  http-equiv="Content-Security-Policy"
  content="
    script-src
      urn:
      https://web-platform.test:8444/resources/testharness.js
      https://web-platform.test:8444/resources/testharnessreport.js
      'unsafe-inline';
    img-src
      https://web-platform.test:8444/web-bundle/resources/wbn/subresource.wbn;
    report-to
      csp-group"
/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
  <script type="webbundle">
    {
      "source": "../resources/wbn/subresource.wbn",
      "resources": ["https://web-platform.test:8444/web-bundle/resources/wbn/fail.png"]
    }
  </script>
  <script type="webbundle">
    {
      "source": "../resources/wbn/uuid-in-package.wbn",
      "resources": ["uuid-in-package:020111b3-437a-4c5c-ae07-adb6bbffb720"]
    }
  </script>
  <script>
    const uuid_bundle_url =
      "https://web-platform.test:8444/web-bundle/resources/wbn/uuid-in-package.wbn";

    function expect_violation() {
      return new Promise((resolve) => {
        document.addEventListener(
          "securitypolicyviolation",
          (e) => {
            e.stopPropagation();
            resolve(e);
          },
          { once: true }
        );
      });
    }

    function getReportID() {
      const cookies = document.cookie.split(";");
      for (var i = 0; i < cookies.length; i++) {
        const name_value = cookies[i].split("=");
        const cookieName = name_value[0].trim();
        if (cookieName === "csp-blocked-report-id") {
          return name_value[1].trim();
        }
      }
    }

    function sortReportsByEffectiveDirective(reports) {
      reports.sort(
        (report1, report2) =>
          report1.body.effectiveDirective.localeCompare(
            report2.body.effectiveDirective
          ) || report1.body.blockedURL.localeCompare(report2.body.blockedURL)
      );
    }

    promise_test(async () => {
      const p = expect_violation();
      const img = document.createElement("img");
      const error_promise = new Promise((resolve) => {
        img.onerror = resolve;
      });
      img.src =
        "https://web-platform.test:8444/web-bundle/resources/wbn/fail.png";
      document.body.appendChild(img);
      const e = await p;
      assert_equals(e.blockedURI, img.src);
      await error_promise;
    }, "URL matching of CSP should be done based on the subresource URL, " +
       "not on the bundle URL, when the subresource URL is HTTPS URL.");

    const testCases = [
      {
        prefix: "uuid-in-package:",
        bundle_url: uuid_bundle_url,
      },
    ];
    for (const params of testCases) {
      promise_test(async () => {
        const urn_uuid = params.prefix + "020111b3-437a-4c5c-ae07-adb6bbffb720";
        const p = expect_violation();
        const script = document.createElement("script");
        script.src = urn_uuid;
        document.body.appendChild(script);
        const e = await p;
        // Currently Chromium is reporting the bundle URL.
        // TODO(crbug.com/1208659): Consider deeper integration with CSP for
        // providing the both URLs.
        assert_equals(e.blockedURI, params.bundle_url);
        assert_equals(e.violatedDirective, "script-src-elem");
      }, "URL matching of script-src CSP should be done based on the bundle URL " +
         `when the subresource URL is ${params.prefix} URL.`);
    }

    promise_test(async () => {
      const retrieve_report_url =
        "/reporting/resources/report.py?op=retrieve_report&timeout=3&reportID=" +
        getReportID();
      const reports = await (await fetch(retrieve_report_url)).json();
      sortReportsByEffectiveDirective(reports);

      assert_equals(reports.length, 2, "Report count.");

      assert_equals(
        reports[0].body.blockedURL,
        "https://web-platform.test:8444/web-bundle/resources/wbn/fail.png"
      );
      assert_equals(reports[0].body.effectiveDirective, "img-src");

      assert_equals(reports[1].body.blockedURL, uuid_bundle_url);
      assert_equals(reports[1].body.effectiveDirective, "script-src-elem");
    }, "Check the CSP violation reports.");
  </script>
</body>
