Backed out changeset 51080108cc0d (bug 1805589) for causing mochitests failures in browser/components/newtab/test/browser/abouthomecache/browser_no_startup_actions.js. CLOSED TREE

This commit is contained in:
Stanca Serban
2023-03-03 21:29:55 +02:00
parent 140b240a03
commit ba2c013d86
11 changed files with 469 additions and 146 deletions

View File

@@ -1609,7 +1609,6 @@ pref("browser.newtabpage.activity-stream.discoverystream.essentialReadsHeader.en
pref("browser.newtabpage.activity-stream.discoverystream.recentSaves.enabled", false);
pref("browser.newtabpage.activity-stream.discoverystream.editorsPicksHeader.enabled", false);
pref("browser.newtabpage.activity-stream.discoverystream.spoc-positions", "1,5,7,11,18,20");
pref("browser.newtabpage.activity-stream.discoverystream.spoc-topsites-positions", "1");
pref("browser.newtabpage.activity-stream.discoverystream.widget-positions", "");
pref("browser.newtabpage.activity-stream.discoverystream.spocs-endpoint", "");

View File

@@ -17,7 +17,7 @@ import { PrivacyLink } from "content-src/components/DiscoveryStreamComponents/Pr
import React from "react";
import { SectionTitle } from "content-src/components/DiscoveryStreamComponents/SectionTitle/SectionTitle";
import { selectLayoutRender } from "content-src/lib/selectLayoutRender";
import { TopSites } from "content-src/components/TopSites/TopSites";
import { TopSites } from "content-src/components/DiscoveryStreamComponents/TopSites/TopSites";
const ALLOWED_CSS_URL_PREFIXES = [
"chrome://",
@@ -114,10 +114,16 @@ export class _DiscoveryStreamBase extends React.PureComponent {
case "Highlights":
return <Highlights />;
case "TopSites":
let positions = [];
if (component?.spocs?.positions?.length) {
positions = component.spocs.positions;
}
return (
<div className="ds-top-sites">
<TopSites isFixed={true} title={component.header?.title} />
</div>
<TopSites
header={component.header}
data={component.data}
promoPositions={positions}
/>
);
case "TextPromo":
return (

View File

@@ -0,0 +1,122 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
import { connect } from "react-redux";
import { TopSites as OldTopSites } from "content-src/components/TopSites/TopSites";
import React from "react";
export class _TopSites extends React.PureComponent {
// Find a SPOC that doesn't already exist in User's TopSites
getFirstAvailableSpoc(topSites, data) {
const { spocs } = data;
if (!spocs || spocs.length === 0) {
return null;
}
const userTopSites = new Set(
topSites.map(topSite => topSite && topSite.url)
);
// We "clean urls" with http in TopSiteForm.jsx
// Spoc domains are in the format 'sponsorname.com'
return spocs.find(
spoc =>
!userTopSites.has(spoc.url) &&
!userTopSites.has(`http://${spoc.domain}`) &&
!userTopSites.has(`https://${spoc.domain}`) &&
!userTopSites.has(`http://www.${spoc.domain}`) &&
!userTopSites.has(`https://www.${spoc.domain}`)
);
}
reformatImageURL(url, width, height) {
// Change the image URL to request a size tailored for the parent container width
// Also: force JPEG, quality 60, no upscaling, no EXIF data
// Uses Thumbor: https://thumbor.readthedocs.io/en/latest/usage.html
return `https://img-getpocket.cdn.mozilla.net/${width}x${height}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/${encodeURIComponent(
url
)}`;
}
// For the time being we only support 1 position.
insertSpocContent(TopSites, data, promoPosition) {
if (
!TopSites.rows ||
TopSites.rows.length === 0 ||
!data.spocs ||
data.spocs.length === 0
) {
return null;
}
let topSites = [...TopSites.rows];
const topSiteSpoc = this.getFirstAvailableSpoc(topSites, data);
if (!topSiteSpoc) {
return null;
}
const link = {
customScreenshotURL: this.reformatImageURL(
topSiteSpoc.raw_image_src,
40,
40
),
type: "SPOC",
label: topSiteSpoc.title || topSiteSpoc.sponsor,
title: topSiteSpoc.title || topSiteSpoc.sponsor,
url: topSiteSpoc.url,
flightId: topSiteSpoc.flight_id,
id: topSiteSpoc.id,
guid: topSiteSpoc.id,
shim: topSiteSpoc.shim,
// For now we are assuming position based on intended position.
// Actual position can shift based on other content.
// We also hard code left and right to be 0 and 7.
// We send the intended position in the ping.
pos: promoPosition,
};
// Remove first contile or regular topsite, then insert new spoc into position.
const replaceIndex = topSites.findIndex(
(topSite, index) =>
index >= promoPosition &&
(!topSite ||
topSite.show_sponsored_label ||
!(topSite.isPinned || topSite.searchTopSite))
);
// If we found something to replace, first remove it.
if (replaceIndex !== -1) {
topSites.splice(replaceIndex, 1);
}
topSites.splice(promoPosition, 0, link);
return { ...TopSites, rows: topSites };
}
render() {
const { header = {}, data, promoPositions, TopSites } = this.props;
const TopSitesWithSpoc =
TopSites && data && promoPositions?.length
? this.insertSpocContent(TopSites, data, promoPositions[0].index)
: null;
return (
<div
className={`ds-top-sites ${TopSitesWithSpoc ? "top-sites-spoc" : ""}`}
>
<OldTopSites
isFixed={true}
title={header.title}
TopSitesWithSpoc={TopSitesWithSpoc}
/>
</div>
);
}
}
export const TopSites = connect(state => ({ TopSites: state.TopSites }))(
_TopSites
);

View File

@@ -207,7 +207,8 @@ export class _TopSites extends React.PureComponent {
}
export const TopSites = connect((state, props) => ({
TopSites: state.TopSites,
// For SPOC Experiment only, take TopSites from DiscoveryStream TopSites that takes in SPOC Data
TopSites: props.TopSitesWithSpoc || state.TopSites,
Prefs: state.Prefs,
TopSitesRows: state.Prefs.values.topSitesRows,
}))(_TopSites);

View File

@@ -12938,7 +12938,8 @@ class _TopSites extends (external_React_default()).PureComponent {
}
const TopSites_TopSites = (0,external_ReactRedux_namespaceObject.connect)((state, props) => ({
TopSites: state.TopSites,
// For SPOC Experiment only, take TopSites from DiscoveryStream TopSites that takes in SPOC Data
TopSites: props.TopSitesWithSpoc || state.TopSites,
Prefs: state.Prefs,
TopSitesRows: state.Prefs.values.topSitesRows
}))(_TopSites);
@@ -13677,6 +13678,100 @@ const selectLayoutRender = ({
layoutRender
};
};
;// CONCATENATED MODULE: ./content-src/components/DiscoveryStreamComponents/TopSites/TopSites.jsx
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
class TopSites_TopSites_TopSites extends (external_React_default()).PureComponent {
// Find a SPOC that doesn't already exist in User's TopSites
getFirstAvailableSpoc(topSites, data) {
const {
spocs
} = data;
if (!spocs || spocs.length === 0) {
return null;
}
const userTopSites = new Set(topSites.map(topSite => topSite && topSite.url)); // We "clean urls" with http in TopSiteForm.jsx
// Spoc domains are in the format 'sponsorname.com'
return spocs.find(spoc => !userTopSites.has(spoc.url) && !userTopSites.has(`http://${spoc.domain}`) && !userTopSites.has(`https://${spoc.domain}`) && !userTopSites.has(`http://www.${spoc.domain}`) && !userTopSites.has(`https://www.${spoc.domain}`));
}
reformatImageURL(url, width, height) {
// Change the image URL to request a size tailored for the parent container width
// Also: force JPEG, quality 60, no upscaling, no EXIF data
// Uses Thumbor: https://thumbor.readthedocs.io/en/latest/usage.html
return `https://img-getpocket.cdn.mozilla.net/${width}x${height}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/${encodeURIComponent(url)}`;
} // For the time being we only support 1 position.
insertSpocContent(TopSites, data, promoPosition) {
if (!TopSites.rows || TopSites.rows.length === 0 || !data.spocs || data.spocs.length === 0) {
return null;
}
let topSites = [...TopSites.rows];
const topSiteSpoc = this.getFirstAvailableSpoc(topSites, data);
if (!topSiteSpoc) {
return null;
}
const link = {
customScreenshotURL: this.reformatImageURL(topSiteSpoc.raw_image_src, 40, 40),
type: "SPOC",
label: topSiteSpoc.title || topSiteSpoc.sponsor,
title: topSiteSpoc.title || topSiteSpoc.sponsor,
url: topSiteSpoc.url,
flightId: topSiteSpoc.flight_id,
id: topSiteSpoc.id,
guid: topSiteSpoc.id,
shim: topSiteSpoc.shim,
// For now we are assuming position based on intended position.
// Actual position can shift based on other content.
// We also hard code left and right to be 0 and 7.
// We send the intended position in the ping.
pos: promoPosition
}; // Remove first contile or regular topsite, then insert new spoc into position.
const replaceIndex = topSites.findIndex((topSite, index) => index >= promoPosition && (!topSite || topSite.show_sponsored_label || !(topSite.isPinned || topSite.searchTopSite))); // If we found something to replace, first remove it.
if (replaceIndex !== -1) {
topSites.splice(replaceIndex, 1);
}
topSites.splice(promoPosition, 0, link);
return { ...TopSites,
rows: topSites
};
}
render() {
const {
header = {},
data,
promoPositions,
TopSites
} = this.props;
const TopSitesWithSpoc = TopSites && data && promoPositions !== null && promoPositions !== void 0 && promoPositions.length ? this.insertSpocContent(TopSites, data, promoPositions[0].index) : null;
return /*#__PURE__*/external_React_default().createElement("div", {
className: `ds-top-sites ${TopSitesWithSpoc ? "top-sites-spoc" : ""}`
}, /*#__PURE__*/external_React_default().createElement(TopSites_TopSites, {
isFixed: true,
title: header.title,
TopSitesWithSpoc: TopSitesWithSpoc
}));
}
}
const DiscoveryStreamComponents_TopSites_TopSites_TopSites = (0,external_ReactRedux_namespaceObject.connect)(state => ({
TopSites: state.TopSites
}))(TopSites_TopSites_TopSites);
;// CONCATENATED MODULE: ./content-src/components/DiscoveryStreamBase/DiscoveryStreamBase.jsx
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
@@ -13769,19 +13864,24 @@ class _DiscoveryStreamBase extends (external_React_default()).PureComponent {
}
renderComponent(component, embedWidth) {
var _component$header;
var _component$spocs, _component$spocs$posi;
switch (component.type) {
case "Highlights":
return /*#__PURE__*/external_React_default().createElement(Highlights, null);
case "TopSites":
return /*#__PURE__*/external_React_default().createElement("div", {
className: "ds-top-sites"
}, /*#__PURE__*/external_React_default().createElement(TopSites_TopSites, {
isFixed: true,
title: (_component$header = component.header) === null || _component$header === void 0 ? void 0 : _component$header.title
}));
let positions = [];
if (component !== null && component !== void 0 && (_component$spocs = component.spocs) !== null && _component$spocs !== void 0 && (_component$spocs$posi = _component$spocs.positions) !== null && _component$spocs$posi !== void 0 && _component$spocs$posi.length) {
positions = component.spocs.positions;
}
return /*#__PURE__*/external_React_default().createElement(DiscoveryStreamComponents_TopSites_TopSites_TopSites, {
header: component.header,
data: component.data,
promoPositions: positions
});
case "TextPromo":
return /*#__PURE__*/external_React_default().createElement(DSTextPromo, {

View File

@@ -703,9 +703,6 @@ class DiscoveryStreamFeed {
spocPositions: this.parseGridPositions(
pocketConfig.spocPositions?.split(`,`)
),
spocTopsitesPositions: this.parseGridPositions(
pocketConfig.spocTopsitesPositions?.split(`,`)
),
widgetPositions: this.parseGridPositions(
pocketConfig.widgetPositions?.split(`,`)
),
@@ -2148,7 +2145,6 @@ class DiscoveryStreamFeed {
`spocsUrl` Changing the url for spocs is used for adding a siteId query param.
`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.
`spocTopsitesPlacementData` Used to set spoc content for topsites.
`sponsoredCollectionsEnabled` Tuns on and off the sponsored collection section.
@@ -2164,7 +2160,6 @@ getHardcodedLayout = ({
spocsUrl = SPOCS_URL,
items = 21,
spocPositions = [1, 5, 7, 11, 18, 20],
spocTopsitesPositions = [1],
spocPlacementData = { ad_types: [3617], zone_ids: [217758, 217995] },
spocTopsitesPlacementData,
widgetPositions = [],
@@ -2203,9 +2198,11 @@ getHardcodedLayout = ({
spocs: {
probability: 1,
prefs: [PREF_SHOW_SPONSORED_TOPSITES],
positions: spocTopsitesPositions.map(position => {
return { index: position };
}),
positions: [
{
index: 1,
},
],
},
}
: {}),

View File

@@ -654,70 +654,6 @@ class TopSitesFeed {
return false;
}
insertDiscoveryStreamSpocs(sponsored) {
const { DiscoveryStream } = this.store.getState();
if (DiscoveryStream) {
const discoveryStreamSpocs =
DiscoveryStream.spocs.data["sponsored-topsites"]?.items;
// Find the first component of a type and remove it from layout
const findSponsoredTopsitesPositions = name => {
for (const row of DiscoveryStream.layout) {
for (const component of row.components) {
if (component.placement?.name === name) {
return component.spocs.positions;
}
}
}
return null;
};
// Get positions from layout for now. This could be improved if we store position data in state.
const discoveryStreamSpocPositions = findSponsoredTopsitesPositions(
"sponsored-topsites"
);
if (discoveryStreamSpocPositions?.length) {
function reformatImageURL(url, width, height) {
// Change the image URL to request a size tailored for the parent container width
// Also: force JPEG, quality 60, no upscaling, no EXIF data
// Uses Thumbor: https://thumbor.readthedocs.io/en/latest/usage.html
return `https://img-getpocket.cdn.mozilla.net/${width}x${height}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/${encodeURIComponent(
url
)}`;
}
// We need to loop through potential spocs and set their positions.
// If we run out of spocs or positions, we stop.
// First, we need to know which array is shortest. This is our exit condition.
const minLength = Math.min(
discoveryStreamSpocPositions.length,
discoveryStreamSpocs.length
);
// Loop until we run out of spocs or positions.
for (let i = 0; i < minLength; i++) {
const positionIndex = discoveryStreamSpocPositions[i].index;
const spoc = discoveryStreamSpocs[i];
const link = {
customScreenshotURL: reformatImageURL(spoc.raw_image_src, 40, 40),
type: "SPOC",
label: spoc.title || spoc.sponsor,
title: spoc.title || spoc.sponsor,
url: spoc.url,
flightId: spoc.flight_id,
id: spoc.id,
guid: spoc.id,
shim: spoc.shim,
// For now we are assuming position based on intended position.
// Actual position can shift based on other content.
// We send the intended position in the ping.
pos: positionIndex,
};
sponsored.push(link);
}
}
}
}
// eslint-disable-next-line max-statements
async getLinksWithDefaults(isStartup = false) {
const prefValues = this.store.getState().Prefs.values;
@@ -819,8 +755,6 @@ class TopSitesFeed {
}
}
this.insertDiscoveryStreamSpocs(sponsored);
// Get pinned links augmented with desired properties
let plainPinned = await this.pinnedCache.request();
@@ -906,23 +840,12 @@ class TopSitesFeed {
return;
}
let index = link.sponsored_position - 1;
// For DiscoveryStream spocs, we use a different position property
if (link.type === "SPOC") {
index = link.pos;
}
if (index > withPinned.length) {
withPinned[index] = link;
} else if (
link.type === "SPOC" &&
withPinned[index].show_sponsored_label
) {
// We currently want DiscoveryStream spocs to replace existing spocs.
withPinned[index] = link;
} else {
withPinned.splice(index, 0, link);
}
});
// Remove excess items after we inserted sponsored ones.
withPinned = withPinned.slice(0, numItems);
@@ -1277,10 +1200,8 @@ class TopSitesFeed {
// fixed.
let adjustedIndex = index;
for (let i = 0; i < index; i++) {
const link = this._linksWithDefaults[i];
if (
link &&
(link.sponsored_position || link.type === "SPOC") &&
this._linksWithDefaults[i]?.sponsored_position &&
this._linksWithDefaults[i]?.url !== site.url
) {
adjustedIndex--;
@@ -1473,10 +1394,6 @@ class TopSitesFeed {
case at.UPDATE_PINNED_SEARCH_SHORTCUTS:
this.updatePinnedSearchShortcuts(action.data);
break;
case at.DISCOVERY_STREAM_SPOCS_UPDATE:
// Refresh to update sponsored topsites.
this.refresh({ broadcast: true });
break;
case at.UNINIT:
this.uninit();
break;

View File

@@ -11,7 +11,7 @@ import { Navigation } from "content-src/components/DiscoveryStreamComponents/Nav
import React from "react";
import { shallow } from "enzyme";
import { SectionTitle } from "content-src/components/DiscoveryStreamComponents/SectionTitle/SectionTitle";
import { TopSites } from "content-src/components/TopSites/TopSites";
import { TopSites } from "content-src/components/DiscoveryStreamComponents/TopSites/TopSites";
describe("<isAllowedCSS>", () => {
it("should allow colors", () => {
@@ -302,7 +302,6 @@ describe("<DiscoveryStreamBase>", () => {
assert.equal(
wrapper
.find(".ds-column-grid div")
.find(".ds-top-sites")
.children()
.at(0)
.type(),

View File

@@ -0,0 +1,219 @@
import { combineReducers, createStore } from "redux";
import {
INITIAL_STATE,
reducers,
TOP_SITES_DEFAULT_ROWS,
} from "common/Reducers.sys.mjs";
import { mount } from "enzyme";
import { TopSites as OldTopSites } from "content-src/components/TopSites/TopSites";
import { Provider } from "react-redux";
import React from "react";
import {
TopSites as TopSitesContainer,
_TopSites as TopSites,
} from "content-src/components/DiscoveryStreamComponents/TopSites/TopSites";
describe("Discovery Stream <TopSites>", () => {
let wrapper;
let store;
let defaultTopSiteRows;
let defaultTopSites;
beforeEach(() => {
defaultTopSiteRows = [
{ label: "facebook" },
{ label: "amazon" },
{ label: "google" },
{ label: "apple" },
];
defaultTopSites = {
rows: defaultTopSiteRows,
};
INITIAL_STATE.Prefs.values.topSitesRows = TOP_SITES_DEFAULT_ROWS;
store = createStore(combineReducers(reducers), INITIAL_STATE);
wrapper = mount(
<Provider store={store}>
<TopSitesContainer TopSites={defaultTopSites} />
</Provider>
);
});
afterEach(() => {
wrapper.unmount();
});
it("should return a wrapper around old TopSites", () => {
const oldTopSites = wrapper.find(OldTopSites);
const dsTopSitesWrapper = wrapper.find(".ds-top-sites");
assert.ok(wrapper.exists());
assert.lengthOf(oldTopSites, 1);
assert.lengthOf(dsTopSitesWrapper, 1);
});
describe("TopSites header", () => {
it("should have header title undefined by default", () => {
const oldTopSites = wrapper.find(OldTopSites);
assert.isUndefined(oldTopSites.props().title);
});
it("should set header title on old TopSites", () => {
let DEFAULT_PROPS = {
header: { title: "test" },
};
wrapper = mount(
<Provider store={store}>
<TopSitesContainer {...DEFAULT_PROPS} />
</Provider>
);
const oldTopSites = wrapper.find(OldTopSites);
assert.equal(oldTopSites.props().title, "test");
});
});
describe("insertSpocContent", () => {
let insertSpocContent;
const topSiteSpoc = {
url: "foo",
sponsor: "bar",
raw_image_src: "foobar",
flight_id: "1234",
id: "5678",
shim: { impression: "1011" },
};
const data = { spocs: [topSiteSpoc] };
const resultSpocFirst = {
customScreenshotURL:
"https://img-getpocket.cdn.mozilla.net/40x40/filters:format(jpeg):quality(60):no_upscale():strip_exif()/foobar",
type: "SPOC",
label: "bar",
title: "bar",
url: "foo",
flightId: "1234",
id: "5678",
guid: "5678",
shim: {
impression: "1011",
},
pos: 0,
};
const resultSpocForth = {
customScreenshotURL:
"https://img-getpocket.cdn.mozilla.net/40x40/filters:format(jpeg):quality(60):no_upscale():strip_exif()/foobar",
type: "SPOC",
label: "bar",
title: "bar",
url: "foo",
flightId: "1234",
id: "5678",
guid: "5678",
shim: {
impression: "1011",
},
pos: 4,
};
const pinnedSite = {
label: "pinnedSite",
isPinned: true,
};
beforeEach(() => {
const instance = wrapper.find(TopSites).instance();
insertSpocContent = instance.insertSpocContent.bind(instance);
});
it("Should return null if no data or no TopSites", () => {
assert.isNull(insertSpocContent(defaultTopSites, {}, 1));
assert.isNull(insertSpocContent({}, data, 1));
});
it("Should return null if an organic SPOC topsite exists", () => {
const topSitesWithOrganicSpoc = {
rows: [...defaultTopSiteRows, topSiteSpoc],
};
assert.isNull(insertSpocContent(topSitesWithOrganicSpoc, data, 1));
});
it("Should return next spoc if the first SPOC is an existing organic top site", () => {
const topSitesWithOrganicSpoc = {
rows: [...defaultTopSiteRows, topSiteSpoc],
};
const extraSpocData = {
spocs: [
topSiteSpoc,
{
url: "foo2",
sponsor: "bar2",
raw_image_src: "foobar2",
flight_id: "1234",
id: "5678",
shim: { impression: "1011" },
},
],
};
const result = insertSpocContent(
topSitesWithOrganicSpoc,
extraSpocData,
5
);
const availableSpoc = {
customScreenshotURL:
"https://img-getpocket.cdn.mozilla.net/40x40/filters:format(jpeg):quality(60):no_upscale():strip_exif()/foobar2",
type: "SPOC",
label: "bar2",
title: "bar2",
url: "foo2",
flightId: "1234",
id: "5678",
guid: "5678",
shim: {
impression: "1011",
},
pos: 5,
};
const expectedResult = {
rows: [...topSitesWithOrganicSpoc.rows, availableSpoc],
};
assert.deepEqual(result, expectedResult);
});
it("should add spoc to the 4th position", () => {
const result = insertSpocContent(defaultTopSites, data, 4);
const expectedResult = {
rows: [...defaultTopSiteRows, resultSpocForth],
};
assert.deepEqual(result, expectedResult);
});
it("should add to first position", () => {
const result = insertSpocContent(defaultTopSites, data, 0);
assert.deepEqual(result, {
rows: [resultSpocFirst, ...defaultTopSiteRows.slice(1)],
});
});
it("should add to first position even if there are pins", () => {
const topSiteRowsWithPins = [
pinnedSite,
pinnedSite,
...defaultTopSiteRows,
];
const result = insertSpocContent({ rows: topSiteRowsWithPins }, data, 0);
assert.deepEqual(result, {
rows: [
resultSpocFirst,
pinnedSite,
pinnedSite,
...defaultTopSiteRows.slice(1),
],
});
});
});
});

View File

@@ -612,39 +612,6 @@ describe("Top Sites Feed", () => {
assert.calledWith(feed._fetchScreenshot, sinon.match.object, "custom");
});
describe("discoverystream", () => {
beforeEach(() => {
feed.store.state.DiscoveryStream = {
layout: [
{
components: [
{
placement: {
name: "sponsored-topsites",
},
spocs: {
positions: [{ index: 1 }],
},
},
],
},
],
spocs: {
data: {
"sponsored-topsites": {
items: [{ title: "test spoc", url: "https://test-spoc.com" }],
},
},
},
};
});
it("should add a sponsored topsite from discoverystream", async () => {
const result = await feed.getLinksWithDefaults();
assert.equal(result[1].type, "SPOC");
assert.equal(result[1].title, "test spoc");
assert.equal(result[1].url, "https://test-spoc.com");
});
});
});
describe("#init", () => {
it("should call refresh (broadcast:true)", async () => {

View File

@@ -330,11 +330,7 @@ pocketNewtab:
spocPositions:
type: string
fallbackPref: browser.newtabpage.activity-stream.discoverystream.spoc-positions
description: CSV string of spoc position indexes on newtab Pocket grid
spocTopsitesPositions:
type: string
fallbackPref: browser.newtabpage.activity-stream.discoverystream.spoc-topsites-positions
description: CSV string of spoc position indexes on newtab topsites section
description: CSV string of spoc position indexes on newtab grid
spocAdTypes:
type: string
fallbackPref: browser.newtabpage.activity-stream.discoverystream.spocAdTypes