|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * Generic nsINavHistoryObserver that doesn't implement anything, but provides |
|
6 * dummy methods to prevent errors about an object not having a certain method. |
|
7 */ |
|
8 function NavHistoryObserver() { |
|
9 } |
|
10 NavHistoryObserver.prototype = { |
|
11 onBeginUpdateBatch: function() { }, |
|
12 onEndUpdateBatch: function() { }, |
|
13 onVisit: function() { }, |
|
14 onTitleChanged: function() { }, |
|
15 onDeleteURI: function() { }, |
|
16 onClearHistory: function() { }, |
|
17 onPageChanged: function() { }, |
|
18 onDeleteVisits: function() { }, |
|
19 QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver]) |
|
20 }; |
|
21 |
|
22 /** |
|
23 * Registers a one-time history observer for and calls the callback |
|
24 * when the specified nsINavHistoryObserver method is called. |
|
25 * Returns a promise that is resolved when the callback returns. |
|
26 */ |
|
27 function onNotify(callback) { |
|
28 let deferred = Promise.defer(); |
|
29 let obs = new NavHistoryObserver(); |
|
30 obs[callback.name] = function () { |
|
31 PlacesUtils.history.removeObserver(this); |
|
32 callback.apply(this, arguments); |
|
33 deferred.resolve(); |
|
34 }; |
|
35 PlacesUtils.history.addObserver(obs, false); |
|
36 return deferred.promise; |
|
37 } |
|
38 |
|
39 /** |
|
40 * Asynchronous task that adds a visit to the history database. |
|
41 */ |
|
42 function task_add_visit(uri, timestamp, transition) { |
|
43 uri = uri || NetUtil.newURI("http://firefox.com/"); |
|
44 timestamp = timestamp || Date.now() * 1000; |
|
45 yield promiseAddVisits({ |
|
46 uri: uri, |
|
47 transition: transition || TRANSITION_TYPED, |
|
48 visitDate: timestamp |
|
49 }); |
|
50 throw new Task.Result([uri, timestamp]); |
|
51 } |
|
52 |
|
53 function run_test() { |
|
54 run_next_test(); |
|
55 } |
|
56 |
|
57 add_task(function test_onVisit() { |
|
58 let promiseNotify = onNotify(function onVisit(aURI, aVisitID, aTime, |
|
59 aSessionID, aReferringID, |
|
60 aTransitionType, aGUID, |
|
61 aHidden) { |
|
62 do_check_true(aURI.equals(testuri)); |
|
63 do_check_true(aVisitID > 0); |
|
64 do_check_eq(aTime, testtime); |
|
65 do_check_eq(aSessionID, 0); |
|
66 do_check_eq(aReferringID, 0); |
|
67 do_check_eq(aTransitionType, TRANSITION_TYPED); |
|
68 do_check_guid_for_uri(aURI, aGUID); |
|
69 do_check_false(aHidden); |
|
70 }); |
|
71 let testuri = NetUtil.newURI("http://firefox.com/"); |
|
72 let testtime = Date.now() * 1000; |
|
73 yield task_add_visit(testuri, testtime); |
|
74 yield promiseNotify; |
|
75 }); |
|
76 |
|
77 add_task(function test_onVisit() { |
|
78 let promiseNotify = onNotify(function onVisit(aURI, aVisitID, aTime, |
|
79 aSessionID, aReferringID, |
|
80 aTransitionType, aGUID, |
|
81 aHidden) { |
|
82 do_check_true(aURI.equals(testuri)); |
|
83 do_check_true(aVisitID > 0); |
|
84 do_check_eq(aTime, testtime); |
|
85 do_check_eq(aSessionID, 0); |
|
86 do_check_eq(aReferringID, 0); |
|
87 do_check_eq(aTransitionType, TRANSITION_FRAMED_LINK); |
|
88 do_check_guid_for_uri(aURI, aGUID); |
|
89 do_check_true(aHidden); |
|
90 }); |
|
91 let testuri = NetUtil.newURI("http://hidden.firefox.com/"); |
|
92 let testtime = Date.now() * 1000; |
|
93 yield task_add_visit(testuri, testtime, TRANSITION_FRAMED_LINK); |
|
94 yield promiseNotify; |
|
95 }); |
|
96 |
|
97 add_task(function test_onDeleteURI() { |
|
98 let promiseNotify = onNotify(function onDeleteURI(aURI, aGUID, aReason) { |
|
99 do_check_true(aURI.equals(testuri)); |
|
100 // Can't use do_check_guid_for_uri() here because the visit is already gone. |
|
101 do_check_eq(aGUID, testguid); |
|
102 do_check_eq(aReason, Ci.nsINavHistoryObserver.REASON_DELETED); |
|
103 }); |
|
104 let [testuri] = yield task_add_visit(); |
|
105 let testguid = do_get_guid_for_uri(testuri); |
|
106 PlacesUtils.bhistory.removePage(testuri); |
|
107 yield promiseNotify; |
|
108 }); |
|
109 |
|
110 add_task(function test_onDeleteVisits() { |
|
111 let promiseNotify = onNotify(function onDeleteVisits(aURI, aVisitTime, aGUID, |
|
112 aReason) { |
|
113 do_check_true(aURI.equals(testuri)); |
|
114 // Can't use do_check_guid_for_uri() here because the visit is already gone. |
|
115 do_check_eq(aGUID, testguid); |
|
116 do_check_eq(aReason, Ci.nsINavHistoryObserver.REASON_DELETED); |
|
117 do_check_eq(aVisitTime, 0); // All visits have been removed. |
|
118 }); |
|
119 let msecs24hrsAgo = Date.now() - (86400 * 1000); |
|
120 let [testuri] = yield task_add_visit(undefined, msecs24hrsAgo * 1000); |
|
121 // Add a bookmark so the page is not removed. |
|
122 PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId, |
|
123 testuri, |
|
124 PlacesUtils.bookmarks.DEFAULT_INDEX, |
|
125 "test"); |
|
126 let testguid = do_get_guid_for_uri(testuri); |
|
127 PlacesUtils.bhistory.removePage(testuri); |
|
128 yield promiseNotify; |
|
129 }); |
|
130 |
|
131 add_task(function test_onTitleChanged() { |
|
132 let promiseNotify = onNotify(function onTitleChanged(aURI, aTitle, aGUID) { |
|
133 do_check_true(aURI.equals(testuri)); |
|
134 do_check_eq(aTitle, title); |
|
135 do_check_guid_for_uri(aURI, aGUID); |
|
136 }); |
|
137 |
|
138 let [testuri] = yield task_add_visit(); |
|
139 let title = "test-title"; |
|
140 yield promiseAddVisits({ |
|
141 uri: testuri, |
|
142 title: title |
|
143 }); |
|
144 yield promiseNotify; |
|
145 }); |
|
146 |
|
147 add_task(function test_onPageChanged() { |
|
148 let promiseNotify = onNotify(function onPageChanged(aURI, aChangedAttribute, |
|
149 aNewValue, aGUID) { |
|
150 do_check_eq(aChangedAttribute, Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON); |
|
151 do_check_true(aURI.equals(testuri)); |
|
152 do_check_eq(aNewValue, SMALLPNG_DATA_URI.spec); |
|
153 do_check_guid_for_uri(aURI, aGUID); |
|
154 }); |
|
155 |
|
156 let [testuri] = yield task_add_visit(); |
|
157 |
|
158 // The new favicon for the page must have data associated with it in order to |
|
159 // receive the onPageChanged notification. To keep this test self-contained, |
|
160 // we use an URI representing the smallest possible PNG file. |
|
161 PlacesUtils.favicons.setAndFetchFaviconForPage(testuri, SMALLPNG_DATA_URI, |
|
162 false, |
|
163 PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, |
|
164 null); |
|
165 yield promiseNotify; |
|
166 }); |