tor-browser

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

commit 1bdf042810bc2fa11a4c4469c11e9dbe7f6307fa
parent 43fcfa103bfa33ab769e60cc0f61bd562b2bd038
Author: scottdowne <sdowne@mozilla.com>
Date:   Wed, 19 Nov 2025 03:01:54 +0000

Bug 1997660 - Newtab remove all code in discovery stream feed related to shortcuts spocs r=home-newtab-reviewers,npypchenko

Differential Revision: https://phabricator.services.mozilla.com/D270961

Diffstat:
Mbrowser/app/profile/firefox.js | 7-------
Mbrowser/extensions/newtab/lib/DiscoveryStreamFeed.sys.mjs | 200+++++++------------------------------------------------------------------------
Mbrowser/extensions/newtab/lib/TopSitesFeed.sys.mjs | 10+---------
Mbrowser/extensions/newtab/test/unit/lib/DiscoveryStreamFeed.test.js | 373+++----------------------------------------------------------------------------
Mtoolkit/components/nimbus/FeatureManifest.yaml | 22----------------------
5 files changed, 31 insertions(+), 581 deletions(-)

diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js @@ -1812,9 +1812,6 @@ pref("browser.topsites.useRemoteSetting", true); pref("browser.topsites.contile.enabled", true); pref("browser.topsites.contile.endpoint", "https://contile.services.mozilla.com/v1/tiles"); -// Whether to enable the Share-of-Voice feature for Sponsored Topsites via Contile. -pref("browser.topsites.contile.sov.enabled", true); - // The base URL for the Quick Suggest anonymizing proxy. To make a request to // the proxy, include a campaign ID in the path. pref("browser.partnerlink.attributionURL", "https://topsites.services.mozilla.com/cid/"); @@ -1965,7 +1962,6 @@ pref("browser.newtabpage.activity-stream.discoverystream.placements.tiles.counts pref("browser.newtabpage.activity-stream.discoverystream.placements.contextualBanners", ""); pref("browser.newtabpage.activity-stream.discoverystream.placements.contextualBanners.counts", ""); -pref("browser.newtabpage.activity-stream.discoverystream.spoc-topsites-positions", "2"); // This is a 0-based index, for consistency with the other position CSVs, // but Contile positions are a 1-based index, so we end up adding 1 to these before using them. pref("browser.newtabpage.activity-stream.discoverystream.contile-topsites-positions", "0,1,2"); @@ -1976,9 +1972,6 @@ pref("browser.newtabpage.activity-stream.discoverystream.spocs-endpoint-query", // Changes the spoc content. pref("browser.newtabpage.activity-stream.discoverystream.spocAdTypes", ""); pref("browser.newtabpage.activity-stream.discoverystream.spocZoneIds", ""); -pref("browser.newtabpage.activity-stream.discoverystream.spocTopsitesAdTypes", ""); -pref("browser.newtabpage.activity-stream.discoverystream.spocTopsitesZoneIds", ""); -pref("browser.newtabpage.activity-stream.discoverystream.spocTopsitesPlacement.enabled", true); pref("browser.newtabpage.activity-stream.discoverystream.spocSiteId", ""); pref("browser.newtabpage.activity-stream.discoverystream.ctaButtonSponsors", ""); pref("browser.newtabpage.activity-stream.discoverystream.ctaButtonVariant", ""); diff --git a/browser/extensions/newtab/lib/DiscoveryStreamFeed.sys.mjs b/browser/extensions/newtab/lib/DiscoveryStreamFeed.sys.mjs @@ -74,19 +74,14 @@ const PREF_SPOCS_ENDPOINT_QUERY = "discoverystream.spocs-endpoint-query"; const PREF_REGION_BASIC_LAYOUT = "discoverystream.region-basic-layout"; const PREF_USER_TOPSTORIES = "feeds.section.topstories"; const PREF_SYSTEM_TOPSTORIES = "feeds.system.topstories"; -const PREF_SYSTEM_TOPSITES = "feeds.system.topsites"; const PREF_UNIFIED_ADS_BLOCKED_LIST = "unifiedAds.blockedAds"; const PREF_UNIFIED_ADS_SPOCS_ENABLED = "unifiedAds.spocs.enabled"; const PREF_UNIFIED_ADS_ADSFEED_ENABLED = "unifiedAds.adsFeed.enabled"; const PREF_UNIFIED_ADS_ENDPOINT = "unifiedAds.endpoint"; const PREF_UNIFIED_ADS_OHTTP = "unifiedAds.ohttp.enabled"; -const PREF_USER_TOPSITES = "feeds.topsites"; const PREF_SPOCS_CLEAR_ENDPOINT = "discoverystream.endpointSpocsClear"; const PREF_SHOW_SPONSORED = "showSponsored"; const PREF_SYSTEM_SHOW_SPONSORED = "system.showSponsored"; -const PREF_SHOW_SPONSORED_TOPSITES = "showSponsoredTopSites"; -// Nimbus variable to enable the SOV feature for sponsored tiles. -const NIMBUS_VARIABLE_CONTILE_SOV_ENABLED = "topSitesContileSovEnabled"; const PREF_SPOC_IMPRESSIONS = "discoverystream.spoc.impressions"; const PREF_FLIGHT_BLOCKS = "discoverystream.flight.blocks"; const PREF_SELECTED_TOPICS = "discoverystream.topicSelection.selectedTopics"; @@ -236,12 +231,6 @@ export class DiscoveryStreamFeed { return this._doLocalInferredRerank; } - get showSpocs() { - // High level overall sponsored check, if one of these is true, - // we know we need some sort of spoc control setup. - return this.showSponsoredStories || this.showSponsoredTopsites; - } - get showSponsoredStories() { // Combine user-set sponsored opt-out with Mozilla-set config return ( @@ -250,15 +239,6 @@ export class DiscoveryStreamFeed { ); } - get showSponsoredTopsites() { - const placements = this.getPlacements(); - // Combine user-set sponsored opt-out with placement data - return !!( - this.store.getState().Prefs.values[PREF_SHOW_SPONSORED_TOPSITES] && - placements.find(placement => placement.name === "sponsored-topsites") - ); - } - get showStories() { // Combine user-set stories opt-out with Mozilla-set config return ( @@ -267,14 +247,6 @@ export class DiscoveryStreamFeed { ); } - get showTopsites() { - // Combine user-set topsites opt-out with Mozilla-set config - return ( - this.store.getState().Prefs.values[PREF_SYSTEM_TOPSITES] && - this.store.getState().Prefs.values[PREF_USER_TOPSITES] - ); - } - get personalized() { return this.recommendationProvider.personalized; } @@ -601,7 +573,9 @@ export class DiscoveryStreamFeed { const { feeds } = cachedData; return { - spocs: this.showSpocs && this.isExpired({ cachedData, key: "spocs" }), + spocs: + this.showSponsoredStories && + this.isExpired({ cachedData, key: "spocs" }), feeds: this.showStories && (!feeds || @@ -621,22 +595,7 @@ export class DiscoveryStreamFeed { // If we find a valid placement, we set it to this value. let placement; - // We need to check to see if this placement is on or not. - // If this placement has a prefs array, check against that. - if (component.spocs.prefs) { - // Check every pref in the array to see if this placement is turned on. - if ( - component.spocs.prefs.length && - component.spocs.prefs.every( - p => this.store.getState().Prefs.values[p] - ) - ) { - // This placement is on. - placement = component.placement; - } - } else if (this.showSponsoredStories) { - // If we do not have a prefs array, use old check. - // This is because Pocket spocs uses an old non pref method. + if (this.showSponsoredStories) { placement = component.placement; } @@ -718,27 +677,7 @@ export class DiscoveryStreamFeed { this.store.getState().Prefs.values[PREF_REGION_BASIC_LAYOUT]; const pocketConfig = this.store.getState().Prefs.values?.pocketConfig || {}; - - // The Unified Ads API does not support the spoc topsite placement. - const unifiedAdsEnabled = - this.store.getState().Prefs.values[PREF_UNIFIED_ADS_SPOCS_ENABLED]; - const spocTopsitesPlacementEnabled = - pocketConfig.spocTopsitesPlacementEnabled && !unifiedAdsEnabled; - - // const layoutExperiment = - // this.store.getState().Prefs.values[PREF_LAYOUT_EXPERIMENT_A] || - // this.store.getState().Prefs.values[PREF_LAYOUT_EXPERIMENT_B]; - - // let items = isBasicLayout ? 3 : 21; - let items = isBasicLayout ? 4 : 24; - // if ( - // pocketConfig.fourCardLayout || - // pocketConfig.hybridLayout || - // layoutExperiment - // ) { - // items = isBasicLayout ? 4 : 24; - // } - + const items = isBasicLayout ? 4 : 24; const ctaButtonSponsors = pocketConfig.ctaButtonSponsors ?.split(",") .map(s => s.trim().toLowerCase()); @@ -777,11 +716,8 @@ export class DiscoveryStreamFeed { const spocAdTypes = prepConfArr(pocketConfig.spocAdTypes); const spocZoneIds = prepConfArr(pocketConfig.spocZoneIds); - const spocTopsitesAdTypes = prepConfArr(pocketConfig.spocTopsitesAdTypes); - const spocTopsitesZoneIds = prepConfArr(pocketConfig.spocTopsitesZoneIds); const { spocSiteId } = pocketConfig; let spocPlacementData; - let spocTopsitesPlacementData; let spocsUrl; if (spocAdTypes?.length && spocZoneIds?.length) { @@ -791,13 +727,6 @@ export class DiscoveryStreamFeed { }; } - if (spocTopsitesAdTypes?.length && spocTopsitesZoneIds?.length) { - spocTopsitesPlacementData = { - ad_types: spocTopsitesAdTypes, - zone_ids: spocTopsitesZoneIds, - }; - } - if (spocSiteId) { const newUrl = new URL(SPOCS_URL); newUrl.searchParams.set("site", spocSiteId); @@ -813,14 +742,9 @@ export class DiscoveryStreamFeed { feedUrl, items, spocPlacementData, - spocTopsitesPlacementEnabled, - spocTopsitesPlacementData, spocPositions: this.parseGridPositions( this.store.getState().Prefs.values[PREF_SPOC_POSITIONS]?.split(`,`) ), - spocTopsitesPositions: this.parseGridPositions( - pocketConfig.spocTopsitesPositions?.split(`,`) - ), widgetPositions: this.parseGridPositions( pocketConfig.widgetPositions?.split(`,`) ), @@ -1224,14 +1148,7 @@ export class DiscoveryStreamFeed { // Currently the order of this is important. // We need to check this after updatePlacements is called, // because some of the spoc logic depends on the result of placement updates. - if ( - !( - (this.showSponsoredStories || - (this.showTopsites && this.showSponsoredTopsites)) && - (this.showSponsoredTopsites || - (this.showStories && this.showSponsoredStories)) - ) - ) { + if (!this.showSponsoredStories) { // Ensure we delete any remote data potentially related to spocs. this.clearSpocs(); } @@ -1254,44 +1171,10 @@ export class DiscoveryStreamFeed { let unifiedAdsPlacements = []; if ( - this.showSpocs && + this.showSponsoredStories && placements?.length && this.isExpired({ cachedData, key: "spocs", isStartup }) ) { - // We optimistically set this to true, because if SOV is not ready, we fetch them. - let useTopsitesPlacement = true; - - // If SOV is turned off or not available, we optimistically fetch sponsored topsites. - if ( - lazy.NimbusFeatures.pocketNewtab.getVariable( - NIMBUS_VARIABLE_CONTILE_SOV_ENABLED - ) && - !unifiedAdsEnabled - ) { - let { positions, ready } = this.store.getState().TopSites.sov; - if (ready) { - // We don't need to await here, because we don't need it now. - this.cache.set("sov", positions); - } else { - // If SOV is not available, and there is a SOV cache, use it. - positions = cachedData.sov; - } - - if (positions?.length) { - // If SOV is ready and turned on, we can check if we need moz-sales position. - useTopsitesPlacement = positions.some( - allocation => allocation.assignedPartner === "moz-sales" - ); - } - } - - // We can filter out the topsite placement from the fetch. - if (!useTopsitesPlacement || unifiedAdsEnabled) { - placements = placements.filter( - placement => placement.name !== "sponsored-topsites" - ); - } - if (placements?.length) { const headers = new Headers(); headers.append("content-type", "application/json"); @@ -2219,16 +2102,13 @@ export class DiscoveryStreamFeed { : this.store.dispatch; this.loadLayout(dispatch, isStartup); - if (this.showStories || this.showTopsites) { + if (this.showStories) { const spocsStartupCacheEnabled = this.store.getState().Prefs.values[PREF_SPOCS_STARTUP_CACHE_ENABLED]; const promises = []; // We don't want to make spoc requests during system tick if on demand is on. if (!(this.spocsOnDemand && isSystemTick)) { - // We could potentially have either or both sponsored topsites or stories. - // We only make one fetch, and control which to request when we fetch. - // So for now we only care if we need to make this request at all. const spocsPromise = this.loadSpocs( dispatch, isStartup && spocsStartupCacheEnabled @@ -2237,15 +2117,10 @@ export class DiscoveryStreamFeed { ); promises.push(spocsPromise); } - if (this.showStories) { - const storiesPromise = this.loadComponentFeeds( - dispatch, - isStartup - ).catch(error => - console.error("Error trying to load component feeds:", error) - ); - promises.push(storiesPromise); - } + const storiesPromise = this.loadComponentFeeds(dispatch, isStartup).catch( + error => console.error("Error trying to load component feeds:", error) + ); + promises.push(storiesPromise); await Promise.all(promises); // We don't need to check onDemand here, // even though _maybeUpdateCachedData fetches spocs. @@ -2311,7 +2186,6 @@ export class DiscoveryStreamFeed { async resetContentCache() { await this.cache.set("feeds", {}); await this.cache.set("spocs", {}); - await this.cache.set("sov", {}); await this.cache.set("recsImpressions", {}); } @@ -2652,26 +2526,9 @@ export class DiscoveryStreamFeed { await this.resetContentFeed(); this.refreshAll({ updateOpenTabs: true }); break; - case PREF_USER_TOPSITES: - case PREF_SYSTEM_TOPSITES: - if ( - !( - this.showTopsites || - (this.showStories && this.showSponsoredStories) - ) - ) { - // Ensure we delete any remote data potentially related to spocs. - this.clearSpocs(); - } - break; case PREF_USER_TOPSTORIES: case PREF_SYSTEM_TOPSTORIES: - if ( - !( - this.showStories || - (this.showTopsites && this.showSponsoredTopsites) - ) - ) { + if (!this.showStories) { // Ensure we delete any remote data potentially related to spocs. this.clearSpocs(); } @@ -2679,9 +2536,8 @@ export class DiscoveryStreamFeed { this.enableStories(); } break; - // Check if spocs was disabled. Remove them if they were. - case PREF_SHOW_SPONSORED: - case PREF_SHOW_SPONSORED_TOPSITES: { + // Remove spocs if turned off. + case PREF_SHOW_SPONSORED: { await this.updateOrRemoveSpocs(); break; } @@ -2815,7 +2671,7 @@ export class DiscoveryStreamFeed { } break; case at.DISCOVERY_STREAM_SPOC_IMPRESSION: - if (this.showSpocs) { + if (this.showSponsoredStories) { this.recordFlightImpression(action.data.flightId); // Apply frequency capping to SPOCs in the redux store, only update the @@ -2894,7 +2750,7 @@ export class DiscoveryStreamFeed { await this.cache.set("feeds", feeds); - if (this.showSpocs) { + if (this.showSponsoredStories) { let blockedItems = []; const spocsState = this.store.getState().DiscoveryStream.spocs; @@ -3013,10 +2869,7 @@ export class DiscoveryStreamFeed { `feedUrl` Where to fetch stories from. `items` How many items to include in the primary card grid. `spocPositions` Changes the position of spoc cards. - `spocTopsitesPositions` Changes the position of spoc topsites. `spocPlacementData` Used to set the spoc content. - `spocTopsitesPlacementEnabled` Tuns on and off the sponsored topsites placement. - `spocTopsitesPlacementData` Used to set spoc content for topsites. `hybridLayout` Changes cards to smaller more compact cards only for specific breakpoints. `hideCardBackground` Removes Pocket card background and borders. `fourCardLayout` Enable four Pocket cards per row. @@ -3030,10 +2883,7 @@ getHardcodedLayout = ({ feedUrl, items = 21, spocPositions = [1, 5, 7, 11, 18, 20], - spocTopsitesPositions = [1], spocPlacementData = { ad_types: [3617], zone_ids: [217758, 217995] }, - spocTopsitesPlacementEnabled = false, - spocTopsitesPlacementData = { ad_types: [3120], zone_ids: [280143] }, widgetPositions = [], widgetData = [], hybridLayout = false, @@ -3060,22 +2910,6 @@ getHardcodedLayout = ({ id: "newtab-section-header-topsites", }, }, - ...(spocTopsitesPlacementEnabled && spocTopsitesPlacementData - ? { - placement: { - name: "sponsored-topsites", - ad_types: spocTopsitesPlacementData.ad_types, - zone_ids: spocTopsitesPlacementData.zone_ids, - }, - spocs: { - probability: 1, - prefs: [PREF_SHOW_SPONSORED_TOPSITES], - positions: spocTopsitesPositions.map(position => { - return { index: position }; - }), - }, - } - : {}), properties: {}, }, { diff --git a/browser/extensions/newtab/lib/TopSitesFeed.sys.mjs b/browser/extensions/newtab/lib/TopSitesFeed.sys.mjs @@ -95,8 +95,6 @@ const NIMBUS_VARIABLE_MAX_SPONSORED = "topSitesMaxSponsored"; //considered for Top Sites. const NIMBUS_VARIABLE_ADDITIONAL_TILES = "topSitesUseAdditionalTilesFromContile"; -// Nimbus variable to enable the SOV feature for sponsored tiles. -const NIMBUS_VARIABLE_CONTILE_SOV_ENABLED = "topSitesContileSovEnabled"; // Nimbu variable for the total number of sponsor topsite that come from Contile // The default will be `CONTILE_MAX_NUM_SPONSORED` if variable is unspecified. const NIMBUS_VARIABLE_CONTILE_MAX_NUM_SPONSORED = "topSitesContileMaxSponsored"; @@ -1594,13 +1592,7 @@ export class TopSitesFeed { _mergeSponsoredLinks(sponsoredLinks) { const { positions: allocatedPositions, ready: sovReady } = this.store.getState().TopSites.sov || {}; - if ( - !this._contile.sov || - !sovReady || - !lazy.NimbusFeatures.pocketNewtab.getVariable( - NIMBUS_VARIABLE_CONTILE_SOV_ENABLED - ) - ) { + if (!this._contile.sov || !sovReady) { return Object.values(sponsoredLinks).flat(); } diff --git a/browser/extensions/newtab/test/unit/lib/DiscoveryStreamFeed.test.js b/browser/extensions/newtab/test/unit/lib/DiscoveryStreamFeed.test.js @@ -521,28 +521,6 @@ describe("DiscoveryStreamFeed", () => { [4560, 7890] ); }); - it("should create a layout with spoc topsite position data", async () => { - feed.store = createStore(combineReducers(reducers), { - Prefs: { - values: { - pocketConfig: { - spocTopsitesPlacementEnabled: true, - spocTopsitesAdTypes: "1230", - spocTopsitesZoneIds: "4560, 7890", - }, - }, - }, - }); - - await feed.loadLayout(feed.store.dispatch); - - const { layout } = feed.store.getState().DiscoveryStream; - assert.deepEqual(layout[0].components[0].placement.ad_types, [1230]); - assert.deepEqual( - layout[0].components[0].placement.zone_ids, - [4560, 7890] - ); - }); it("should create a layout with proper spoc url with a site id", async () => { feed.store = createStore(combineReducers(reducers), { Prefs: { @@ -588,39 +566,6 @@ describe("DiscoveryStreamFeed", () => { meta: { isStartup: false }, }); }); - it("should dispatch DISCOVERY_STREAM_SPOCS_PLACEMENTS with prefs array", () => { - sandbox.spy(feed.store, "dispatch"); - feed.store.getState = () => ({ - Prefs: { - values: { - showSponsored: true, - withPref: true, - "system.showSponsored": true, - }, - }, - }); - const fakeComponents = { - components: [ - { placement: { name: "withPref" }, spocs: { prefs: ["withPref"] } }, - { placement: { name: "withoutPref1" }, spocs: {} }, - { - placement: { name: "withoutPref2" }, - spocs: { prefs: ["whatever"] }, - }, - { placement: { name: "withoutPref3" }, spocs: { prefs: [] } }, - ], - }; - const fakeLayout = [fakeComponents]; - - feed.updatePlacements(feed.store.dispatch, fakeLayout); - - assert.calledOnce(feed.store.dispatch); - assert.calledWith(feed.store.dispatch, { - type: "DISCOVERY_STREAM_SPOCS_PLACEMENTS", - data: { placements: [{ name: "withPref" }, { name: "withoutPref1" }] }, - meta: { isStartup: false }, - }); - }); it("should fire update placements from loadLayout", async () => { sandbox.spy(feed, "updatePlacements"); @@ -807,7 +752,7 @@ describe("DiscoveryStreamFeed", () => { }; sandbox.stub(feed, "getPlacements").returns([{ name: "spocs" }]); - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); }); it("should not fetch or update cache if no spocs endpoint is defined", async () => { feed.store.dispatch( @@ -953,9 +898,6 @@ describe("DiscoveryStreamFeed", () => { // We don't need this for just this test, we are setting placements // manually. feed.getPlacements.restore(); - Object.defineProperty(feed, "showSponsoredStories", { - get: () => true, - }); sandbox.stub(feed.cache, "get").returns(Promise.resolve()); sandbox @@ -993,9 +935,6 @@ describe("DiscoveryStreamFeed", () => { // We don't need this for just this test, we are setting placements // manually. feed.getPlacements.restore(); - Object.defineProperty(feed, "showSponsoredStories", { - get: () => true, - }); sandbox.stub(feed.cache, "get").returns(Promise.resolve()); sandbox.stub(feed, "fetchFromEndpoint").resolves({ placement1: { @@ -1070,175 +1009,6 @@ describe("DiscoveryStreamFeed", () => { "geoname_id" ); }); - describe("test SOV behaviour", () => { - beforeEach(() => { - globals.set("NimbusFeatures", { - pocketNewtab: { - getVariable: sandbox.stub(), - }, - }); - global.NimbusFeatures.pocketNewtab.getVariable - .withArgs("topSitesContileSovEnabled") - .returns(true); - // We don't need this for just this test, we are setting placements - // manually. - feed.getPlacements.restore(); - Object.defineProperty(feed, "showSponsoredStories", { - get: () => true, - }); - const fakeComponents = { - components: [ - { placement: { name: "sponsored-topsites" }, spocs: {} }, - { placement: { name: "spocs" }, spocs: {} }, - ], - }; - feed.updatePlacements(feed.store.dispatch, [fakeComponents]); - sandbox.stub(feed.cache, "get").returns(Promise.resolve()); - sandbox.stub(feed, "fetchFromEndpoint").resolves({ - spocs: [{ id: "spoc1" }], - "sponsored-topsites": [{ id: "topsite1" }], - }); - }); - it("should use topsites placement by default if there is no SOV", async () => { - await feed.loadSpocs(feed.store.dispatch); - - assert.equal( - feed.fetchFromEndpoint.firstCall.args[1].body, - JSON.stringify({ - pocket_id: "{foo-123-foo}", - version: 2, - placements: [ - { - name: "sponsored-topsites", - }, - { - name: "spocs", - }, - ], - }) - ); - }); - it("should use cache if cache is available and SOV is not ready", async () => { - const cache = { - sov: [{ assignedPartner: "amp" }], - }; - feed.cache.get.resolves(cache); - await feed.loadSpocs(feed.store.dispatch); - - assert.equal( - feed.fetchFromEndpoint.firstCall.args[1].body, - JSON.stringify({ - pocket_id: "{foo-123-foo}", - version: 2, - placements: [ - { - name: "spocs", - }, - ], - }) - ); - }); - it("should properly set placements", async () => { - sandbox.spy(feed.cache, "set"); - - // Testing only 1 placement type. - feed.store.dispatch( - ac.OnlyToMain({ - type: at.SOV_UPDATED, - data: { - ready: true, - positions: [ - { - position: 1, - assignedPartner: "amp", - }, - { - position: 2, - assignedPartner: "amp", - }, - ], - }, - }) - ); - - await feed.loadSpocs(feed.store.dispatch); - - const firstCall = feed.cache.set.getCall(0); - assert.deepEqual(firstCall.args[0], "sov"); - assert.deepEqual(firstCall.args[1], [ - { - position: 1, - assignedPartner: "amp", - }, - { - position: 2, - assignedPartner: "amp", - }, - ]); - assert.equal( - feed.fetchFromEndpoint.firstCall.args[1].body, - JSON.stringify({ - pocket_id: "{foo-123-foo}", - version: 2, - placements: [ - { - name: "spocs", - }, - ], - }) - ); - - // Testing 2 placement types. - feed.store.dispatch( - ac.OnlyToMain({ - type: at.SOV_UPDATED, - data: { - ready: true, - positions: [ - { - position: 1, - assignedPartner: "amp", - }, - { - position: 2, - assignedPartner: "moz-sales", - }, - ], - }, - }) - ); - - await feed.loadSpocs(feed.store.dispatch); - - const secondCall = feed.cache.set.getCall(2); - assert.deepEqual(secondCall.args[0], "sov"); - assert.deepEqual(secondCall.args[1], [ - { - position: 1, - assignedPartner: "amp", - }, - { - position: 2, - assignedPartner: "moz-sales", - }, - ]); - assert.equal( - feed.fetchFromEndpoint.secondCall.args[1].body, - JSON.stringify({ - pocket_id: "{foo-123-foo}", - version: 2, - placements: [ - { - name: "sponsored-topsites", - }, - { - name: "spocs", - }, - ], - }) - ); - }); - }); }); describe("#normalizeSpocsItems", () => { @@ -1279,45 +1049,6 @@ describe("DiscoveryStreamFeed", () => { }); }); - describe("#showSpocs", () => { - it("should return true from showSpocs if showSponsoredStories is false", async () => { - Object.defineProperty(feed, "showSponsoredStories", { - get: () => false, - }); - Object.defineProperty(feed, "showSponsoredTopsites", { - get: () => true, - }); - assert.isTrue(feed.showSpocs); - }); - it("should return true from showSpocs if showSponsoredTopsites is false", async () => { - Object.defineProperty(feed, "showSponsoredStories", { - get: () => true, - }); - Object.defineProperty(feed, "showSponsoredTopsites", { - get: () => false, - }); - assert.isTrue(feed.showSpocs); - }); - it("should return true from showSpocs if both are true", async () => { - Object.defineProperty(feed, "showSponsoredStories", { - get: () => true, - }); - Object.defineProperty(feed, "showSponsoredTopsites", { - get: () => true, - }); - assert.isTrue(feed.showSpocs); - }); - it("should return false from showSpocs if both are false", async () => { - Object.defineProperty(feed, "showSponsoredStories", { - get: () => false, - }); - Object.defineProperty(feed, "showSponsoredTopsites", { - get: () => false, - }); - assert.isFalse(feed.showSpocs); - }); - }); - describe("#showSponsoredStories", () => { it("should return false from showSponsoredStories if user pref showSponsored is false", async () => { feed.store.getState = () => ({ @@ -1348,31 +1079,6 @@ describe("DiscoveryStreamFeed", () => { }); }); - describe("#showSponsoredTopsites", () => { - it("should return false from showSponsoredTopsites if user pref showSponsoredTopSites is false", async () => { - feed.store.getState = () => ({ - Prefs: { values: { showSponsoredTopSites: false } }, - DiscoveryStream: { - spocs: { - placements: [{ name: "sponsored-topsites" }], - }, - }, - }); - assert.isFalse(feed.showSponsoredTopsites); - }); - it("should return true from showSponsoredTopsites if user pref showSponsoredTopSites is true", async () => { - feed.store.getState = () => ({ - Prefs: { values: { showSponsoredTopSites: true } }, - DiscoveryStream: { - spocs: { - placements: [{ name: "sponsored-topsites" }], - }, - }, - }); - assert.isTrue(feed.showSponsoredTopsites); - }); - }); - describe("#showStories", () => { it("should return false from showStories if user pref is false", async () => { feed.store.getState = () => ({ @@ -1409,42 +1115,6 @@ describe("DiscoveryStreamFeed", () => { }); }); - describe("#showTopsites", () => { - it("should return false from showTopsites if user pref is false", async () => { - feed.store.getState = () => ({ - Prefs: { - values: { - "feeds.topsites": false, - "feeds.system.topsites": true, - }, - }, - }); - assert.isFalse(feed.showTopsites); - }); - it("should return false from showTopsites if system pref is false", async () => { - feed.store.getState = () => ({ - Prefs: { - values: { - "feeds.topsites": true, - "feeds.system.topsites": false, - }, - }, - }); - assert.isFalse(feed.showTopsites); - }); - it("should return true from showTopsites if both prefs are true", async () => { - feed.store.getState = () => ({ - Prefs: { - values: { - "feeds.topsites": true, - "feeds.system.topsites": true, - }, - }, - }); - assert.isTrue(feed.showTopsites); - }); - }); - describe("#clearSpocs", () => { let defaultState; let DiscoveryStream; @@ -1452,17 +1122,11 @@ describe("DiscoveryStreamFeed", () => { beforeEach(() => { DiscoveryStream = { layout: [], - spocs: { - placements: [{ name: "sponsored-topsites" }], - }, }; Prefs = { values: { "feeds.section.topstories": true, "feeds.system.topstories": true, - "feeds.topsites": true, - "feeds.system.topsites": true, - showSponsoredTopSites: true, showSponsored: true, "system.showSponsored": true, }, @@ -1519,7 +1183,6 @@ describe("DiscoveryStreamFeed", () => { assert.notCalled(feed.clearSpocs); - Prefs.values.showSponsoredTopSites = false; Prefs.values.showSponsored = false; await feed.onAction({ @@ -1529,10 +1192,9 @@ describe("DiscoveryStreamFeed", () => { assert.calledOnce(feed.clearSpocs); }); - it("should call clearSpocs when top stories and top sites is turned off", async () => { + it("should call clearSpocs when top stories are turned off", async () => { sandbox.stub(feed, "clearSpocs").returns(Promise.resolve()); Prefs.values["feeds.section.topstories"] = false; - Prefs.values["feeds.topsites"] = false; await feed.onAction({ type: at.PREF_CHANGED, @@ -1540,13 +1202,6 @@ describe("DiscoveryStreamFeed", () => { }); assert.calledOnce(feed.clearSpocs); - - await feed.onAction({ - type: at.PREF_CHANGED, - data: { name: "feeds.topsites" }, - }); - - assert.calledTwice(feed.clearSpocs); }); }); @@ -1603,20 +1258,18 @@ describe("DiscoveryStreamFeed", () => { }); describe("#resetCache", () => { - it("should set .feeds .spocs and .sov to {}", async () => { + it("should set .feeds and .spocs and to {}", async () => { sandbox.stub(feed.cache, "set").returns(Promise.resolve()); await feed.resetCache(); - assert.callCount(feed.cache.set, 4); + assert.callCount(feed.cache.set, 3); const firstCall = feed.cache.set.getCall(0); const secondCall = feed.cache.set.getCall(1); const thirdCall = feed.cache.set.getCall(2); - const fourthCall = feed.cache.set.getCall(3); assert.deepEqual(firstCall.args, ["feeds", {}]); assert.deepEqual(secondCall.args, ["spocs", {}]); - assert.deepEqual(thirdCall.args, ["sov", {}]); - assert.deepEqual(fourthCall.args, ["recsImpressions", {}]); + assert.deepEqual(thirdCall.args, ["recsImpressions", {}]); }); }); @@ -2251,7 +1904,7 @@ describe("DiscoveryStreamFeed", () => { it("should call dispatch to ac.AlsoToPreloaded with filtered spoc data", async () => { sandbox.stub(feed, "getPlacements").returns([{ name: "spocs" }]); - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); const fakeImpressions = { seen: [Date.now() - 1], }; @@ -2288,7 +1941,7 @@ describe("DiscoveryStreamFeed", () => { }); it("should not call dispatch to ac.AlsoToPreloaded if spocs were not changed by frequency capping", async () => { sandbox.stub(feed, "getPlacements").returns([{ name: "spocs" }]); - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); const fakeImpressions = {}; sandbox.stub(feed, "recordFlightImpression").returns(); sandbox.stub(feed, "readDataPref").returns(fakeImpressions); @@ -2303,7 +1956,7 @@ describe("DiscoveryStreamFeed", () => { }); it("should attempt feq cap on valid spocs with placements on impression", async () => { sandbox.restore(); - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); const fakeImpressions = {}; sandbox.stub(feed, "recordFlightImpression").returns(); sandbox.stub(feed, "readDataPref").returns(fakeImpressions); @@ -2378,7 +2031,7 @@ describe("DiscoveryStreamFeed", () => { }); }); it("should call dispatch if found a blocked spoc", async () => { - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); Object.defineProperty(feed, "spocsOnDemand", { get: () => false }); Object.defineProperty(feed, "spocsCacheUpdateTime", { get: () => 30 * 60 * 1000, @@ -2397,7 +2050,7 @@ describe("DiscoveryStreamFeed", () => { ); }); it("should dispatch once if the blocked is not a SPOC", async () => { - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); sandbox.spy(feed.store, "dispatch"); await feed.onAction({ @@ -2412,7 +2065,7 @@ describe("DiscoveryStreamFeed", () => { ); }); it("should dispatch a DISCOVERY_STREAM_SPOC_BLOCKED for a blocked spoc", async () => { - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); Object.defineProperty(feed, "spocsOnDemand", { get: () => false }); Object.defineProperty(feed, "spocsCacheUpdateTime", { get: () => 30 * 60 * 1000, @@ -2948,7 +2601,7 @@ describe("DiscoveryStreamFeed", () => { feeds: { "foo.com": { lastUpdated: Date.now() } }, spocs: { lastUpdated: Date.now() }, }; - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); sandbox.stub(feed.cache, "get").resolves(cache); }); @@ -3004,7 +2657,7 @@ describe("DiscoveryStreamFeed", () => { sandbox.stub(feed, "loadComponentFeeds").resolves(); sandbox.stub(feed, "loadSpocs").resolves(); sandbox.spy(feed.store, "dispatch"); - Object.defineProperty(feed, "showSpocs", { get: () => true }); + Object.defineProperty(feed, "showSponsoredStories", { get: () => true }); }); it("should call layout, component, spocs update and telemetry reporting functions", async () => { diff --git a/toolkit/components/nimbus/FeatureManifest.yaml b/toolkit/components/nimbus/FeatureManifest.yaml @@ -1748,10 +1748,6 @@ pocketNewtab: hasExposure: false isEarlyStartup: true variables: - spocTopsitesPositions: - type: string - fallbackPref: browser.newtabpage.activity-stream.discoverystream.spoc-topsites-positions - description: CSV string of spoc position indexes on newtab topsites section contileTopsitesPositions: type: string fallbackPref: browser.newtabpage.activity-stream.discoverystream.contile-topsites-positions @@ -1764,18 +1760,6 @@ pocketNewtab: type: string fallbackPref: browser.newtabpage.activity-stream.discoverystream.spocZoneIds description: CSV string of data to set the spoc content. - spocTopsitesAdTypes: - type: string - fallbackPref: browser.newtabpage.activity-stream.discoverystream.spocTopsitesAdTypes - description: CSV string of data to set the spoc content. - spocTopsitesZoneIds: - type: string - fallbackPref: browser.newtabpage.activity-stream.discoverystream.spocTopsitesZoneIds - description: CSV string of data to set the spoc content. - spocTopsitesPlacementEnabled: - type: boolean - fallbackPref: browser.newtabpage.activity-stream.discoverystream.spocTopsitesPlacement.enabled - description: Tuns on and off the sponsored topsites placement. spocSiteId: type: string fallbackPref: browser.newtabpage.activity-stream.discoverystream.spocSiteId @@ -1996,12 +1980,6 @@ pocketNewtab: # Defined under `pocketNewtab` as it needs to be used along with other variables type: int description: The maximum number of sponsored Top Sites used from Contile - topSitesContileSovEnabled: - # Defined under `pocketNewtab` as it needs to be used along with other variables - description: Enable the Share-of-Voice feature for Sponsored Topsites. - type: boolean - fallbackPref: >- - browser.topsites.contile.sov.enabled pocketFeedParameters: type: string fallbackPref: >-