Backed out changeset 94eef72cb9b7 (bug 993901) for causing OSX bc1 to frequently fail in browser_tabopen_reflows.js

This commit is contained in:
Wes Kocher 2014-05-28 17:00:32 -07:00
Родитель 306fb2f082
Коммит dd116b95d3
6 изменённых файлов: 68 добавлений и 331 удалений

Просмотреть файл

@ -1464,7 +1464,7 @@ pref("browser.newtabpage.rows", 3);
// number of columns of newtab grid // number of columns of newtab grid
pref("browser.newtabpage.columns", 3); pref("browser.newtabpage.columns", 3);
pref("browser.newtabpage.directory.source", "chrome://global/content/directoryLinks.json"); pref("browser.newtabpage.directorySource", "chrome://global/content/directoryLinks.json");
// Enable the DOM fullscreen API. // Enable the DOM fullscreen API.
pref("full-screen-api.enabled", true); pref("full-screen-api.enabled", true);

Просмотреть файл

@ -217,7 +217,6 @@ let gPage = {
} }
} }
DirectoryLinksProvider.reportShownCount(directoryCount);
// Record how many directory sites were shown, but place counts over the // Record how many directory sites were shown, but place counts over the
// default 9 in the same bucket // default 9 in the same bucket
for (let type of Object.keys(directoryCount)) { for (let type of Object.keys(directoryCount)) {

Просмотреть файл

@ -56,7 +56,7 @@ const EXPECTED_REFLOWS = [
]; ];
const PREF_PRELOAD = "browser.newtab.preload"; const PREF_PRELOAD = "browser.newtab.preload";
const PREF_NEWTAB_DIRECTORYSOURCE = "browser.newtabpage.directory.source"; const PREF_NEWTAB_DIRECTORYSOURCE = "browser.newtabpage.directorySource";
/* /*
* This test ensures that there are no unexpected * This test ensures that there are no unexpected
@ -64,47 +64,26 @@ const PREF_NEWTAB_DIRECTORYSOURCE = "browser.newtabpage.directory.source";
*/ */
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
let DirectoryLinksProvider = Cu.import("resource://gre/modules/DirectoryLinksProvider.jsm", {}).DirectoryLinksProvider;
let Promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
// resolves promise when directory links are downloaded and written to disk
function watchLinksChangeOnce() {
let deferred = Promise.defer();
let observer = {
onManyLinksChanged: () => {
DirectoryLinksProvider.removeObserver(observer);
deferred.resolve();
}
};
observer.onDownloadFail = observer.onManyLinksChanged;
DirectoryLinksProvider.addObserver(observer);
return deferred.promise;
};
Services.prefs.setBoolPref(PREF_PRELOAD, false);
Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, "data:application/json,{}");
registerCleanupFunction(() => { registerCleanupFunction(() => {
Services.prefs.clearUserPref(PREF_PRELOAD); Services.prefs.clearUserPref(PREF_PRELOAD);
Services.prefs.clearUserPref(PREF_NEWTAB_DIRECTORYSOURCE); Services.prefs.clearUserPref(PREF_NEWTAB_DIRECTORYSOURCE);
return watchLinksChangeOnce();
}); });
// run tests when directory source change completes // Add a reflow observer and open a new tab.
watchLinksChangeOnce().then(() => { docShell.addWeakReflowObserver(observer);
// Add a reflow observer and open a new tab. BrowserOpenTab();
docShell.addWeakReflowObserver(observer);
BrowserOpenTab();
// Wait until the tabopen animation has finished. // Wait until the tabopen animation has finished.
waitForTransitionEnd(function () { waitForTransitionEnd(function () {
// Remove reflow observer and clean up. // Remove reflow observer and clean up.
docShell.removeWeakReflowObserver(observer); docShell.removeWeakReflowObserver(observer);
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish();
}); finish();
}); });
Services.prefs.setBoolPref(PREF_PRELOAD, false);
// set directory source to empty links
Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, "data:application/json,{}");
} }
let observer = { let observer = {

Просмотреть файл

@ -2,19 +2,20 @@
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
const PREF_NEWTAB_ENABLED = "browser.newtabpage.enabled"; const PREF_NEWTAB_ENABLED = "browser.newtabpage.enabled";
const PREF_NEWTAB_DIRECTORYSOURCE = "browser.newtabpage.directory.source"; const PREF_NEWTAB_DIRECTORYSOURCE = "browser.newtabpage.directorySource";
Services.prefs.setBoolPref(PREF_NEWTAB_ENABLED, true); Services.prefs.setBoolPref(PREF_NEWTAB_ENABLED, true);
// start with no directory links by default
Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, "data:application/json,{}");
let tmp = {}; let tmp = {};
Cu.import("resource://gre/modules/Promise.jsm", tmp); Cu.import("resource://gre/modules/Promise.jsm", tmp);
Cu.import("resource://gre/modules/NewTabUtils.jsm", tmp); Cu.import("resource://gre/modules/NewTabUtils.jsm", tmp);
Cu.import("resource://gre/modules/DirectoryLinksProvider.jsm", tmp);
Cc["@mozilla.org/moz/jssubscript-loader;1"] Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader) .getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://browser/content/sanitize.js", tmp); .loadSubScript("chrome://browser/content/sanitize.js", tmp);
Cu.import("resource://gre/modules/Timer.jsm", tmp); Cu.import("resource://gre/modules/Timer.jsm", tmp);
let {Promise, NewTabUtils, Sanitizer, clearTimeout, DirectoryLinksProvider} = tmp; let {Promise, NewTabUtils, Sanitizer, clearTimeout} = tmp;
let uri = Services.io.newURI("about:newtab", null, null); let uri = Services.io.newURI("about:newtab", null, null);
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri); let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
@ -59,45 +60,22 @@ registerCleanupFunction(function () {
if (oldInnerHeight) if (oldInnerHeight)
gBrowser.contentWindow.innerHeight = oldInnerHeight; gBrowser.contentWindow.innerHeight = oldInnerHeight;
Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
Services.prefs.clearUserPref(PREF_NEWTAB_DIRECTORYSOURCE);
// Stop any update timers to prevent unexpected updates in later tests // Stop any update timers to prevent unexpected updates in later tests
let timer = NewTabUtils.allPages._scheduleUpdateTimeout; let timer = NewTabUtils.allPages._scheduleUpdateTimeout;
if (timer) { if (timer) {
clearTimeout(timer); clearTimeout(timer);
delete NewTabUtils.allPages._scheduleUpdateTimeout; delete NewTabUtils.allPages._scheduleUpdateTimeout;
} }
Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
Services.prefs.clearUserPref(PREF_NEWTAB_DIRECTORYSOURCE);
return watchLinksChangeOnce();
}); });
/**
* Resolves promise when directory links are downloaded and written to disk
*/
function watchLinksChangeOnce() {
let deferred = Promise.defer();
let observer = {
onManyLinksChanged: () => {
DirectoryLinksProvider.removeObserver(observer);
deferred.resolve();
}
};
observer.onDownloadFail = observer.onManyLinksChanged;
DirectoryLinksProvider.addObserver(observer);
return deferred.promise;
};
/** /**
* Provide the default test function to start our test runner. * Provide the default test function to start our test runner.
*/ */
function test() { function test() {
waitForExplicitFinish(); TestRunner.run();
// start TestRunner.run() after directory links is downloaded and written to disk
watchLinksChangeOnce().then(() => {
TestRunner.run();
});
Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, "data:application/json,{}");
} }
/** /**
@ -108,6 +86,8 @@ let TestRunner = {
* Starts the test runner. * Starts the test runner.
*/ */
run: function () { run: function () {
waitForExplicitFinish();
this._iter = runTests(); this._iter = runTests();
this.next(); this.next();
}, },

