Skip to content

Commit

Permalink
Merge pull request #10864 from bbc/WSTEAMA-402-amp-component-uses-bff
Browse files Browse the repository at this point in the history
WSTEAMA-402: Most Read AMP component uses simorgh-bff to fetch data
  • Loading branch information
karinathomasbbc authored Jun 20, 2023
2 parents 993e465 + c859bd9 commit 94e9caf
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 65 deletions.
150 changes: 150 additions & 0 deletions data/mundo/mostRead/mundo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
{
"data": {
"generated": "2023-06-15T14:59:17.801Z",
"lastRecordTimeStamp": "2023-06-15T14:57:00Z",
"firstRecordTimeStamp": "2023-06-15T14:42:00Z",
"items": [
{
"id": "4adf2180-74e0-4ea9-836b-a00797fa0f48",
"rank": 1,
"title": "Quién es Valerii Zaluzhnyi, el popular \"general de hierro\" que está al mando de la contraofensiva ucraniana",
"href": "/mundo/noticias-internacional-65909204",
"timestamp": 1686821815000
},
{
"id": "7cd5b8ff-6587-4c92-917d-107aba6aa2d6",
"rank": 2,
"title": "El director de la morgue de la Universidad de Harvard es acusado de robar y vender partes de cadáveres humanos",
"href": "/mundo/noticias-65917580",
"timestamp": 1686832214000
},
{
"id": "b2c8768e-b7e9-448d-b163-e82f38d41f22",
"rank": 3,
"title": "Qué busca Bukele con la reducción de 262 a 44 municipios en El Salvador (y por qué causa polémica)",
"href": "/mundo/noticias-america-latina-65911008",
"timestamp": 1686826839000
},
{
"id": "781266b2-f28e-48f4-81a1-93fa29db1499",
"rank": 4,
"title": "Los estudios que muestran cómo la taurina puede alargar la vida",
"href": "/mundo/noticias-65863611",
"timestamp": 1686823420000
},
{
"id": "30ccf622-8542-40ed-b19d-81a77f38f0a1",
"rank": 5,
"title": "El inesperado peligro medioambiental que pueden generar los paneles solares",
"href": "/mundo/noticias-65815486",
"timestamp": 1686782133000
},
{
"id": "21331ae7-9b0b-4e93-a0ad-23b5ad254d32",
"rank": 6,
"title": "Qué es y qué queda del \"Tanomoshi\", el sistema que permitió prosperar a los japoneses que llegaron a Perú",
"href": "/mundo/noticias-america-latina-65851680",
"timestamp": 1686834397000
},
{
"id": "05a53fcc-a62e-4c25-95ad-0634e9969807",
"rank": 7,
"title": "Los contrastes de Colombia que revela la historia de los niños indígenas que estuvieron perdidos en la selva",
"href": "/mundo/noticias-america-latina-65899580",
"timestamp": 1686740548000
},
{
"id": "9bc341bf-308a-42d5-bb07-50c6cb7b90bf",
"rank": 8,
"title": "Muere la legendaria actriz inglesa Glenda Jackson, que inspiró al escritor argentino Julio Cortázar",
"href": "/mundo/noticias-65920533",
"timestamp": 1686839483000
},
{
"id": "0aa9876c-a4a4-4e88-9a5b-13ccea229a32",
"rank": 9,
"title": "Al menos 79 muertos y cientos de desaparecidos en el naufragio de un barco de migrantes frente a las costas de Grecia",
"href": "/mundo/noticias-internacional-65908697",
"timestamp": 1686801120000
},
{
"id": "1b2c3053-2fb3-4ffb-b0d0-ce1f868e47d2",
"rank": 10,
"title": "\"No se entiende que, con todo lo que recorrimos, encontráramos a los niños por donde ya habíamos pasado\"",
"href": "/mundo/noticias-america-latina-65886379",
"timestamp": 1686613016000
},
{
"id": "edbec380-d45e-491d-9d65-a7daa0eb28cd",
"rank": 11,
"title": "Quién es María Asunción Aramburuzabala, la mujer más rica de México",
"href": "/mundo/noticias-62897874",
"timestamp": 1664284329000
},
{
"id": "2a684580-b743-4180-8943-ca3f665e0f21",
"rank": 12,
"title": "\"Nos golpean día y noche sin parar\": las torturas y secuestros que sufren los migrantes que huyen del Talibán",
"href": "/mundo/noticias-internacional-65903588",
"timestamp": 1686797230000
},
{
"id": "0bd1529c-1339-48c1-9c06-c3d4a741e648",
"rank": 13,
"title": "Las incógnitas sobre quién heredará el imperio de US$6.500 millones de Silvio Berlusconi",
"href": "/mundo/noticias-internacional-65904977",
"timestamp": 1686748823000
},
{
"id": "30fa30ca-e382-4f92-b85d-9ffa56df4cc5",
"rank": 14,
"title": "3 áreas en las que la inteligencia artificial ya está mejorando nuestras vidas",
"href": "/mundo/noticias-65839988",
"timestamp": 1686735365000
},
{
"id": "e9301754-82ea-46e6-b8cc-e1cdaea0029f",
"rank": 15,
"title": "Investigación BBC | Los hombres que venden videos toqueteando a chicas en el metro de Japón (y cómo los están persiguiendo)",
"href": "/mundo/noticias-internacional-65861189",
"timestamp": 1686535346000
},
{
"id": "256c9c44-624a-47ac-8d48-e03908500b89",
"rank": 16,
"title": "\"La selva no era la amenaza, la selva los salvó\": ¿cómo pudieron sobrevivir los 4 niños que pasaron 40 días en la Amazonía colombiana?",
"href": "/mundo/noticias-america-latina-65869230",
"timestamp": 1686438275000
},
{
"id": "2534c64f-f53e-4af8-adcb-19d3eeeec700",
"rank": 17,
"title": "Françoise Gilot, la artista que amó y abandonó a Picasso (y que reveló el lado oscuro del genio)",
"href": "/mundo/noticias-65851130",
"timestamp": 1686482061000
},
{
"id": "fd1f78e8-9800-4905-b532-2dc5a6ad0b3b",
"rank": 18,
"title": "4 asombrosas historias de supervivencia y rescate que conmovieron al mundo",
"href": "/mundo/noticias-internacional-65885939",
"timestamp": 1686614917000
},
{
"id": "e1c294e0-90ba-425a-8d8e-2a89a1af5efa",
"rank": 19,
"title": "Por qué salir del clóset puede durar “toda la vida” para las personas LGBT+ (y cómo el apoyo familiar puede marcar la diferencia)",
"href": "/mundo/vert-fut-65891479",
"timestamp": 1686738366000
},
{
"id": "8edfba76-2d51-4261-aba1-fdb9d1800270",
"rank": 20,
"title": "Quién es el heredero de George Soros que tomará el control de su imperio de US$25.000 millones",
"href": "/mundo/noticias-internacional-65883449",
"timestamp": 1686588543000
}
]
},
"contentType": "application/json; charset=utf-8"
}
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ exports[`AmpMostRead should render as expected 1`] = `
>
<amp-list
height="50"
items="records"
items="items"
layout="responsive"
max-items="10"
src="amp-script:dataFunctions.getRemoteData"
Expand Down Expand Up @@ -266,9 +266,9 @@ exports[`AmpMostRead should render as expected 1`] = `
>
<a
class="focusIndicatorDisplayTableCell emotion-7"
href="{{promo.locators.assetUri}}"
href="{{href}}"
>
{{promo.headlines.shortHeadline}}
{{title}}
</a>
</div>
</div>
Expand Down
32 changes: 32 additions & 0 deletions src/app/components/MostRead/Amp/getRemoteDataScript/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable no-eval */
import { transformData } from '.';
import { WesternArabic } from '../../../../legacy/psammead/psammead-locales/src/numerals';
import { data as pidginMostRead } from '../../../../../../data/pidgin/mostRead/pidgin.json';

