<!DOCTYPE html>
<html>
  <head>
    <title>
      Test allow attribute with "web-share" and share() method
    </title>
    <meta name="viewport" content="initial-scale=1, width=device-width" />
    <script src="/js-test-resources/ui-helper.js"></script>
    <script src="../resources/js-test-pre.js"></script>
    <script>
      testRunner?.dumpAsText();
      testRunner?.waitUntilDone();

      function waitFor(target, eventName) {
        return new Promise((resolve) => {
          target.addEventListener(eventName, resolve, { once: true });
        });
      }

      function userActivation(element) {
        const promise = UIHelper.isIOSFamily()
          ? UIHelper.tapElement(element)
          : UIHelper.activateElement(element);
        return promise;
      }

      const iframeDetails = [
        {
          enabled: "false",
          src: "https://localhost:8443/webshare/resources/webshare-postmessage.html",
        },
        {
          enabled: "true",
          src: "./resources/webshare-postmessage.html",
        },
        {
          allow: "web-share",
          enabled: "true",
          src: "https://localhost:8443/webshare/resources/webshare-postmessage.html",
        },
        {
          allow: "web-share",
          enabled: "true",
          src: "./resources/webshare-postmessage.html",
        },
        {
          allow: "web-share *",
          enabled: "true",
          src: "https://localhost:8443/webshare/resources/webshare-postmessage.html",
        },
        {
          allow: "web-share *",
          enabled: "true",
          src: "./resources/webshare-postmessage.html",
        },
        {
          allow: "web-share 'none'",
          enabled: "false",
          src: "https://localhost:8443/webshare/resources/webshare-postmessage.html",
        },
        {
          allow: "web-share 'none'",
          enabled: "false",
          src: "./resources/webshare-postmessage.html",
        },
        {
          allow: "web-share 'self'",
          enabled: "false",
          src: "https://localhost:8443/webshare/resources/webshare-postmessage.html",
        },
        {
          allow: "web-share 'self'",
          enabled: "true",
          src: "./resources/webshare-postmessage.html",
        },
        {
          allow: "web-share https://localhost:8443",
          enabled: "true",
          src: "https://localhost:8443/webshare/resources/webshare-postmessage.html",
        },
        {
          allow: "web-share https://localhost:8443",
          enabled: "false",
          src: "./resources/webshare-postmessage.html",
        },
      ];

      async function loadIframe(details) {
        const iframe = document.createElement("iframe");
        if (details.hasOwnProperty("allow")) {
          iframe.setAttribute("allow", details.allow);
        }
        iframe.dataset.enabled = details.enabled;
        iframe.src = details.src;
        document.body.appendChild(iframe);
        await waitFor(iframe, "load");
        return iframe;
      }

      async function runTests () {
        for (const details of iframeDetails) {
          const iframe = await loadIframe(details);
          const { enabled } = iframe.dataset;
          const isAllowed = enabled === "true";
          const action = "call share()";
          iframe.contentWindow.postMessage({ action }, "*");
          const { data: activateMe } = await waitFor(window, "message");
          if (activateMe !== "activate me!") {
            throw new Error("Expected an activate request:" + activateMe);
          }
          await userActivation(iframe);
          const { data } = await waitFor(window, "message");
          const { exceptionMessage, exceptionName, result } = data;
          const msg = `iframe src: "${iframe.src}" with allow="${
            iframe.allow
          }" ${
            isAllowed ? "is allowed to" : "MUST NOT be allowed to"
          } ${action}. ${exceptionName ?? ""} ${exceptionMessage ?? ""}`;
          switch (result) {
            case "share completed":
              isAllowed ? testPassed(msg) : testFailed(msg);
              break;
            case "threw":
              if (
                !isAllowed &&
                exceptionName === "NotAllowedError" &&
                exceptionMessage.endsWith("Feature-Policy (web-share)")
              ) {
                testPassed(msg);
              } else {
                testFailed(msg);
              }
              break;
            default:
              testFailed(msg + ` - result was: ${result}`);
          }
          iframe.remove();
        }
        testRunner.notifyDone();
      }
    </script>
  </head>
  <body onload="runTests()">
</html>
