<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Tabs create Test</title>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
  <script type="text/javascript" src="head.js"></script>
  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head>
<body>

<script type="text/javascript">
"use strict";

add_task(async function() {
  await SpecialPowers.pushPrefEnv({
    set: [
      ["privacy.userContext.enabled", true],
      ["dom.security.https_first", false],
    ],
  });
  const extension = ExtensionTestUtils.loadExtension({
    manifest: {
      "permissions": ["tabs", "cookies"],

      "background": {"page": "bg/background.html"},
    },

    files: {
      "bg/blank.html": `<html><head><meta charset="utf-8"></head></html>`,

      "bg/background.html": `<html><head>
        <meta charset="utf-8">
        <script src="background.js"><\/script>
      </head></html>`,

      "bg/background.js": function() {
        let activeTab;

        function runTests() {
          const DEFAULTS = {
            active: true,
            url: "about:blank",
          };

          const tests = [
            {
              create: {url: "http://example.com/"},
              result: {url: "http://example.com/"},
            },
            {
              create: {url: "blank.html"},
              result: {url: browser.runtime.getURL("bg/blank.html")},
            },
            {
              create: {},
            },
            {
              create: {active: false},
              result: {active: false},
            },
            {
              create: {active: true},
              result: {active: true},
            },
            {
              create: {cookieStoreId: null},
              result: {cookieStoreId: "firefox-default"},
            },
            {
              create: {cookieStoreId: "firefox-container-1"},
              result: {cookieStoreId: "firefox-container-1"},
            },
          ];

          async function nextTest() {
            if (!tests.length) {
              browser.test.notifyPass("tabs.create");
              return;
            }

            const test = tests.shift();
            const expected = Object.assign({}, DEFAULTS, test.result);

            browser.test.log(`Testing tabs.create(${JSON.stringify(test.create)}), expecting ${JSON.stringify(test.result)}`);

            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 && (expected.url == "about:blank" || changed.url != "about:blank")) {
                  browser.tabs.onUpdated.removeListener(onUpdated);
                  resolve({tabId: changedTabId, url: changed.url});
                }
              };
              browser.tabs.onUpdated.addListener(onUpdated);
            });

            const createdPromise = new Promise(resolve => {
              const onCreated = tab => {
                browser.test.assertTrue("id" in tab, `Expected tabs.onCreated callback to receive tab object`);
                resolve();
              };
              browser.tabs.onCreated.addListener(onCreated);
            });

            const [tab] = await Promise.all([
              browser.tabs.create(test.create),
              createdPromise,
            ]);
            const tabId = tab.id;

            for (const key of Object.keys(expected)) {
              if (key === "url") {
                // FIXME: This doesn't get updated until later in the load cycle.
                continue;
              }

              browser.test.assertEq(expected[key], tab[key], `Expected value for tab.${key}`);
            }

            const updated = await updatedPromise;
            browser.test.assertEq(tabId, updated.tabId, `Expected value for tab.id`);
            browser.test.assertEq(expected.url, updated.url, `Expected value for tab.url`);

            await browser.tabs.remove(tabId);
            await browser.tabs.update(activeTab, {active: true});

            nextTest();
          }

          nextTest();
        }

        browser.tabs.query({active: true, currentWindow: true}, tabs => {
          activeTab = tabs[0].id;

          runTests();
        });
      },
    },
  });

  await extension.startup();
  await extension.awaitFinish("tabs.create");
  await extension.unload();
  await SpecialPowers.popPrefEnv();
});
</script>

</body>
</html>