describe('getRemoteDataScript', () => {
it('transformData should append rankTranslation to each item', async () => {
const data = pidginMostRead;

const translations = WesternArabic;

eval(transformData());

data.items.forEach((item: object, index: number) => {
expect(item).toHaveProperty('rankTranslation');
// @ts-expect-error required for testing purposes
expect(item.rankTranslation).toBe(translations[index + 1]);
});
});

it('transformData should throw an error if there are empty items in the data response', async () => {
const data = { ...pidginMostRead, items: [] };
expect(data.items).toHaveLength(0);

const translations = WesternArabic;
expect(translations).toBeDefined();

expect(() => eval(transformData())).toThrowError(
'Empty records from mostread endpoint',
);
});
});
42 changes: 42 additions & 0 deletions src/app/components/MostRead/Amp/getRemoteDataScript/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Services } from '../../../../models/types/global';
import { serviceNumerals } from '../../Canonical/Rank';

export const transformData = () => {
return `
if (data.items.length === 0) {
throw new Error('Empty records from mostread endpoint');
}
data.items.forEach((item, index) => {
item.rankTranslation = translations[index + 1];
});
`;
};

export default ({
endpoint,
service,
}: {
endpoint: string;
service: Services;
}) => {
return `
const translations = ${JSON.stringify(serviceNumerals(service))}
const getRemoteData = async () => {
try {
const response = await fetch("${endpoint}");
const { data } = await response.json();
${transformData()}
return data;
} catch (error) {
console.warn(error);
return [];
}
}
exportFunction('getRemoteData', getRemoteData);
`;
};
19 changes: 13 additions & 6 deletions src/app/components/MostRead/Amp/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { render, act } from '../../react-testing-library-with-providers';
import { ServiceContextProvider } from '../../../contexts/ServiceContext';
import AmpMostRead from '.';
import { Services } from '../../../models/types/global';
import mundoMostReadResponse from '../../../../../data/mundo/mostRead/index.json';
import { data as mundoMostReadResponse } from '../../../../../data/mundo/mostRead/mundo.json';