Просмотреть файл

@ -14,7 +14,6 @@ const XMLHttpRequest =
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm"); "resource://gre/modules/NetUtil.jsm");
@ -33,7 +32,7 @@ const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale"; const PREF_SELECTED_LOCALE = "general.useragent.locale";
// The preference that tells where to obtain directory links // The preference that tells where to obtain directory links
const PREF_DIRECTORY_SOURCE = "browser.newtabpage.directory.source"; const PREF_DIRECTORY_SOURCE = "browser.newtabpage.directorySource";
// The frecency of a directory link // The frecency of a directory link
const DIRECTORY_FRECENCY = 1000; const DIRECTORY_FRECENCY = 1000;
@ -53,13 +52,7 @@ let DirectoryLinksProvider = {
__linksURL: null, __linksURL: null,
_observers: new Set(), _observers: [],
// links download deferred, resolved upon download completion
_downloadDeferred: null,
// download default interval is 24 hours in milliseconds
_downloadIntervalMS: 86400000,
get _observedPrefs() Object.freeze({ get _observedPrefs() Object.freeze({
linksURL: PREF_DIRECTORY_SOURCE, linksURL: PREF_DIRECTORY_SOURCE,
@ -118,9 +111,8 @@ let DirectoryLinksProvider = {
if (aData == this._observedPrefs["linksURL"]) { if (aData == this._observedPrefs["linksURL"]) {
delete this.__linksURL; delete this.__linksURL;
} }
this._callObservers("onManyLinksChanged");
} }
// force directory download on changes to any of the observed prefs
this._fetchAndCacheLinksIfNecessary(true);
}, },
_addPrefsObserver: function DirectoryLinksProvider_addObserver() { _addPrefsObserver: function DirectoryLinksProvider_addObserver() {
@ -180,9 +172,11 @@ let DirectoryLinksProvider = {
if (this.status && this.status != 200) { if (this.status && this.status != 200) {
json = "{}"; json = "{}";
} }
OS.File.writeAtomic(self._directoryFilePath, json, {tmpPath: self._directoryFilePath + ".tmp"}) let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, DIRECTORY_LINKS_FILE);
OS.File.writeAtomic(directoryLinksFilePath, json, {tmpPath: directoryLinksFilePath + ".tmp"})
.then(() => { .then(() => {
deferred.resolve(); deferred.resolve();
self._callObservers("onManyLinksChanged");
}, },
() => { () => {
deferred.reject("Error writing uri data in profD."); deferred.reject("Error writing uri data in profD.");
@ -203,64 +197,6 @@ let DirectoryLinksProvider = {
return deferred.promise; return deferred.promise;
}, },
/**
* Downloads directory links if needed
* @return promise resolved immediately if no download needed, or upon completion
*/
_fetchAndCacheLinksIfNecessary: function DirectoryLinksProvider_fetchAndCacheLinksIfNecessary(forceDownload=false) {
if (this._downloadDeferred) {
// fetching links already - just return the promise
return this._downloadDeferred.promise;
}
if (forceDownload || this._needsDownload) {
this._downloadDeferred = Promise.defer();
this._fetchAndCacheLinks(this._linksURL).then(() => {
// the new file was successfully downloaded and cached, so update a timestamp
this._lastDownloadMS = Date.now();
this._downloadDeferred.resolve();
this._downloadDeferred = null;
this._callObservers("onManyLinksChanged")
},
error => {
this._downloadDeferred.resolve();
this._downloadDeferred = null;
this._callObservers("onDownloadFail");
});
return this._downloadDeferred.promise;
}
// download is not needed
return Promise.resolve();
},
/**
* @return true if download is needed, false otherwise
*/
get _needsDownload () {
// fail if last download occured less then 24 hours ago
if ((Date.now() - this._lastDownloadMS) > this._downloadIntervalMS) {
return true;
}
return false;
},
/**
* Submits counts of shown directory links for each type and
* triggers directory download if sponsored link was shown
*
* @param object keyed on types containing counts
* @return download promise
*/
reportShownCount: function DirectoryLinksProvider_reportShownCount(directoryCount) {
if (directoryCount.sponsored > 0
|| directoryCount.affiliate > 0
|| directoryCount.organic > 0) {
return this._fetchAndCacheLinksIfNecessary();
}
return Promise.resolve();
},
/** /**
* Gets the current set of directory links. * Gets the current set of directory links.
* @param aCallback The function that the array of links is passed to. * @param aCallback The function that the array of links is passed to.
@ -278,19 +214,6 @@ let DirectoryLinksProvider = {
init: function DirectoryLinksProvider_init() { init: function DirectoryLinksProvider_init() {
this._addPrefsObserver(); this._addPrefsObserver();
// setup directory file path and last download timestamp
this._directoryFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, DIRECTORY_LINKS_FILE);
this._lastDownloadMS = 0;
return Task.spawn(function() {
// get the last modified time of the links file if it exists
let doesFileExists = yield OS.File.exists(this._directoryFilePath);
if (doesFileExists) {
let fileInfo = yield OS.File.stat(this._directoryFilePath);
this._lastDownloadMS = Date.parse(fileInfo.lastModificationDate);
}
// fetch directory on startup without force
yield this._fetchAndCacheLinksIfNecessary();
}.bind(this));
}, },
/** /**
@ -303,11 +226,7 @@ let DirectoryLinksProvider = {
}, },
addObserver: function DirectoryLinksProvider_addObserver(aObserver) { addObserver: function DirectoryLinksProvider_addObserver(aObserver) {
this._observers.add(aObserver); this._observers.push(aObserver);
},
removeObserver: function DirectoryLinksProvider_removeObserver(aObserver) {
this._observers.delete(aObserver);
}, },
_callObservers: function DirectoryLinksProvider__callObservers(aMethodName, aArg) { _callObservers: function DirectoryLinksProvider__callObservers(aMethodName, aArg) {
@ -323,6 +242,8 @@ let DirectoryLinksProvider = {
}, },
_removeObservers: function() { _removeObservers: function() {
this._observers.clear(); while (this._observers.length) {
this._observers.pop();
}
} }
}; };

Просмотреть файл

@ -14,9 +14,7 @@ Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Http.jsm"); Cu.import("resource://gre/modules/Http.jsm");
Cu.import("resource://testing-common/httpd.js"); Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://gre/modules/osfile.jsm") Cu.import("resource://gre/modules/osfile.jsm")
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm"); "resource://gre/modules/NetUtil.jsm");
@ -31,10 +29,6 @@ const kTestURL = 'data:application/json,' + JSON.stringify(kURLData);
const kLocalePref = DirectoryLinksProvider._observedPrefs.prefSelectedLocale; const kLocalePref = DirectoryLinksProvider._observedPrefs.prefSelectedLocale;
const kSourceUrlPref = DirectoryLinksProvider._observedPrefs.linksURL; const kSourceUrlPref = DirectoryLinksProvider._observedPrefs.linksURL;
// app/profile/firefox.js are not avaialble in xpcshell: hence, preset them
Services.prefs.setCharPref(kLocalePref, "en-US");
Services.prefs.setCharPref(kSourceUrlPref, kTestURL);
// httpd settings // httpd settings
var server; var server;
const kDefaultServerPort = 9000; const kDefaultServerPort = 9000;
@ -109,44 +103,19 @@ function cleanJsonFile(jsonFile = DIRECTORY_LINKS_FILE) {
return OS.File.remove(directoryLinksFilePath); return OS.File.remove(directoryLinksFilePath);
} }
function LinksChangeObserver() { // All tests that call setupDirectoryLinksProvider() must also call cleanDirectoryLinksProvider().
this.deferred = Promise.defer(); function setupDirectoryLinksProvider(options = {}) {
this.onManyLinksChanged = () => this.deferred.resolve(); let linksURL = options.linksURL || kTestURL;
this.onDownloadFail = this.onManyLinksChanged; DirectoryLinksProvider.init();
Services.prefs.setCharPref(kLocalePref, options.locale || "en-US");
Services.prefs.setCharPref(kSourceUrlPref, linksURL);
do_check_eq(DirectoryLinksProvider._linksURL, linksURL);
} }
function promiseDirectoryDownloadOnPrefChange(pref, newValue) { function cleanDirectoryLinksProvider() {
let oldValue = Services.prefs.getCharPref(pref); DirectoryLinksProvider.reset();
if (oldValue != newValue) { Services.prefs.clearUserPref(kLocalePref);
// if the preference value is already equal to newValue Services.prefs.clearUserPref(kSourceUrlPref);
// the pref service will not call our observer and we
// deadlock. Hence only setup observer if values differ
let observer = new LinksChangeObserver();
DirectoryLinksProvider.addObserver(observer);
Services.prefs.setCharPref(pref, newValue);
return observer.deferred.promise;
}
return Promise.resolve();
}
function promiseSetupDirectoryLinksProvider(options = {}) {
return Task.spawn(function() {
let linksURL = options.linksURL || kTestURL;
yield DirectoryLinksProvider.init();
yield promiseDirectoryDownloadOnPrefChange(kLocalePref, options.locale || "en-US");
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, linksURL);
do_check_eq(DirectoryLinksProvider._linksURL, linksURL);
DirectoryLinksProvider._lastDownloadMS = options.lastDownloadMS || 0;
});
}
function promiseCleanDirectoryLinksProvider() {
return Task.spawn(function() {
yield promiseDirectoryDownloadOnPrefChange(kLocalePref, "en-US");
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kTestURL);
DirectoryLinksProvider._lastDownloadMS = 0;
DirectoryLinksProvider.reset();
});
} }
function run_test() { function run_test() {
@ -161,14 +130,10 @@ function run_test() {
// Teardown. // Teardown.
do_register_cleanup(function() { do_register_cleanup(function() {
server.stop(function() { }); server.stop(function() { });
DirectoryLinksProvider.reset();
Services.prefs.clearUserPref(kLocalePref);
Services.prefs.clearUserPref(kSourceUrlPref);
}); });
} }
add_task(function test_fetchAndCacheLinks_local() { add_task(function test_fetchAndCacheLinks_local() {
yield DirectoryLinksProvider.init();
yield cleanJsonFile(); yield cleanJsonFile();
// Trigger cache of data or chrome uri files in profD // Trigger cache of data or chrome uri files in profD
yield DirectoryLinksProvider._fetchAndCacheLinks(kTestURL); yield DirectoryLinksProvider._fetchAndCacheLinks(kTestURL);
@ -177,7 +142,6 @@ add_task(function test_fetchAndCacheLinks_local() {
}); });
add_task(function test_fetchAndCacheLinks_remote() { add_task(function test_fetchAndCacheLinks_remote() {
yield DirectoryLinksProvider.init();
yield cleanJsonFile(); yield cleanJsonFile();
// this must trigger directory links json download and save it to cache file // this must trigger directory links json download and save it to cache file
yield DirectoryLinksProvider._fetchAndCacheLinks(kExampleURL); yield DirectoryLinksProvider._fetchAndCacheLinks(kExampleURL);
@ -186,7 +150,6 @@ add_task(function test_fetchAndCacheLinks_remote() {
}); });
add_task(function test_fetchAndCacheLinks_malformedURI() { add_task(function test_fetchAndCacheLinks_malformedURI() {
yield DirectoryLinksProvider.init();
yield cleanJsonFile(); yield cleanJsonFile();
let someJunk = "some junk"; let someJunk = "some junk";
try { try {
@ -202,7 +165,6 @@ add_task(function test_fetchAndCacheLinks_malformedURI() {
}); });
add_task(function test_fetchAndCacheLinks_unknownHost() { add_task(function test_fetchAndCacheLinks_unknownHost() {
yield DirectoryLinksProvider.init();
yield cleanJsonFile(); yield cleanJsonFile();
let nonExistentServer = "http://nosuchhost"; let nonExistentServer = "http://nosuchhost";
try { try {
@ -218,7 +180,6 @@ add_task(function test_fetchAndCacheLinks_unknownHost() {
}); });
add_task(function test_fetchAndCacheLinks_non200Status() { add_task(function test_fetchAndCacheLinks_non200Status() {
yield DirectoryLinksProvider.init();
yield cleanJsonFile(); yield cleanJsonFile();
yield DirectoryLinksProvider._fetchAndCacheLinks(kFailURL); yield DirectoryLinksProvider._fetchAndCacheLinks(kFailURL);
let data = yield readJsonFile(); let data = yield readJsonFile();
@ -226,19 +187,24 @@ add_task(function test_fetchAndCacheLinks_non200Status() {
}); });
// To test onManyLinksChanged observer, trigger a fetch // To test onManyLinksChanged observer, trigger a fetch
add_task(function test_DirectoryLinksProvider__linkObservers() { add_task(function test_linkObservers() {
yield DirectoryLinksProvider.init(); let deferred = Promise.defer();
let testObserver = {
onManyLinksChanged: function() {
deferred.resolve();
}
}
let testObserver = new LinksChangeObserver(); DirectoryLinksProvider.init();
DirectoryLinksProvider.addObserver(testObserver); DirectoryLinksProvider.addObserver(testObserver);
do_check_eq(DirectoryLinksProvider._observers.size, 1); do_check_eq(DirectoryLinksProvider._observers.length, 1);
DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true); DirectoryLinksProvider._fetchAndCacheLinks(kTestURL);
yield testObserver.deferred.promise; yield deferred.promise;
DirectoryLinksProvider._removeObservers(); DirectoryLinksProvider._removeObservers();
do_check_eq(DirectoryLinksProvider._observers.size, 0); do_check_eq(DirectoryLinksProvider._observers.length, 0);
yield promiseCleanDirectoryLinksProvider(); cleanDirectoryLinksProvider();
}); });
add_task(function test_linksURL_locale() { add_task(function test_linksURL_locale() {
@ -251,7 +217,7 @@ add_task(function test_linksURL_locale() {
}; };
let dataURI = 'data:application/json,' + JSON.stringify(data); let dataURI = 'data:application/json,' + JSON.stringify(data);
yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); setupDirectoryLinksProvider({linksURL: dataURI});
let links; let links;
let expected_data; let expected_data;
@ -261,7 +227,7 @@ add_task(function test_linksURL_locale() {
expected_data = [{url: "http://example.com", title: "US", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}]; expected_data = [{url: "http://example.com", title: "US", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}];
isIdentical(links, expected_data); isIdentical(links, expected_data);
yield promiseDirectoryDownloadOnPrefChange("general.useragent.locale", "zh-CN"); Services.prefs.setCharPref('general.useragent.locale', 'zh-CN');
links = yield fetchData(); links = yield fetchData();
do_check_eq(links.length, 2) do_check_eq(links.length, 2)
@ -271,11 +237,11 @@ add_task(function test_linksURL_locale() {
]; ];
isIdentical(links, expected_data); isIdentical(links, expected_data);
yield promiseCleanDirectoryLinksProvider(); cleanDirectoryLinksProvider();
}); });
add_task(function test_DirectoryLinksProvider__prefObserver_url() { add_task(function test_prefObserver_url() {
yield promiseSetupDirectoryLinksProvider({linksURL: kTestURL}); setupDirectoryLinksProvider({linksURL: kTestURL});
let links = yield fetchData(); let links = yield fetchData();
do_check_eq(links.length, 1); do_check_eq(links.length, 1);
@ -286,126 +252,18 @@ add_task(function test_DirectoryLinksProvider__prefObserver_url() {
// 1. _linksURL is properly set after the pref change // 1. _linksURL is properly set after the pref change
// 2. invalid source url is correctly handled // 2. invalid source url is correctly handled
let exampleUrl = 'http://nosuchhost/bad'; let exampleUrl = 'http://nosuchhost/bad';
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, exampleUrl); Services.prefs.setCharPref(kSourceUrlPref, exampleUrl);
do_check_eq(DirectoryLinksProvider._linksURL, exampleUrl); do_check_eq(DirectoryLinksProvider._linksURL, exampleUrl);
let newLinks = yield fetchData(); let newLinks = yield fetchData();
isIdentical(newLinks, []); isIdentical(newLinks, []);
yield promiseCleanDirectoryLinksProvider(); cleanDirectoryLinksProvider();
}); });
add_task(function test_DirectoryLinksProvider_getLinks_noLocaleData() { add_task(function test_getLinks_noLocaleData() {
yield promiseSetupDirectoryLinksProvider({locale: 'zh-CN'}); setupDirectoryLinksProvider({locale: 'zh-CN'});
let links = yield fetchData(); let links = yield fetchData();
do_check_eq(links.length, 0); do_check_eq(links.length, 0);
yield promiseCleanDirectoryLinksProvider(); cleanDirectoryLinksProvider();
});
add_task(function test_DirectoryLinksProvider_needsDownload() {
// test timestamping
DirectoryLinksProvider._lastDownloadMS = 0;
do_check_true(DirectoryLinksProvider._needsDownload);
DirectoryLinksProvider._lastDownloadMS = Date.now();
do_check_false(DirectoryLinksProvider._needsDownload);
DirectoryLinksProvider._lastDownloadMS = Date.now() - (60*60*24 + 1)*1000;
do_check_true(DirectoryLinksProvider._needsDownload);
DirectoryLinksProvider._lastDownloadMS = 0;
});
add_task(function test_DirectoryLinksProvider_fetchAndCacheLinksIfNecessary() {
yield DirectoryLinksProvider.init();
yield cleanJsonFile();
// explicitly change source url to cause the download during setup
yield promiseSetupDirectoryLinksProvider({linksURL: kTestURL+" "});
yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary();
// inspect lastDownloadMS timestamp which should be 5 seconds less then now()
let lastDownloadMS = DirectoryLinksProvider._lastDownloadMS;
do_check_true((Date.now() - lastDownloadMS) < 5000);
// we should have fetched a new file during setup
let data = yield readJsonFile();
isIdentical(data, kURLData);
// attempt to download again - the timestamp should not change
yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary();
do_check_eq(DirectoryLinksProvider._lastDownloadMS, lastDownloadMS);
// clean the file and force the download
yield cleanJsonFile();
yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
data = yield readJsonFile();
isIdentical(data, kURLData);
// make sure that failed download does not corrupt the file, nor changes lastDownloadMS
lastDownloadMS = DirectoryLinksProvider._lastDownloadMS;
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, "http://");
yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
data = yield readJsonFile();
isIdentical(data, kURLData);
do_check_eq(DirectoryLinksProvider._lastDownloadMS, lastDownloadMS);
// _fetchAndCacheLinksIfNecessary must return same promise if download is in progress
let downloadPromise = DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
let anotherPromise = DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
do_check_true(downloadPromise === anotherPromise);
yield downloadPromise;
yield promiseCleanDirectoryLinksProvider();
});
add_task(function test_DirectoryLinksProvider_fetchDirectoryOnPrefChange() {
yield DirectoryLinksProvider.init();
let testObserver = new LinksChangeObserver();
DirectoryLinksProvider.addObserver(testObserver);
yield cleanJsonFile();
// ensure that provider does not think it needs to download
do_check_false(DirectoryLinksProvider._needsDownload);
// change the source URL, which should force directory download
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kExampleURL);
// then wait for testObserver to fire and test that json is downloaded
yield testObserver.deferred.promise;
let data = yield readJsonFile();
isIdentical(data, kHttpHandlerData[kExamplePath]);
yield promiseCleanDirectoryLinksProvider();
});
add_task(function test_DirectoryLinksProvider_fetchDirectoryOnShowCount() {
yield promiseSetupDirectoryLinksProvider();
// set lastdownload to 0 to make DirectoryLinksProvider want to download
DirectoryLinksProvider._lastDownloadMS = 0;
do_check_true(DirectoryLinksProvider._needsDownload);
// Tell DirectoryLinksProvider that newtab has no room for sponsored links
let directoryCount = {sponsored: 0};
yield DirectoryLinksProvider.reportShownCount(directoryCount);
// the provider must skip download, hence that lastdownload is still 0
do_check_eq(DirectoryLinksProvider._lastDownloadMS, 0);
// make room for sponsored links and repeat, download should happen
directoryCount.sponsored = 1;
yield DirectoryLinksProvider.reportShownCount(directoryCount);
do_check_true(DirectoryLinksProvider._lastDownloadMS != 0);
yield promiseCleanDirectoryLinksProvider();
});
add_task(function test_DirectoryLinksProvider_fetchDirectoryOnInit() {
// ensure preferences are set to defaults
yield promiseSetupDirectoryLinksProvider();
// now clean to provider, so we can init it again
yield promiseCleanDirectoryLinksProvider();
yield cleanJsonFile();
yield DirectoryLinksProvider.init();
let data = yield readJsonFile();
isIdentical(data, kURLData);
yield promiseCleanDirectoryLinksProvider();
}); });