gecko-dev/toolkit/modules/tests/xpcshell/test_NewTabUtils.js
Dave Townsend 76c0eab703 Bug 1229519: Fix toolkit/modules to pass eslint checks. r=mak
--HG--
extra : commitid : 9muV4FzxxCp
extra : rebase_source : 2d651bfb17cd89768cff1f62d2ee7550a9c2589d
extra : amend_source : 5a0584163aaec0534dab50a8cac8597b58214f24
2015-12-03 09:58:56 -08:00

378 lines
13 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// See also browser/base/content/test/newtab/.
var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
Cu.import("resource://gre/modules/NewTabUtils.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const PREF_NEWTAB_ENHANCED = "browser.newtabpage.enhanced";
function run_test() {
Services.prefs.setBoolPref(PREF_NEWTAB_ENHANCED, true);
run_next_test();
}
add_task(function* validCacheMidPopulation() {
let expectedLinks = makeLinks(0, 3, 1);
let provider = new TestProvider(done => done(expectedLinks));
provider.maxNumLinks = expectedLinks.length;
NewTabUtils.initWithoutProviders();
NewTabUtils.links.addProvider(provider);
let promise = new Promise(resolve => NewTabUtils.links.populateCache(resolve));
// isTopSiteGivenProvider() and getProviderLinks() should still return results
// even when cache is empty or being populated.
do_check_false(NewTabUtils.isTopSiteGivenProvider("example1.com", provider));
do_check_links(NewTabUtils.getProviderLinks(provider), []);
yield promise;
// Once the cache is populated, we get the expected results
do_check_true(NewTabUtils.isTopSiteGivenProvider("example1.com", provider));
do_check_links(NewTabUtils.getProviderLinks(provider), expectedLinks);
NewTabUtils.links.removeProvider(provider);
});
add_task(function* notifyLinkDelete() {
let expectedLinks = makeLinks(0, 3, 1);
let provider = new TestProvider(done => done(expectedLinks));
provider.maxNumLinks = expectedLinks.length;
NewTabUtils.initWithoutProviders();
NewTabUtils.links.addProvider(provider);
yield new Promise(resolve => NewTabUtils.links.populateCache(resolve));
do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
// Remove a link.
let removedLink = expectedLinks[2];
provider.notifyLinkChanged(removedLink, 2, true);
let links = NewTabUtils.links._providers.get(provider);
// Check that sortedLinks is correctly updated.
do_check_links(NewTabUtils.links.getLinks(), expectedLinks.slice(0, 2));
// Check that linkMap is accurately updated.
do_check_eq(links.linkMap.size, 2);
do_check_true(links.linkMap.get(expectedLinks[0].url));
do_check_true(links.linkMap.get(expectedLinks[1].url));
do_check_false(links.linkMap.get(removedLink.url));
// Check that siteMap is correctly updated.
do_check_eq(links.siteMap.size, 2);
do_check_true(links.siteMap.has(NewTabUtils.extractSite(expectedLinks[0].url)));
do_check_true(links.siteMap.has(NewTabUtils.extractSite(expectedLinks[1].url)));
do_check_false(links.siteMap.has(NewTabUtils.extractSite(removedLink.url)));
NewTabUtils.links.removeProvider(provider);
});
add_task(function* populatePromise() {
let count = 0;
let expectedLinks = makeLinks(0, 10, 2);
let getLinksFcn = Task.async(function* (callback) {
//Should not be calling getLinksFcn twice
count++;
do_check_eq(count, 1);
yield Promise.resolve();
callback(expectedLinks);
});
let provider = new TestProvider(getLinksFcn);
NewTabUtils.initWithoutProviders();
NewTabUtils.links.addProvider(provider);
NewTabUtils.links.populateProviderCache(provider, () => {});
NewTabUtils.links.populateProviderCache(provider, () => {
do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
NewTabUtils.links.removeProvider(provider);
});
});
add_task(function* isTopSiteGivenProvider() {
let expectedLinks = makeLinks(0, 10, 2);
// The lowest 2 frecencies have the same base domain.
expectedLinks[expectedLinks.length - 2].url = expectedLinks[expectedLinks.length - 1].url + "Test";
let provider = new TestProvider(done => done(expectedLinks));
provider.maxNumLinks = expectedLinks.length;
NewTabUtils.initWithoutProviders();
NewTabUtils.links.addProvider(provider);
yield new Promise(resolve => NewTabUtils.links.populateCache(resolve));
do_check_eq(NewTabUtils.isTopSiteGivenProvider("example2.com", provider), true);
do_check_eq(NewTabUtils.isTopSiteGivenProvider("example1.com", provider), false);
// Push out frecency 2 because the maxNumLinks is reached when adding frecency 3
let newLink = makeLink(3);
provider.notifyLinkChanged(newLink);
// There is still a frecent url with example2 domain, so it's still frecent.
do_check_eq(NewTabUtils.isTopSiteGivenProvider("example3.com", provider), true);
do_check_eq(NewTabUtils.isTopSiteGivenProvider("example2.com", provider), true);
// Push out frecency 3
newLink = makeLink(5);
provider.notifyLinkChanged(newLink);
// Push out frecency 4
newLink = makeLink(9);
provider.notifyLinkChanged(newLink);
// Our count reached 0 for the example2.com domain so it's no longer a frecent site.
do_check_eq(NewTabUtils.isTopSiteGivenProvider("example5.com", provider), true);
do_check_eq(NewTabUtils.isTopSiteGivenProvider("example2.com", provider), false);
NewTabUtils.links.removeProvider(provider);
});
add_task(function* multipleProviders() {
// Make each provider generate NewTabUtils.links.maxNumLinks links to check
// that no more than maxNumLinks are actually returned in the merged list.
let evenLinks = makeLinks(0, 2 * NewTabUtils.links.maxNumLinks, 2);
let evenProvider = new TestProvider(done => done(evenLinks));
let oddLinks = makeLinks(0, 2 * NewTabUtils.links.maxNumLinks - 1, 2);
let oddProvider = new TestProvider(done => done(oddLinks));
NewTabUtils.initWithoutProviders();
NewTabUtils.links.addProvider(evenProvider);
NewTabUtils.links.addProvider(oddProvider);
yield new Promise(resolve => NewTabUtils.links.populateCache(resolve));
let links = NewTabUtils.links.getLinks();
let expectedLinks = makeLinks(NewTabUtils.links.maxNumLinks,
2 * NewTabUtils.links.maxNumLinks,
1);
do_check_eq(links.length, NewTabUtils.links.maxNumLinks);
do_check_links(links, expectedLinks);
NewTabUtils.links.removeProvider(evenProvider);
NewTabUtils.links.removeProvider(oddProvider);
});
add_task(function* changeLinks() {
let expectedLinks = makeLinks(0, 20, 2);
let provider = new TestProvider(done => done(expectedLinks));
NewTabUtils.initWithoutProviders();
NewTabUtils.links.addProvider(provider);
yield new Promise(resolve => NewTabUtils.links.populateCache(resolve));
do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
// Notify of a new link.
let newLink = makeLink(19);
expectedLinks.splice(1, 0, newLink);
provider.notifyLinkChanged(newLink);
do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
// Notify of a link that's changed sort criteria.
newLink.frecency = 17;
expectedLinks.splice(1, 1);
expectedLinks.splice(2, 0, newLink);
provider.notifyLinkChanged({
url: newLink.url,
frecency: 17,
});
do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
// Notify of a link that's changed title.
newLink.title = "My frecency is now 17";
provider.notifyLinkChanged({
url: newLink.url,
title: newLink.title,
});
do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
// Notify of a new link again, but this time make it overflow maxNumLinks.
provider.maxNumLinks = expectedLinks.length;
newLink = makeLink(21);
expectedLinks.unshift(newLink);
expectedLinks.pop();
do_check_eq(expectedLinks.length, provider.maxNumLinks); // Sanity check.
provider.notifyLinkChanged(newLink);
do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
// Notify of many links changed.
expectedLinks = makeLinks(0, 3, 1);
provider.notifyManyLinksChanged();
// Since _populateProviderCache() is async, we must wait until the provider's
// populate promise has been resolved.
yield NewTabUtils.links._providers.get(provider).populatePromise;
// NewTabUtils.links will now repopulate its cache
do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
NewTabUtils.links.removeProvider(provider);
});
add_task(function* oneProviderAlreadyCached() {
let links1 = makeLinks(0, 10, 1);
let provider1 = new TestProvider(done => done(links1));
NewTabUtils.initWithoutProviders();
NewTabUtils.links.addProvider(provider1);
yield new Promise(resolve => NewTabUtils.links.populateCache(resolve));
do_check_links(NewTabUtils.links.getLinks(), links1);
let links2 = makeLinks(10, 20, 1);
let provider2 = new TestProvider(done => done(links2));
NewTabUtils.links.addProvider(provider2);
yield new Promise(resolve => NewTabUtils.links.populateCache(resolve));
do_check_links(NewTabUtils.links.getLinks(), links2.concat(links1));
NewTabUtils.links.removeProvider(provider1);
NewTabUtils.links.removeProvider(provider2);
});
add_task(function* newLowRankedLink() {
// Init a provider with 10 links and make its maximum number also 10.
let links = makeLinks(0, 10, 1);
let provider = new TestProvider(done => done(links));
provider.maxNumLinks = links.length;
NewTabUtils.initWithoutProviders();
NewTabUtils.links.addProvider(provider);
yield new Promise(resolve => NewTabUtils.links.populateCache(resolve));
do_check_links(NewTabUtils.links.getLinks(), links);
// Notify of a new link that's low-ranked enough not to make the list.
let newLink = makeLink(0);
provider.notifyLinkChanged(newLink);
do_check_links(NewTabUtils.links.getLinks(), links);
// Notify about the new link's title change.
provider.notifyLinkChanged({
url: newLink.url,
title: "a new title",
});
do_check_links(NewTabUtils.links.getLinks(), links);
NewTabUtils.links.removeProvider(provider);
});
add_task(function* extractSite() {
// All these should extract to the same site
[ "mozilla.org",
"m.mozilla.org",
"mobile.mozilla.org",
"www.mozilla.org",
"www3.mozilla.org",
].forEach(host => {
let url = "http://" + host;
do_check_eq(NewTabUtils.extractSite(url), "mozilla.org", "extracted same " + host);
});
// All these should extract to the same subdomain
[ "bugzilla.mozilla.org",
"www.bugzilla.mozilla.org",
].forEach(host => {
let url = "http://" + host;
do_check_eq(NewTabUtils.extractSite(url), "bugzilla.mozilla.org", "extracted eTLD+2 " + host);
});
// All these should not extract to the same site
[ "bugzilla.mozilla.org",
"bug123.bugzilla.mozilla.org",
"too.many.levels.bugzilla.mozilla.org",
"m2.mozilla.org",
"mobile30.mozilla.org",
"ww.mozilla.org",
"ww2.mozilla.org",
"wwwww.mozilla.org",
"wwwww50.mozilla.org",
"wwws.mozilla.org",
"secure.mozilla.org",
"secure10.mozilla.org",
"many.levels.deep.mozilla.org",
"just.check.in",
"192.168.0.1",
"localhost",
].forEach(host => {
let url = "http://" + host;
do_check_neq(NewTabUtils.extractSite(url), "mozilla.org", "extracted diff " + host);
});
// All these should not extract to the same site
[ "about:blank",
"file:///Users/user/file",
"chrome://browser/something",
"ftp://ftp.mozilla.org/",
].forEach(url => {
do_check_neq(NewTabUtils.extractSite(url), "mozilla.org", "extracted diff url " + url);
});
});
function TestProvider(getLinksFn) {
this.getLinks = getLinksFn;
this._observers = new Set();
}
TestProvider.prototype = {
addObserver: function (observer) {
this._observers.add(observer);
},
notifyLinkChanged: function (link, index=-1, deleted=false) {
this._notifyObservers("onLinkChanged", link, index, deleted);
},
notifyManyLinksChanged: function () {
this._notifyObservers("onManyLinksChanged");
},
_notifyObservers: function () {
let observerMethodName = arguments[0];
let args = Array.prototype.slice.call(arguments, 1);
args.unshift(this);
for (let obs of this._observers) {
if (obs[observerMethodName])
obs[observerMethodName].apply(NewTabUtils.links, args);
}
},
};
function do_check_links(actualLinks, expectedLinks) {
do_check_true(Array.isArray(actualLinks));
do_check_eq(actualLinks.length, expectedLinks.length);
for (let i = 0; i < expectedLinks.length; i++) {
let expected = expectedLinks[i];
let actual = actualLinks[i];
do_check_eq(actual.url, expected.url);
do_check_eq(actual.title, expected.title);
do_check_eq(actual.frecency, expected.frecency);
do_check_eq(actual.lastVisitDate, expected.lastVisitDate);
}
}
function makeLinks(frecRangeStart, frecRangeEnd, step) {
let links = [];
// Remember, links are ordered by frecency descending.
for (let i = frecRangeEnd; i > frecRangeStart; i -= step) {
links.push(makeLink(i));
}
return links;
}
function makeLink(frecency) {
return {
url: "http://example" + frecency + ".com/",
title: "My frecency is " + frecency,
frecency: frecency,
lastVisitDate: 0,
};
}