2014-03-27 12:03:42 +04:00
|
|
|
/* Any copyright is dedicated to the Public Domain.
|
|
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This file tests the DirectoryLinksProvider singleton in the DirectoryLinksProvider.jsm module.
|
|
|
|
*/
|
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu, Constructor: CC } = Components;
|
2014-03-27 12:03:42 +04:00
|
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
|
|
Cu.import("resource://gre/modules/DirectoryLinksProvider.jsm");
|
|
|
|
Cu.import("resource://gre/modules/Promise.jsm");
|
2014-05-09 19:24:30 +04:00
|
|
|
Cu.import("resource://gre/modules/Http.jsm");
|
|
|
|
Cu.import("resource://testing-common/httpd.js");
|
|
|
|
Cu.import("resource://gre/modules/osfile.jsm")
|
2014-05-28 00:59:33 +04:00
|
|
|
Cu.import("resource://gre/modules/Task.jsm");
|
2014-05-09 19:24:30 +04:00
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
2014-05-28 00:59:33 +04:00
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
|
|
|
"resource://gre/modules/NetUtil.jsm");
|
2014-03-27 12:03:42 +04:00
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
do_get_profile();
|
|
|
|
|
|
|
|
const DIRECTORY_LINKS_FILE = "directoryLinks.json";
|
2014-03-27 12:03:42 +04:00
|
|
|
const DIRECTORY_FRECENCY = 1000;
|
2014-05-09 19:24:30 +04:00
|
|
|
const kURLData = {"en-US": [{"url":"http://example.com","title":"LocalSource"}]};
|
|
|
|
const kTestURL = 'data:application/json,' + JSON.stringify(kURLData);
|
|
|
|
|
|
|
|
// DirectoryLinksProvider preferences
|
|
|
|
const kLocalePref = DirectoryLinksProvider._observedPrefs.prefSelectedLocale;
|
|
|
|
const kSourceUrlPref = DirectoryLinksProvider._observedPrefs.linksURL;
|
2014-06-10 09:03:23 +04:00
|
|
|
const kReportClickUrlPref = "browser.newtabpage.directory.reportClickEndPoint";
|
|
|
|
const kTelemetryEnabledPref = "toolkit.telemetry.enabled";
|
2014-05-28 00:59:33 +04:00
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
// httpd settings
|
|
|
|
var server;
|
|
|
|
const kDefaultServerPort = 9000;
|
|
|
|
const kBaseUrl = "http://localhost:" + kDefaultServerPort;
|
|
|
|
const kExamplePath = "/exampleTest/";
|
|
|
|
const kFailPath = "/fail/";
|
2014-06-10 09:03:23 +04:00
|
|
|
const kReportClickPath = "/reportClick/";
|
2014-05-09 19:24:30 +04:00
|
|
|
const kExampleURL = kBaseUrl + kExamplePath;
|
|
|
|
const kFailURL = kBaseUrl + kFailPath;
|
2014-06-10 09:03:23 +04:00
|
|
|
const kReportClickUrl = kBaseUrl + kReportClickPath;
|
|
|
|
|
|
|
|
// app/profile/firefox.js are not avaialble in xpcshell: hence, preset them
|
|
|
|
Services.prefs.setCharPref(kLocalePref, "en-US");
|
|
|
|
Services.prefs.setCharPref(kSourceUrlPref, kTestURL);
|
|
|
|
Services.prefs.setCharPref(kReportClickUrlPref, kReportClickUrl);
|
|
|
|
Services.prefs.setBoolPref(kTelemetryEnabledPref, true);
|
2014-05-09 19:24:30 +04:00
|
|
|
|
|
|
|
const kHttpHandlerData = {};
|
|
|
|
kHttpHandlerData[kExamplePath] = {"en-US": [{"url":"http://example.com","title":"RemoteSource"}]};
|
|
|
|
|
2014-06-02 20:14:08 +04:00
|
|
|
const expectedBodyObject = {locale: DirectoryLinksProvider.locale};
|
2014-05-09 19:24:30 +04:00
|
|
|
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
|
|
|
|
"nsIBinaryInputStream",
|
|
|
|
"setInputStream");
|
|
|
|
|
|
|
|
function getHttpHandler(path) {
|
|
|
|
let code = 200;
|
|
|
|
let body = JSON.stringify(kHttpHandlerData[path]);
|
|
|
|
if (path == kFailPath) {
|
|
|
|
code = 204;
|
|
|
|
}
|
|
|
|
return function(aRequest, aResponse) {
|
|
|
|
let bodyStream = new BinaryInputStream(aRequest.bodyInputStream);
|
2014-06-02 20:14:08 +04:00
|
|
|
let bodyObject = JSON.parse(NetUtil.readInputStreamToString(bodyStream, bodyStream.available()));
|
|
|
|
isIdentical(bodyObject, expectedBodyObject);
|
2014-05-09 19:24:30 +04:00
|
|
|
|
|
|
|
aResponse.setStatusLine(null, code);
|
|
|
|
aResponse.setHeader("Content-Type", "application/json");
|
|
|
|
aResponse.write(body);
|
|
|
|
};
|
|
|
|
}
|
2014-03-27 12:03:42 +04:00
|
|
|
|
|
|
|
function isIdentical(actual, expected) {
|
|
|
|
if (expected == null) {
|
|
|
|
do_check_eq(actual, expected);
|
|
|
|
}
|
|
|
|
else if (typeof expected == "object") {
|
|
|
|
// Make sure all the keys match up
|
|
|
|
do_check_eq(Object.keys(actual).sort() + "", Object.keys(expected).sort());
|
|
|
|
|
|
|
|
// Recursively check each value individually
|
|
|
|
Object.keys(expected).forEach(key => {
|
|
|
|
isIdentical(actual[key], expected[key]);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
do_check_eq(actual, expected);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
function fetchData() {
|
2014-03-27 12:03:42 +04:00
|
|
|
let deferred = Promise.defer();
|
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
DirectoryLinksProvider.getLinks(linkData => {
|
2014-03-27 12:03:42 +04:00
|
|
|
deferred.resolve(linkData);
|
|
|
|
});
|
|
|
|
return deferred.promise;
|
|
|
|
}
|
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
function readJsonFile(jsonFile = DIRECTORY_LINKS_FILE) {
|
|
|
|
let decoder = new TextDecoder();
|
|
|
|
let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, jsonFile);
|
|
|
|
return OS.File.read(directoryLinksFilePath).then(array => {
|
|
|
|
let json = decoder.decode(array);
|
|
|
|
return JSON.parse(json);
|
|
|
|
}, () => { return "" });
|
|
|
|
}
|
|
|
|
|
|
|
|
function cleanJsonFile(jsonFile = DIRECTORY_LINKS_FILE) {
|
|
|
|
let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, jsonFile);
|
|
|
|
return OS.File.remove(directoryLinksFilePath);
|
|
|
|
}
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
function LinksChangeObserver() {
|
|
|
|
this.deferred = Promise.defer();
|
|
|
|
this.onManyLinksChanged = () => this.deferred.resolve();
|
|
|
|
this.onDownloadFail = this.onManyLinksChanged;
|
2014-05-09 19:24:30 +04:00
|
|
|
}
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
function promiseDirectoryDownloadOnPrefChange(pref, newValue) {
|
|
|
|
let oldValue = Services.prefs.getCharPref(pref);
|
|
|
|
if (oldValue != newValue) {
|
|
|
|
// if the preference value is already equal to newValue
|
|
|
|
// 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();
|
|
|
|
});
|
2014-05-09 19:24:30 +04:00
|
|
|
}
|
|
|
|
|
2014-03-27 12:03:42 +04:00
|
|
|
function run_test() {
|
2014-05-09 19:24:30 +04:00
|
|
|
// Set up a mock HTTP server to serve a directory page
|
|
|
|
server = new HttpServer();
|
|
|
|
server.registerPrefixHandler(kExamplePath, getHttpHandler(kExamplePath));
|
|
|
|
server.registerPrefixHandler(kFailPath, getHttpHandler(kFailPath));
|
|
|
|
server.start(kDefaultServerPort);
|
|
|
|
|
2014-03-27 12:03:42 +04:00
|
|
|
run_next_test();
|
2014-05-09 19:24:30 +04:00
|
|
|
|
|
|
|
// Teardown.
|
|
|
|
do_register_cleanup(function() {
|
|
|
|
server.stop(function() { });
|
2014-05-28 00:59:33 +04:00
|
|
|
DirectoryLinksProvider.reset();
|
|
|
|
Services.prefs.clearUserPref(kLocalePref);
|
|
|
|
Services.prefs.clearUserPref(kSourceUrlPref);
|
2014-06-10 09:03:23 +04:00
|
|
|
Services.prefs.clearUserPref(kReportClickUrlPref);
|
|
|
|
Services.prefs.clearUserPref(kTelemetryEnabledPref);
|
2014-05-09 19:24:30 +04:00
|
|
|
});
|
2014-03-27 12:03:42 +04:00
|
|
|
}
|
|
|
|
|
2014-06-10 09:03:23 +04:00
|
|
|
add_task(function test_reportLinkAction() {
|
|
|
|
let link = 1;
|
|
|
|
let action = "click";
|
|
|
|
let tile = 2;
|
|
|
|
let score = 3;
|
|
|
|
let pin = 1;
|
|
|
|
let expectedQuery = "list=&link=1&action=click&tile=2&score=3&pin=1"
|
|
|
|
let expectedPath = kReportClickPath;
|
|
|
|
|
|
|
|
let deferred = Promise.defer();
|
|
|
|
server.registerPrefixHandler(kReportClickPath, (aRequest, aResponse) => {
|
|
|
|
do_check_eq(aRequest.path, expectedPath);
|
|
|
|
do_check_eq(aRequest.queryString, expectedQuery);
|
|
|
|
deferred.resolve();
|
|
|
|
});
|
|
|
|
|
|
|
|
DirectoryLinksProvider.reportLinkAction({directoryIndex: link, frecency: score}, action, tile, pin);
|
|
|
|
return deferred.promise;
|
|
|
|
});
|
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
add_task(function test_fetchAndCacheLinks_local() {
|
2014-05-28 00:59:33 +04:00
|
|
|
yield DirectoryLinksProvider.init();
|
2014-05-09 19:24:30 +04:00
|
|
|
yield cleanJsonFile();
|
|
|
|
// Trigger cache of data or chrome uri files in profD
|
|
|
|
yield DirectoryLinksProvider._fetchAndCacheLinks(kTestURL);
|
|
|
|
let data = yield readJsonFile();
|
|
|
|
isIdentical(data, kURLData);
|
|
|
|
});
|
|
|
|
|
|
|
|
add_task(function test_fetchAndCacheLinks_remote() {
|
2014-05-28 00:59:33 +04:00
|
|
|
yield DirectoryLinksProvider.init();
|
2014-05-09 19:24:30 +04:00
|
|
|
yield cleanJsonFile();
|
|
|
|
// this must trigger directory links json download and save it to cache file
|
|
|
|
yield DirectoryLinksProvider._fetchAndCacheLinks(kExampleURL);
|
|
|
|
let data = yield readJsonFile();
|
|
|
|
isIdentical(data, kHttpHandlerData[kExamplePath]);
|
|
|
|
});
|
|
|
|
|
|
|
|
add_task(function test_fetchAndCacheLinks_malformedURI() {
|
2014-05-28 00:59:33 +04:00
|
|
|
yield DirectoryLinksProvider.init();
|
2014-05-09 19:24:30 +04:00
|
|
|
yield cleanJsonFile();
|
|
|
|
let someJunk = "some junk";
|
|
|
|
try {
|
|
|
|
yield DirectoryLinksProvider._fetchAndCacheLinks(someJunk);
|
|
|
|
do_throw("Malformed URIs should fail")
|
|
|
|
} catch (e) {
|
|
|
|
do_check_eq(e, "Error fetching " + someJunk)
|
|
|
|
}
|
|
|
|
|
|
|
|
// File should be empty.
|
|
|
|
let data = yield readJsonFile();
|
|
|
|
isIdentical(data, "");
|
|
|
|
});
|
|
|
|
|
|
|
|
add_task(function test_fetchAndCacheLinks_unknownHost() {
|
2014-05-28 00:59:33 +04:00
|
|
|
yield DirectoryLinksProvider.init();
|
2014-05-09 19:24:30 +04:00
|
|
|
yield cleanJsonFile();
|
2014-06-06 22:02:55 +04:00
|
|
|
let nonExistentServer = "http://nosuchhost.localhost";
|
2014-05-09 19:24:30 +04:00
|
|
|
try {
|
|
|
|
yield DirectoryLinksProvider._fetchAndCacheLinks(nonExistentServer);
|
|
|
|
do_throw("BAD URIs should fail");
|
|
|
|
} catch (e) {
|
|
|
|
do_check_true(e.startsWith("Fetching " + nonExistentServer + " results in error code: "))
|
|
|
|
}
|
|
|
|
|
|
|
|
// File should be empty.
|
|
|
|
let data = yield readJsonFile();
|
|
|
|
isIdentical(data, "");
|
|
|
|
});
|
|
|
|
|
|
|
|
add_task(function test_fetchAndCacheLinks_non200Status() {
|
2014-05-28 00:59:33 +04:00
|
|
|
yield DirectoryLinksProvider.init();
|
2014-05-09 19:24:30 +04:00
|
|
|
yield cleanJsonFile();
|
|
|
|
yield DirectoryLinksProvider._fetchAndCacheLinks(kFailURL);
|
|
|
|
let data = yield readJsonFile();
|
|
|
|
isIdentical(data, {});
|
|
|
|
});
|
|
|
|
|
|
|
|
// To test onManyLinksChanged observer, trigger a fetch
|
2014-05-28 00:59:33 +04:00
|
|
|
add_task(function test_DirectoryLinksProvider__linkObservers() {
|
|
|
|
yield DirectoryLinksProvider.init();
|
2014-03-27 12:03:42 +04:00
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
let testObserver = new LinksChangeObserver();
|
2014-05-09 19:24:30 +04:00
|
|
|
DirectoryLinksProvider.addObserver(testObserver);
|
2014-05-28 00:59:33 +04:00
|
|
|
do_check_eq(DirectoryLinksProvider._observers.size, 1);
|
|
|
|
DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true);
|
2014-03-27 12:03:42 +04:00
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
yield testObserver.deferred.promise;
|
2014-05-09 19:24:30 +04:00
|
|
|
DirectoryLinksProvider._removeObservers();
|
2014-05-28 00:59:33 +04:00
|
|
|
do_check_eq(DirectoryLinksProvider._observers.size, 0);
|
2014-03-27 12:03:42 +04:00
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
yield promiseCleanDirectoryLinksProvider();
|
2014-03-27 12:03:42 +04:00
|
|
|
});
|
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
add_task(function test_linksURL_locale() {
|
2014-03-27 12:03:42 +04:00
|
|
|
let data = {
|
|
|
|
"en-US": [{url: "http://example.com", title: "US"}],
|
|
|
|
"zh-CN": [
|
|
|
|
{url: "http://example.net", title: "CN"},
|
|
|
|
{url:"http://example.net/2", title: "CN2"}
|
|
|
|
],
|
|
|
|
};
|
|
|
|
let dataURI = 'data:application/json,' + JSON.stringify(data);
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
|
2014-03-27 12:03:42 +04:00
|
|
|
|
|
|
|
let links;
|
|
|
|
let expected_data;
|
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
links = yield fetchData();
|
2014-03-27 12:03:42 +04:00
|
|
|
do_check_eq(links.length, 1);
|
2014-06-05 11:29:51 +04:00
|
|
|
expected_data = [{url: "http://example.com", title: "US", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1, directoryIndex: 0}];
|
2014-03-27 12:03:42 +04:00
|
|
|
isIdentical(links, expected_data);
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
yield promiseDirectoryDownloadOnPrefChange("general.useragent.locale", "zh-CN");
|
2014-03-27 12:03:42 +04:00
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
links = yield fetchData();
|
2014-03-27 12:03:42 +04:00
|
|
|
do_check_eq(links.length, 2)
|
|
|
|
expected_data = [
|
2014-06-05 11:29:51 +04:00
|
|
|
{url: "http://example.net", title: "CN", frecency: DIRECTORY_FRECENCY, lastVisitDate: 2, directoryIndex: 0},
|
|
|
|
{url: "http://example.net/2", title: "CN2", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1, directoryIndex: 1}
|
2014-03-27 12:03:42 +04:00
|
|
|
];
|
|
|
|
isIdentical(links, expected_data);
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
yield promiseCleanDirectoryLinksProvider();
|
2014-03-27 12:03:42 +04:00
|
|
|
});
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
add_task(function test_DirectoryLinksProvider__prefObserver_url() {
|
|
|
|
yield promiseSetupDirectoryLinksProvider({linksURL: kTestURL});
|
2014-03-27 12:03:42 +04:00
|
|
|
|
2014-05-09 19:24:30 +04:00
|
|
|
let links = yield fetchData();
|
2014-03-27 12:03:42 +04:00
|
|
|
do_check_eq(links.length, 1);
|
2014-06-05 11:29:51 +04:00
|
|
|
let expectedData = [{url: "http://example.com", title: "LocalSource", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1, directoryIndex: 0}];
|
2014-03-27 12:03:42 +04:00
|
|
|
isIdentical(links, expectedData);
|
|
|
|
|
|
|
|
// tests these 2 things:
|
2014-05-09 19:24:30 +04:00
|
|
|
// 1. _linksURL is properly set after the pref change
|
|
|
|
// 2. invalid source url is correctly handled
|
2014-06-06 22:02:55 +04:00
|
|
|
let exampleUrl = 'http://nosuchhost.localhost/bad';
|
2014-05-28 00:59:33 +04:00
|
|
|
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, exampleUrl);
|
2014-05-09 19:24:30 +04:00
|
|
|
do_check_eq(DirectoryLinksProvider._linksURL, exampleUrl);
|
2014-03-27 12:03:42 +04:00
|
|
|
|
2014-05-28 00:59:34 +04:00
|
|
|
// since the download fail, the directory file must remain the same
|
2014-05-09 19:24:30 +04:00
|
|
|
let newLinks = yield fetchData();
|
2014-05-28 00:59:34 +04:00
|
|
|
isIdentical(newLinks, expectedData);
|
|
|
|
|
|
|
|
// now remove the file, and re-download
|
|
|
|
yield cleanJsonFile();
|
|
|
|
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, exampleUrl + " ");
|
|
|
|
// we now should see empty links
|
|
|
|
newLinks = yield fetchData();
|
2014-03-27 12:03:42 +04:00
|
|
|
isIdentical(newLinks, []);
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
yield promiseCleanDirectoryLinksProvider();
|
2014-03-27 12:03:42 +04:00
|
|
|
});
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
add_task(function test_DirectoryLinksProvider_getLinks_noLocaleData() {
|
|
|
|
yield promiseSetupDirectoryLinksProvider({locale: 'zh-CN'});
|
2014-05-09 19:24:30 +04:00
|
|
|
let links = yield fetchData();
|
2014-03-27 12:03:42 +04:00
|
|
|
do_check_eq(links.length, 0);
|
2014-05-28 00:59:33 +04:00
|
|
|
yield promiseCleanDirectoryLinksProvider();
|
|
|
|
});
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
2014-06-02 20:14:08 +04:00
|
|
|
// test that directoryCount object reaches the backend server
|
|
|
|
expectedBodyObject.directoryCount = directoryCount;
|
|
|
|
// set kSourceUrlPref to kExampleURL, causing request to test http server
|
|
|
|
// server handler validates that expectedBodyObject has correct directoryCount
|
|
|
|
yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kExampleURL);
|
|
|
|
// reset expectedBodyObject to its original state
|
|
|
|
delete expectedBodyObject.directoryCount;
|
|
|
|
|
2014-05-28 00:59:33 +04:00
|
|
|
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();
|
2014-03-27 12:03:42 +04:00
|
|
|
});
|
2014-05-28 00:59:34 +04:00
|
|
|
|
|
|
|
add_task(function test_DirectoryLinksProvider_getLinksFromCorruptedFile() {
|
|
|
|
yield promiseSetupDirectoryLinksProvider();
|
|
|
|
|
|
|
|
// write bogus json to a file and attempt to fetch from it
|
|
|
|
let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.profileDir, DIRECTORY_LINKS_FILE);
|
|
|
|
yield OS.File.writeAtomic(directoryLinksFilePath, '{"en-US":');
|
|
|
|
let data = yield fetchData();
|
|
|
|
isIdentical(data, []);
|
|
|
|
|
|
|
|
yield promiseCleanDirectoryLinksProvider();
|
|
|
|
});
|