Sat, 03 Jan 2015 20:18:00 +0100
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 }