interface MostReadAmpWithContextProps {
service: Services;
Expand Down Expand Up @@ -45,6 +45,9 @@ describe('AmpMostRead', () => {

const { container, getByText } = render(
<MostReadAmpWithContext service="mundo" />,
{
service: 'mundo',
},
);

await act(async () => {
Expand All @@ -58,17 +61,19 @@ describe('AmpMostRead', () => {
});
});

it('should render fallback when fetch records are empty', async () => {
it('should render fallback when items are empty', async () => {
fetchMock.mock('localhost:7080/mundo/mostread.json', {
generated: '2022-05-03T14:44:35.496Z',
lastRecordTimeStamp: '2022-05-03T14:42:00Z',
firstRecordTimeStamp: '2022-05-03T14:27:00Z',
totalRecords: 20,
records: [],
items: [],
});

const { container, getByText } = render(
<MostReadAmpWithContext service="mundo" />,
{
service: 'mundo',
},
);

await act(async () => {
Expand All @@ -82,16 +87,18 @@ describe('AmpMostRead', () => {
});
});

it('should render fallback when fetch records is undefined', async () => {
it('should render fallback when items are undefined', async () => {
fetchMock.mock('localhost:7080/mundo/mostread.json', {
generated: '2022-05-03T14:44:35.496Z',
lastRecordTimeStamp: '2022-05-03T14:42:00Z',
firstRecordTimeStamp: '2022-05-03T14:27:00Z',
totalRecords: 20,
});

const { container, getByText } = render(
<MostReadAmpWithContext service="mundo" />,
{
service: 'mundo',
},
);

await act(async () => {
Expand Down
47 changes: 6 additions & 41 deletions src/app/components/MostRead/Amp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,11 @@ import {
import pathOr from 'ramda/src/pathOr';
import { ServiceContext } from '../../../contexts/ServiceContext';
import { MostReadItemWrapper, MostReadLink } from '../Canonical/Item';
import MostReadRank, { serviceNumerals } from '../Canonical/Rank';
import MostReadRank from '../Canonical/Rank';
import generateCSPHash from '../utilities/generateCSPHash';
import { Services } from '../../../models/types/global';
import { Size, Direction } from '../types';
import styles from './index.styles';

const rankTranslationScript = (endpoint: string, service: Services) => {
const translation = serviceNumerals(service);
return `
const translations = ${JSON.stringify(translation)}
const getRemoteData = async () => {
try{
const response = await fetch("${endpoint}");
const data = await response.json();
if(data.records.length === 0){
throw new Error("Empty records from mostread endpoint");
}
data.records.forEach((item, index) => {
item.rankTranslation = translations[index+1];
if (!item.promo.headlines.shortHeadline) {
item.promo.headlines.shortHeadline = item.promo.headlines.seoHeadline;
}
if(!item.promo.locators.assetUri) {
item.promo.locators.assetUri = item.promo.locators.canonicalUrl;
}
});
return data;
} catch(error){
console.warn(error);
return [];
}
}
exportFunction('getRemoteData', getRemoteData);`;
};
import getRemoteDataScript from './getRemoteDataScript';

interface AmpMostReadProps {
endpoint: string;
Expand All @@ -64,7 +29,7 @@ const AmpMostRead = ({ endpoint, size = 'default' }: AmpMostReadProps) => {
translations,
} = useContext(ServiceContext);

const onlyinnerscript = rankTranslationScript(endpoint, service);
const onlyinnerscript = getRemoteDataScript({ endpoint, service });

const fallbackText = pathOr(
'Content is not available',
Expand Down Expand Up @@ -103,7 +68,7 @@ const AmpMostRead = ({ endpoint, size = 'default' }: AmpMostReadProps) => {
</Helmet>
<amp-list
src="amp-script:dataFunctions.getRemoteData"
items="records"
items="items"
max-items={numberOfItems}
layout="responsive"
width="300"
Expand All @@ -127,8 +92,8 @@ const AmpMostRead = ({ endpoint, size = 'default' }: AmpMostReadProps) => {
<MostReadLink
dir={direction}
service={service}
title="{{promo.headlines.shortHeadline}}"
href="{{promo.locators.assetUri}}"
title="{{title}}"
href="{{href}}"
size={size}
/>
</MostReadItemWrapper>
Expand Down
Loading

0 comments on commit 94e9caf

Please sign in to comment.