|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * These tests check the auto-update facility of the thumbnail service. |
|
6 */ |
|
7 |
|
8 function runTests() { |
|
9 // A "trampoline" - a generator that iterates over sub-iterators |
|
10 let tests = [ |
|
11 simpleCaptureTest, |
|
12 capIfStaleErrorResponseUpdateTest, |
|
13 capIfStaleGoodResponseUpdateTest, |
|
14 regularCapErrorResponseUpdateTest, |
|
15 regularCapGoodResponseUpdateTest |
|
16 ]; |
|
17 for (let test of tests) { |
|
18 info("Running subtest " + test.name); |
|
19 for (let iterator of test()) |
|
20 yield iterator; |
|
21 } |
|
22 } |
|
23 |
|
24 function ensureThumbnailStale(url) { |
|
25 // We go behind the back of the thumbnail service and change the |
|
26 // mtime of the file to be in the past. |
|
27 let fname = PageThumbsStorage.getFilePathForURL(url); |
|
28 let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); |
|
29 file.initWithPath(fname); |
|
30 ok(file.exists(), fname + " should exist"); |
|
31 // Set it as very stale... |
|
32 file.lastModifiedTime = Date.now() - 1000000000; |
|
33 } |
|
34 |
|
35 function getThumbnailModifiedTime(url) { |
|
36 let fname = PageThumbsStorage.getFilePathForURL(url); |
|
37 let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); |
|
38 file.initWithPath(fname); |
|
39 return file.lastModifiedTime; |
|
40 } |
|
41 |
|
42 // The tests! |
|
43 /* Check functionality of a normal captureAndStoreIfStale request */ |
|
44 function simpleCaptureTest() { |
|
45 let numNotifications = 0; |
|
46 const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?simple"; |
|
47 |
|
48 function observe(subject, topic, data) { |
|
49 is(topic, "page-thumbnail:create", "got expected topic"); |
|
50 is(data, URL, "data is our test URL"); |
|
51 if (++numNotifications == 2) { |
|
52 // This is the final notification and signals test success... |
|
53 Services.obs.removeObserver(observe, "page-thumbnail:create"); |
|
54 gBrowser.removeTab(gBrowser.selectedTab); |
|
55 next(); |
|
56 } |
|
57 } |
|
58 |
|
59 Services.obs.addObserver(observe, "page-thumbnail:create", false); |
|
60 // Create a tab - we don't care what the content is. |
|
61 yield addTab(URL); |
|
62 let browser = gBrowser.selectedBrowser; |
|
63 |
|
64 // Capture the screenshot. |
|
65 PageThumbs.captureAndStore(browser, function () { |
|
66 // We've got a capture so should have seen the observer. |
|
67 is(numNotifications, 1, "got notification of item being created."); |
|
68 // The capture is now "fresh" - so requesting the URL should not cause |
|
69 // a new capture. |
|
70 PageThumbs.captureAndStoreIfStale(browser); |
|
71 is(numNotifications, 1, "still only 1 notification of item being created."); |
|
72 |
|
73 ensureThumbnailStale(URL); |
|
74 // Ask for it to be updated. |
|
75 PageThumbs.captureAndStoreIfStale(browser); |
|
76 // But it's async, so wait - our observer above will call next() when |
|
77 // the notification comes. |
|
78 }); |
|
79 yield undefined // wait for callbacks to call 'next'... |
|
80 } |
|
81 |
|
82 /* Check functionality of captureAndStoreIfStale when there is an error response |
|
83 from the server. |
|
84 */ |
|
85 function capIfStaleErrorResponseUpdateTest() { |
|
86 const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?fail"; |
|
87 yield addTab(URL); |
|
88 |
|
89 yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); |
|
90 // update the thumbnail to be stale, then re-request it. The server will |
|
91 // return a 400 response and a red thumbnail. |
|
92 // The service should not save the thumbnail - so we (a) check the thumbnail |
|
93 // remains green and (b) check the mtime of the file is < now. |
|
94 ensureThumbnailStale(URL); |
|
95 yield navigateTo(URL); |
|
96 // now() returns a higher-precision value than the modified time of a file. |
|
97 // As we set the thumbnail very stale, allowing 1 second of "slop" here |
|
98 // works around this while still keeping the test valid. |
|
99 let now = Date.now() - 1000 ; |
|
100 PageThumbs.captureAndStoreIfStale(gBrowser.selectedBrowser, () => { |
|
101 ok(getThumbnailModifiedTime(URL) < now, "modified time should be < now"); |
|
102 retrieveImageDataForURL(URL, function ([r, g, b]) { |
|
103 is("" + [r,g,b], "" + [0, 255, 0], "thumbnail is still green"); |
|
104 gBrowser.removeTab(gBrowser.selectedTab); |
|
105 next(); |
|
106 }); |
|
107 }); |
|
108 yield undefined; // wait for callback to call 'next'... |
|
109 } |
|
110 |
|
111 /* Check functionality of captureAndStoreIfStale when there is a non-error |
|
112 response from the server. This test is somewhat redundant - although it is |
|
113 using a http:// URL instead of a data: url like most others. |
|
114 */ |
|
115 function capIfStaleGoodResponseUpdateTest() { |
|
116 const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?ok"; |
|
117 yield addTab(URL); |
|
118 let browser = gBrowser.selectedBrowser; |
|
119 |
|
120 yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); |
|
121 // update the thumbnail to be stale, then re-request it. The server will |
|
122 // return a 200 response and a red thumbnail - so that new thumbnail should |
|
123 // end up captured. |
|
124 ensureThumbnailStale(URL); |
|
125 yield navigateTo(URL); |
|
126 // now() returns a higher-precision value than the modified time of a file. |
|
127 // As we set the thumbnail very stale, allowing 1 second of "slop" here |
|
128 // works around this while still keeping the test valid. |
|
129 let now = Date.now() - 1000 ; |
|
130 PageThumbs.captureAndStoreIfStale(browser, () => { |
|
131 ok(getThumbnailModifiedTime(URL) >= now, "modified time should be >= now"); |
|
132 // the captureAndStoreIfStale request saw a 200 response with the red body, |
|
133 // so we expect to see the red version here. |
|
134 retrieveImageDataForURL(URL, function ([r, g, b]) { |
|
135 is("" + [r,g,b], "" + [255, 0, 0], "thumbnail is now red"); |
|
136 next(); |
|
137 }); |
|
138 }); |
|
139 yield undefined; // wait for callback to call 'next'... |
|
140 } |
|
141 |
|
142 /* Check functionality of captureAndStore when there is an error response |
|
143 from the server. |
|
144 */ |
|
145 function regularCapErrorResponseUpdateTest() { |
|
146 const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?fail"; |
|
147 yield addTab(URL); |
|
148 yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); |
|
149 gBrowser.removeTab(gBrowser.selectedTab); |
|
150 // do it again - the server will return a 400, so the foreground service |
|
151 // should not update it. |
|
152 yield addTab(URL); |
|
153 yield captureAndCheckColor(0, 255, 0, "we still have a green thumbnail"); |
|
154 } |
|
155 |
|
156 /* Check functionality of captureAndStore when there is an OK response |
|
157 from the server. |
|
158 */ |
|
159 function regularCapGoodResponseUpdateTest() { |
|
160 const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?ok"; |
|
161 yield addTab(URL); |
|
162 yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); |
|
163 gBrowser.removeTab(gBrowser.selectedTab); |
|
164 // do it again - the server will return a 200, so the foreground service |
|
165 // should update it. |
|
166 yield addTab(URL); |
|
167 yield captureAndCheckColor(255, 0, 0, "we now have a red thumbnail"); |
|
168 } |