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:
@@ -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", "");
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
);
|
||||
@@ -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);
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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),
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user