Skip to content

Commit

Permalink
Merge pull request #12333 from bbc/WSTEAMA-1514-update-topics-urls-to…
Browse files Browse the repository at this point in the history
…-include-script-at-the-end

WSTEAMA-1515-added support for routes to have variants at the end
  • Loading branch information
Nabeel1276 authored Jan 27, 2025
2 parents aa66329 + dbb4df9 commit bbb633d
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/app/routes/topic/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { TopicPage } from '#pages';
import { topicPath } from '#app/routes/utils/regex';
import { topicPath, variantTopicPath } from '#app/routes/utils/regex';
import { TOPIC_PAGE } from '#app/routes/utils/pageTypes';
import getInitialData from './getInitialData';

export default {
path: [topicPath, '/persian/afghanistan'],
path: [topicPath, variantTopicPath, '/persian/afghanistan'],
exact: true,
component: TopicPage,
getInitialData,
Expand Down
8 changes: 7 additions & 1 deletion src/app/routes/utils/constructPageFetchUrl/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ describe('constructPageFetchUrl', () => {
${TOPIC_PAGE} | ${null} | ${null} | ${'local'} | ${'/ukrainian/topics/c0000000000t'} | ${'http://localhost/ukrainian/topics/c0000000000t'}
${TOPIC_PAGE} | ${null} | ${null} | ${'test'} | ${'/ukrainian/topics/c0000000000t'} | ${'https://mock-bff-path/?id=c0000000000t&service=ukrainian&pageType=topic&serviceEnv=test'}
${TOPIC_PAGE} | ${null} | ${null} | ${'live'} | ${'/ukrainian/topics/c0000000000t'} | ${'https://mock-bff-path/?id=c0000000000t&service=ukrainian&pageType=topic&serviceEnv=live'}
${TOPIC_PAGE} | ${null} | ${'ru-UA'} | ${'local'} | ${'/ukrainian/topics/c0000000000t'} | ${'http://localhost/ukrainian/ru-UA/topics/c0000000000t'}
${TOPIC_PAGE} | ${null} | ${'ru-UA'} | ${'local'} | ${'/ukrainian/topics/c0000000000t'} | ${'http://localhost/ukrainian/topics/c0000000000t/ru-UA'}
${TOPIC_PAGE} | ${null} | ${'ru-UA'} | ${'test'} | ${'/ukrainian/topics/c0000000000t'} | ${'https://mock-bff-path/?id=c0000000000t&service=ukrainian&pageType=topic&variant=ru-UA&serviceEnv=test'}
${TOPIC_PAGE} | ${null} | ${'ru-UA'} | ${'live'} | ${'/ukrainian/topics/c0000000000t'} | ${'https://mock-bff-path/?id=c0000000000t&service=ukrainian&pageType=topic&variant=ru-UA&serviceEnv=live'}
${TOPIC_PAGE} | ${'persian'} | ${null} | ${'local'} | ${'/persian/afghanistan'} | ${'http://localhost/persian/topics/crezq2dg9zwt'}
Expand All @@ -122,6 +122,12 @@ describe('constructPageFetchUrl', () => {
${TOPIC_PAGE} | ${'persian'} | ${null} | ${'local'} | ${'/persian/topics/c00000000000t'} | ${'http://localhost/persian/topics/c00000000000t'}
${TOPIC_PAGE} | ${'persian'} | ${null} | ${'test'} | ${'/persian/topics/c00000000000t'} | ${'https://mock-bff-path/?id=c00000000000t&service=persian&pageType=topic&serviceEnv=test'}
${TOPIC_PAGE} | ${'persian'} | ${null} | ${'live'} | ${'/persian/topics/c00000000000t'} | ${'https://mock-bff-path/?id=c00000000000t&service=persian&pageType=topic&serviceEnv=live'}
${TOPIC_PAGE} | ${'zhongwen'} | ${'trad'} | ${'local'} | ${'/zhongwen/topics/cpydz21p02et/trad'} | ${'http://localhost/zhongwen/topics/cpydz21p02et/trad'}
${TOPIC_PAGE} | ${'zhongwen'} | ${'simp'} | ${'local'} | ${'/zhongwen/topics/c4vmr03pyn6t/simp'} | ${'http://localhost/zhongwen/topics/c4vmr03pyn6t/simp'}
${TOPIC_PAGE} | ${'zhongwen'} | ${'trad'} | ${'test'} | ${'/zhongwen/topics/cpydz21p02et/trad'} | ${'https://mock-bff-path/?id=cpydz21p02et&service=zhongwen&pageType=topic&variant=trad&serviceEnv=test'}
${TOPIC_PAGE} | ${'zhongwen'} | ${'simp'} | ${'test'} | ${'/zhongwen/topics/c4vmr03pyn6t/simp'} | ${'https://mock-bff-path/?id=c4vmr03pyn6t&service=zhongwen&pageType=topic&variant=simp&serviceEnv=test'}
${TOPIC_PAGE} | ${'zhongwen'} | ${'trad'} | ${'live'} | ${'/zhongwen/topics/cpydz21p02et/trad'} | ${'https://mock-bff-path/?id=cpydz21p02et&service=zhongwen&pageType=topic&variant=trad&serviceEnv=live'}
${TOPIC_PAGE} | ${'zhongwen'} | ${'simp'} | ${'live'} | ${'/zhongwen/topics/c4vmr03pyn6t/simp'} | ${'https://mock-bff-path/?id=c4vmr03pyn6t&service=zhongwen&pageType=topic&variant=simp&serviceEnv=live'}
${UGC_PAGE} | ${'mundo'} | ${null} | ${'local'} | ${'/u50853489'} | ${'http://localhost/api/local/mundo/send/u50853489'}
${TV_PAGE} | ${'hausa'} | ${null} | ${'local'} | ${'/hausa/bbc_hausa_tv/tv/w172yjj7rfhxp1p'} | ${'http://localhost/hausa/bbc_hausa_tv/tv/w172yjj7rfhxp1p'}
${TV_PAGE} | ${'hindi'} | ${null} | ${'local'} | ${'/hindi/bbc_hindi_tv/tv_programmes/w13xttlw'} | ${'http://localhost/hindi/bbc_hindi_tv/tv_programmes/w13xttlw'}
Expand Down
2 changes: 1 addition & 1 deletion src/app/routes/utils/constructPageFetchUrl/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ const constructPageFetchUrl = ({
break;
case TOPIC_PAGE: {
const variantPath = variant ? `/${variant}` : '';
fetchUrl = Url(`/${service}${variantPath}/topics/${id}`);
fetchUrl = Url(`/${service}/topics/${id}${variantPath}`);
break;
}
case LIVE_PAGE: {
Expand Down
3 changes: 3 additions & 0 deletions src/app/routes/utils/regex/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
getOnDemandRadioRegex,
getOnDemandTvRegex,
getTopicPageRegex,
getVariantTopicPageRegex,
getErrorPageRegex,
getLegacyAssetRegex,
getMostReadPageRegex,
Expand Down Expand Up @@ -65,6 +66,8 @@ export const onDemandTvDataPath = `${onDemandTvPath}.json`;
export const topicPath = getTopicPageRegex(allServices);
export const topicDataPath = `${topicPath}.json`;

export const variantTopicPath = getVariantTopicPageRegex(allServices);

export const errorPagePath = getErrorPageRegex(allServices);

export const legacyAssetPagePath = getLegacyAssetRegex(allServices);
Expand Down
48 changes: 48 additions & 0 deletions src/app/routes/utils/regex/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
secondaryColumnDataRegexPath,
tipoHomeDataPath,
tipoHomePath,
topicPath,
variantTopicPath,
} from './index';

import serviceConfig from '../../../lib/config/services/loadableConfig';
Expand Down Expand Up @@ -603,3 +605,49 @@ describe('frontPage -> homePage migration', () => {
shouldNotMatchInvalidRoutes(liveFrontPageRoutes, homePageRegex);
});
});

describe('topicPath', () => {
const validRoutes = [
'/zhongwen/trad/topics/cd6qem06z92t',
'/zhongwen/trad/topics/c1ez1k4emn0t',
'/serbian/lat/topics/cr50vdy9q6wt',
'/serbian/lat/topics/c2lej05e1eqt',
'/pidgin/topics/c2dwqd1zr92t',
];
shouldMatchValidRoutes(validRoutes, topicPath);

const invalidRoutes = [
'/serbian/topics/c2lej05e1eqt/lat',
'/serbian/topics/c2lej05qwesae1eqt/lat',
'/zhongwen/c1ez1k4emn0t',
'/zhongwen/trad/topics',
'/hindi/topic/c5jje4ejkqv',
'/mundo/topic/',
'/serbian/topic/c5jje4ejkqvo/foobar',
'/urdu/topic/c5jje4ejkqvo/.amp',
];
shouldNotMatchInvalidRoutes(invalidRoutes, topicPath);
});

describe('topicVariantPath', () => {
const validRoutes = [
'/zhongwen/topics/cd6qem06z92t/trad',
'/zhongwen/topics/c1ez1k4emn0t/trad',
'/serbian/topics/cr50vdy9q6wt/lat',
'/serbian/topics/c2lej05e1eqt/lat',
'/pidgin/topics/c2dwqd1zr92t',
];
shouldMatchValidRoutes(validRoutes, variantTopicPath);

const invalidRoutes = [
'/serbian/lat/topics/c2lej05e1eqt',
'/serbian/lat/topics/c2lej05qwesae1eqt',
'/zhongwen/c1ez1k4emn0t',
'/zhongwen/trad/topics',
'/hindi/topic/c5jje4ejkqv',
'/mundo/topic/',
'/serbian/topic/c5jje4ejkqvo/foobar',
'/urdu/topic/c5jje4ejkqvo/.amp',
];
shouldNotMatchInvalidRoutes(invalidRoutes, variantTopicPath);
});
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,7 @@ exports[`regex utils snapshots should create expected regex from getTipoHomeRege
exports[`regex utils snapshots should create expected regex from getTopicPageRegex when isLive = false 1`] = `"/:service(afaanoromoo|afrique|amharic|arabic|archive|azeri|bengali|burmese|cymrufyw|gahuza|gujarati|hausa|hindi|igbo|indonesia|japanese|korean|kyrgyz|marathi|mundo|naidheachdan|nepali|news|newsround|pashto|persian|pidgin|portuguese|punjabi|russian|scotland|serbian|sinhala|somali|sport|swahili|tamil|telugu|thai|tigrinya|turkce|ukchina|ukrainian|urdu|uzbek|vietnamese|ws|yoruba|zhongwen):variant(/simp|/trad|/cyr|/lat)?/topics/:id([a-z0-9]+)?:lite(.lite)?"`;

exports[`regex utils snapshots should create expected regex from getTopicPageRegex when isLive = true 1`] = `"/:service(afaanoromoo|afrique|amharic|arabic|archive|azeri|bengali|burmese|cymrufyw|gahuza|gujarati|hausa|hindi|igbo|indonesia|japanese|korean|kyrgyz|marathi|mundo|naidheachdan|nepali|news|newsround|pashto|persian|pidgin|portuguese|punjabi|russian|scotland|serbian|sinhala|somali|sport|swahili|tamil|telugu|thai|tigrinya|turkce|ukchina|ukrainian|urdu|uzbek|vietnamese|ws|yoruba|zhongwen):variant(/simp|/trad|/cyr|/lat)?/topics/:id([a-z0-9]+)?:lite(.lite)?"`;

exports[`regex utils snapshots should create expected regex from getVariantTopicPageRegex when isLive = false 1`] = `"/:service(afaanoromoo|afrique|amharic|arabic|archive|azeri|bengali|burmese|cymrufyw|gahuza|gujarati|hausa|hindi|igbo|indonesia|japanese|korean|kyrgyz|marathi|mundo|naidheachdan|nepali|news|newsround|pashto|persian|pidgin|portuguese|punjabi|russian|scotland|serbian|sinhala|somali|sport|swahili|tamil|telugu|thai|tigrinya|turkce|ukchina|ukrainian|urdu|uzbek|vietnamese|ws|yoruba|zhongwen)/topics/:id([a-z0-9]+)?:variant(/simp|/trad|/cyr|/lat)?:lite(.lite)?"`;

exports[`regex utils snapshots should create expected regex from getVariantTopicPageRegex when isLive = true 1`] = `"/:service(afaanoromoo|afrique|amharic|arabic|archive|azeri|bengali|burmese|cymrufyw|gahuza|gujarati|hausa|hindi|igbo|indonesia|japanese|korean|kyrgyz|marathi|mundo|naidheachdan|nepali|news|newsround|pashto|persian|pidgin|portuguese|punjabi|russian|scotland|serbian|sinhala|somali|sport|swahili|tamil|telugu|thai|tigrinya|turkce|ukchina|ukrainian|urdu|uzbek|vietnamese|ws|yoruba|zhongwen)/topics/:id([a-z0-9]+)?:variant(/simp|/trad|/cyr|/lat)?:lite(.lite)?"`;
5 changes: 5 additions & 0 deletions src/app/routes/utils/regex/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ export const getTopicPageRegex = services => {
return `/:service(${serviceRegex}):variant(${variantRegex})?/topics/:id(${topicIdRegex})?:lite(${liteRegex})?`;
};

export const getVariantTopicPageRegex = services => {
const serviceRegex = getServiceRegex(services);
return `/:service(${serviceRegex})/topics/:id(${topicIdRegex})?:variant(${variantRegex})?:lite(${liteRegex})?`;
};

export const getErrorPageRegex = services => {
const serviceRegex = getServiceRegex(services);
return `/:service(${serviceRegex})/:errorCode(${errorCodeRegex}):variant(${variantRegex})?:lite(${liteRegex})?`;
Expand Down
192 changes: 192 additions & 0 deletions src/server/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,194 @@ const testArticles = ({ platform, service, variant, queryString = '' }) => {
});
};

const testTopics = ({ service, variant, queryString = '' }) => {
describe(`Tipo Topic: /${service}/${variant}/topics/tipoId${queryString}`, () => {
const successDataResponse = {
data: { some: 'data' },
service: 'someService',
status: 200,
};

const notFoundDataResponse = {
data: { some: 'data' },
service: 'someService',
status: 404,
};

const id = `c0000000001o`;
const topicURL = `/${service}/${variant}/topics/${id}${queryString}`;

describe('Successful render', () => {
describe('200 status code', () => {
beforeEach(() => {
mockRouteProps({
id,
service,
dataResponse: successDataResponse,
variant,
});
});

const configs = {
url: topicURL,
service,
successDataResponse,
variant,
};

it('should respond with rendered data', testRenderedData(configs));
});

describe('404 status code', () => {
const pageType = 'topic';

beforeEach(() => {
mockRouteProps({
id,
service,
dataResponse: notFoundDataResponse,
variant,
pageType,
});
});

it('should respond with a rendered 404', async () => {
const { status, text } = await makeRequest(topicURL);
expect(status).toBe(404);
expect(text).toEqual(
'<!doctype html><html><body><h1>Mock app</h1></body></html>',
);
});

assertNon200ResponseCustomMetrics({
requestUrl: topicURL,
pageType,
statusCode: 404,
});
});
});

describe('Unknown error within the data fetch, react router or its dependencies', () => {
const pageType = 'topic';
beforeEach(() => {
mockRouteProps({
id,
service,
dataResponse: Error('Error!'),
responseType: 'reject',
variant,
pageType,
});
});

it('should respond with a 500', async () => {
const { status, text } = await makeRequest(topicURL);
expect(status).toEqual(500);
expect(text).toEqual('Internal server error');
});

assertNon200ResponseCustomMetrics({
requestUrl: topicURL,
pageType,
});
});
});
};

const testVariantTopics = ({ service, variant, queryString = '' }) => {
describe(`Tipo Topic: /${service}/topics/tipoId/${variant}${queryString}`, () => {
const successDataResponse = {
data: { some: 'data' },
service: 'someService',
status: 200,
};

const notFoundDataResponse = {
data: { some: 'data' },
service: 'someService',
status: 404,
};

const id = `c0000000001o`;
const topicURL = `/${service}/topics/${id}/${variant}${queryString}`;

describe('Successful render', () => {
describe('200 status code', () => {
beforeEach(() => {
mockRouteProps({
id,
service,
dataResponse: successDataResponse,
variant,
});
});

const configs = {
url: topicURL,
service,
successDataResponse,
variant,
};

it('should respond with rendered data', testRenderedData(configs));
});

describe('404 status code', () => {
const pageType = 'topic';

beforeEach(() => {
mockRouteProps({
id,
service,
dataResponse: notFoundDataResponse,
variant,
pageType,
});
});

it('should respond with a rendered 404', async () => {
const { status, text } = await makeRequest(topicURL);
expect(status).toBe(404);
expect(text).toEqual(
'<!doctype html><html><body><h1>Mock app</h1></body></html>',
);
});

assertNon200ResponseCustomMetrics({
requestUrl: topicURL,
pageType,
statusCode: 404,
});
});
});

describe('Unknown error within the data fetch, react router or its dependencies', () => {
const pageType = 'topic';
beforeEach(() => {
mockRouteProps({
id,
service,
dataResponse: Error('Error!'),
responseType: 'reject',
variant,
pageType,
});
});

it('should respond with a 500', async () => {
const { status, text } = await makeRequest(topicURL);
expect(status).toEqual(500);
expect(text).toEqual('Internal server error');
});

assertNon200ResponseCustomMetrics({
requestUrl: topicURL,
pageType,
});
});
});
};

const testAssetPages = ({
platform,
service,
Expand Down Expand Up @@ -1201,6 +1389,10 @@ describe('Server', () => {
queryString: QUERY_STRING,
});

testTopics({ service: 'pidgin' });

testVariantTopics({ service: 'zhongwen', variant: 'simp' });

testMediaPages({
platform: 'amp',
service: 'korean',
Expand Down

0 comments on commit bbb633d

Please sign in to comment.