<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Tabs update 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";

async function testTabsUpdateURL(existentTabURL, tabsUpdateURL, isErrorExpected) {
  const extension = ExtensionTestUtils.loadExtension({
    manifest: {
      "permissions": ["tabs"],
    },

    files: {
      "tab.html": `
        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="utf-8">
          </head>
          <body>
            <h1>tab page</h1>
          </body>
        </html>
      `.trim(),
    },
    background: function() {
      browser.test.sendMessage("ready", browser.runtime.getURL("tab.html"));

      browser.test.onMessage.addListener(async (msg, tabsUpdateURL, isErrorExpected) => {
        const tabs = await browser.tabs.query({lastFocusedWindow: true});

        try {
          const tab = await browser.tabs.update(tabs[0].id, {url: tabsUpdateURL});

          browser.test.assertFalse(isErrorExpected, `tabs.update with URL ${tabsUpdateURL} should be rejected`);
          browser.test.assertTrue(tab, "on success the tab should be defined");
        } catch (error) {
          browser.test.assertTrue(isErrorExpected, `tabs.update with URL ${tabsUpdateURL} should not be rejected`);
          browser.test.assertTrue(/^Illegal URL/.test(error.message),
                                  "tabs.update should be rejected with the expected error message");
        }

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

  await extension.startup();

  const mozExtTabURL = await extension.awaitMessage("ready");

  if (tabsUpdateURL == "self") {
    tabsUpdateURL = mozExtTabURL;
  }

  info(`tab.update URL "${tabsUpdateURL}" on tab with URL "${existentTabURL}"`);

  const tab1 = window.open(existentTabURL);

  extension.sendMessage("start", tabsUpdateURL, isErrorExpected);
  await extension.awaitMessage("done");

  tab1.close();
  await extension.unload();
}

add_task(async function() {
  info("Start testing tabs.update on javascript URLs");

  const dataURLPage = `data:text/html,
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
      </head>
      <body>
        <h1>data url page</h1>
      </body>
    </html>`;

  const checkList = [
    {
      tabsUpdateURL: "http://example.net",
      isErrorExpected: false,
    },
    {
      tabsUpdateURL: "self",
      isErrorExpected: false,
    },
    {
      tabsUpdateURL: "about:addons",
      isErrorExpected: true,
    },
    {
      tabsUpdateURL: "javascript:console.log('tabs.update execute javascript')",
      isErrorExpected: true,
    },
    {
      tabsUpdateURL: dataURLPage,
      isErrorExpected: true,
    },
  ];

  const testCases = checkList
        .map((check) => Object.assign({}, check, {existentTabURL: "about:blank"}));

  for (const {existentTabURL, tabsUpdateURL, isErrorExpected} of testCases) {
    await testTabsUpdateURL(existentTabURL, tabsUpdateURL, isErrorExpected);
  }

  info("done");
});
</script>

</body>
</html>
