tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_TopSitesFeed_glean.js (59863B)


      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  ContileIntegration: "resource://newtab/lib/TopSitesFeed.sys.mjs",
      8  NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
      9  sinon: "resource://testing-common/Sinon.sys.mjs",
     10  SearchService: "resource://gre/modules/SearchService.sys.mjs",
     11  TopSitesFeed: "resource://newtab/lib/TopSitesFeed.sys.mjs",
     12 });
     13 
     14 const SHOW_SPONSORED_PREF = "showSponsoredTopSites";
     15 const TOP_SITES_BLOCKED_SPONSORS_PREF = "browser.topsites.blockedSponsors";
     16 const CONTILE_CACHE_VALID_FOR_PREF = "browser.topsites.contile.cacheValidFor";
     17 const CONTILE_CACHE_LAST_FETCH_PREF = "browser.topsites.contile.lastFetch";
     18 const NIMBUS_VARIABLE_MAX_SPONSORED = "topSitesMaxSponsored";
     19 const NIMBUS_VARIABLE_CONTILE_POSITIONS = "contileTopsitesPositions";
     20 const NIMBUS_VARIABLE_CONTILE_ENABLED = "topSitesContileEnabled";
     21 const NIMBUS_VARIABLE_CONTILE_MAX_NUM_SPONSORED = "topSitesContileMaxSponsored";
     22 
     23 let contileTile1 = {
     24  id: 74357,
     25  name: "Brand1",
     26  url: "https://www.brand1.com",
     27  click_url: "https://clickurl.com",
     28  image_url: "https://contile-images.jpg",
     29  image_size: 200,
     30  impression_url: "https://impression_url.com",
     31 };
     32 let contileTile2 = {
     33  id: 74925,
     34  name: "Brand2",
     35  url: "https://www.brand2.com",
     36  click_url: "https://click_url.com",
     37  image_url: "https://contile-images.jpg",
     38  image_size: 200,
     39  impression_url: "https://impression_url.com",
     40 };
     41 let contileTile3 = {
     42  id: 75001,
     43  name: "Brand3",
     44  url: "https://www.brand3.com",
     45  click_url: "https://click_url.com",
     46  image_url: "https://contile-images.jpg",
     47  image_size: 200,
     48  impression_url: "https://impression_url.com",
     49 };
     50 let contileTile4 = {
     51  id: 75899,
     52  name: "Brand4",
     53  url: "https://www.brand4.com",
     54  click_url: "https://click_url.com",
     55  image_url: "https://contile-images.jpg",
     56  image_size: 200,
     57  impression_url: "https://impression_url.com",
     58 };
     59 let mozSalesTile = [
     60  {
     61    label: "MozSales Title",
     62    title: "MozSales Title",
     63    url: "https://mozsale.net",
     64    sponsored_position: 1,
     65    partner: "moz-sales",
     66  },
     67 ];
     68 
     69 function getTopSitesFeedForTest(sandbox) {
     70  sandbox.stub(ContileIntegration.prototype, "PersistentCache").returns({
     71    set: sandbox.stub(),
     72    get: sandbox.stub(),
     73  });
     74 
     75  let feed = new TopSitesFeed();
     76  const storage = {
     77    init: sandbox.stub().resolves(),
     78    get: sandbox.stub().resolves(),
     79    set: sandbox.stub().resolves(),
     80  };
     81 
     82  feed._storage = storage;
     83  feed.store = {
     84    dispatch: sinon.spy(),
     85    getState() {
     86      return this.state;
     87    },
     88    state: {
     89      Prefs: { values: { topSitesRows: 2 } },
     90      TopSites: { rows: Array(12).fill("site") },
     91    },
     92    dbStorage: { getDbTable: sandbox.stub().returns(storage) },
     93  };
     94 
     95  return feed;
     96 }
     97 
     98 function prepFeed(feed, sandbox) {
     99  feed.store.state.Prefs.values[SHOW_SPONSORED_PREF] = true;
    100  let fetchStub = sandbox.stub(feed, "fetch");
    101  return { feed, fetchStub };
    102 }
    103 
    104 function setNimbusVariablesForNumTiles(nimbusPocketStub, numTiles) {
    105  nimbusPocketStub.withArgs(NIMBUS_VARIABLE_MAX_SPONSORED).returns(numTiles);
    106  nimbusPocketStub
    107    .withArgs(NIMBUS_VARIABLE_CONTILE_MAX_NUM_SPONSORED)
    108    .returns(numTiles);
    109  // when setting num tiles to > 2 need to set the positions or the > 2 has no effect.
    110  // can be defaulted to undefined
    111  let positionsArray = Array.from(
    112    { length: numTiles },
    113    (value, index) => index
    114  );
    115  nimbusPocketStub
    116    .withArgs(NIMBUS_VARIABLE_CONTILE_POSITIONS)
    117    .returns(positionsArray.toString());
    118 }
    119 
    120 add_setup(async () => {
    121  do_get_profile();
    122  Services.fog.initializeFOG();
    123 
    124  let sandbox = sinon.createSandbox();
    125  sandbox.stub(SearchService.prototype, "init").resolves();
    126 
    127  const nimbusStub = sandbox.stub(NimbusFeatures.newtab, "getVariable");
    128  nimbusStub.withArgs(NIMBUS_VARIABLE_CONTILE_ENABLED).returns(true);
    129 
    130  sandbox.spy(Glean.topsites.sponsoredTilesConfigured, "set");
    131  sandbox.spy(Glean.topsites.sponsoredTilesReceived, "set");
    132 
    133  // Temporarily setting isInAutomation to false.
    134  // If Cu.isInAutomation is true then the check for Cu.isInAutomation in
    135  // ContileIntegration._readDefaults passes, bypassing Contile, resulting in
    136  // not being able use stubbed values.
    137  if (Cu.isInAutomation) {
    138    Services.prefs.setBoolPref(
    139      "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer",
    140      false
    141    );
    142 
    143    if (Cu.isInAutomation) {
    144      // This condition is unexpected, because it is enforced at:
    145      // https://searchfox.org/mozilla-central/rev/ea65de7c/js/xpconnect/src/xpcpublic.h#753-759
    146      throw new Error("Failed to set isInAutomation to false");
    147    }
    148  }
    149  registerCleanupFunction(() => {
    150    if (!Cu.isInAutomation) {
    151      Services.prefs.setBoolPref(
    152        "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer",
    153        true
    154      );
    155 
    156      if (!Cu.isInAutomation) {
    157        // This condition is unexpected, because it is enforced at:
    158        // https://searchfox.org/mozilla-central/rev/ea65de7c/js/xpconnect/src/xpcpublic.h#753-759
    159        throw new Error("Failed to set isInAutomation to true");
    160      }
    161    }
    162 
    163    sandbox.restore();
    164  });
    165 });
    166 
    167 add_task(async function test_set_contile_tile_to_oversold() {
    168  let sandbox = sinon.createSandbox();
    169  let feed = getTopSitesFeedForTest(sandbox);
    170 
    171  feed._telemetryUtility.setSponsoredTilesConfigured();
    172  feed._telemetryUtility.setTiles([
    173    contileTile1,
    174    contileTile2,
    175    contileTile3,
    176    contileTile4,
    177  ]);
    178 
    179  let mergedTiles = [
    180    {
    181      url: "https://www.brand1.com",
    182      label: "brand1",
    183      sponsored_position: 1,
    184      partner: "amp",
    185    },
    186    {
    187      url: "https://www.brand2.com",
    188      label: "brand2",
    189      sponsored_position: 2,
    190      partner: "amp",
    191    },
    192    {
    193      url: "https://www.brand3.com",
    194      label: "brand3",
    195      sponsored_position: 3,
    196      partner: "amp",
    197    },
    198  ];
    199 
    200  feed._telemetryUtility.determineFilteredTilesAndSetToOversold(mergedTiles);
    201  feed._telemetryUtility.finalizeNewtabPingFields(mergedTiles);
    202 
    203  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
    204 
    205  let expectedResult = {
    206    sponsoredTilesReceived: [
    207      {
    208        advertiser: "brand1",
    209        provider: "amp",
    210        display_position: 1,
    211        display_fail_reason: null,
    212      },
    213      {
    214        advertiser: "brand2",
    215        provider: "amp",
    216        display_position: 2,
    217        display_fail_reason: null,
    218      },
    219      {
    220        advertiser: "brand3",
    221        provider: "amp",
    222        display_position: 3,
    223        display_fail_reason: null,
    224      },
    225      {
    226        advertiser: "brand4",
    227        provider: "amp",
    228        display_position: null,
    229        display_fail_reason: "oversold",
    230      },
    231    ],
    232  };
    233  Assert.equal(
    234    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    235    JSON.stringify(expectedResult)
    236  );
    237  sandbox.restore();
    238 });
    239 
    240 add_task(async function test_set_moz_sale_tile_to_oversold() {
    241  let sandbox = sinon.createSandbox();
    242  info(
    243    "determineFilteredTilesAndSetToOversold should set moz-sale tile to oversold when_contile tiles are displayed"
    244  );
    245  let feed = getTopSitesFeedForTest(sandbox);
    246 
    247  feed._telemetryUtility.setSponsoredTilesConfigured();
    248  feed._telemetryUtility.setTiles([contileTile1, contileTile2]);
    249  feed._telemetryUtility.setTiles(mozSalesTile);
    250 
    251  let mergedTiles = [
    252    {
    253      url: "https://www.brand1.com",
    254      label: "brand1",
    255      sponsored_position: 1,
    256      partner: "amp",
    257    },
    258    {
    259      url: "https://www.brand2.com",
    260      label: "brand2",
    261      sponsored_position: 2,
    262      partner: "amp",
    263    },
    264  ];
    265 
    266  feed._telemetryUtility.determineFilteredTilesAndSetToOversold(mergedTiles);
    267  feed._telemetryUtility.finalizeNewtabPingFields(mergedTiles);
    268 
    269  let expectedResult = {
    270    sponsoredTilesReceived: [
    271      {
    272        advertiser: "brand1",
    273        provider: "amp",
    274        display_position: 1,
    275        display_fail_reason: null,
    276      },
    277      {
    278        advertiser: "brand2",
    279        provider: "amp",
    280        display_position: 2,
    281        display_fail_reason: null,
    282      },
    283      {
    284        advertiser: "mozsales title",
    285        provider: "moz-sales",
    286        display_position: null,
    287        display_fail_reason: "oversold",
    288      },
    289    ],
    290  };
    291  Assert.equal(
    292    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    293    JSON.stringify(expectedResult)
    294  );
    295  sandbox.restore();
    296 });
    297 
    298 add_task(async function test_set_contile_tile_to_oversold() {
    299  let sandbox = sinon.createSandbox();
    300  info(
    301    "determineFilteredTilesAndSetToOversold should set contile tile to oversold when moz-sale tile is displayed"
    302  );
    303  let feed = getTopSitesFeedForTest(sandbox);
    304 
    305  feed._telemetryUtility.setSponsoredTilesConfigured();
    306  feed._telemetryUtility.setTiles([contileTile1, contileTile2]);
    307  feed._telemetryUtility.setTiles(mozSalesTile);
    308  let mergedTiles = [
    309    {
    310      url: "https://www.brand1.com",
    311      label: "brand1",
    312      sponsored_position: 1,
    313      partner: "amp",
    314    },
    315    {
    316      label: "MozSales Title",
    317      title: "MozSales Title",
    318      url: "https://mozsale.net",
    319      sponsored_position: 2,
    320      partner: "moz-sales",
    321    },
    322  ];
    323 
    324  feed._telemetryUtility.determineFilteredTilesAndSetToOversold(mergedTiles);
    325  feed._telemetryUtility.finalizeNewtabPingFields(mergedTiles);
    326 
    327  let expectedResult = {
    328    sponsoredTilesReceived: [
    329      {
    330        advertiser: "brand1",
    331        provider: "amp",
    332        display_position: 1,
    333        display_fail_reason: null,
    334      },
    335      {
    336        advertiser: "brand2",
    337        provider: "amp",
    338        display_position: null,
    339        display_fail_reason: "oversold",
    340      },
    341      {
    342        advertiser: "mozsales title",
    343        provider: "moz-sales",
    344        display_position: 2,
    345        display_fail_reason: null,
    346      },
    347    ],
    348  };
    349  Assert.equal(
    350    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    351    JSON.stringify(expectedResult)
    352  );
    353  sandbox.restore();
    354 });
    355 
    356 add_task(async function test_set_contile_tiles_to_dismissed() {
    357  let sandbox = sinon.createSandbox();
    358  let feed = getTopSitesFeedForTest(sandbox);
    359 
    360  feed._telemetryUtility.setSponsoredTilesConfigured();
    361  feed._telemetryUtility.setTiles([contileTile1, contileTile2, contileTile3]);
    362 
    363  let mergedTiles = [
    364    {
    365      url: "https://www.brand1.com",
    366      label: "brand1",
    367      sponsored_position: 1,
    368      partner: "amp",
    369    },
    370    {
    371      url: "https://www.brand2.com",
    372      label: "brand2",
    373      sponsored_position: 2,
    374      partner: "amp",
    375    },
    376  ];
    377 
    378  feed._telemetryUtility.determineFilteredTilesAndSetToDismissed(mergedTiles);
    379  feed._telemetryUtility.finalizeNewtabPingFields(mergedTiles);
    380 
    381  let expectedResult = {
    382    sponsoredTilesReceived: [
    383      {
    384        advertiser: "brand1",
    385        provider: "amp",
    386        display_position: 1,
    387        display_fail_reason: null,
    388      },
    389      {
    390        advertiser: "brand2",
    391        provider: "amp",
    392        display_position: 2,
    393        display_fail_reason: null,
    394      },
    395      {
    396        advertiser: "brand3",
    397        provider: "amp",
    398        display_position: null,
    399        display_fail_reason: "dismissed",
    400      },
    401    ],
    402  };
    403  Assert.equal(
    404    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    405    JSON.stringify(expectedResult)
    406  );
    407  sandbox.restore();
    408 });
    409 
    410 add_task(async function test_set_all_contile_tiles_to_dismissed() {
    411  let sandbox = sinon.createSandbox();
    412  let feed = getTopSitesFeedForTest(sandbox);
    413 
    414  feed._telemetryUtility.setSponsoredTilesConfigured();
    415  feed._telemetryUtility.setTiles([contileTile1, contileTile2, contileTile3]);
    416 
    417  let mergedTiles = [];
    418 
    419  feed._telemetryUtility.determineFilteredTilesAndSetToDismissed(mergedTiles);
    420  feed._telemetryUtility.finalizeNewtabPingFields(mergedTiles);
    421 
    422  let expectedResult = {
    423    sponsoredTilesReceived: [
    424      {
    425        advertiser: "brand1",
    426        provider: "amp",
    427        display_position: null,
    428        display_fail_reason: "dismissed",
    429      },
    430      {
    431        advertiser: "brand2",
    432        provider: "amp",
    433        display_position: null,
    434        display_fail_reason: "dismissed",
    435      },
    436      {
    437        advertiser: "brand3",
    438        provider: "amp",
    439        display_position: null,
    440        display_fail_reason: "dismissed",
    441      },
    442    ],
    443  };
    444  Assert.equal(
    445    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    446    JSON.stringify(expectedResult)
    447  );
    448  sandbox.restore();
    449 });
    450 
    451 add_task(async function test_set_moz_sales_tiles_to_dismissed() {
    452  let sandbox = sinon.createSandbox();
    453  let feed = getTopSitesFeedForTest(sandbox);
    454 
    455  feed._telemetryUtility.setSponsoredTilesConfigured();
    456  feed._telemetryUtility.setTiles([contileTile1, contileTile2]);
    457  feed._telemetryUtility.setTiles(mozSalesTile);
    458  let mergedTiles = [
    459    {
    460      url: "https://www.brand1.com",
    461      label: "brand1",
    462      sponsored_position: 1,
    463      partner: "amp",
    464    },
    465    {
    466      url: "https://www.brand2.com",
    467      label: "brand2",
    468      sponsored_position: 2,
    469      partner: "amp",
    470    },
    471  ];
    472 
    473  feed._telemetryUtility.determineFilteredTilesAndSetToDismissed(mergedTiles);
    474  feed._telemetryUtility.finalizeNewtabPingFields(mergedTiles);
    475 
    476  let expectedResult = {
    477    sponsoredTilesReceived: [
    478      {
    479        advertiser: "brand1",
    480        provider: "amp",
    481        display_position: 1,
    482        display_fail_reason: null,
    483      },
    484      {
    485        advertiser: "brand2",
    486        provider: "amp",
    487        display_position: 2,
    488        display_fail_reason: null,
    489      },
    490      {
    491        advertiser: "mozsales title",
    492        provider: "moz-sales",
    493        display_position: null,
    494        display_fail_reason: "dismissed",
    495      },
    496    ],
    497  };
    498  Assert.equal(
    499    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    500    JSON.stringify(expectedResult)
    501  );
    502  sandbox.restore();
    503 });
    504 
    505 add_task(async function test_set_tiles_to_dismissed_then_updated() {
    506  let sandbox = sinon.createSandbox();
    507  let feed = getTopSitesFeedForTest(sandbox);
    508  feed._telemetryUtility.setSponsoredTilesConfigured();
    509 
    510  // Step 1:  Set initial tiles
    511  feed._telemetryUtility.setTiles([
    512    contileTile1,
    513    contileTile2,
    514    contileTile3,
    515    contileTile4,
    516  ]);
    517 
    518  // Step 2:  Set all tiles to dismissed
    519  feed._telemetryUtility.determineFilteredTilesAndSetToDismissed([]);
    520 
    521  let updatedTiles = [
    522    {
    523      url: "https://www.brand1.com",
    524      label: "brand1",
    525      sponsored_position: 1,
    526      partner: "amp",
    527    },
    528    {
    529      url: "https://www.brand2.com",
    530      label: "brand2",
    531      sponsored_position: 2,
    532      partner: "amp",
    533    },
    534    {
    535      url: "https://www.brand3.com",
    536      label: "brand3",
    537      sponsored_position: 3,
    538      partner: "amp",
    539    },
    540  ];
    541 
    542  // Step 3:  Finalize with the updated list of tiles.
    543  feed._telemetryUtility.finalizeNewtabPingFields(updatedTiles);
    544 
    545  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
    546 
    547  let expectedResult = {
    548    sponsoredTilesReceived: [
    549      {
    550        advertiser: "brand1",
    551        provider: "amp",
    552        display_position: null,
    553        display_fail_reason: "dismissed",
    554      },
    555      {
    556        advertiser: "brand2",
    557        provider: "amp",
    558        display_position: null,
    559        display_fail_reason: "dismissed",
    560      },
    561      {
    562        advertiser: "brand3",
    563        provider: "amp",
    564        display_position: null,
    565        display_fail_reason: "dismissed",
    566      },
    567      {
    568        advertiser: "brand4",
    569        provider: "amp",
    570        display_position: null,
    571        display_fail_reason: "dismissed",
    572      },
    573    ],
    574  };
    575  Assert.equal(
    576    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    577    JSON.stringify(expectedResult)
    578  );
    579  sandbox.restore();
    580 });
    581 
    582 add_task(async function test_set_tile_positions_after_updated_list() {
    583  let sandbox = sinon.createSandbox();
    584  let feed = getTopSitesFeedForTest(sandbox);
    585  feed._telemetryUtility.setSponsoredTilesConfigured();
    586 
    587  // Step 1:  Set initial tiles
    588  feed._telemetryUtility.setTiles([
    589    contileTile1,
    590    contileTile2,
    591    contileTile3,
    592    contileTile4,
    593  ]);
    594 
    595  // Step 2:  Set 1 tile to oversold (brand3)
    596  let mergedTiles = [
    597    {
    598      url: "https://www.brand1.com",
    599      label: "brand1",
    600      sponsored_position: 1,
    601      partner: "amp",
    602    },
    603    {
    604      url: "https://www.brand2.com",
    605      label: "brand2",
    606      sponsored_position: 2,
    607      partner: "amp",
    608    },
    609    {
    610      url: "https://www.brand3.com",
    611      label: "brand3",
    612      sponsored_position: 3,
    613      partner: "amp",
    614    },
    615  ];
    616  feed._telemetryUtility.determineFilteredTilesAndSetToOversold(mergedTiles);
    617 
    618  // Step 3:  Finalize with the updated list of tiles.
    619  let updatedTiles = [
    620    {
    621      url: "https://www.replacement.com",
    622      label: "replacement",
    623      sponsored_position: 1,
    624      partner: "amp",
    625    },
    626    {
    627      url: "https://www.brand2.com",
    628      label: "brand2",
    629      sponsored_position: 2,
    630      partner: "amp",
    631    },
    632    {
    633      url: "https://www.brand3.com",
    634      label: "brand3",
    635      sponsored_position: 3,
    636      partner: "amp",
    637    },
    638  ];
    639  feed._telemetryUtility.finalizeNewtabPingFields(updatedTiles);
    640 
    641  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
    642 
    643  let expectedResult = {
    644    sponsoredTilesReceived: [
    645      {
    646        advertiser: "brand1",
    647        provider: "amp",
    648        display_position: 1,
    649        display_fail_reason: null,
    650      },
    651      {
    652        advertiser: "brand2",
    653        provider: "amp",
    654        display_position: 2,
    655        display_fail_reason: null,
    656      },
    657      {
    658        advertiser: "brand3",
    659        provider: "amp",
    660        display_position: 3,
    661        display_fail_reason: null,
    662      },
    663      {
    664        advertiser: "brand4",
    665        provider: "amp",
    666        display_position: null,
    667        display_fail_reason: "oversold",
    668      },
    669    ],
    670  };
    671  Assert.equal(
    672    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    673    JSON.stringify(expectedResult)
    674  );
    675  sandbox.restore();
    676 });
    677 
    678 add_task(async function test_set_tile_positions_after_updated_list_all_tiles() {
    679  let sandbox = sinon.createSandbox();
    680  let feed = getTopSitesFeedForTest(sandbox);
    681  feed._telemetryUtility.setSponsoredTilesConfigured();
    682 
    683  // Step 1:  Set initial tiles
    684  feed._telemetryUtility.setTiles([
    685    contileTile1,
    686    contileTile2,
    687    contileTile3,
    688    contileTile4,
    689  ]);
    690 
    691  // Step 2:  Set 1 tile to oversold (brand3)
    692  let mergedTiles = [
    693    {
    694      url: "https://www.brand1.com",
    695      label: "brand1",
    696      sponsored_position: 1,
    697      partner: "amp",
    698    },
    699    {
    700      url: "https://www.brand2.com",
    701      label: "brand2",
    702      sponsored_position: 2,
    703      partner: "amp",
    704    },
    705    {
    706      url: "https://www.brand3.com",
    707      label: "brand3",
    708      sponsored_position: 3,
    709      partner: "amp",
    710    },
    711  ];
    712  feed._telemetryUtility.determineFilteredTilesAndSetToOversold(mergedTiles);
    713 
    714  // Step 3:  Finalize with the updated list of tiles.
    715  let updatedTiles = [
    716    {
    717      url: "https://www.replacement.com",
    718      label: "replacement",
    719      sponsored_position: 1,
    720      partner: "amp",
    721    },
    722    {
    723      url: "https://www.replacement2.com",
    724      label: "replacement2",
    725      sponsored_position: 2,
    726      partner: "amp",
    727    },
    728    {
    729      url: "https://www.replacement3.com",
    730      label: "replacement3",
    731      sponsored_position: 3,
    732      partner: "amp",
    733    },
    734  ];
    735  feed._telemetryUtility.finalizeNewtabPingFields(updatedTiles);
    736 
    737  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
    738 
    739  let expectedResult = {
    740    sponsoredTilesReceived: [
    741      {
    742        advertiser: "brand1",
    743        provider: "amp",
    744        display_position: 1,
    745        display_fail_reason: null,
    746      },
    747      {
    748        advertiser: "brand2",
    749        provider: "amp",
    750        display_position: 2,
    751        display_fail_reason: null,
    752      },
    753      {
    754        advertiser: "brand3",
    755        provider: "amp",
    756        display_position: 3,
    757        display_fail_reason: null,
    758      },
    759      {
    760        advertiser: "brand4",
    761        provider: "amp",
    762        display_position: null,
    763        display_fail_reason: "oversold",
    764      },
    765    ],
    766  };
    767  Assert.equal(
    768    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    769    JSON.stringify(expectedResult)
    770  );
    771  sandbox.restore();
    772 });
    773 
    774 add_task(
    775  async function test_set_tile_positions_after_no_refresh_no_tiles_changed() {
    776    let sandbox = sinon.createSandbox();
    777    let feed = getTopSitesFeedForTest(sandbox);
    778    feed._telemetryUtility.setSponsoredTilesConfigured();
    779 
    780    // Step 1:  Set initial tiles
    781    feed._telemetryUtility.setTiles([
    782      contileTile1,
    783      contileTile2,
    784      contileTile3,
    785      contileTile4,
    786    ]);
    787 
    788    // Step 2:  Set 1 tile to oversold (brand3)
    789    let mergedTiles = [
    790      {
    791        url: "https://www.brand1.com",
    792        label: "brand1",
    793        sponsored_position: 1,
    794        partner: "amp",
    795      },
    796      {
    797        url: "https://www.brand2.com",
    798        label: "brand2",
    799        sponsored_position: 2,
    800        partner: "amp",
    801      },
    802      {
    803        url: "https://www.brand3.com",
    804        label: "brand3",
    805        sponsored_position: 3,
    806        partner: "amp",
    807      },
    808    ];
    809    feed._telemetryUtility.determineFilteredTilesAndSetToOversold(mergedTiles);
    810 
    811    // Step 3:  Finalize with the updated list of tiles.
    812    let updatedTiles = [
    813      {
    814        url: "https://www.brand1.com",
    815        label: "brand1",
    816        sponsored_position: 1,
    817        partner: "amp",
    818      },
    819      {
    820        url: "https://www.brand2.com",
    821        label: "brand2",
    822        sponsored_position: 2,
    823        partner: "amp",
    824      },
    825      {
    826        url: "https://www.brand3.com",
    827        label: "brand3",
    828        sponsored_position: 3,
    829        partner: "amp",
    830      },
    831    ];
    832    feed._telemetryUtility.finalizeNewtabPingFields(updatedTiles);
    833 
    834    Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
    835 
    836    let expectedResult = {
    837      sponsoredTilesReceived: [
    838        {
    839          advertiser: "brand1",
    840          provider: "amp",
    841          display_position: 1,
    842          display_fail_reason: null,
    843        },
    844        {
    845          advertiser: "brand2",
    846          provider: "amp",
    847          display_position: 2,
    848          display_fail_reason: null,
    849        },
    850        {
    851          advertiser: "brand3",
    852          provider: "amp",
    853          display_position: 3,
    854          display_fail_reason: null,
    855        },
    856        {
    857          advertiser: "brand4",
    858          provider: "amp",
    859          display_position: null,
    860          display_fail_reason: "oversold",
    861        },
    862      ],
    863    };
    864    Assert.equal(
    865      Glean.topsites.sponsoredTilesReceived.testGetValue(),
    866      JSON.stringify(expectedResult)
    867    );
    868    sandbox.restore();
    869  }
    870 );
    871 
    872 add_task(async function test_set_contile_tile_to_unresolved() {
    873  let sandbox = sinon.createSandbox();
    874  let feed = getTopSitesFeedForTest(sandbox);
    875 
    876  // Create the error state, need to bypass existing checks.
    877  feed._telemetryUtility.allSponsoredTiles = {
    878    ampbrand1: {
    879      advertiser: "brand1",
    880      provider: "amp",
    881      display_position: 1,
    882      display_fail_reason: "oversold",
    883    },
    884    ampbrand2: {
    885      advertiser: "brand2",
    886      provider: "amp",
    887      display_position: null,
    888      display_fail_reason: null,
    889    },
    890  };
    891 
    892  feed._telemetryUtility._detectErrorConditionAndSetUnresolved();
    893 
    894  let result = JSON.stringify({
    895    sponsoredTilesReceived: Object.values(
    896      feed._telemetryUtility.allSponsoredTiles
    897    ),
    898  });
    899 
    900  let expectedResult = {
    901    sponsoredTilesReceived: [
    902      {
    903        advertiser: "brand1",
    904        provider: "amp",
    905        display_position: null,
    906        display_fail_reason: "unresolved",
    907      },
    908      {
    909        advertiser: "brand2",
    910        provider: "amp",
    911        display_position: null,
    912        display_fail_reason: "unresolved",
    913      },
    914    ],
    915  };
    916  Assert.equal(result, JSON.stringify(expectedResult));
    917  sandbox.restore();
    918 });
    919 
    920 add_task(async function test_set_position_to_value_gt_3() {
    921  let sandbox = sinon.createSandbox();
    922  info("Test setTilePositions uses sponsored_position value, not array index.");
    923  let feed = getTopSitesFeedForTest(sandbox);
    924 
    925  feed._telemetryUtility.setSponsoredTilesConfigured();
    926  feed._telemetryUtility.setTiles([contileTile1, contileTile2, contileTile3]);
    927 
    928  let filteredContileTiles = [
    929    {
    930      url: "https://www.brand1.com",
    931      label: "brand1",
    932      sponsored_position: 1,
    933      partner: "amp",
    934    },
    935    {
    936      url: "https://www.brand2.com",
    937      label: "brand2",
    938      sponsored_position: 2,
    939      partner: "amp",
    940    },
    941    {
    942      url: "https://www.brand3.com",
    943      label: "brand3",
    944      sponsored_position: 6,
    945      partner: "amp",
    946    },
    947  ];
    948 
    949  feed._telemetryUtility.determineFilteredTilesAndSetToOversold(
    950    filteredContileTiles
    951  );
    952  feed._telemetryUtility.finalizeNewtabPingFields(filteredContileTiles);
    953 
    954  let expectedResult = {
    955    sponsoredTilesReceived: [
    956      {
    957        advertiser: "brand1",
    958        provider: "amp",
    959        display_position: 1,
    960        display_fail_reason: null,
    961      },
    962      {
    963        advertiser: "brand2",
    964        provider: "amp",
    965        display_position: 2,
    966        display_fail_reason: null,
    967      },
    968      {
    969        advertiser: "brand3",
    970        provider: "amp",
    971        display_position: 6,
    972        display_fail_reason: null,
    973      },
    974    ],
    975  };
    976  Assert.equal(
    977    Glean.topsites.sponsoredTilesReceived.testGetValue(),
    978    JSON.stringify(expectedResult)
    979  );
    980  sandbox.restore();
    981 });
    982 
    983 add_task(async function test_all_tiles_displayed() {
    984  let sandbox = sinon.createSandbox();
    985  info("if all provided tiles are displayed, the display_fail_reason is null");
    986  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
    987 
    988  fetchStub.resolves({
    989    ok: true,
    990    status: 200,
    991    headers: new Map([
    992      ["cache-control", "private, max-age=859, stale-if-error=10463"],
    993    ]),
    994    json: () =>
    995      Promise.resolve({
    996        tiles: [
    997          {
    998            url: "https://www.brand1.com",
    999            image_url: "images/brand1-com.png",
   1000            click_url: "https://www.brand1-click.com",
   1001            impression_url: "https://www.brand1-impression.com",
   1002            name: "brand1",
   1003          },
   1004          {
   1005            url: "https://www.brand2.com",
   1006            image_url: "images/brand2-com.png",
   1007            click_url: "https://www.brand2-click.com",
   1008            impression_url: "https://www.brand2-impression.com",
   1009            name: "brand2",
   1010          },
   1011        ],
   1012      }),
   1013  });
   1014 
   1015  const fetched = await feed._contile._fetchSites();
   1016  Assert.ok(fetched);
   1017  Assert.equal(feed._contile.sites.length, 2);
   1018 
   1019  await feed._readDefaults();
   1020  await feed.getLinksWithDefaults(false);
   1021  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1022 
   1023  let expectedResult = {
   1024    sponsoredTilesReceived: [
   1025      {
   1026        advertiser: "brand1",
   1027        provider: "amp",
   1028        display_position: 1,
   1029        display_fail_reason: null,
   1030      },
   1031      {
   1032        advertiser: "brand2",
   1033        provider: "amp",
   1034        display_position: 2,
   1035        display_fail_reason: null,
   1036      },
   1037    ],
   1038  };
   1039  Assert.equal(
   1040    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1041    JSON.stringify(expectedResult)
   1042  );
   1043  sandbox.restore();
   1044 });
   1045 
   1046 add_task(async function test_set_one_tile_display_fail_reason_to_oversold() {
   1047  let sandbox = sinon.createSandbox();
   1048 
   1049  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
   1050 
   1051  fetchStub.resolves({
   1052    ok: true,
   1053    status: 200,
   1054    headers: new Map([
   1055      ["cache-control", "private, max-age=859, stale-if-error=10463"],
   1056    ]),
   1057    json: () =>
   1058      Promise.resolve({
   1059        tiles: [
   1060          {
   1061            url: "https://www.brand1.com",
   1062            image_url: "images/brand1-com.png",
   1063            click_url: "https://www.brand1-click.com",
   1064            impression_url: "https://www.brand1-impression.com",
   1065            name: "brand1",
   1066          },
   1067          {
   1068            url: "https://www.brand2.com",
   1069            image_url: "images/brand2-com.png",
   1070            click_url: "https://www.brand2-click.com",
   1071            impression_url: "https://www.brand2-impression.com",
   1072            name: "brand2",
   1073          },
   1074          {
   1075            url: "https://www.brand3.com",
   1076            image_url: "images/brnad3-com.png",
   1077            click_url: "https://www.brand3-click.com",
   1078            impression_url: "https://www.brand3-impression.com",
   1079            name: "brand3",
   1080          },
   1081          {
   1082            url: "https://www.brand4.com",
   1083            image_url: "images/brnad4-com.png",
   1084            click_url: "https://www.brand4-click.com",
   1085            impression_url: "https://www.brand4-impression.com",
   1086            name: "brand4",
   1087          },
   1088        ],
   1089      }),
   1090  });
   1091 
   1092  const fetched = await feed._contile._fetchSites();
   1093  Assert.ok(fetched);
   1094  Assert.equal(feed._contile.sites.length, 3);
   1095 
   1096  await feed._readDefaults();
   1097  await feed.getLinksWithDefaults(false);
   1098 
   1099  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1100  let expectedResult = {
   1101    sponsoredTilesReceived: [
   1102      {
   1103        advertiser: "brand1",
   1104        provider: "amp",
   1105        display_position: 1,
   1106        display_fail_reason: null,
   1107      },
   1108      {
   1109        advertiser: "brand2",
   1110        provider: "amp",
   1111        display_position: 2,
   1112        display_fail_reason: null,
   1113      },
   1114      {
   1115        advertiser: "brand3",
   1116        provider: "amp",
   1117        display_position: 3,
   1118        display_fail_reason: null,
   1119      },
   1120      {
   1121        advertiser: "brand4",
   1122        provider: "amp",
   1123        display_position: null,
   1124        display_fail_reason: "oversold",
   1125      },
   1126    ],
   1127  };
   1128  Assert.equal(
   1129    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1130    JSON.stringify(expectedResult)
   1131  );
   1132  sandbox.restore();
   1133 });
   1134 
   1135 add_task(async function test_set_one_tile_display_fail_reason_to_dismissed() {
   1136  let sandbox = sinon.createSandbox();
   1137  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
   1138 
   1139  fetchStub.resolves({
   1140    ok: true,
   1141    status: 200,
   1142    headers: new Map([
   1143      ["cache-control", "private, max-age=859, stale-if-error=10463"],
   1144    ]),
   1145    json: () =>
   1146      Promise.resolve({
   1147        tiles: [
   1148          {
   1149            url: "https://foo.com",
   1150            image_url: "images/foo.png",
   1151            click_url: "https://www.foo-click.com",
   1152            impression_url: "https://www.foo-impression.com",
   1153            name: "foo",
   1154          },
   1155          {
   1156            url: "https://www.brand2.com",
   1157            image_url: "images/brnad2-com.png",
   1158            click_url: "https://www.brand2-click.com",
   1159            impression_url: "https://www.brand2-impression.com",
   1160            name: "brand2",
   1161          },
   1162          {
   1163            url: "https://www.brand3.com",
   1164            image_url: "images/brand3-com.png",
   1165            click_url: "https://www.brand3-click.com",
   1166            impression_url: "https://www.brand3-impression.com",
   1167            name: "brand3",
   1168          },
   1169        ],
   1170      }),
   1171  });
   1172 
   1173  Services.prefs.setStringPref(
   1174    TOP_SITES_BLOCKED_SPONSORS_PREF,
   1175    `["foo","bar"]`
   1176  );
   1177 
   1178  const fetched = await feed._contile._fetchSites();
   1179  Assert.ok(fetched);
   1180  Assert.equal(feed._contile.sites.length, 2);
   1181 
   1182  await feed._readDefaults();
   1183  await feed.getLinksWithDefaults(false);
   1184 
   1185  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1186 
   1187  let expectedResult = {
   1188    sponsoredTilesReceived: [
   1189      {
   1190        advertiser: "foo",
   1191        provider: "amp",
   1192        display_position: null,
   1193        display_fail_reason: "dismissed",
   1194      },
   1195      {
   1196        advertiser: "brand2",
   1197        provider: "amp",
   1198        display_position: 1,
   1199        display_fail_reason: null,
   1200      },
   1201      {
   1202        advertiser: "brand3",
   1203        provider: "amp",
   1204        display_position: 2,
   1205        display_fail_reason: null,
   1206      },
   1207    ],
   1208  };
   1209  Assert.equal(
   1210    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1211    JSON.stringify(expectedResult)
   1212  );
   1213  Services.prefs.clearUserPref(TOP_SITES_BLOCKED_SPONSORS_PREF);
   1214  sandbox.restore();
   1215 });
   1216 
   1217 add_task(
   1218  async function test_set_one_tile_to_dismissed_and_one_tile_to_oversold() {
   1219    let sandbox = sinon.createSandbox();
   1220    let { feed, fetchStub } = prepFeed(
   1221      getTopSitesFeedForTest(sandbox),
   1222      sandbox
   1223    );
   1224 
   1225    fetchStub.resolves({
   1226      ok: true,
   1227      status: 200,
   1228      headers: new Map([
   1229        ["cache-control", "private, max-age=859, stale-if-error=10463"],
   1230      ]),
   1231      json: () =>
   1232        Promise.resolve({
   1233          tiles: [
   1234            {
   1235              url: "https://foo.com",
   1236              image_url: "images/foo.png",
   1237              click_url: "https://www.foo-click.com",
   1238              impression_url: "https://www.foo-impression.com",
   1239              name: "foo",
   1240            },
   1241            {
   1242              url: "https://www.brand2.com",
   1243              image_url: "images/brand2-com.png",
   1244              click_url: "https://www.brand2-click.com",
   1245              impression_url: "https://www.brand2-impression.com",
   1246              name: "brand2",
   1247            },
   1248            {
   1249              url: "https://www.brand3.com",
   1250              image_url: "images/brand3-com.png",
   1251              click_url: "https://www.brand3-click.com",
   1252              impression_url: "https://www.brand3-impression.com",
   1253              name: "brand3",
   1254            },
   1255            {
   1256              url: "https://www.brand4.com",
   1257              image_url: "images/brand4-com.png",
   1258              click_url: "https://www.brand4-click.com",
   1259              impression_url: "https://www.brand4-impression.com",
   1260              name: "brand4",
   1261            },
   1262            {
   1263              url: "https://www.brand5.com",
   1264              image_url: "images/brand5-com.png",
   1265              click_url: "https://www.brand5-click.com",
   1266              impression_url: "https://www.brand5-impression.com",
   1267              name: "brand5",
   1268            },
   1269          ],
   1270        }),
   1271    });
   1272 
   1273    Services.prefs.setStringPref(
   1274      TOP_SITES_BLOCKED_SPONSORS_PREF,
   1275      `["foo","bar"]`
   1276    );
   1277 
   1278    const fetched = await feed._contile._fetchSites();
   1279    Assert.ok(fetched);
   1280    Assert.equal(feed._contile.sites.length, 3);
   1281 
   1282    await feed._readDefaults();
   1283    await feed.getLinksWithDefaults(false);
   1284 
   1285    Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1286 
   1287    let expectedResult = {
   1288      sponsoredTilesReceived: [
   1289        {
   1290          advertiser: "foo",
   1291          provider: "amp",
   1292          display_position: null,
   1293          display_fail_reason: "dismissed",
   1294        },
   1295        {
   1296          advertiser: "brand2",
   1297          provider: "amp",
   1298          display_position: 1,
   1299          display_fail_reason: null,
   1300        },
   1301        {
   1302          advertiser: "brand3",
   1303          provider: "amp",
   1304          display_position: 2,
   1305          display_fail_reason: null,
   1306        },
   1307        {
   1308          advertiser: "brand4",
   1309          provider: "amp",
   1310          display_position: 3,
   1311          display_fail_reason: null,
   1312        },
   1313        {
   1314          advertiser: "brand5",
   1315          provider: "amp",
   1316          display_position: null,
   1317          display_fail_reason: "oversold",
   1318        },
   1319      ],
   1320    };
   1321    Assert.equal(
   1322      Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1323      JSON.stringify(expectedResult)
   1324    );
   1325    Services.prefs.clearUserPref(TOP_SITES_BLOCKED_SPONSORS_PREF);
   1326    sandbox.restore();
   1327  }
   1328 );
   1329 
   1330 add_task(
   1331  async function test_set_one_cached_tile_display_fail_reason_to_dismissed() {
   1332    let sandbox = sinon.createSandbox();
   1333    info("confirm the telemetry is valid when using cached tiles.");
   1334 
   1335    let { feed, fetchStub } = prepFeed(
   1336      getTopSitesFeedForTest(sandbox),
   1337      sandbox
   1338    );
   1339 
   1340    const tiles = [
   1341      {
   1342        url: "https://www.brand1.com",
   1343        image_url: "images/brand1-com.png",
   1344        click_url: "https://www.brand1-click.com",
   1345        impression_url: "https://www.brand1-impression.com",
   1346        name: "brand1",
   1347      },
   1348      {
   1349        url: "https://foo.com",
   1350        image_url: "images/foo-com.png",
   1351        click_url: "https://www.foo-click.com",
   1352        impression_url: "https://www.foo-impression.com",
   1353        name: "foo",
   1354      },
   1355    ];
   1356 
   1357    feed._contile.cache.get.returns({ contile: tiles });
   1358    Services.prefs.setIntPref(CONTILE_CACHE_VALID_FOR_PREF, 60 * 15);
   1359    Services.prefs.setIntPref(
   1360      CONTILE_CACHE_LAST_FETCH_PREF,
   1361      Math.round(Date.now() / 1000)
   1362    );
   1363    Services.prefs.setStringPref(
   1364      TOP_SITES_BLOCKED_SPONSORS_PREF,
   1365      `["foo","bar"]`
   1366    );
   1367 
   1368    fetchStub.resolves({
   1369      status: 304,
   1370    });
   1371 
   1372    const fetched = await feed._contile._fetchSites();
   1373    Assert.ok(fetched);
   1374    Assert.equal(feed._contile.sites.length, 1);
   1375 
   1376    await feed._readDefaults();
   1377    await feed.getLinksWithDefaults(false);
   1378 
   1379    Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1380 
   1381    let expectedResult = {
   1382      sponsoredTilesReceived: [
   1383        {
   1384          advertiser: "brand1",
   1385          provider: "amp",
   1386          display_position: 1,
   1387          display_fail_reason: null,
   1388        },
   1389        {
   1390          advertiser: "foo",
   1391          provider: "amp",
   1392          display_position: null,
   1393          display_fail_reason: "dismissed",
   1394        },
   1395      ],
   1396    };
   1397    Assert.equal(
   1398      Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1399      JSON.stringify(expectedResult)
   1400    );
   1401    Services.prefs.clearUserPref(TOP_SITES_BLOCKED_SPONSORS_PREF);
   1402    sandbox.restore();
   1403  }
   1404 );
   1405 
   1406 add_task(async function test_update_tile_count() {
   1407  let sandbox = sinon.createSandbox();
   1408  info(
   1409    "the tile count should update when topSitesMaxSponsored is updated by Nimbus"
   1410  );
   1411  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
   1412 
   1413  fetchStub.resolves({
   1414    ok: true,
   1415    status: 200,
   1416    headers: new Map([
   1417      ["cache-control", "private, max-age=859, stale-if-error=10463"],
   1418    ]),
   1419    json: () =>
   1420      Promise.resolve({
   1421        tiles: [
   1422          {
   1423            url: "https://www.brand1.com",
   1424            image_url: "images/brand1-com.png",
   1425            click_url: "https://www.brand1-click.com",
   1426            impression_url: "https://www.brand1-impression.com",
   1427            name: "brand1",
   1428          },
   1429          {
   1430            url: "https://www.brand2.com",
   1431            image_url: "images/brand2-com.png",
   1432            click_url: "https://www.brand2-click.com",
   1433            impression_url: "https://www.brand2-impression.com",
   1434            name: "brand2",
   1435          },
   1436          {
   1437            url: "https://www.brand3.com",
   1438            image_url: "images/brand3-com.png",
   1439            click_url: "https://www.brand3-click.com",
   1440            impression_url: "https://www.brand3-impression.com",
   1441            name: "brand3",
   1442          },
   1443          {
   1444            url: "https://www.brand4.com",
   1445            image_url: "images/brand4-com.png",
   1446            click_url: "https://www.brand4-click.com",
   1447            impression_url: "https://www.brand4-impression.com",
   1448            name: "brand4",
   1449          },
   1450        ],
   1451      }),
   1452  });
   1453 
   1454  // 1.  Initially the Nimbus pref is set to 2 tiles
   1455  let fetched = await feed._contile._fetchSites();
   1456  Assert.ok(fetched);
   1457  Assert.equal(feed._contile.sites.length, 3);
   1458  await feed._readDefaults();
   1459  await feed.getLinksWithDefaults(false);
   1460 
   1461  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1462 
   1463  let expectedResult = {
   1464    sponsoredTilesReceived: [
   1465      {
   1466        advertiser: "brand1",
   1467        provider: "amp",
   1468        display_position: 1,
   1469        display_fail_reason: null,
   1470      },
   1471      {
   1472        advertiser: "brand2",
   1473        provider: "amp",
   1474        display_position: 2,
   1475        display_fail_reason: null,
   1476      },
   1477      {
   1478        advertiser: "brand3",
   1479        provider: "amp",
   1480        display_position: 3,
   1481        display_fail_reason: null,
   1482      },
   1483      {
   1484        advertiser: "brand4",
   1485        provider: "amp",
   1486        display_position: null,
   1487        display_fail_reason: "oversold",
   1488      },
   1489    ],
   1490  };
   1491  Assert.equal(
   1492    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1493    JSON.stringify(expectedResult)
   1494  );
   1495 
   1496  // 2.  Set the Numbus pref to 3, confirm previous count still used.
   1497  const nimbusPocketStub = sandbox.stub(
   1498    NimbusFeatures.pocketNewtab,
   1499    "getVariable"
   1500  );
   1501  setNimbusVariablesForNumTiles(nimbusPocketStub, 3);
   1502 
   1503  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1504 
   1505  expectedResult = {
   1506    sponsoredTilesReceived: [
   1507      {
   1508        advertiser: "brand1",
   1509        provider: "amp",
   1510        display_position: 1,
   1511        display_fail_reason: null,
   1512      },
   1513      {
   1514        advertiser: "brand2",
   1515        provider: "amp",
   1516        display_position: 2,
   1517        display_fail_reason: null,
   1518      },
   1519      {
   1520        advertiser: "brand3",
   1521        provider: "amp",
   1522        display_position: 3,
   1523        display_fail_reason: null,
   1524      },
   1525      {
   1526        advertiser: "brand4",
   1527        provider: "amp",
   1528        display_position: null,
   1529        display_fail_reason: "oversold",
   1530      },
   1531    ],
   1532  };
   1533  Assert.equal(
   1534    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1535    JSON.stringify(expectedResult)
   1536  );
   1537 
   1538  // 3.  Confirm the new count is applied when data pulled from Contile., 3 tiles displayed
   1539  fetched = await feed._contile._fetchSites();
   1540  Assert.ok(fetched);
   1541  Assert.equal(feed._contile.sites.length, 3);
   1542  await feed._readDefaults();
   1543  await feed.getLinksWithDefaults(false);
   1544 
   1545  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1546 
   1547  expectedResult = {
   1548    sponsoredTilesReceived: [
   1549      {
   1550        advertiser: "brand1",
   1551        provider: "amp",
   1552        display_position: 1,
   1553        display_fail_reason: null,
   1554      },
   1555      {
   1556        advertiser: "brand2",
   1557        provider: "amp",
   1558        display_position: 2,
   1559        display_fail_reason: null,
   1560      },
   1561      {
   1562        advertiser: "brand3",
   1563        provider: "amp",
   1564        display_position: 3,
   1565        display_fail_reason: null,
   1566      },
   1567      {
   1568        advertiser: "brand4",
   1569        provider: "amp",
   1570        display_position: null,
   1571        display_fail_reason: "oversold",
   1572      },
   1573    ],
   1574  };
   1575  Assert.equal(
   1576    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1577    JSON.stringify(expectedResult)
   1578  );
   1579 
   1580  sandbox.restore();
   1581 });
   1582 
   1583 add_task(async function test_update_tile_count_sourced_from_cache() {
   1584  let sandbox = sinon.createSandbox();
   1585 
   1586  info(
   1587    "the tile count should update from cache when topSitesMaxSponsored is updated by Nimbus"
   1588  );
   1589  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
   1590 
   1591  const tiles = [
   1592    {
   1593      url: "https://www.brand1.com",
   1594      image_url: "images/brand1-com.png",
   1595      click_url: "https://www.brand1-click.com",
   1596      impression_url: "https://www.brand1-impression.com",
   1597      name: "brand1",
   1598    },
   1599    {
   1600      url: "https://www.brand2.com",
   1601      image_url: "images/brand2-com.png",
   1602      click_url: "https://www.brand2-click.com",
   1603      impression_url: "https://www.brand2-impression.com",
   1604      name: "brand2",
   1605    },
   1606    {
   1607      url: "https://www.brand3.com",
   1608      image_url: "images/brand3-com.png",
   1609      click_url: "https://www.brand3-click.com",
   1610      impression_url: "https://www.brand3-impression.com",
   1611      name: "brand3",
   1612    },
   1613    {
   1614      url: "https://www.brand4.com",
   1615      image_url: "images/brand4-com.png",
   1616      click_url: "https://www.brand4-click.com",
   1617      impression_url: "https://www.brand4-impression.com",
   1618      name: "brand4",
   1619    },
   1620  ];
   1621 
   1622  feed._contile.cache.get.returns({ contile: tiles });
   1623  Services.prefs.setIntPref(CONTILE_CACHE_VALID_FOR_PREF, 60 * 15);
   1624  Services.prefs.setIntPref(
   1625    CONTILE_CACHE_LAST_FETCH_PREF,
   1626    Math.round(Date.now() / 1000)
   1627  );
   1628 
   1629  fetchStub.resolves({
   1630    status: 304,
   1631  });
   1632 
   1633  // 1.  Initially the Nimbus pref is set to 2 tiles
   1634  // Ensure ContileIntegration._fetchSites is working populate _sites and initilize TelemetryUtility
   1635  let fetched = await feed._contile._fetchSites();
   1636  Assert.ok(fetched);
   1637  Assert.equal(feed._contile.sites.length, 4);
   1638  await feed._readDefaults();
   1639  await feed.getLinksWithDefaults(false);
   1640 
   1641  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1642 
   1643  let expectedResult = {
   1644    sponsoredTilesReceived: [
   1645      {
   1646        advertiser: "brand1",
   1647        provider: "amp",
   1648        display_position: 1,
   1649        display_fail_reason: null,
   1650      },
   1651      {
   1652        advertiser: "brand2",
   1653        provider: "amp",
   1654        display_position: 2,
   1655        display_fail_reason: null,
   1656      },
   1657      {
   1658        advertiser: "brand3",
   1659        provider: "amp",
   1660        display_position: 3,
   1661        display_fail_reason: null,
   1662      },
   1663      {
   1664        advertiser: "brand4",
   1665        provider: "amp",
   1666        display_position: null,
   1667        display_fail_reason: "oversold",
   1668      },
   1669    ],
   1670  };
   1671  Assert.equal(
   1672    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1673    JSON.stringify(expectedResult)
   1674  );
   1675 
   1676  // 2.  Set the Numbus pref to 3, confirm previous count still used.
   1677  const nimbusPocketStub = sandbox.stub(
   1678    NimbusFeatures.pocketNewtab,
   1679    "getVariable"
   1680  );
   1681  setNimbusVariablesForNumTiles(nimbusPocketStub, 3);
   1682 
   1683  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1684 
   1685  // 3.  Confirm the new count is applied when data pulled from Contile, 3 tiles displayed
   1686  fetched = await feed._contile._fetchSites();
   1687  Assert.ok(fetched);
   1688  Assert.equal(feed._contile.sites.length, 4);
   1689  await feed._readDefaults();
   1690  await feed.getLinksWithDefaults(false);
   1691 
   1692  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1693 
   1694  expectedResult = {
   1695    sponsoredTilesReceived: [
   1696      {
   1697        advertiser: "brand1",
   1698        provider: "amp",
   1699        display_position: 1,
   1700        display_fail_reason: null,
   1701      },
   1702      {
   1703        advertiser: "brand2",
   1704        provider: "amp",
   1705        display_position: 2,
   1706        display_fail_reason: null,
   1707      },
   1708      {
   1709        advertiser: "brand3",
   1710        provider: "amp",
   1711        display_position: 3,
   1712        display_fail_reason: null,
   1713      },
   1714      {
   1715        advertiser: "brand4",
   1716        provider: "amp",
   1717        display_position: null,
   1718        display_fail_reason: "oversold",
   1719      },
   1720    ],
   1721  };
   1722  Assert.equal(
   1723    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1724    JSON.stringify(expectedResult)
   1725  );
   1726  sandbox.restore();
   1727 });
   1728 
   1729 add_task(
   1730  async function test_update_telemetry_fields_if_dismissed_brands_list_is_updated() {
   1731    let sandbox = sinon.createSandbox();
   1732    info(
   1733      "if the user dismisses a brand, that dismissed tile shoudl be represented in the next ping."
   1734    );
   1735    let { feed, fetchStub } = prepFeed(
   1736      getTopSitesFeedForTest(sandbox),
   1737      sandbox
   1738    );
   1739 
   1740    fetchStub.resolves({
   1741      ok: true,
   1742      status: 200,
   1743      headers: new Map([
   1744        ["cache-control", "private, max-age=859, stale-if-error=10463"],
   1745      ]),
   1746      json: () =>
   1747        Promise.resolve({
   1748          tiles: [
   1749            {
   1750              url: "https://foo.com",
   1751              image_url: "images/foo.png",
   1752              click_url: "https://www.foo-click.com",
   1753              impression_url: "https://www.foo-impression.com",
   1754              name: "foo",
   1755            },
   1756            {
   1757              url: "https://www.brand2.com",
   1758              image_url: "images/brand2-com.png",
   1759              click_url: "https://www.brand2-click.com",
   1760              impression_url: "https://www.brand2-impression.com",
   1761              name: "brand2",
   1762            },
   1763            {
   1764              url: "https://www.brand3.com",
   1765              image_url: "images/brand3-com.png",
   1766              click_url: "https://www.brand3-click.com",
   1767              impression_url: "https://www.brand3-impression.com",
   1768              name: "brand3",
   1769            },
   1770          ],
   1771        }),
   1772    });
   1773    Services.prefs.setStringPref(
   1774      TOP_SITES_BLOCKED_SPONSORS_PREF,
   1775      `["foo","bar"]`
   1776    );
   1777 
   1778    let fetched = await feed._contile._fetchSites();
   1779    Assert.ok(fetched);
   1780    Assert.equal(feed._contile.sites.length, 2);
   1781 
   1782    await feed._readDefaults();
   1783    await feed.getLinksWithDefaults(false);
   1784 
   1785    Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1786 
   1787    let expectedResult = {
   1788      sponsoredTilesReceived: [
   1789        {
   1790          advertiser: "foo",
   1791          provider: "amp",
   1792          display_position: null,
   1793          display_fail_reason: "dismissed",
   1794        },
   1795        {
   1796          advertiser: "brand2",
   1797          provider: "amp",
   1798          display_position: 1,
   1799          display_fail_reason: null,
   1800        },
   1801        {
   1802          advertiser: "brand3",
   1803          provider: "amp",
   1804          display_position: 2,
   1805          display_fail_reason: null,
   1806        },
   1807      ],
   1808    };
   1809    Assert.equal(
   1810      Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1811      JSON.stringify(expectedResult)
   1812    );
   1813 
   1814    Services.prefs.setStringPref(
   1815      TOP_SITES_BLOCKED_SPONSORS_PREF,
   1816      `["foo","bar","brand2"]`
   1817    );
   1818 
   1819    fetched = await feed._contile._fetchSites();
   1820    Assert.ok(fetched);
   1821    Assert.equal(feed._contile.sites.length, 1);
   1822 
   1823    await feed._readDefaults();
   1824    await feed.getLinksWithDefaults(false);
   1825 
   1826    Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1827 
   1828    expectedResult = {
   1829      sponsoredTilesReceived: [
   1830        {
   1831          advertiser: "foo",
   1832          provider: "amp",
   1833          display_position: null,
   1834          display_fail_reason: "dismissed",
   1835        },
   1836        {
   1837          advertiser: "brand2",
   1838          provider: "amp",
   1839          display_position: null,
   1840          display_fail_reason: "dismissed",
   1841        },
   1842        {
   1843          advertiser: "brand3",
   1844          provider: "amp",
   1845          display_position: 1,
   1846          display_fail_reason: null,
   1847        },
   1848      ],
   1849    };
   1850    Assert.equal(
   1851      Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1852      JSON.stringify(expectedResult)
   1853    );
   1854 
   1855    Services.prefs.clearUserPref(TOP_SITES_BLOCKED_SPONSORS_PREF);
   1856    sandbox.restore();
   1857  }
   1858 );
   1859 
   1860 add_task(async function test_sponsoredTilesReceived_not_set() {
   1861  let sandbox = sinon.createSandbox();
   1862  info("sponsoredTilesReceived should be empty if tiles service returns 204");
   1863  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
   1864 
   1865  fetchStub.resolves({ ok: true, status: 204 });
   1866 
   1867  const fetched = await feed._contile._fetchSites();
   1868  Assert.ok(!fetched);
   1869  Assert.ok(!feed._contile.sites.length);
   1870 
   1871  await feed._readDefaults();
   1872  await feed.getLinksWithDefaults(false);
   1873 
   1874  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1875  let expectedResult = { sponsoredTilesReceived: [] };
   1876 
   1877  Assert.equal(
   1878    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1879    JSON.stringify(expectedResult)
   1880  );
   1881  sandbox.restore();
   1882 });
   1883 
   1884 add_task(async function test_telemetry_data_updates() {
   1885  let sandbox = sinon.createSandbox();
   1886  info("sponsoredTilesReceived should update when new tiles received.");
   1887  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
   1888 
   1889  fetchStub.resolves({
   1890    ok: true,
   1891    status: 200,
   1892    headers: new Map([
   1893      ["cache-control", "private, max-age=859, stale-if-error=10463"],
   1894    ]),
   1895    json: () =>
   1896      Promise.resolve({
   1897        tiles: [
   1898          {
   1899            url: "https://foo.com",
   1900            image_url: "images/foo.png",
   1901            click_url: "https://www.foo-click.com",
   1902            impression_url: "https://www.foo-impression.com",
   1903            name: "foo",
   1904          },
   1905          {
   1906            url: "https://www.brand2.com",
   1907            image_url: "images/brand2-com.png",
   1908            click_url: "https://www.brand2-click.com",
   1909            impression_url: "https://www.brand2-impression.com",
   1910            name: "brand2",
   1911          },
   1912          {
   1913            url: "https://www.brand3.com",
   1914            image_url: "images/brand3-com.png",
   1915            click_url: "https://www.brand3-click.com",
   1916            impression_url: "https://www.brand3-impression.com",
   1917            name: "brand3",
   1918          },
   1919        ],
   1920      }),
   1921  });
   1922  Services.prefs.setStringPref(
   1923    TOP_SITES_BLOCKED_SPONSORS_PREF,
   1924    `["foo","bar"]`
   1925  );
   1926 
   1927  const fetched = await feed._contile._fetchSites();
   1928  Assert.ok(fetched);
   1929  Assert.equal(feed._contile.sites.length, 2);
   1930 
   1931  await feed._readDefaults();
   1932  await feed.getLinksWithDefaults(false);
   1933 
   1934  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   1935 
   1936  let expectedResult = {
   1937    sponsoredTilesReceived: [
   1938      {
   1939        advertiser: "foo",
   1940        provider: "amp",
   1941        display_position: null,
   1942        display_fail_reason: "dismissed",
   1943      },
   1944      {
   1945        advertiser: "brand2",
   1946        provider: "amp",
   1947        display_position: 1,
   1948        display_fail_reason: null,
   1949      },
   1950      {
   1951        advertiser: "brand3",
   1952        provider: "amp",
   1953        display_position: 2,
   1954        display_fail_reason: null,
   1955      },
   1956    ],
   1957  };
   1958  Assert.equal(
   1959    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   1960    JSON.stringify(expectedResult)
   1961  );
   1962 
   1963  fetchStub.resolves({
   1964    ok: true,
   1965    status: 200,
   1966    headers: new Map([
   1967      ["cache-control", "private, max-age=859, stale-if-error=10463"],
   1968    ]),
   1969    json: () =>
   1970      Promise.resolve({
   1971        tiles: [
   1972          {
   1973            url: "https://foo.com",
   1974            image_url: "images/foo.png",
   1975            click_url: "https://www.foo-click.com",
   1976            impression_url: "https://www.foo-impression.com",
   1977            name: "foo",
   1978          },
   1979          {
   1980            url: "https://bar.com",
   1981            image_url: "images/bar-com.png",
   1982            click_url: "https://www.bar-click.com",
   1983            impression_url: "https://www.bar-impression.com",
   1984            name: "bar",
   1985          },
   1986          {
   1987            url: "https://www.brand3.com",
   1988            image_url: "images/brand3-com.png",
   1989            click_url: "https://www.brand3-click.com",
   1990            impression_url: "https://www.brand3-impression.com",
   1991            name: "brand3",
   1992          },
   1993        ],
   1994      }),
   1995  });
   1996 
   1997  await feed._contile._fetchSites();
   1998  Assert.ok(fetched);
   1999  Assert.equal(feed._contile.sites.length, 1);
   2000 
   2001  await feed._readDefaults();
   2002  await feed.getLinksWithDefaults(false);
   2003 
   2004  expectedResult = {
   2005    sponsoredTilesReceived: [
   2006      {
   2007        advertiser: "foo",
   2008        provider: "amp",
   2009        display_position: null,
   2010        display_fail_reason: "dismissed",
   2011      },
   2012      {
   2013        advertiser: "bar",
   2014        provider: "amp",
   2015        display_position: null,
   2016        display_fail_reason: "dismissed",
   2017      },
   2018      {
   2019        advertiser: "brand3",
   2020        provider: "amp",
   2021        display_position: 1,
   2022        display_fail_reason: null,
   2023      },
   2024    ],
   2025  };
   2026  Assert.equal(
   2027    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   2028    JSON.stringify(expectedResult)
   2029  );
   2030  Services.prefs.clearUserPref(TOP_SITES_BLOCKED_SPONSORS_PREF);
   2031  sandbox.restore();
   2032 });
   2033 
   2034 add_task(async function test_reset_telemetry_data() {
   2035  let sandbox = sinon.createSandbox();
   2036  info(
   2037    "sponsoredTilesReceived should be cleared when no tiles received and cache refreshed."
   2038  );
   2039  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
   2040 
   2041  fetchStub.resolves({
   2042    ok: true,
   2043    status: 200,
   2044    headers: new Map([
   2045      ["cache-control", "private, max-age=859, stale-if-error=10463"],
   2046    ]),
   2047    json: () =>
   2048      Promise.resolve({
   2049        tiles: [
   2050          {
   2051            url: "https://foo.com",
   2052            image_url: "images/foo.png",
   2053            click_url: "https://www.foo-click.com",
   2054            impression_url: "https://www.foo-impression.com",
   2055            name: "foo",
   2056          },
   2057          {
   2058            url: "https://www.brand2.com",
   2059            image_url: "images/brand2-com.png",
   2060            click_url: "https://www.brand2-click.com",
   2061            impression_url: "https://www.brand2-impression.com",
   2062            name: "brand2",
   2063          },
   2064          {
   2065            url: "https://www.brand3.com",
   2066            image_url: "images/brand3-com.png",
   2067            click_url: "https://www.brand3-click.com",
   2068            impression_url: "https://www.brand3-impression.com",
   2069            name: "test3",
   2070          },
   2071        ],
   2072      }),
   2073  });
   2074  Services.prefs.setStringPref(
   2075    TOP_SITES_BLOCKED_SPONSORS_PREF,
   2076    `["foo","bar"]`
   2077  );
   2078 
   2079  let fetched = await feed._contile._fetchSites();
   2080  Assert.ok(fetched);
   2081  Assert.equal(feed._contile.sites.length, 2);
   2082 
   2083  await feed._readDefaults();
   2084  await feed.getLinksWithDefaults(false);
   2085 
   2086  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   2087 
   2088  let expectedResult = {
   2089    sponsoredTilesReceived: [
   2090      {
   2091        advertiser: "foo",
   2092        provider: "amp",
   2093        display_position: null,
   2094        display_fail_reason: "dismissed",
   2095      },
   2096      {
   2097        advertiser: "brand2",
   2098        provider: "amp",
   2099        display_position: 1,
   2100        display_fail_reason: null,
   2101      },
   2102      {
   2103        advertiser: "brand3",
   2104        provider: "amp",
   2105        display_position: 2,
   2106        display_fail_reason: null,
   2107      },
   2108    ],
   2109  };
   2110  Assert.equal(
   2111    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   2112    JSON.stringify(expectedResult)
   2113  );
   2114 
   2115  fetchStub.resolves({ ok: true, status: 204 });
   2116 
   2117  fetched = await feed._contile._fetchSites();
   2118  Assert.ok(fetched);
   2119  Assert.ok(!feed._contile.sites.length);
   2120 
   2121  await feed._readDefaults();
   2122  await feed.getLinksWithDefaults(false);
   2123 
   2124  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   2125 
   2126  expectedResult = { sponsoredTilesReceived: [] };
   2127  Assert.equal(
   2128    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   2129    JSON.stringify(expectedResult)
   2130  );
   2131  Services.prefs.clearUserPref(TOP_SITES_BLOCKED_SPONSORS_PREF);
   2132  sandbox.restore();
   2133 });
   2134 
   2135 add_task(async function test_set_telemetry_for_moz_sales_tiles() {
   2136  let sandbox = sinon.createSandbox();
   2137  let { feed, fetchStub } = prepFeed(getTopSitesFeedForTest(sandbox), sandbox);
   2138 
   2139  sandbox.stub(feed, "fetchDiscoveryStreamSpocs").returns([
   2140    {
   2141      label: "MozSales Title",
   2142      title: "MozSales Title",
   2143      url: "https://mozsale.net",
   2144      sponsored_position: 1,
   2145      partner: "moz-sales",
   2146    },
   2147  ]);
   2148 
   2149  fetchStub.resolves({
   2150    ok: true,
   2151    status: 200,
   2152    headers: new Map([
   2153      ["cache-control", "private, max-age=859, stale-if-error=10463"],
   2154    ]),
   2155    json: () =>
   2156      Promise.resolve({
   2157        tiles: [
   2158          {
   2159            url: "https://www.brand1.com",
   2160            image_url: "images/brand1-com.png",
   2161            click_url: "https://www.brand1-click.com",
   2162            impression_url: "https://www.brand1-impression.com",
   2163            name: "brand1",
   2164          },
   2165          {
   2166            url: "https://www.brand2.com",
   2167            image_url: "images/brand2-com.png",
   2168            click_url: "https://www.brand2-click.com",
   2169            impression_url: "https://www.brand2-impression.com",
   2170            name: "brand2",
   2171          },
   2172          {
   2173            url: "https://www.brand3.com",
   2174            image_url: "images/brand3-com.png",
   2175            click_url: "https://www.brand3-click.com",
   2176            impression_url: "https://www.brand3-impression.com",
   2177            name: "brand2",
   2178          },
   2179        ],
   2180      }),
   2181  });
   2182  const fetched = await feed._contile._fetchSites();
   2183  Assert.ok(fetched);
   2184  Assert.equal(feed._contile.sites.length, 3);
   2185 
   2186  await feed._readDefaults();
   2187  await feed.getLinksWithDefaults(false);
   2188 
   2189  Assert.equal(Glean.topsites.sponsoredTilesConfigured.testGetValue(), 3);
   2190  let expectedResult = {
   2191    sponsoredTilesReceived: [
   2192      {
   2193        advertiser: "brand1",
   2194        provider: "amp",
   2195        display_position: 1,
   2196        display_fail_reason: null,
   2197      },
   2198      {
   2199        advertiser: "brand2",
   2200        provider: "amp",
   2201        display_position: 2,
   2202        display_fail_reason: null,
   2203      },
   2204      {
   2205        advertiser: "brand3",
   2206        provider: "amp",
   2207        display_position: 3,
   2208        display_fail_reason: null,
   2209      },
   2210      {
   2211        advertiser: "mozsales title",
   2212        provider: "moz-sales",
   2213        display_position: null,
   2214        display_fail_reason: "oversold",
   2215      },
   2216    ],
   2217  };
   2218  Assert.equal(
   2219    Glean.topsites.sponsoredTilesReceived.testGetValue(),
   2220    JSON.stringify(expectedResult)
   2221  );
   2222  sandbox.restore();
   2223 });