|
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 /** |
|
8 * Tests that requesting clear history at shutdown will really clear history. |
|
9 */ |
|
10 |
|
11 const URIS = [ |
|
12 "http://a.example1.com/" |
|
13 , "http://b.example1.com/" |
|
14 , "http://b.example2.com/" |
|
15 , "http://c.example3.com/" |
|
16 ]; |
|
17 |
|
18 const TOPIC_CONNECTION_CLOSED = "places-connection-closed"; |
|
19 |
|
20 let EXPECTED_NOTIFICATIONS = [ |
|
21 "places-shutdown" |
|
22 , "places-will-close-connection" |
|
23 , "places-expiration-finished" |
|
24 , "places-connection-closed" |
|
25 ]; |
|
26 |
|
27 const UNEXPECTED_NOTIFICATIONS = [ |
|
28 "xpcom-shutdown" |
|
29 ]; |
|
30 |
|
31 const URL = "ftp://localhost/clearHistoryOnShutdown/"; |
|
32 |
|
33 // Send the profile-after-change notification to the form history component to ensure |
|
34 // that it has been initialized. |
|
35 var formHistoryStartup = Cc["@mozilla.org/satchel/form-history-startup;1"]. |
|
36 getService(Ci.nsIObserver); |
|
37 formHistoryStartup.observe(null, "profile-after-change", null); |
|
38 |
|
39 let notificationIndex = 0; |
|
40 |
|
41 let notificationsObserver = { |
|
42 observe: function observe(aSubject, aTopic, aData) { |
|
43 print("Received notification: " + aTopic); |
|
44 |
|
45 // Note that some of these notifications could arrive multiple times, for |
|
46 // example in case of sync, we allow that. |
|
47 if (EXPECTED_NOTIFICATIONS[notificationIndex] != aTopic) |
|
48 notificationIndex++; |
|
49 do_check_eq(EXPECTED_NOTIFICATIONS[notificationIndex], aTopic); |
|
50 |
|
51 if (aTopic != TOPIC_CONNECTION_CLOSED) |
|
52 return; |
|
53 |
|
54 getDistinctNotifications().forEach( |
|
55 function (topic) Services.obs.removeObserver(notificationsObserver, topic) |
|
56 ); |
|
57 |
|
58 print("Looking for uncleared stuff."); |
|
59 |
|
60 let stmt = DBConn().createStatement( |
|
61 "SELECT id FROM moz_places WHERE url = :page_url " |
|
62 ); |
|
63 |
|
64 try { |
|
65 URIS.forEach(function(aUrl) { |
|
66 stmt.params.page_url = aUrl; |
|
67 do_check_false(stmt.executeStep()); |
|
68 stmt.reset(); |
|
69 }); |
|
70 } finally { |
|
71 stmt.finalize(); |
|
72 } |
|
73 |
|
74 // Check cache. |
|
75 checkCache(URL); |
|
76 } |
|
77 } |
|
78 |
|
79 let timeInMicroseconds = Date.now() * 1000; |
|
80 |
|
81 function run_test() { |
|
82 run_next_test(); |
|
83 } |
|
84 |
|
85 add_task(function test_execute() { |
|
86 do_test_pending(); |
|
87 |
|
88 print("Initialize browserglue before Places"); |
|
89 |
|
90 // Avoid default bookmarks import. |
|
91 let glue = Cc["@mozilla.org/browser/browserglue;1"]. |
|
92 getService(Ci.nsIObserver); |
|
93 glue.observe(null, "initial-migration-will-import-default-bookmarks", null); |
|
94 |
|
95 Services.prefs.setBoolPref("privacy.clearOnShutdown.cache", true); |
|
96 Services.prefs.setBoolPref("privacy.clearOnShutdown.cookies", true); |
|
97 Services.prefs.setBoolPref("privacy.clearOnShutdown.offlineApps", true); |
|
98 Services.prefs.setBoolPref("privacy.clearOnShutdown.history", true); |
|
99 Services.prefs.setBoolPref("privacy.clearOnShutdown.downloads", true); |
|
100 Services.prefs.setBoolPref("privacy.clearOnShutdown.cookies", true); |
|
101 Services.prefs.setBoolPref("privacy.clearOnShutdown.formData", true); |
|
102 Services.prefs.setBoolPref("privacy.clearOnShutdown.passwords", true); |
|
103 Services.prefs.setBoolPref("privacy.clearOnShutdown.sessions", true); |
|
104 Services.prefs.setBoolPref("privacy.clearOnShutdown.siteSettings", true); |
|
105 |
|
106 Services.prefs.setBoolPref("privacy.sanitize.sanitizeOnShutdown", true); |
|
107 |
|
108 print("Add visits."); |
|
109 for (let aUrl of URIS) { |
|
110 yield promiseAddVisits({uri: uri(aUrl), visitDate: timeInMicroseconds++, |
|
111 transition: PlacesUtils.history.TRANSITION_TYPED}) |
|
112 } |
|
113 print("Add cache."); |
|
114 storeCache(URL, "testData"); |
|
115 }); |
|
116 |
|
117 function run_test_continue() |
|
118 { |
|
119 print("Simulate and wait shutdown."); |
|
120 getDistinctNotifications().forEach( |
|
121 function (topic) |
|
122 Services.obs.addObserver(notificationsObserver, topic, false) |
|
123 ); |
|
124 |
|
125 shutdownPlaces(); |
|
126 |
|
127 // Shutdown the download manager. |
|
128 Services.obs.notifyObservers(null, "quit-application", null); |
|
129 } |
|
130 |
|
131 function getDistinctNotifications() { |
|
132 let ar = EXPECTED_NOTIFICATIONS.concat(UNEXPECTED_NOTIFICATIONS); |
|
133 return [ar[i] for (i in ar) if (ar.slice(0, i).indexOf(ar[i]) == -1)]; |
|
134 } |
|
135 |
|
136 function storeCache(aURL, aContent) { |
|
137 let cache = Services.cache2; |
|
138 let storage = cache.diskCacheStorage(LoadContextInfo.default, false); |
|
139 |
|
140 var storeCacheListener = { |
|
141 onCacheEntryCheck: function (entry, appcache) { |
|
142 return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; |
|
143 }, |
|
144 |
|
145 onCacheEntryAvailable: function (entry, isnew, appcache, status) { |
|
146 do_check_eq(status, Cr.NS_OK); |
|
147 |
|
148 entry.setMetaDataElement("servertype", "0"); |
|
149 var os = entry.openOutputStream(0); |
|
150 |
|
151 var written = os.write(aContent, aContent.length); |
|
152 if (written != aContent.length) { |
|
153 do_throw("os.write has not written all data!\n" + |
|
154 " Expected: " + written + "\n" + |
|
155 " Actual: " + aContent.length + "\n"); |
|
156 } |
|
157 os.close(); |
|
158 entry.close(); |
|
159 do_execute_soon(run_test_continue); |
|
160 } |
|
161 }; |
|
162 |
|
163 storage.asyncOpenURI(Services.io.newURI(aURL, null, null), "", |
|
164 Ci.nsICacheStorage.OPEN_NORMALLY, |
|
165 storeCacheListener); |
|
166 } |
|
167 |
|
168 |
|
169 function checkCache(aURL) { |
|
170 let cache = Services.cache2; |
|
171 let storage = cache.diskCacheStorage(LoadContextInfo.default, false); |
|
172 |
|
173 var checkCacheListener = { |
|
174 onCacheEntryAvailable: function (entry, isnew, appcache, status) { |
|
175 do_check_eq(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND); |
|
176 do_test_finished(); |
|
177 } |
|
178 }; |
|
179 |
|
180 storage.asyncOpenURI(Services.io.newURI(aURL, null, null), "", |
|
181 Ci.nsICacheStorage.OPEN_READONLY, |
|
182 checkCacheListener); |
|
183 } |