Bug 1126182: Extract related tiles data from links json and store for later selection. r=adw, a=sylvestre
authorMarina Samuel <msamuel@mozilla.com>
Tue, 10 Mar 2015 17:08:30 -0400
changeset 258187 83bcf11d00ef
parent 258185 818e63fbfba2
child 258188 869ba4681d1b
push id4619
push useredilee@gmail.com
push date2015-04-02 05:50 +0000
treeherdermozilla-beta@daf8a9291a9b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw, sylvestre
bugs1126182
milestone38.0
Bug 1126182: Extract related tiles data from links json and store for later selection. r=adw, a=sylvestre
browser/modules/DirectoryLinksProvider.jsm
browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
--- a/browser/modules/DirectoryLinksProvider.jsm
+++ b/browser/modules/DirectoryLinksProvider.jsm
@@ -79,16 +79,21 @@ let DirectoryLinksProvider = {
   // download default interval is 24 hours in milliseconds
   _downloadIntervalMS: 86400000,
 
   /**
    * A mapping from eTLD+1 to an enhanced link objects
    */
   _enhancedLinks: new Map(),
 
+  /**
+   * A mapping from site to a list of related link objects
+   */
+  _relatedLinks: new Map(),
+
   get _observedPrefs() Object.freeze({
     enhanced: PREF_NEWTAB_ENHANCED,
     linksURL: PREF_DIRECTORY_SOURCE,
     matchOSLocale: PREF_MATCH_OS_LOCALE,
     prefSelectedLocale: PREF_SELECTED_LOCALE,
   }),
 
   get _linksURL() {
@@ -182,16 +187,24 @@ let DirectoryLinksProvider = {
 
   _removePrefsObserver: function DirectoryLinksProvider_removeObserver() {
     for (let pref in this._observedPrefs) {
       let prefName = this._observedPrefs[pref];
       Services.prefs.removeObserver(prefName, this);
     }
   },
 
+  _cacheRelatedLinks: function(link) {
+    for (let relatedSite of link.related) {
+      let relatedMap = this._relatedLinks.get(relatedSite) || new Map();
+      relatedMap.set(link.url, link);
+      this._relatedLinks.set(relatedSite, relatedMap);
+    }
+  },
+
   _fetchAndCacheLinks: function DirectoryLinksProvider_fetchAndCacheLinks(uri) {
     // Replace with the same display locale used for selecting links data
     uri = uri.replace("%LOCALE%", this.locale);
 
     let deferred = Promise.defer();
     let xmlHttp = new XMLHttpRequest();
 
     let self = this;
@@ -384,34 +397,43 @@ let DirectoryLinksProvider = {
   },
 
   /**
    * Gets the current set of directory links.
    * @param aCallback The function that the array of links is passed to.
    */
   getLinks: function DirectoryLinksProvider_getLinks(aCallback) {
     this._readDirectoryLinksFile().then(rawLinks => {
-      // Reset the cache of enhanced images for this new set of links
+      // Reset the cache of related tiles and enhanced images for this new set of links
       this._enhancedLinks.clear();
+      this._relatedLinks.clear();
 
-      return rawLinks.filter(link => {
+      let links = [];
+      rawLinks.filter(link => {
         // Make sure the link url is allowed and images too if they exist
         return this.isURLAllowed(link.url, ALLOWED_LINK_SCHEMES) &&
                this.isURLAllowed(link.imageURI, ALLOWED_IMAGE_SCHEMES) &&
                this.isURLAllowed(link.enhancedImageURI, ALLOWED_IMAGE_SCHEMES);
-      }).map((link, position) => {
+      }).forEach((link, position) => {
         // Stash the enhanced image for the site
         if (link.enhancedImageURI) {
           this._enhancedLinks.set(NewTabUtils.extractSite(link.url), link);
         }
+        link.lastVisitDate = rawLinks.length - position;
 
+        // We cache related tiles here but do not push any of them in the links list yet.
+        // The decision for which related tile to include will be made separately.
+        if ("related" == link.type) {
+          this._cacheRelatedLinks(link);
+          return;
+        }
         link.frecency = DIRECTORY_FRECENCY;
-        link.lastVisitDate = rawLinks.length - position;
-        return link;
+        links.push(link);
       });
+      return links;
     }).catch(ex => {
       Cu.reportError(ex);
       return [];
     }).then(aCallback);
   },
 
   init: function DirectoryLinksProvider_init() {
     this._setDefaultEnhanced();
--- a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
+++ b/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
@@ -170,16 +170,81 @@ function run_test() {
     DirectoryLinksProvider.reset();
     Services.prefs.clearUserPref(kLocalePref);
     Services.prefs.clearUserPref(kSourceUrlPref);
     Services.prefs.clearUserPref(kPingUrlPref);
     Services.prefs.clearUserPref(kNewtabEnhancedPref);
   });
 }
 
+add_task(function test_relatedLinksMap() {
+  let relatedTile1 = {
+    url: "http://turbotax.com",
+    type: "related",
+    lastVisitDate: 4,
+    related: [
+      "taxact.com",
+      "hrblock.com",
+      "1040.com",
+      "taxslayer.com"
+    ]
+  };
+  let relatedTile2 = {
+    url: "http://irs.gov",
+    type: "related",
+    lastVisitDate: 3,
+    related: [
+      "taxact.com",
+      "hrblock.com",
+      "freetaxusa.com",
+      "taxslayer.com"
+    ]
+  };
+  let relatedTile3 = {
+    url: "http://hrblock.com",
+    type: "related",
+    lastVisitDate: 2,
+    related: [
+      "taxact.com",
+      "freetaxusa.com",
+      "1040.com",
+      "taxslayer.com"
+    ]
+  };
+  let someOtherSite = {url: "http://someothersite.com", title: "Not_A_Related_Site"};
+  let data = {"en-US": [relatedTile1, relatedTile2, relatedTile3, someOtherSite]};
+  let dataURI = 'data:application/json,' + JSON.stringify(data);
+
+  yield promiseSetupDirectoryLinksProvider({linksURL: dataURI});
+  let links = yield fetchData();
+
+  // Ensure the related tiles were not considered directory tiles.
+  do_check_eq(links.length, 1);
+  let expected_data = [{url: "http://someothersite.com", title: "Not_A_Related_Site", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}];
+  isIdentical(links, expected_data);
+
+  // Check for correctly saved related tiles data.
+  expected_data = {
+    "taxact.com": [relatedTile1, relatedTile2, relatedTile3],
+    "hrblock.com": [relatedTile1, relatedTile2],
+    "1040.com": [relatedTile1, relatedTile3],
+    "taxslayer.com": [relatedTile1, relatedTile2, relatedTile3],
+    "freetaxusa.com": [relatedTile2, relatedTile3],
+  };
+
+  DirectoryLinksProvider._relatedLinks.forEach((relatedLinks, site) => {
+    let relatedLinksItr = relatedLinks.values();
+    for (let link of expected_data[site]) {
+      isIdentical(relatedLinksItr.next().value, link);
+    }
+  })
+
+  yield promiseCleanDirectoryLinksProvider();
+});
+
 add_task(function test_reportSitesAction() {
   yield DirectoryLinksProvider.init();
   let deferred, expectedPath, expectedPost;
   let done = false;
   server.registerPrefixHandler(kPingPath, (aRequest, aResponse) => {
     if (done) {
       return;
     }