1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/thumbnails/test/browser_thumbnails_update.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,168 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +/** 1.8 + * These tests check the auto-update facility of the thumbnail service. 1.9 + */ 1.10 + 1.11 +function runTests() { 1.12 + // A "trampoline" - a generator that iterates over sub-iterators 1.13 + let tests = [ 1.14 + simpleCaptureTest, 1.15 + capIfStaleErrorResponseUpdateTest, 1.16 + capIfStaleGoodResponseUpdateTest, 1.17 + regularCapErrorResponseUpdateTest, 1.18 + regularCapGoodResponseUpdateTest 1.19 + ]; 1.20 + for (let test of tests) { 1.21 + info("Running subtest " + test.name); 1.22 + for (let iterator of test()) 1.23 + yield iterator; 1.24 + } 1.25 +} 1.26 + 1.27 +function ensureThumbnailStale(url) { 1.28 + // We go behind the back of the thumbnail service and change the 1.29 + // mtime of the file to be in the past. 1.30 + let fname = PageThumbsStorage.getFilePathForURL(url); 1.31 + let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 1.32 + file.initWithPath(fname); 1.33 + ok(file.exists(), fname + " should exist"); 1.34 + // Set it as very stale... 1.35 + file.lastModifiedTime = Date.now() - 1000000000; 1.36 +} 1.37 + 1.38 +function getThumbnailModifiedTime(url) { 1.39 + let fname = PageThumbsStorage.getFilePathForURL(url); 1.40 + let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 1.41 + file.initWithPath(fname); 1.42 + return file.lastModifiedTime; 1.43 +} 1.44 + 1.45 +// The tests! 1.46 +/* Check functionality of a normal captureAndStoreIfStale request */ 1.47 +function simpleCaptureTest() { 1.48 + let numNotifications = 0; 1.49 + const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?simple"; 1.50 + 1.51 + function observe(subject, topic, data) { 1.52 + is(topic, "page-thumbnail:create", "got expected topic"); 1.53 + is(data, URL, "data is our test URL"); 1.54 + if (++numNotifications == 2) { 1.55 + // This is the final notification and signals test success... 1.56 + Services.obs.removeObserver(observe, "page-thumbnail:create"); 1.57 + gBrowser.removeTab(gBrowser.selectedTab); 1.58 + next(); 1.59 + } 1.60 + } 1.61 + 1.62 + Services.obs.addObserver(observe, "page-thumbnail:create", false); 1.63 + // Create a tab - we don't care what the content is. 1.64 + yield addTab(URL); 1.65 + let browser = gBrowser.selectedBrowser; 1.66 + 1.67 + // Capture the screenshot. 1.68 + PageThumbs.captureAndStore(browser, function () { 1.69 + // We've got a capture so should have seen the observer. 1.70 + is(numNotifications, 1, "got notification of item being created."); 1.71 + // The capture is now "fresh" - so requesting the URL should not cause 1.72 + // a new capture. 1.73 + PageThumbs.captureAndStoreIfStale(browser); 1.74 + is(numNotifications, 1, "still only 1 notification of item being created."); 1.75 + 1.76 + ensureThumbnailStale(URL); 1.77 + // Ask for it to be updated. 1.78 + PageThumbs.captureAndStoreIfStale(browser); 1.79 + // But it's async, so wait - our observer above will call next() when 1.80 + // the notification comes. 1.81 + }); 1.82 + yield undefined // wait for callbacks to call 'next'... 1.83 +} 1.84 + 1.85 +/* Check functionality of captureAndStoreIfStale when there is an error response 1.86 + from the server. 1.87 + */ 1.88 +function capIfStaleErrorResponseUpdateTest() { 1.89 + const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?fail"; 1.90 + yield addTab(URL); 1.91 + 1.92 + yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); 1.93 + // update the thumbnail to be stale, then re-request it. The server will 1.94 + // return a 400 response and a red thumbnail. 1.95 + // The service should not save the thumbnail - so we (a) check the thumbnail 1.96 + // remains green and (b) check the mtime of the file is < now. 1.97 + ensureThumbnailStale(URL); 1.98 + yield navigateTo(URL); 1.99 + // now() returns a higher-precision value than the modified time of a file. 1.100 + // As we set the thumbnail very stale, allowing 1 second of "slop" here 1.101 + // works around this while still keeping the test valid. 1.102 + let now = Date.now() - 1000 ; 1.103 + PageThumbs.captureAndStoreIfStale(gBrowser.selectedBrowser, () => { 1.104 + ok(getThumbnailModifiedTime(URL) < now, "modified time should be < now"); 1.105 + retrieveImageDataForURL(URL, function ([r, g, b]) { 1.106 + is("" + [r,g,b], "" + [0, 255, 0], "thumbnail is still green"); 1.107 + gBrowser.removeTab(gBrowser.selectedTab); 1.108 + next(); 1.109 + }); 1.110 + }); 1.111 + yield undefined; // wait for callback to call 'next'... 1.112 +} 1.113 + 1.114 +/* Check functionality of captureAndStoreIfStale when there is a non-error 1.115 + response from the server. This test is somewhat redundant - although it is 1.116 + using a http:// URL instead of a data: url like most others. 1.117 + */ 1.118 +function capIfStaleGoodResponseUpdateTest() { 1.119 + const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?ok"; 1.120 + yield addTab(URL); 1.121 + let browser = gBrowser.selectedBrowser; 1.122 + 1.123 + yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); 1.124 + // update the thumbnail to be stale, then re-request it. The server will 1.125 + // return a 200 response and a red thumbnail - so that new thumbnail should 1.126 + // end up captured. 1.127 + ensureThumbnailStale(URL); 1.128 + yield navigateTo(URL); 1.129 + // now() returns a higher-precision value than the modified time of a file. 1.130 + // As we set the thumbnail very stale, allowing 1 second of "slop" here 1.131 + // works around this while still keeping the test valid. 1.132 + let now = Date.now() - 1000 ; 1.133 + PageThumbs.captureAndStoreIfStale(browser, () => { 1.134 + ok(getThumbnailModifiedTime(URL) >= now, "modified time should be >= now"); 1.135 + // the captureAndStoreIfStale request saw a 200 response with the red body, 1.136 + // so we expect to see the red version here. 1.137 + retrieveImageDataForURL(URL, function ([r, g, b]) { 1.138 + is("" + [r,g,b], "" + [255, 0, 0], "thumbnail is now red"); 1.139 + next(); 1.140 + }); 1.141 + }); 1.142 + yield undefined; // wait for callback to call 'next'... 1.143 +} 1.144 + 1.145 +/* Check functionality of captureAndStore when there is an error response 1.146 + from the server. 1.147 + */ 1.148 +function regularCapErrorResponseUpdateTest() { 1.149 + const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?fail"; 1.150 + yield addTab(URL); 1.151 + yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); 1.152 + gBrowser.removeTab(gBrowser.selectedTab); 1.153 + // do it again - the server will return a 400, so the foreground service 1.154 + // should not update it. 1.155 + yield addTab(URL); 1.156 + yield captureAndCheckColor(0, 255, 0, "we still have a green thumbnail"); 1.157 +} 1.158 + 1.159 +/* Check functionality of captureAndStore when there is an OK response 1.160 + from the server. 1.161 + */ 1.162 +function regularCapGoodResponseUpdateTest() { 1.163 + const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?ok"; 1.164 + yield addTab(URL); 1.165 + yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); 1.166 + gBrowser.removeTab(gBrowser.selectedTab); 1.167 + // do it again - the server will return a 200, so the foreground service 1.168 + // should update it. 1.169 + yield addTab(URL); 1.170 + yield captureAndCheckColor(255, 0, 0, "we now have a red thumbnail"); 1.171 +}