toolkit/components/places/tests/favicons/test_replaceFaviconDataFromDataURL.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* Any copyright is dedicated to the Public Domain.
     2  *    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 /*
     5  * Tests for mozIAsyncFavicons::replaceFaviconData()
     6  */
     8 let iconsvc = PlacesUtils.favicons;
     9 let histsvc = PlacesUtils.history;
    11 let originalFavicon = {
    12   file: do_get_file("favicon-normal16.png"),
    13   uri: uri(do_get_file("favicon-normal16.png")),
    14   data: readFileData(do_get_file("favicon-normal16.png")),
    15   mimetype: "image/png"
    16 };
    18 let uniqueFaviconId = 0;
    19 function createFavicon(fileName) {
    20   let tempdir = Services.dirsvc.get("TmpD", Ci.nsILocalFile);
    22   // remove any existing file at the path we're about to copy to
    23   let outfile = tempdir.clone();
    24   outfile.append(fileName);
    25   try { outfile.remove(false); } catch (e) {}
    27   originalFavicon.file.copyToFollowingLinks(tempdir, fileName);
    29   let stream = Cc["@mozilla.org/network/file-output-stream;1"]
    30     .createInstance(Ci.nsIFileOutputStream);
    31   stream.init(outfile, 0x02 | 0x08 | 0x10, 0600, 0);
    33   // append some data that sniffers/encoders will ignore that will distinguish
    34   // the different favicons we'll create
    35   uniqueFaviconId++;
    36   let uniqueStr = "uid:" + uniqueFaviconId;
    37   stream.write(uniqueStr, uniqueStr.length);
    38   stream.close();
    40   do_check_eq(outfile.leafName.substr(0, fileName.length), fileName);
    42   return {
    43     file: outfile,
    44     uri: uri(outfile),
    45     data: readFileData(outfile),
    46     mimetype: "image/png"
    47   };
    48 }
    50 function createDataURLForFavicon(favicon) {
    51   return "data:" + favicon.mimetype + ";base64," + toBase64(favicon.data);
    52 }
    54 function checkCallbackSucceeded(callbackMimetype, callbackData, sourceMimetype, sourceData) {
    55   do_check_eq(callbackMimetype, sourceMimetype);
    56   do_check_true(compareArrays(callbackData, sourceData));
    57 }
    59 function run_test() {
    60   // check that the favicon loaded correctly
    61   do_check_eq(originalFavicon.data.length, 286);
    62   run_next_test();
    63 };
    65 add_task(function test_replaceFaviconDataFromDataURL_validHistoryURI() {
    66   do_log_info("test replaceFaviconDataFromDataURL for valid history uri");
    68   let pageURI = uri("http://test1.bar/");
    69   yield promiseAddVisits(pageURI);
    71   let favicon = createFavicon("favicon1.png");
    72   iconsvc.replaceFaviconDataFromDataURL(favicon.uri, createDataURLForFavicon(favicon));
    74   let deferSetAndFetchFavicon = Promise.defer();
    75   iconsvc.setAndFetchFaviconForPage(pageURI, favicon.uri, true,
    76     PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
    77     function test_replaceFaviconDataFromDataURL_validHistoryURI_check(aURI, aDataLen, aData, aMimeType) {
    78       checkCallbackSucceeded(aMimeType, aData, favicon.mimetype, favicon.data);
    79       checkFaviconDataForPage(
    80         pageURI, favicon.mimetype, favicon.data,
    81         function test_replaceFaviconDataFromDataURL_validHistoryURI_callback() {
    82           favicon.file.remove(false);
    83           deferSetAndFetchFavicon.resolve();
    84         });
    85     });
    86   yield deferSetAndFetchFavicon.promise;
    88   yield promiseClearHistory();
    89 });
    91 add_task(function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon() {
    92   do_log_info("test replaceFaviconDataFromDataURL to override a later setAndFetchFaviconForPage");
    94   let pageURI = uri("http://test2.bar/");
    95   yield promiseAddVisits(pageURI);
    97   let firstFavicon = createFavicon("favicon2.png");
    98   let secondFavicon = createFavicon("favicon3.png");
   100   iconsvc.replaceFaviconDataFromDataURL(firstFavicon.uri, createDataURLForFavicon(secondFavicon));
   102   let deferSetAndFetchFavicon = Promise.defer();
   103   iconsvc.setAndFetchFaviconForPage(
   104     pageURI, firstFavicon.uri, true,
   105     PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
   106     function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon_check(aURI, aDataLen, aData, aMimeType) {
   107       checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data);
   108       checkFaviconDataForPage(
   109         pageURI, secondFavicon.mimetype, secondFavicon.data,
   110         function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon_callback() {
   111           firstFavicon.file.remove(false);
   112           secondFavicon.file.remove(false);
   113           deferSetAndFetchFavicon.resolve();
   114         });
   115     });
   116   yield deferSetAndFetchFavicon.promise;
   118   yield promiseClearHistory();
   119 });
   121 add_task(function test_replaceFaviconDataFromDataURL_replaceExisting() {
   122   do_log_info("test replaceFaviconDataFromDataURL to override a previous setAndFetchFaviconForPage");
   124   let pageURI = uri("http://test3.bar");
   125   yield promiseAddVisits(pageURI);
   127   let firstFavicon = createFavicon("favicon4.png");
   128   let secondFavicon = createFavicon("favicon5.png");
   130   let deferSetAndFetchFavicon = Promise.defer();
   131   iconsvc.setAndFetchFaviconForPage(
   132     pageURI, firstFavicon.uri, true,
   133     PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
   134     function test_replaceFaviconDataFromDataURL_replaceExisting_firstSet_check(aURI, aDataLen, aData, aMimeType) {
   135       checkCallbackSucceeded(aMimeType, aData, firstFavicon.mimetype, firstFavicon.data);
   136       checkFaviconDataForPage(
   137         pageURI, firstFavicon.mimetype, firstFavicon.data,
   138         function test_replaceFaviconDataFromDataURL_replaceExisting_firstCallback() {
   139           iconsvc.replaceFaviconDataFromDataURL(firstFavicon.uri, createDataURLForFavicon(secondFavicon));
   140           checkFaviconDataForPage(
   141             pageURI, secondFavicon.mimetype, secondFavicon.data,
   142             function test_replaceFaviconDataFromDataURL_replaceExisting_secondCallback() {
   143               firstFavicon.file.remove(false);
   144               secondFavicon.file.remove(false);
   145               deferSetAndFetchFavicon.resolve();
   146             });
   147         });
   148     });
   149   yield deferSetAndFetchFavicon.promise;
   151   yield promiseClearHistory();
   152 });
   154 add_task(function test_replaceFaviconDataFromDataURL_unrelatedReplace() {
   155   do_log_info("test replaceFaviconDataFromDataURL to not make unrelated changes");
   157   let pageURI = uri("http://test4.bar/");
   158   yield promiseAddVisits(pageURI);
   160   let favicon = createFavicon("favicon6.png");
   161   let unrelatedFavicon = createFavicon("favicon7.png");
   163   iconsvc.replaceFaviconDataFromDataURL(unrelatedFavicon.uri, createDataURLForFavicon(unrelatedFavicon));
   165   let deferSetAndFetchFavicon = Promise.defer();
   166   iconsvc.setAndFetchFaviconForPage(
   167     pageURI, favicon.uri, true,
   168     PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
   169     function test_replaceFaviconDataFromDataURL_unrelatedReplace_check(aURI, aDataLen, aData, aMimeType) {
   170       checkCallbackSucceeded(aMimeType, aData, favicon.mimetype, favicon.data);
   171       checkFaviconDataForPage(
   172         pageURI, favicon.mimetype, favicon.data,
   173         function test_replaceFaviconDataFromDataURL_unrelatedReplace_callback() {
   174           favicon.file.remove(false);
   175           unrelatedFavicon.file.remove(false);
   176           deferSetAndFetchFavicon.resolve();
   177         });
   178     });
   179   yield deferSetAndFetchFavicon.promise;
   181   yield promiseClearHistory();
   182 });
   184 add_task(function test_replaceFaviconDataFromDataURL_badInputs() {
   185   do_log_info("test replaceFaviconDataFromDataURL to throw on bad inputs");
   187   let favicon = createFavicon("favicon8.png");
   189   let ex = null;
   190   try {
   191     iconsvc.replaceFaviconDataFromDataURL(favicon.uri, "");
   192   } catch (e) {
   193     ex = e;
   194   } finally {
   195     do_check_true(!!ex);
   196   }
   198   ex = null;
   199   try {
   200     iconsvc.replaceFaviconDataFromDataURL(null, createDataURLForFavicon(favicon));
   201   } catch (e) {
   202     ex = e;
   203   } finally {
   204     do_check_true(!!ex);
   205   }
   207   favicon.file.remove(false);
   209   yield promiseClearHistory();
   210 });
   212 add_task(function test_replaceFaviconDataFromDataURL_twiceReplace() {
   213   do_log_info("test replaceFaviconDataFromDataURL on multiple replacements");
   215   let pageURI = uri("http://test5.bar/");
   216   yield promiseAddVisits(pageURI);
   218   let firstFavicon = createFavicon("favicon9.png");
   219   let secondFavicon = createFavicon("favicon10.png");
   221   iconsvc.replaceFaviconDataFromDataURL(firstFavicon.uri, createDataURLForFavicon(firstFavicon));
   222   iconsvc.replaceFaviconDataFromDataURL(firstFavicon.uri, createDataURLForFavicon(secondFavicon));
   224   let deferSetAndFetchFavicon = Promise.defer();
   225   iconsvc.setAndFetchFaviconForPage(
   226     pageURI, firstFavicon.uri, true,
   227     PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
   228     function test_replaceFaviconDataFromDataURL_twiceReplace_check(aURI, aDataLen, aData, aMimeType) {
   229       checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data);
   230       checkFaviconDataForPage(
   231         pageURI, secondFavicon.mimetype, secondFavicon.data,
   232         function test_replaceFaviconDataFromDataURL_twiceReplace_callback() {
   233           firstFavicon.file.remove(false);
   234           secondFavicon.file.remove(false);
   235           deferSetAndFetchFavicon.resolve();
   236         });
   237     });
   238   yield deferSetAndFetchFavicon.promise;
   240   yield promiseClearHistory();
   241 });
   243 add_task(function test_replaceFaviconDataFromDataURL_afterRegularAssign() {
   244   do_log_info("test replaceFaviconDataFromDataURL after replaceFaviconData");
   246   let pageURI = uri("http://test6.bar/");
   247   yield promiseAddVisits(pageURI);
   249   let firstFavicon = createFavicon("favicon11.png");
   250   let secondFavicon = createFavicon("favicon12.png");
   252   iconsvc.replaceFaviconData(
   253     firstFavicon.uri, firstFavicon.data, firstFavicon.data.length,
   254     firstFavicon.mimetype);
   255   iconsvc.replaceFaviconDataFromDataURL(firstFavicon.uri, createDataURLForFavicon(secondFavicon));
   257   let deferSetAndFetchFavicon = Promise.defer();
   258   iconsvc.setAndFetchFaviconForPage(
   259     pageURI, firstFavicon.uri, true,
   260     PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
   261     function test_replaceFaviconDataFromDataURL_afterRegularAssign_check(aURI, aDataLen, aData, aMimeType) {
   262       checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data);
   263       checkFaviconDataForPage(
   264         pageURI, secondFavicon.mimetype, secondFavicon.data,
   265         function test_replaceFaviconDataFromDataURL_afterRegularAssign_callback() {
   266           firstFavicon.file.remove(false);
   267           secondFavicon.file.remove(false);
   268           deferSetAndFetchFavicon.resolve();
   269         });
   270     });
   271   yield deferSetAndFetchFavicon.promise;
   273   yield promiseClearHistory();
   274 });
   276 add_task(function test_replaceFaviconDataFromDataURL_beforeRegularAssign() {
   277   do_log_info("test replaceFaviconDataFromDataURL before replaceFaviconData");
   279   let pageURI = uri("http://test7.bar/");
   280   yield promiseAddVisits(pageURI);
   282   let firstFavicon = createFavicon("favicon13.png");
   283   let secondFavicon = createFavicon("favicon14.png");
   285   iconsvc.replaceFaviconDataFromDataURL(firstFavicon.uri, createDataURLForFavicon(firstFavicon));
   286   iconsvc.replaceFaviconData(
   287     firstFavicon.uri, secondFavicon.data, secondFavicon.data.length,
   288     secondFavicon.mimetype);
   290   let deferSetAndFetchFavicon = Promise.defer();
   291   iconsvc.setAndFetchFaviconForPage(
   292     pageURI, firstFavicon.uri, true,
   293     PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
   294     function test_replaceFaviconDataFromDataURL_beforeRegularAssign_check(aURI, aDataLen, aData, aMimeType) {
   295       checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data);
   296       checkFaviconDataForPage(
   297         pageURI, secondFavicon.mimetype, secondFavicon.data,
   298         function test_replaceFaviconDataFromDataURL_beforeRegularAssign_callback() {
   299           firstFavicon.file.remove(false);
   300           secondFavicon.file.remove(false);
   301           deferSetAndFetchFavicon.resolve();
   302         });
   303     });
   304   yield deferSetAndFetchFavicon.promise;
   306   yield promiseClearHistory();
   307 });
   309 /* toBase64 copied from image/test/unit/test_encoder_png.js */
   311 /* Convert data (an array of integers) to a Base64 string. */
   312 const toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +
   313     '0123456789+/';
   314 const base64Pad = '=';
   315 function toBase64(data) {
   316   let result = '';
   317   let length = data.length;
   318   let i;
   319   // Convert every three bytes to 4 ascii characters.
   320   for (i = 0; i < (length - 2); i += 3) {
   321     result += toBase64Table[data[i] >> 2];
   322     result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
   323     result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)];
   324     result += toBase64Table[data[i+2] & 0x3f];
   325   }
   327   // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
   328   if (length%3) {
   329     i = length - (length%3);
   330     result += toBase64Table[data[i] >> 2];
   331     if ((length%3) == 2) {
   332       result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
   333       result += toBase64Table[(data[i+1] & 0x0f) << 2];
   334       result += base64Pad;
   335     } else {
   336       result += toBase64Table[(data[i] & 0x03) << 4];
   337       result += base64Pad + base64Pad;
   338     }
   339   }
   341   return result;
   342 }

mercurial