|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /** |
|
6 * This file tests setAndFetchFaviconForPage when it is called with invalid |
|
7 * arguments, and when no favicon is stored for the given arguments. |
|
8 */ |
|
9 function test() { |
|
10 // Initialization |
|
11 waitForExplicitFinish(); |
|
12 let windowsToClose = []; |
|
13 let favIcon16Location = |
|
14 "http://example.org/tests/toolkit/components/places/tests/browser/favicon-normal16.png"; |
|
15 let favIcon32Location = |
|
16 "http://example.org/tests/toolkit/components/places/tests/browser/favicon-normal32.png"; |
|
17 let favIcon16URI = NetUtil.newURI(favIcon16Location); |
|
18 let favIcon32URI = NetUtil.newURI(favIcon32Location); |
|
19 let lastPageURI = NetUtil.newURI("http://example.com/verification"); |
|
20 // This error icon must stay in sync with FAVICON_ERRORPAGE_URL in |
|
21 // nsIFaviconService.idl, aboutCertError.xhtml and netError.xhtml. |
|
22 let favIconErrorPageURI = |
|
23 NetUtil.newURI("chrome://global/skin/icons/warning-16.png"); |
|
24 let favIconsResultCount = 0; |
|
25 let pageURI; |
|
26 |
|
27 function testOnWindow(aOptions, aCallback) { |
|
28 whenNewWindowLoaded(aOptions, function(aWin) { |
|
29 windowsToClose.push(aWin); |
|
30 executeSoon(function() aCallback(aWin)); |
|
31 }); |
|
32 }; |
|
33 |
|
34 // This function is called after calling finish() on the test. |
|
35 registerCleanupFunction(function() { |
|
36 windowsToClose.forEach(function(aWin) { |
|
37 aWin.close(); |
|
38 }); |
|
39 }); |
|
40 |
|
41 function checkFavIconsDBCount(aCallback) { |
|
42 let stmt = DBConn().createAsyncStatement("SELECT url FROM moz_favicons"); |
|
43 stmt.executeAsync({ |
|
44 handleResult: function final_handleResult(aResultSet) { |
|
45 for (let row; (row = aResultSet.getNextRow()); ) { |
|
46 favIconsResultCount++; |
|
47 } |
|
48 }, |
|
49 handleError: function final_handleError(aError) { |
|
50 throw("Unexpected error (" + aError.result + "): " + aError.message); |
|
51 }, |
|
52 handleCompletion: function final_handleCompletion(aReason) { |
|
53 //begin testing |
|
54 info("Previous records in moz_favicons: " + favIconsResultCount); |
|
55 if (aCallback) { |
|
56 aCallback(); |
|
57 } |
|
58 } |
|
59 }); |
|
60 stmt.finalize(); |
|
61 } |
|
62 |
|
63 function testNullPageURI(aWindow, aCallback) { |
|
64 try { |
|
65 aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(null, favIcon16URI, |
|
66 true, aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); |
|
67 throw("Exception expected because aPageURI is null."); |
|
68 } catch (ex) { |
|
69 // We expected an exception. |
|
70 ok(true, "Exception expected because aPageURI is null"); |
|
71 } |
|
72 |
|
73 if (aCallback) { |
|
74 aCallback(); |
|
75 } |
|
76 } |
|
77 |
|
78 function testNullFavIconURI(aWindow, aCallback) { |
|
79 try { |
|
80 aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage( |
|
81 NetUtil.newURI("http://example.com/null_faviconURI"), null, true, |
|
82 aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); |
|
83 throw("Exception expected because aFaviconURI is null."); |
|
84 } catch (ex) { |
|
85 // We expected an exception. |
|
86 ok(true, "Exception expected because aFaviconURI is null."); |
|
87 } |
|
88 |
|
89 if (aCallback) { |
|
90 aCallback(); |
|
91 } |
|
92 } |
|
93 |
|
94 function testAboutURI(aWindow, aCallback) { |
|
95 aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage( |
|
96 NetUtil.newURI("about:testAboutURI"), favIcon16URI, true, |
|
97 aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); |
|
98 |
|
99 if (aCallback) { |
|
100 aCallback(); |
|
101 } |
|
102 } |
|
103 |
|
104 function testPrivateBrowsingNonBookmarkedURI(aWindow, aCallback) { |
|
105 let pageURI = NetUtil.newURI("http://example.com/privateBrowsing"); |
|
106 addVisits({ uri: pageURI, transitionType: TRANSITION_TYPED }, aWindow, |
|
107 function () { |
|
108 aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, |
|
109 favIcon16URI, true, aWindow.PlacesUtils.favicons.FAVICON_LOAD_PRIVATE); |
|
110 |
|
111 if (aCallback) { |
|
112 aCallback(); |
|
113 } |
|
114 }); |
|
115 } |
|
116 |
|
117 function testDisabledHistory(aWindow, aCallback) { |
|
118 let pageURI = NetUtil.newURI("http://example.com/disabledHistory"); |
|
119 addVisits({ uri: pageURI, transition: TRANSITION_TYPED }, aWindow, |
|
120 function () { |
|
121 aWindow.Services.prefs.setBoolPref("places.history.enabled", false); |
|
122 |
|
123 aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, |
|
124 favIcon16URI, true, |
|
125 aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); |
|
126 |
|
127 // The setAndFetchFaviconForPage function calls CanAddURI synchronously, thus |
|
128 // we can set the preference back to true immediately . We don't clear the |
|
129 // preference because not all products enable Places by default. |
|
130 aWindow.Services.prefs.setBoolPref("places.history.enabled", true); |
|
131 |
|
132 if (aCallback) { |
|
133 aCallback(); |
|
134 } |
|
135 }); |
|
136 } |
|
137 |
|
138 function testErrorIcon(aWindow, aCallback) { |
|
139 let pageURI = NetUtil.newURI("http://example.com/errorIcon"); |
|
140 let places = [{ uri: pageURI, transition: TRANSITION_TYPED }]; |
|
141 addVisits({ uri: pageURI, transition: TRANSITION_TYPED }, aWindow, |
|
142 function () { |
|
143 aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, |
|
144 favIconErrorPageURI, true, |
|
145 aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); |
|
146 |
|
147 if (aCallback) { |
|
148 aCallback(); |
|
149 } |
|
150 }); |
|
151 } |
|
152 |
|
153 function testNonExistingPage(aWindow, aCallback) { |
|
154 aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage( |
|
155 NetUtil.newURI("http://example.com/nonexistingPage"), favIcon16URI, true, |
|
156 aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); |
|
157 |
|
158 if (aCallback) { |
|
159 aCallback(); |
|
160 } |
|
161 } |
|
162 |
|
163 function testFinalVerification(aWindow, aCallback) { |
|
164 // Only the last test should raise the onPageChanged notification, |
|
165 // executing the waitForFaviconChanged callback. |
|
166 waitForFaviconChanged(lastPageURI, favIcon32URI, aWindow, |
|
167 function final_callback() { |
|
168 // Check that only one record corresponding to the last favicon is present. |
|
169 let resultCount = 0; |
|
170 let stmt = DBConn().createAsyncStatement("SELECT url FROM moz_favicons"); |
|
171 stmt.executeAsync({ |
|
172 handleResult: function final_handleResult(aResultSet) { |
|
173 |
|
174 // If the moz_favicons DB had been previously loaded (before our |
|
175 // test began), we should focus only in the URI we are testing and |
|
176 // skip the URIs not related to our test. |
|
177 if (favIconsResultCount > 0) { |
|
178 for (let row; (row = aResultSet.getNextRow()); ) { |
|
179 if (favIcon32URI.spec === row.getResultByIndex(0)) { |
|
180 is(favIcon32URI.spec, row.getResultByIndex(0), |
|
181 "Check equal favicons"); |
|
182 resultCount++; |
|
183 } |
|
184 } |
|
185 } else { |
|
186 for (let row; (row = aResultSet.getNextRow()); ) { |
|
187 is(favIcon32URI.spec, row.getResultByIndex(0), |
|
188 "Check equal favicons"); |
|
189 resultCount++; |
|
190 } |
|
191 } |
|
192 }, |
|
193 handleError: function final_handleError(aError) { |
|
194 throw("Unexpected error (" + aError.result + "): " + aError.message); |
|
195 }, |
|
196 handleCompletion: function final_handleCompletion(aReason) { |
|
197 is(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason, |
|
198 "Check reasons are equal"); |
|
199 is(1, resultCount, "Check result count"); |
|
200 if (aCallback) { |
|
201 aCallback(); |
|
202 } |
|
203 } |
|
204 }); |
|
205 stmt.finalize(); |
|
206 }); |
|
207 |
|
208 // This is the only test that should cause the waitForFaviconChanged |
|
209 // callback to be invoked. In turn, the callback will invoke |
|
210 // finish() causing the tests to finish. |
|
211 addVisits({ uri: lastPageURI, transition: TRANSITION_TYPED }, aWindow, |
|
212 function () { |
|
213 aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(lastPageURI, |
|
214 favIcon32URI, true, |
|
215 aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); |
|
216 }); |
|
217 } |
|
218 |
|
219 checkFavIconsDBCount(function () { |
|
220 testOnWindow({}, function(aWin) { |
|
221 testNullPageURI(aWin, function () { |
|
222 testOnWindow({}, function(aWin) { |
|
223 testNullFavIconURI(aWin, function() { |
|
224 testOnWindow({}, function(aWin) { |
|
225 testAboutURI(aWin, function() { |
|
226 testOnWindow({private: true}, function(aWin) { |
|
227 testPrivateBrowsingNonBookmarkedURI(aWin, function () { |
|
228 testOnWindow({}, function(aWin) { |
|
229 testDisabledHistory(aWin, function () { |
|
230 testOnWindow({}, function(aWin) { |
|
231 testErrorIcon(aWin, function() { |
|
232 testOnWindow({}, function(aWin) { |
|
233 testNonExistingPage(aWin, function() { |
|
234 testOnWindow({}, function(aWin) { |
|
235 testFinalVerification(aWin, function() { |
|
236 finish(); |
|
237 }); |
|
238 }); |
|
239 }); |
|
240 }); |
|
241 }); |
|
242 }); |
|
243 }); |
|
244 }); |
|
245 }); |
|
246 }); |
|
247 }); |
|
248 }); |
|
249 }); |
|
250 }); |
|
251 }); |
|
252 }); |
|
253 }); |
|
254 } |