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