/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /** * These tests check the auto-update facility of the thumbnail service. */ function* runTests() { // A "trampoline" - a generator that iterates over sub-iterators let tests = [ simpleCaptureTest, capIfStaleErrorResponseUpdateTest, capIfStaleGoodResponseUpdateTest, regularCapErrorResponseUpdateTest, regularCapGoodResponseUpdateTest ]; for (let test of tests) { info("Running subtest " + test.name); for (let iterator of test()) yield iterator; } } function ensureThumbnailStale(url) { // We go behind the back of the thumbnail service and change the // mtime of the file to be in the past. let fname = PageThumbsStorage.getFilePathForURL(url); let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(fname); ok(file.exists(), fname + " should exist"); // Set it as very stale... file.lastModifiedTime = Date.now() - 1000000000; } function getThumbnailModifiedTime(url) { let fname = PageThumbsStorage.getFilePathForURL(url); let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(fname); return file.lastModifiedTime; } // The tests! /* Check functionality of a normal captureAndStoreIfStale request */ function* simpleCaptureTest() { let numNotifications = 0; const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?simple"; function observe(subject, topic, data) { is(topic, "page-thumbnail:create", "got expected topic"); is(data, URL, "data is our test URL"); if (++numNotifications == 2) { // This is the final notification and signals test success... Services.obs.removeObserver(observe, "page-thumbnail:create"); gBrowser.removeTab(gBrowser.selectedTab); next(); } } Services.obs.addObserver(observe, "page-thumbnail:create", false); // Create a tab - we don't care what the content is. yield addTab(URL); let browser = gBrowser.selectedBrowser; // Capture the screenshot. PageThumbs.captureAndStore(browser, function () { // We've got a capture so should have seen the observer. is(numNotifications, 1, "got notification of item being created."); // The capture is now "fresh" - so requesting the URL should not cause // a new capture. PageThumbs.captureAndStoreIfStale(browser, function() { is(numNotifications, 1, "still only 1 notification of item being created."); ensureThumbnailStale(URL); // Ask for it to be updated. PageThumbs.captureAndStoreIfStale(browser); // But it's async, so wait - our observer above will call next() when // the notification comes. }); }); yield undefined // wait for callbacks to call 'next'... } /* Check functionality of captureAndStoreIfStale when there is an error response from the server. */ function* capIfStaleErrorResponseUpdateTest() { const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?fail"; yield addTab(URL); yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); // update the thumbnail to be stale, then re-request it. The server will // return a 400 response and a red thumbnail. // The service should not save the thumbnail - so we (a) check the thumbnail // remains green and (b) check the mtime of the file is < now. ensureThumbnailStale(URL); yield navigateTo(URL); // now() returns a higher-precision value than the modified time of a file. // As we set the thumbnail very stale, allowing 1 second of "slop" here // works around this while still keeping the test valid. let now = Date.now() - 1000 ; PageThumbs.captureAndStoreIfStale(gBrowser.selectedBrowser, () => { ok(getThumbnailModifiedTime(URL) < now, "modified time should be < now"); retrieveImageDataForURL(URL, function ([r, g, b]) { is("" + [r, g, b], "" + [0, 255, 0], "thumbnail is still green"); gBrowser.removeTab(gBrowser.selectedTab); next(); }); }); yield undefined; // wait for callback to call 'next'... } /* Check functionality of captureAndStoreIfStale when there is a non-error response from the server. This test is somewhat redundant - although it is using a http:// URL instead of a data: url like most others. */ function* capIfStaleGoodResponseUpdateTest() { const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?ok"; yield addTab(URL); let browser = gBrowser.selectedBrowser; yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); // update the thumbnail to be stale, then re-request it. The server will // return a 200 response and a red thumbnail - so that new thumbnail should // end up captured. ensureThumbnailStale(URL); yield navigateTo(URL); // now() returns a higher-precision value than the modified time of a file. // As we set the thumbnail very stale, allowing 1 second of "slop" here // works around this while still keeping the test valid. let now = Date.now() - 1000 ; PageThumbs.captureAndStoreIfStale(browser, () => { ok(getThumbnailModifiedTime(URL) >= now, "modified time should be >= now"); // the captureAndStoreIfStale request saw a 200 response with the red body, // so we expect to see the red version here. retrieveImageDataForURL(URL, function ([r, g, b]) { is("" + [r, g, b], "" + [255, 0, 0], "thumbnail is now red"); next(); }); }); yield undefined; // wait for callback to call 'next'... } /* Check functionality of captureAndStore when there is an error response from the server. */ function* regularCapErrorResponseUpdateTest() { const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?fail"; yield addTab(URL); yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); gBrowser.removeTab(gBrowser.selectedTab); // do it again - the server will return a 400, so the foreground service // should not update it. yield addTab(URL); yield captureAndCheckColor(0, 255, 0, "we still have a green thumbnail"); } /* Check functionality of captureAndStore when there is an OK response from the server. */ function* regularCapGoodResponseUpdateTest() { const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?ok"; yield addTab(URL); yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail"); gBrowser.removeTab(gBrowser.selectedTab); // do it again - the server will return a 200, so the foreground service // should update it. yield addTab(URL); yield captureAndCheckColor(255, 0, 0, "we now have a red thumbnail"); }