/*
 * Test icon URI functionality
 *
 */

const Ci = Components.interfaces;
const Cc = Components.classes;

// There are 3 types of valid icon URIs:
// 1. moz-icon:[valid URL]
// 2. moz-icon://[file name]
// 3. moz-icon://stock/[icon identifier]
// Plus we also support moz-icon://[valid URL] for backwards compatibility.

// Main test entry point.
function run_test() {
  let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
  let currentSpec = ""; // the uri spec that we're currently testing
  let exception = false; // whether or not an exception was thrown
  let uri = null; // the current URI
  let iconURI = null; // the current icon URI

  // Note that if the scheme is not correct the ioservice won't even create an icon URI
  // so don't bother testing incorrect schemes here.

  // Make sure a valid file name icon URI can be created and that we can obtain
  // all arguments, the spec, and the file extension.
  currentSpec = "moz-icon://foo.html?contentType=bar&size=button&state=normal";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, false);
  exception = false; // reset exception value

  iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
  do_check_eq(iconURI.iconSize, "button");
  do_check_eq(iconURI.iconState, "normal");
  do_check_eq(iconURI.contentType, "bar");
  do_check_eq(iconURI.fileExtension, ".html");

  // Make sure a valid file name icon URI can be created with a numeric size,
  // and make sure the numeric size is handled properly
  currentSpec = "moz-icon://foo.html?size=3";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, false);
  exception = false; // reset exception value

  iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
  do_check_eq(iconURI.iconSize, "");
  do_check_eq(iconURI.imageSize, 3);

  // Make sure a valid stock icon URI can be created and that we can obtain
  // the stock icon's name.
  currentSpec = "moz-icon://stock/foo";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, false);
  exception = false; // reset exception value

  iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
  do_check_eq(iconURI.stockIcon, "foo");

  // Make sure an invalid stock icon URI, missing icon identifier, throws.
  currentSpec = "moz-icon://stock/?size=3";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_true(exception);
  exception = false; // reset exception value

  // Make sure a valid file URL icon URI can be created and that we can obtain
  // the URL and QI it to an nsIFileURL.
  currentSpec = "moz-icon:file://foo.txt";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, false);
  exception = false; // reset exception value

  iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
  let fileURL = null;
  try {
    fileURL = iconURI.iconURL.QueryInterface(Ci.nsIFileURL);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, false);
  exception = false; // reset exception value

  do_check_neq(fileURL, null);

  // Now test a file URI which has been created with an extra //
  currentSpec = "moz-icon://file://foo.txt";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, false);
  exception = false; // reset exception value

  iconURI = uri.QueryInterface(Ci.nsIMozIconURI);
  let fileURL = null;
  try {
    fileURL = iconURI.iconURL.QueryInterface(Ci.nsIFileURL);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, false);
  exception = false; // reset exception value

  do_check_neq(fileURL, null);

  // Now test a simple invalid icon URI. This should fail.
  currentSpec = "moz-icon:foo";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, true);
  exception = false; // reset exception value

  // Now test an icon URI that has a URI for a path but that is not a URL. This should fail.
  // This is png data for a little red dot that I got from wikipedia.
  currentSpec = "moz-icon:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IAAAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1JREFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jqch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0vr4MkhoXe0rZigAAAABJRU5ErkJggg==";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, true);
  exception = false; // reset exception value

  // Now test a URI that should be a file name but is ridiculously long. This should fail.
  currentSpec = "moz-icon://data:application/vnd.ms-excel;base64,[encoded data, 22996 characters]";
  try {
    uri = ioService.newURI(currentSpec, null, null);
  } catch (e) {
    exception = true;
  }
  do_check_eq(exception, true);
  exception = false; // reset exception value
};
