test_search_telemetry_categorization_logic.js (9360B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 /** 5 * This test ensures we are correctly applying the SERP categorization logic to 6 * the domains that have been extracted from the SERP. 7 */ 8 9 "use strict"; 10 11 ChromeUtils.defineESModuleGetters(this, { 12 SERPCategorization: 13 "moz-src:///browser/components/search/SERPCategorization.sys.mjs", 14 SERPDomainToCategoriesMap: 15 "moz-src:///browser/components/search/SERPCategorization.sys.mjs", 16 CATEGORIZATION_SETTINGS: 17 "moz-src:///browser/components/search/SERPCategorization.sys.mjs", 18 }); 19 20 ChromeUtils.defineLazyGetter(this, "gCryptoHash", () => { 21 return Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash); 22 }); 23 24 function convertDomainsToHashes(domainsToCategories) { 25 let newObj = {}; 26 for (let [key, value] of Object.entries(domainsToCategories)) { 27 gCryptoHash.init(gCryptoHash.SHA256); 28 let bytes = new TextEncoder().encode(key); 29 gCryptoHash.update(bytes, key.length); 30 let hash = gCryptoHash.finish(true); 31 newObj[hash] = value; 32 } 33 return newObj; 34 } 35 36 const TEST_DOMAIN_TO_CATEGORIES_MAP_SIMPLE = convertDomainsToHashes({ 37 "test1.com": [2, 90], 38 "test2.com": [2, 95], 39 "test3.com": [2, 78, 4, 10], 40 "test4.com": [2, 56, 4, 24], 41 "test5.com": [2, 89], 42 "test6.com": [2, 43], 43 "test7.com": [2, 65], 44 "test8.com": [2, 67], 45 "test9.com": [2, 89], 46 "test10.com": [2, 99], 47 }); 48 49 const TEST_DOMAIN_TO_CATEGORIES_MAP_INCONCLUSIVE = convertDomainsToHashes({ 50 "test11.com": [0, 0], 51 "test12.com": [0, 0], 52 "test13.com": [0, 0], 53 "test14.com": [0, 0], 54 "test15.com": [0, 0], 55 "test16.com": [0, 0], 56 "test17.com": [0, 0], 57 "test18.com": [0, 0], 58 "test19.com": [0, 0], 59 "test20.com": [0, 0], 60 }); 61 62 const TEST_DOMAIN_TO_CATEGORIES_MAP_UNKNOWN_AND_INCONCLUSIVE = 63 convertDomainsToHashes({ 64 "test31.com": [0, 0], 65 "test32.com": [0, 0], 66 "test33.com": [0, 0], 67 "test34.com": [0, 0], 68 "test35.com": [0, 0], 69 }); 70 71 const TEST_DOMAIN_TO_CATEGORIES_MAP_ALL_TYPES = convertDomainsToHashes({ 72 "test51.com": [3, 90], 73 "test52.com": [3, 88], 74 "test53.com": [3, 90, 6, 2], 75 "test54.com": [3, 78, 6, 7], 76 "test55.com": [3, 97], 77 "test56.com": [0, 0], 78 "test57.com": [0, 0], 79 }); 80 81 const TEST_DOMAIN_TO_CATEGORIES_MAP_TIE = convertDomainsToHashes({ 82 "test41.com": [1, 50, 2, 50], 83 "test42.com": [1, 50, 2, 50], 84 "test43.com": [1, 50, 2, 50], 85 "test44.com": [1, 50, 2, 50], 86 "test45.com": [1, 50, 2, 50], 87 "test46.com": [3, 50, 4, 50], 88 "test47.com": [5, 50, 6, 50], 89 "test48.com": [7, 50, 8, 50], 90 "test49.com": [9, 50, 10, 50], 91 "test50.com": [11, 50, 12, 50], 92 }); 93 94 const TEST_DOMAIN_TO_CATEGORIES_MAP_RANK_PENALIZATION_1 = 95 convertDomainsToHashes({ 96 "test51.com": [1, 45], 97 "test52.com": [2, 45], 98 "test53.com": [3, 45], 99 "test54.com": [4, 45], 100 "test55.com": [5, 45], 101 "test56.com": [6, 45], 102 "test57.com": [7, 45], 103 "test58.com": [8, 45], 104 "test59.com": [9, 45], 105 "test60.com": [10, 45], 106 }); 107 108 const TEST_DOMAIN_TO_CATEGORIES_MAP_RANK_PENALIZATION_2 = 109 convertDomainsToHashes({ 110 "test61.com": [1, 35, 2, 4], 111 "test62.com": [1, 5, 2, 94], 112 }); 113 114 add_setup(async () => { 115 do_get_profile(); 116 Services.prefs.setBoolPref( 117 "browser.search.serpEventTelemetryCategorization.enabled", 118 true 119 ); 120 await SERPDomainToCategoriesMap.init(); 121 }); 122 123 add_task(async function test_categorization_simple() { 124 await SERPDomainToCategoriesMap.overrideMapForTests( 125 TEST_DOMAIN_TO_CATEGORIES_MAP_SIMPLE 126 ); 127 128 let domains = new Set([ 129 "test1.com", 130 "test2.com", 131 "test3.com", 132 "test4.com", 133 "test5.com", 134 "test6.com", 135 "test7.com", 136 "test8.com", 137 "test9.com", 138 "test10.com", 139 ]); 140 141 let resultsToReport = 142 await SERPCategorization.applyCategorizationLogic(domains); 143 144 Assert.deepEqual( 145 resultsToReport, 146 { 147 category: "2", 148 num_domains: "10", 149 num_inconclusive: "0", 150 num_unknown: "0", 151 }, 152 "Should report the correct values for categorizing the SERP." 153 ); 154 }); 155 156 add_task(async function test_categorization_inconclusive() { 157 await SERPDomainToCategoriesMap.overrideMapForTests( 158 TEST_DOMAIN_TO_CATEGORIES_MAP_INCONCLUSIVE 159 ); 160 161 let domains = new Set([ 162 "test11.com", 163 "test12.com", 164 "test13.com", 165 "test14.com", 166 "test15.com", 167 "test16.com", 168 "test17.com", 169 "test18.com", 170 "test19.com", 171 "test20.com", 172 ]); 173 174 let resultsToReport = 175 await SERPCategorization.applyCategorizationLogic(domains); 176 177 Assert.deepEqual( 178 resultsToReport, 179 { 180 category: CATEGORIZATION_SETTINGS.INCONCLUSIVE, 181 num_domains: "10", 182 num_inconclusive: "10", 183 num_unknown: "0", 184 }, 185 "Should report the correct values for categorizing the SERP." 186 ); 187 }); 188 189 add_task(async function test_categorization_unknown() { 190 // Reusing TEST_DOMAIN_TO_CATEGORIES_MAP_SIMPLE since none of this task's 191 // domains will be keys within it. 192 await SERPDomainToCategoriesMap.overrideMapForTests( 193 TEST_DOMAIN_TO_CATEGORIES_MAP_SIMPLE 194 ); 195 196 let domains = new Set([ 197 "test21.com", 198 "test22.com", 199 "test23.com", 200 "test24.com", 201 "test25.com", 202 "test26.com", 203 "test27.com", 204 "test28.com", 205 "test29.com", 206 "test30.com", 207 ]); 208 209 let resultsToReport = 210 await SERPCategorization.applyCategorizationLogic(domains); 211 212 Assert.deepEqual( 213 resultsToReport, 214 { 215 category: CATEGORIZATION_SETTINGS.INCONCLUSIVE, 216 num_domains: "10", 217 num_inconclusive: "0", 218 num_unknown: "10", 219 }, 220 "Should report the correct values for categorizing the SERP." 221 ); 222 }); 223 224 add_task(async function test_categorization_unknown_and_inconclusive() { 225 await SERPDomainToCategoriesMap.overrideMapForTests( 226 TEST_DOMAIN_TO_CATEGORIES_MAP_UNKNOWN_AND_INCONCLUSIVE 227 ); 228 229 let domains = new Set([ 230 "test31.com", 231 "test32.com", 232 "test33.com", 233 "test34.com", 234 "test35.com", 235 "test36.com", 236 "test37.com", 237 "test38.com", 238 "test39.com", 239 "test40.com", 240 ]); 241 242 let resultsToReport = 243 await SERPCategorization.applyCategorizationLogic(domains); 244 245 Assert.deepEqual( 246 resultsToReport, 247 { 248 category: CATEGORIZATION_SETTINGS.INCONCLUSIVE, 249 num_domains: "10", 250 num_inconclusive: "5", 251 num_unknown: "5", 252 }, 253 "Should report the correct values for categorizing the SERP." 254 ); 255 }); 256 257 // Tests a mixture of categorized, inconclusive and unknown domains. 258 add_task(async function test_categorization_all_types() { 259 await SERPDomainToCategoriesMap.overrideMapForTests( 260 TEST_DOMAIN_TO_CATEGORIES_MAP_ALL_TYPES 261 ); 262 263 // First 5 domains are categorized, 6th and 7th are inconclusive and the last 264 // 3 are unknown. 265 let domains = new Set([ 266 "test51.com", 267 "test52.com", 268 "test53.com", 269 "test54.com", 270 "test55.com", 271 "test56.com", 272 "test57.com", 273 "test58.com", 274 "test59.com", 275 "test60.com", 276 ]); 277 278 let resultsToReport = 279 await SERPCategorization.applyCategorizationLogic(domains); 280 281 Assert.deepEqual( 282 resultsToReport, 283 { 284 category: "3", 285 num_domains: "10", 286 num_inconclusive: "2", 287 num_unknown: "3", 288 }, 289 "Should report the correct values for categorizing the SERP." 290 ); 291 }); 292 293 add_task(async function test_categorization_tie() { 294 await SERPDomainToCategoriesMap.overrideMapForTests( 295 TEST_DOMAIN_TO_CATEGORIES_MAP_TIE 296 ); 297 298 let domains = new Set([ 299 "test41.com", 300 "test42.com", 301 "test43.com", 302 "test44.com", 303 "test45.com", 304 "test46.com", 305 "test47.com", 306 "test48.com", 307 "test49.com", 308 "test50.com", 309 ]); 310 311 let resultsToReport = 312 await SERPCategorization.applyCategorizationLogic(domains); 313 314 Assert.equal( 315 ["1", "2"].includes(resultsToReport.category), 316 true, 317 "Category should be one of the 2 categories with the max score." 318 ); 319 delete resultsToReport.category; 320 Assert.deepEqual( 321 resultsToReport, 322 { 323 num_domains: "10", 324 num_inconclusive: "0", 325 num_unknown: "0", 326 }, 327 "Should report the correct counts for the various domain types." 328 ); 329 }); 330 331 add_task(async function test_rank_penalization_equal_scores() { 332 await SERPDomainToCategoriesMap.overrideMapForTests( 333 TEST_DOMAIN_TO_CATEGORIES_MAP_RANK_PENALIZATION_1 334 ); 335 336 let domains = new Set([ 337 "test51.com", 338 "test52.com", 339 "test53.com", 340 "test54.com", 341 "test55.com", 342 "test56.com", 343 "test57.com", 344 "test58.com", 345 "test59.com", 346 "test60.com", 347 ]); 348 349 let resultsToReport = 350 await SERPCategorization.applyCategorizationLogic(domains); 351 352 Assert.deepEqual( 353 resultsToReport, 354 { 355 category: "1", 356 num_domains: "10", 357 num_inconclusive: "0", 358 num_unknown: "0", 359 }, 360 "Should report the correct values for categorizing the SERP." 361 ); 362 }); 363 364 add_task(async function test_rank_penalization_highest_score_lower_on_page() { 365 await SERPDomainToCategoriesMap.overrideMapForTests( 366 TEST_DOMAIN_TO_CATEGORIES_MAP_RANK_PENALIZATION_2 367 ); 368 369 let domains = new Set(["test61.com", "test62.com"]); 370 371 let resultsToReport = 372 await SERPCategorization.applyCategorizationLogic(domains); 373 374 Assert.deepEqual( 375 resultsToReport, 376 { 377 category: "2", 378 num_domains: "2", 379 num_inconclusive: "0", 380 num_unknown: "0", 381 }, 382 "Should report the correct values for categorizing the SERP." 383 ); 384 });