test_TopSitesFeed_frecencyDeduping.js (9487B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 ChromeUtils.defineESModuleGetters(this, { 7 sinon: "resource://testing-common/Sinon.sys.mjs", 8 TopSitesFeed: "resource://newtab/lib/TopSitesFeed.sys.mjs", 9 DEFAULT_TOP_SITES: "resource://newtab/lib/TopSitesFeed.sys.mjs", 10 }); 11 12 const PREF_SOV_ENABLED = "sov.enabled"; 13 const SHOW_SPONSORED_PREF = "showSponsoredTopSites"; 14 const ROWS_PREF = "topSitesRows"; 15 16 async function getTopSitesFeedForTest( 17 sandbox, 18 { frecent = [], contile = [] } = {} 19 ) { 20 let feed = new TopSitesFeed(); 21 22 feed.store = { 23 dispatch: sandbox.spy(), 24 getState() { 25 return this.state; 26 }, 27 state: { 28 Prefs: { 29 values: { 30 [PREF_SOV_ENABLED]: true, 31 [SHOW_SPONSORED_PREF]: true, 32 [ROWS_PREF]: 1, 33 }, 34 }, 35 TopSites: { 36 sov: { 37 ready: true, 38 positions: [ 39 { position: 1, assignedPartner: "amp" }, 40 { position: 2, assignedPartner: "frec-boost" }, 41 ], 42 }, 43 }, 44 }, 45 }; 46 47 feed.frecentCache = { 48 request() { 49 return this.cache; 50 }, 51 cache: frecent, 52 }; 53 feed.frecencyBoostProvider.frecentCache = feed.frecentCache; 54 55 feed._contile = { 56 sov: true, 57 sovEnabled: () => true, 58 sites: contile, 59 }; 60 61 const frecencyBoostedSponsors = new Map([ 62 [ 63 "domain1", 64 { 65 domain: "https://domain1.com", 66 faviconDataURI: "faviconDataURI1", 67 hostname: "domain1", 68 redirectURL: "https://redirectURL1.com", 69 title: "title1", 70 }, 71 ], 72 [ 73 "domain2", 74 { 75 domain: "https://domain2.com", 76 faviconDataURI: "faviconDataURI2", 77 hostname: "domain2", 78 redirectURL: "https://redirectURL2.com", 79 title: "title2", 80 }, 81 ], 82 ]); 83 84 sandbox 85 .stub(feed.frecencyBoostProvider, "_frecencyBoostedSponsors") 86 .value(frecencyBoostedSponsors); 87 88 // Stub random fallback to return null for testing deduping logic. 89 sandbox 90 .stub(feed.frecencyBoostProvider, "retrieveRandomFrecencyTile") 91 .returns(null); 92 93 // We need to refresh, because TopSitesFeed's 94 // DEFAULT_TOP_SITES acts like a singleton. 95 DEFAULT_TOP_SITES.length = 0; 96 feed._readContile(); 97 98 // Kick off an update so the cache is populated. 99 await feed.frecencyBoostProvider.update(); 100 101 return feed; 102 } 103 104 add_task(async function test_dedupeSponsorsAgainstNothing() { 105 let sandbox = sinon.createSandbox(); 106 { 107 info("TopSitesFeed.getLinksWithDefaults - Should return all defaults"); 108 const feed = await getTopSitesFeedForTest(sandbox, { 109 frecent: [ 110 { url: "https://default1.com", frecency: 1000 }, 111 { url: "https://default2.com", frecency: 1000 }, 112 { url: "https://default3.com", frecency: 1000 }, 113 { url: "https://default4.com", frecency: 1000 }, 114 { url: "https://default5.com", frecency: 1000 }, 115 { url: "https://default6.com", frecency: 1000 }, 116 { url: "https://default7.com", frecency: 1000 }, 117 { url: "https://default8.com", frecency: 1000 }, 118 ], 119 contile: [{ url: "https://contile1.com", name: "contile1" }], 120 }); 121 122 const withPinned = await feed.getLinksWithDefaults(); 123 Assert.equal(withPinned.length, 8); 124 Assert.equal(withPinned[1].hostname, "default1"); 125 126 sandbox.restore(); 127 } 128 { 129 info( 130 "TopSitesFeed.getLinksWithDefaults - " + 131 "Should return a frecency match in the second position" 132 ); 133 const feed = await getTopSitesFeedForTest(sandbox, { 134 frecent: [ 135 { url: "https://default1.com", frecency: 1000 }, 136 { url: "https://default2.com", frecency: 1000 }, 137 { url: "https://default3.com", frecency: 1000 }, 138 { url: "https://default4.com", frecency: 1000 }, 139 { url: "https://default5.com", frecency: 1000 }, 140 { url: "https://default6.com", frecency: 1000 }, 141 { url: "https://default7.com", frecency: 1000 }, 142 { url: "https://default8.com", frecency: 1000 }, 143 { url: "https://domain1.com", frecency: 1000 }, 144 ], 145 contile: [{ url: "https://contile1.com", name: "contile1" }], 146 }); 147 148 const withPinned = await feed.getLinksWithDefaults(); 149 Assert.equal(withPinned.length, 8); 150 Assert.equal(withPinned[1].hostname, "domain1"); 151 152 sandbox.restore(); 153 } 154 { 155 info( 156 "TopSitesFeed.getLinksWithDefaults - " + 157 "Should return a frecency match with path in the second position" 158 ); 159 const feed = await getTopSitesFeedForTest(sandbox, { 160 frecent: [ 161 { url: "https://default1.com", frecency: 1000 }, 162 { url: "https://default2.com", frecency: 1000 }, 163 { url: "https://default3.com", frecency: 1000 }, 164 { url: "https://default4.com", frecency: 1000 }, 165 { url: "https://default5.com", frecency: 1000 }, 166 { url: "https://default6.com", frecency: 1000 }, 167 { url: "https://default7.com", frecency: 1000 }, 168 { url: "https://default8.com", frecency: 1000 }, 169 { url: "https://domain1.com/path", frecency: 1000 }, 170 ], 171 contile: [{ url: "https://contile1.com", name: "contile1" }], 172 }); 173 174 const withPinned = await feed.getLinksWithDefaults(); 175 Assert.equal(withPinned.length, 8); 176 Assert.equal(withPinned[1].hostname, "domain1"); 177 178 sandbox.restore(); 179 } 180 }); 181 182 add_task(async function test_dedupeSponsorsAgainstTopsites() { 183 let sandbox = sinon.createSandbox(); 184 { 185 info( 186 "TopSitesFeed.getLinksWithDefaults - " + 187 "Should dedupe against matching topsite" 188 ); 189 const feed = await getTopSitesFeedForTest(sandbox, { 190 frecent: [ 191 { url: "https://default1.com", frecency: 1000 }, 192 { url: "https://default2.com", frecency: 1000 }, 193 { url: "https://default3.com", frecency: 1000 }, 194 { url: "https://default4.com", frecency: 1000 }, 195 { url: "https://default5.com", frecency: 1000 }, 196 { url: "https://domain1.com", frecency: 1000 }, 197 { url: "https://default6.com", frecency: 1000 }, 198 { url: "https://default7.com", frecency: 1000 }, 199 { url: "https://default8.com", frecency: 1000 }, 200 ], 201 contile: [{ url: "https://contile1.com", name: "contile1" }], 202 }); 203 204 const withPinned = await feed.getLinksWithDefaults(); 205 Assert.equal(withPinned.length, 8); 206 Assert.equal(withPinned[1].hostname, "default1"); 207 208 sandbox.restore(); 209 } 210 { 211 info( 212 "TopSitesFeed.getLinksWithDefaults - " + 213 "Should dedupe against matching topsite with path" 214 ); 215 const feed = await getTopSitesFeedForTest(sandbox, { 216 frecent: [ 217 { url: "https://default1.com", frecency: 1000 }, 218 { url: "https://default2.com", frecency: 1000 }, 219 { url: "https://default3.com", frecency: 1000 }, 220 { url: "https://default4.com", frecency: 1000 }, 221 { url: "https://default5.com", frecency: 1000 }, 222 { url: "https://domain1.com/page", frecency: 1000 }, 223 { url: "https://default6.com", frecency: 1000 }, 224 { url: "https://default7.com", frecency: 1000 }, 225 { url: "https://default8.com", frecency: 1000 }, 226 ], 227 contile: [{ url: "https://contile1.com", name: "contile1" }], 228 }); 229 230 const withPinned = await feed.getLinksWithDefaults(); 231 Assert.equal(withPinned.length, 8); 232 Assert.equal(withPinned[1].hostname, "default1"); 233 234 sandbox.restore(); 235 } 236 }); 237 238 add_task(async function test_dedupeSponsorsAgainstContile() { 239 let sandbox = sinon.createSandbox(); 240 { 241 info( 242 "TopSitesFeed.getLinksWithDefaults - " + 243 "Should dedupe against matching contile" 244 ); 245 const feed = await getTopSitesFeedForTest(sandbox, { 246 frecent: [ 247 { url: "https://default1.com", frecency: 1000 }, 248 { url: "https://default2.com", frecency: 1000 }, 249 { url: "https://default3.com", frecency: 1000 }, 250 { url: "https://default4.com", frecency: 1000 }, 251 { url: "https://default5.com", frecency: 1000 }, 252 { url: "https://default6.com", frecency: 1000 }, 253 { url: "https://default7.com", frecency: 1000 }, 254 { url: "https://default8.com", frecency: 1000 }, 255 { url: "https://domain1.com", frecency: 1000 }, 256 ], 257 contile: [{ url: "https://domain1.com", name: "contile1" }], 258 }); 259 260 const withPinned = await feed.getLinksWithDefaults(); 261 Assert.equal(withPinned.length, 8); 262 Assert.equal(withPinned[1].hostname, "default1"); 263 264 sandbox.restore(); 265 } 266 { 267 info( 268 "TopSitesFeed.getLinksWithDefaults - " + 269 "Should dedupe against matching contile label" 270 ); 271 const feed = await getTopSitesFeedForTest(sandbox, { 272 frecent: [ 273 { url: "https://default1.com", frecency: 1000 }, 274 { url: "https://default2.com", frecency: 1000 }, 275 { url: "https://default3.com", frecency: 1000 }, 276 { url: "https://default4.com", frecency: 1000 }, 277 { url: "https://default5.com", frecency: 1000 }, 278 { url: "https://default6.com", frecency: 1000 }, 279 { url: "https://default7.com", frecency: 1000 }, 280 { url: "https://default8.com", frecency: 1000 }, 281 { url: "https://domain1.com", frecency: 1000 }, 282 ], 283 contile: [{ url: "https://contile1.com", name: "title1" }], 284 }); 285 286 const withPinned = await feed.getLinksWithDefaults(); 287 Assert.equal(withPinned.length, 8); 288 Assert.equal(withPinned[1].hostname, "default1"); 289 290 sandbox.restore(); 291 } 292 });