<!DOCTYPE html>
<html lang="en">
<head>
  <title>Test tabs.create(cookieStoreId)</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
  <script type="text/javascript" src="head.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="text/javascript">
"use strict";

add_task(async function no_cookies_permission() {
  await SpecialPowers.pushPrefEnv({
    set: [["privacy.userContext.enabled", true]],
  });

  let extension = ExtensionTestUtils.loadExtension({
    async background() {
      await browser.test.assertRejects(
        browser.tabs.create({ cookieStoreId: "firefox-container-1" }),
        /No permission for cookieStoreId/,
        "cookieStoreId requires cookies permission"
      );
      browser.test.sendMessage("done");
    },
  });

  await extension.startup();
  await extension.awaitMessage("done");
  await extension.unload();
  await SpecialPowers.popPrefEnv();
});

add_task(async function invalid_cookieStoreId() {
  await SpecialPowers.pushPrefEnv({
    set: [["privacy.userContext.enabled", true]],
  });

  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      permissions: ["tabs", "cookies"],
    },
    async background() {
      await browser.test.assertRejects(
        browser.tabs.create({ cookieStoreId: "not-firefox-container-1" }),
        /Illegal cookieStoreId/,
        "cookieStoreId must be valid"
      );

      await browser.test.assertRejects(
        browser.tabs.create({ cookieStoreId: "firefox-private" }),
        /Illegal to set private cookieStoreId in a non-private window/,
        "cookieStoreId cannot be private in a non-private window"
      );

      browser.test.sendMessage("done");
    },
  });

  await extension.startup();
  await extension.awaitMessage("done");
  await extension.unload();
  await SpecialPowers.popPrefEnv();
});

add_task(async function perma_private_browsing_mode() {
  await SpecialPowers.pushPrefEnv({
    set: [["browser.privatebrowsing.autostart", true]],
  });

  let extension = ExtensionTestUtils.loadExtension({
    incognitoOverride: "spanning",
    manifest: {
      permissions: ["tabs", "cookies"],
    },
    async background() {
      await browser.test.assertRejects(
        browser.tabs.create({ cookieStoreId: "firefox-container-1" }),
        /Contextual identities are unavailable in permanent private browsing mode/,
        "cookieStoreId cannot be a container tab ID in perma-private browsing mode"
      );

      browser.test.sendMessage("done");
    },
  });
  await extension.startup();
  await extension.awaitMessage("done");
  await extension.unload();
  await SpecialPowers.popPrefEnv();
});

add_task(async function userContext_disabled() {
  await SpecialPowers.pushPrefEnv({
    set: [["privacy.userContext.enabled", false]],
  });
  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      permissions: ["tabs", "cookies"],
    },
    async background() {
      await browser.test.assertRejects(
        browser.tabs.create({ cookieStoreId: "firefox-container-1" }),
        /Contextual identities are currently disabled/,
        "cookieStoreId cannot be a container tab ID when contextual identities are disabled"
      );
      browser.test.sendMessage("done");
    },
  });
  await extension.startup();
  await extension.awaitMessage("done");
  await extension.unload();
  await SpecialPowers.popPrefEnv();
});

add_task(async function valid_cookieStoreId() {
  await SpecialPowers.pushPrefEnv({
    set: [["privacy.userContext.enabled", true]],
  });

  const testCases = [
    {
      description: "no explicit URL",
      createProperties: {
        cookieStoreId: "firefox-container-1",
      },
      expectedCookieStoreId: "firefox-container-1",
    },
    {
      description: "pass explicit url",
      createProperties: {
        url: "about:blank",
        cookieStoreId: "firefox-container-1",
      },
      expectedCookieStoreId: "firefox-container-1",
    },{
      description: "pass explicit not-blank url",
      createProperties: {
        url: "https://example.com/",
        cookieStoreId: "firefox-container-1",
      },
      expectedCookieStoreId: "firefox-container-1",
    },{
      description: "pass extension page url",
      createProperties: {
        url: "blank.html",
        cookieStoreId: "firefox-container-1",
      },
      expectedCookieStoreId: "firefox-container-1",
    }
  ];

  async function background(testCases) {
    for (let { createProperties, expectedCookieStoreId } of testCases) {
      const { url } = createProperties;
      const updatedPromise = new Promise(resolve => {
        const onUpdated = (changedTabId, changed) => {
          // Loading an extension page causes two `about:blank` messages
          // because of the process switch
          if (changed.url && (url == "about:blank" || changed.url != "about:blank")) {
            browser.tabs.onUpdated.removeListener(onUpdated);
            resolve({tabId: changedTabId, url: changed.url});
          }
        };
        browser.tabs.onUpdated.addListener(onUpdated);
      });

      const tab = await browser.tabs.create(createProperties);
      browser.test.assertEq(
        expectedCookieStoreId,
        tab.cookieStoreId,
        "Expected cookieStoreId for container tab"
      );

      if (url && url !== "about:blank") {
        // Make sure tab can load successfully
        const updated = await updatedPromise;
        browser.test.assertEq(tab.id, updated.tabId, `Expected value for tab.id`);
        if (updated.url.startsWith("moz-extension")) {
          browser.test.assertEq(browser.runtime.getURL(url), updated.url,
            `Expected value for extension page url`);
        } else {
          browser.test.assertEq(url, updated.url, `Expected value for tab.url`);
        }
      }

      await browser.tabs.remove(tab.id);
    }
    browser.test.sendMessage("done");
  }

  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      permissions: ["tabs", "cookies"],
    },
    files: {
      "blank.html": `<html><head><meta charset="utf-8"></head></html>`,
    },
    background: `(${background})(${JSON.stringify(testCases)})`,
  });

  await extension.startup();
  await extension.awaitMessage("done");
  await extension.unload();
  await SpecialPowers.popPrefEnv();
});
</script>
</body>
</html>
