diff --git a/envConfig/live.env b/envConfig/live.env index 47df7b2893b..a57826305da 100644 --- a/envConfig/live.env +++ b/envConfig/live.env @@ -23,6 +23,9 @@ AWS_EMF_SERVICE_NAME=Simorgh AWS_EMF_LOG_GROUP_NAME=SimorghServer AWS_EMF_ENVIRONMENT=EC2 +# Reverb Reporting +SIMORGH_REVERB_SOURCE=https://mybbc-analytics.files.bbci.co.uk/reverb-client-js/reverb-3.9.2.js + ## WebVitals Reporting SIMORGH_WEBVITALS_REPORTING_ENDPOINT=https://ws.bbc-reporting-api.app/report-endpoint SIMORGH_WEBVITALS_DEFAULT_SAMPLING_RATE=20 diff --git a/envConfig/local.env b/envConfig/local.env index 3722b33b66c..dd7590e9d4f 100644 --- a/envConfig/local.env +++ b/envConfig/local.env @@ -23,6 +23,9 @@ AWS_EMF_SERVICE_NAME=Simorgh AWS_EMF_LOG_GROUP_NAME=SimorghServer AWS_EMF_ENVIRONMENT=Local +# Reverb Reporting +SIMORGH_REVERB_SOURCE=https://mybbc-analytics.files.bbci.co.uk/reverb-client-js/reverb-3.9.2.js + ## WebVitals Reporting SIMORGH_WEBVITALS_REPORTING_ENDPOINT=https://ws.bbc-reporting-api.app/report-endpoint SIMORGH_WEBVITALS_DEFAULT_SAMPLING_RATE=100 diff --git a/envConfig/preview1.env b/envConfig/preview1.env index 6c0c2c493e1..0ac9627348c 100644 --- a/envConfig/preview1.env +++ b/envConfig/preview1.env @@ -23,6 +23,9 @@ AWS_EMF_SERVICE_NAME=Simorgh AWS_EMF_LOG_GROUP_NAME=SimorghServer AWS_EMF_ENVIRONMENT=EC2 +# Reverb Reporting +SIMORGH_REVERB_SOURCE=https://mybbc-analytics.files.bbci.co.uk/reverb-client-js/reverb-3.9.2.js + ## WebVitals Reporting SIMORGH_WEBVITALS_REPORTING_ENDPOINT=https://ws.bbc-reporting-api.app/report-endpoint SIMORGH_WEBVITALS_DEFAULT_SAMPLING_RATE=100 diff --git a/envConfig/preview2.env b/envConfig/preview2.env index 5d7459d6d07..4943c350e29 100644 --- a/envConfig/preview2.env +++ b/envConfig/preview2.env @@ -23,6 +23,9 @@ AWS_EMF_SERVICE_NAME=Simorgh AWS_EMF_LOG_GROUP_NAME=SimorghServer AWS_EMF_ENVIRONMENT=EC2 +# Reverb Reporting +SIMORGH_REVERB_SOURCE=https://mybbc-analytics.files.bbci.co.uk/reverb-client-js/reverb-3.9.2.js + ## WebVitals Reporting SIMORGH_WEBVITALS_REPORTING_ENDPOINT=https://ws.bbc-reporting-api.app/report-endpoint SIMORGH_WEBVITALS_DEFAULT_SAMPLING_RATE=100 diff --git a/envConfig/test.env b/envConfig/test.env index b700cfb8b01..a9eb398fd55 100644 --- a/envConfig/test.env +++ b/envConfig/test.env @@ -23,6 +23,9 @@ AWS_EMF_SERVICE_NAME=Simorgh AWS_EMF_LOG_GROUP_NAME=SimorghServer AWS_EMF_ENVIRONMENT=EC2 +# Reverb Reporting +SIMORGH_REVERB_SOURCE=https://mybbc-analytics.files.bbci.co.uk/reverb-client-js/reverb-3.9.2.js + ## WebVitals Reporting SIMORGH_WEBVITALS_REPORTING_ENDPOINT=https://ws.bbc-reporting-api.app/report-endpoint SIMORGH_WEBVITALS_DEFAULT_SAMPLING_RATE=100 diff --git a/src/app/components/ATIAnalytics/atiUrl/index.test.ts b/src/app/components/ATIAnalytics/atiUrl/index.test.ts index a26c5acbe09..7f9ad991e74 100644 --- a/src/app/components/ATIAnalytics/atiUrl/index.test.ts +++ b/src/app/components/ATIAnalytics/atiUrl/index.test.ts @@ -1,6 +1,12 @@ import { resetWindowValue } from '#psammead/psammead-test-helpers/src'; +import { Platforms } from '#app/models/types/global'; import * as genericLabelHelpers from '../../../lib/analyticsUtils'; -import { buildATIPageTrackPath, buildATIEventTrackUrl } from '.'; +import { + buildATIPageTrackPath, + buildATIEventTrackUrl, + buildReverbAnalyticsModel, + buildReverbPageSectionEventModel, +} from '.'; // @ts-expect-error required for testing purposes const mockAndSet = ({ name, source }, response) => { @@ -50,6 +56,7 @@ describe('getThingAttributes', () => { afterEach(() => { jest.resetAllMocks(); + resetWindowValue('location', windowLocation); }); @@ -278,3 +285,159 @@ describe('buildATIEventTrackUrl', () => { ]); }); }); + +describe('Reverb', () => { + describe('buildReverbAnalyticsModel', () => { + beforeEach(() => { + analyticsUtilFunctions.forEach(func => { + mockAndSet(func, func.name); + }); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + const input = { + appName: 'news', + campaigns: [ + { + campaignId: '1', + campaignName: 'campaign1', + }, + { + campaignId: '2', + campaignName: 'campaign2', + }, + ], + categoryName: 'categoryName', + contentId: 'contentId', + contentType: 'contentType', + language: 'language', + ldpThingIds: 'ldpThingIds', + ldpThingLabels: 'ldpThingLabels', + libraryVersion: 'libraryVersion', + pageIdentifier: 'pageIdentifier', + pageTitle: 'pageTitle', + platform: 'canonical' as Platforms, + previousPath: '', + producerName: 'producerName', + origin: 'http://localhost', + nationsProducer: '', + statsDestination: 'statsDestination', + timePublished: 'timePublished', + timeUpdated: 'timeUpdated', + }; + + it('should return the correct Reverb analytics model', () => { + const reverbAnalyticsModel = buildReverbAnalyticsModel(input); + + const pageParams = { + contentId: 'contentId', + contentType: 'contentType', + destination: 'statsDestination', + name: 'pageIdentifier', + producer: 'producerName', + additionalProperties: { + app_name: 'news', + app_type: 'getAppType', + content_language: 'language', + product_platform: null, + referrer_url: 'getReferrer', + x5: 'getHref', + x8: 'libraryVersion', + x9: 'sanitise', + x10: '', + x11: 'timePublished', + x12: 'timeUpdated', + x13: 'ldpThingLabels', + x14: 'ldpThingIds', + x16: 'campaign1~campaign2', + x17: 'categoryName', + x18: 'isLocServeCookieSet', + }, + }; + + expect(reverbAnalyticsModel.params.page).toEqual(pageParams); + expect(reverbAnalyticsModel.eventDetails).toEqual({ + eventName: 'pageView', + }); + }); + }); + + describe('buildReverbPageSectionEventModel', () => { + const input = { + pageIdentifier: 'mundo.page', + producerName: 'MUNDO', + statsDestination: 'statsDestination', + componentName: 'top-stories', + campaignID: '1234', + format: 'format', + type: 'view', + advertiserID: 'advertiserID', + url: 'http://localhost', + }; + + it('should return the correct Reverb page section view event model', () => { + const reverbPageSectionViewEventModel = + buildReverbPageSectionEventModel(input); + + const pageSectionViewEventParams = { + destination: 'statsDestination', + name: 'mundo.page', + producer: 'MUNDO', + additionalProperties: { + ati: 'PUB-[1234]-[top-stories]-[]-[format]-[mundo.page]-[]-[advertiserID]-[http://localhost]', + type: 'AT', + }, + }; + + expect(reverbPageSectionViewEventModel.params.page).toEqual( + pageSectionViewEventParams, + ); + }); + + it('should return the correct eventName for the Reverb page section view event model', () => { + const reverbPageSectionViewEventModel = + buildReverbPageSectionEventModel(input); + + expect(reverbPageSectionViewEventModel.eventDetails).toEqual({ + eventName: 'sectionView', + }); + }); + + it('should return the correct Reverb page section click event model', () => { + const reverbPageSectionViewEventModel = buildReverbPageSectionEventModel({ + ...input, + type: 'click', + }); + + const pageSectionViewEventParams = { + destination: 'statsDestination', + name: 'mundo.page', + producer: 'MUNDO', + additionalProperties: { + atc: 'PUB-[1234]-[top-stories]-[]-[format]-[mundo.page]-[]-[advertiserID]-[http://localhost]', + type: 'AT', + }, + }; + + expect(reverbPageSectionViewEventModel.params.page).toEqual( + pageSectionViewEventParams, + ); + }); + + it('should return the correct event details for the Reverb page section click event model', () => { + const reverbPageSectionViewEventModel = buildReverbPageSectionEventModel({ + ...input, + type: 'click', + }); + + expect(reverbPageSectionViewEventModel.eventDetails).toEqual({ + eventName: 'sectionClick', + componentName: 'top-stories', + container: '1234', + }); + }); + }); +}); diff --git a/src/app/components/ATIAnalytics/atiUrl/index.ts b/src/app/components/ATIAnalytics/atiUrl/index.ts index 73f3d1d351e..6b1256eb5a4 100644 --- a/src/app/components/ATIAnalytics/atiUrl/index.ts +++ b/src/app/components/ATIAnalytics/atiUrl/index.ts @@ -417,3 +417,122 @@ export const buildATIEventTrackUrl = ({ eventTrackingBeaconValues, )}&type=AT`; }; + +export const buildReverbAnalyticsModel = ({ + appName, + campaigns, + categoryName, + contentId, + contentType, + language, + ldpThingIds, + ldpThingLabels, + libraryVersion, + pageIdentifier, + pageTitle, + platform, + previousPath, + producerName, + origin, + nationsProducer, + statsDestination, + timePublished, + timeUpdated, +}: ATIPageTrackingProps) => { + const href = getHref(platform); + const referrer = getReferrer(platform, origin, previousPath); + + const aggregatedCampaigns = (Array.isArray(campaigns) ? campaigns : []) + .map(({ campaignName }) => campaignName) + .join('~'); + + const eventDetails = { + eventName: 'pageView', + }; + + const reverbVariables = { + params: { + page: { + contentId, + contentType, + destination: statsDestination, + name: pageIdentifier, + producer: producerName, + additionalProperties: { + app_name: platform === 'app' ? `${appName}-app` : appName, + app_type: getAppType(platform), + content_language: language, + product_platform: onOnionTld() ? 'tor-bbc' : null, + referrer_url: + referrer && encodeURIComponent(encodeURIComponent(referrer)), + x5: href && encodeURIComponent(encodeURIComponent(href)), + x8: libraryVersion, + x9: sanitise(pageTitle), + x10: nationsProducer && nationsProducer, + x11: timePublished, + x12: timeUpdated, + x13: ldpThingLabels, + x14: ldpThingIds, + x16: aggregatedCampaigns, + x17: categoryName, + x18: isLocServeCookieSet(), + }, + }, + user: { + hashedId: getAtUserId(), + isSignedIn: false, + }, + }, + eventDetails, + }; + + return reverbVariables; +}; + +export const buildReverbPageSectionEventModel = ({ + pageIdentifier, + producerName, + statsDestination, + componentName, + campaignID, + format, + type, + advertiserID, + url, +}: ATIEventTrackingProps) => { + const eventPublisher = type === 'view' ? 'ati' : 'atc'; + + const eventDetails = { + eventName: type === 'view' ? 'sectionView' : 'sectionClick', + ...(type === 'click' && { + componentName, + container: campaignID, + }), + }; + + return { + params: { + page: { + destination: statsDestination, + name: pageIdentifier, + producer: producerName, + additionalProperties: { + [eventPublisher]: getEventInfo({ + campaignID, + componentName, + format, + pageIdentifier, + advertiserID, + url, + }), + type: 'AT', + }, + }, + user: { + hashedId: getAtUserId(), + isSignedIn: false, + }, + }, + eventDetails, + }; +}; diff --git a/src/app/components/ATIAnalytics/beacon/index.test.ts b/src/app/components/ATIAnalytics/beacon/index.test.ts index 325d2a0d9c2..db1f8ab828b 100644 --- a/src/app/components/ATIAnalytics/beacon/index.test.ts +++ b/src/app/components/ATIAnalytics/beacon/index.test.ts @@ -11,6 +11,18 @@ const sendBeaconSpy = jest.spyOn(sendBeacon, 'default'); .fn() .mockReturnValue('00-00-00'); +const reverbMock = { + isReady: jest.fn(), + initialise: jest.fn(() => Promise.resolve()), + viewEvent: jest.fn(), + userActionEvent: jest.fn(), +}; + +// eslint-disable-next-line no-underscore-dangle +window.__reverb = { + __reverbLoadedPromise: Promise.resolve(reverbMock), +}; + describe('beacon', () => { const originalATIBaseUrl = process.env.SIMORGH_ATI_BASE_URL; const atiBaseUrl = 'https://foobar.com?'; @@ -48,5 +60,45 @@ describe('beacon', () => { type: 'AT', }); }); + + describe('Reverb', () => { + it('should call reverb view event exactly once', async () => { + await sendEventBeacon({ + type: 'view', + service: 'news', + componentName: 'component', + pageIdentifier: 'pageIdentifier', + detailedPlacement: 'detailedPlacement', + useReverb: true, + }); + expect(sendBeaconSpy).toHaveBeenCalledTimes(1); + + expect(reverbMock.viewEvent).toHaveBeenCalledTimes(1); + }); + + it('should call reverb click event exactly once', async () => { + await sendEventBeacon({ + type: 'click', + service: 'news', + componentName: 'component', + campaignID: 'campaign1', + pageIdentifier: 'pageIdentifier', + detailedPlacement: 'detailedPlacement', + useReverb: true, + }); + expect(sendBeaconSpy).toHaveBeenCalledTimes(1); + + expect(reverbMock.userActionEvent).toHaveBeenCalledTimes(1); + + expect(reverbMock.userActionEvent).toHaveBeenCalledWith( + 'click', + 'component', + { container: 'campaign1' }, + {}, + {}, + true, + ); + }); + }); }); }); diff --git a/src/app/components/ATIAnalytics/beacon/index.ts b/src/app/components/ATIAnalytics/beacon/index.ts index 54941ccc95b..28a5fa35933 100644 --- a/src/app/components/ATIAnalytics/beacon/index.ts +++ b/src/app/components/ATIAnalytics/beacon/index.ts @@ -1,5 +1,8 @@ import sendBeacon from '../../../lib/analyticsUtils/sendBeacon'; -import { buildATIEventTrackUrl } from '../atiUrl'; +import { + buildATIEventTrackUrl, + buildReverbPageSectionEventModel, +} from '../atiUrl'; import { ATIEventTrackingProps } from '../types'; export const sendEventBeacon = async ({ @@ -9,6 +12,7 @@ export const sendEventBeacon = async ({ pageIdentifier, platform, producerId, + producerName, service, statsDestination, type, @@ -16,24 +20,39 @@ export const sendEventBeacon = async ({ url, detailedPlacement, experimentVariant, + useReverb, }: ATIEventTrackingProps) => { - await sendBeacon( - buildATIEventTrackUrl({ - campaignID, - componentName, - format, - pageIdentifier, - platform, - producerId, - service, - statsDestination, - type, - advertiserID, - url, - detailedPlacement, - experimentVariant, - }), - ); + const atiClickTrackingUrl = buildATIEventTrackUrl({ + campaignID, + componentName, + format, + pageIdentifier, + platform, + producerId, + service, + statsDestination, + type, + advertiserID, + url, + detailedPlacement, + experimentVariant, + }); + + const reverbParams = useReverb + ? buildReverbPageSectionEventModel({ + pageIdentifier, + producerName, + statsDestination, + componentName, + campaignID, + format, + type, + advertiserID, + url, + }) + : null; + + await sendBeacon(atiClickTrackingUrl, reverbParams); }; export default sendEventBeacon; diff --git a/src/app/components/ATIAnalytics/canonical/index.test.tsx b/src/app/components/ATIAnalytics/canonical/index.test.tsx index 536ef8e1457..61ff5e9b1ea 100644 --- a/src/app/components/ATIAnalytics/canonical/index.test.tsx +++ b/src/app/components/ATIAnalytics/canonical/index.test.tsx @@ -22,13 +22,14 @@ describe('Canonical ATI Analytics', () => { it('calls atiBaseURL and sendBeacon with required params', () => { const expectedUrl = `${atiBaseUrl}${mockPageviewParams}`; + const reverbConfig = undefined; act(() => { render(); }); expect(mockSendBeacon).toHaveBeenCalledTimes(1); - expect(mockSendBeacon).toHaveBeenCalledWith(expectedUrl); + expect(mockSendBeacon).toHaveBeenCalledWith(expectedUrl, reverbConfig); }); it('should render lite Helmet script when isLite is true', () => { diff --git a/src/app/components/ATIAnalytics/canonical/index.tsx b/src/app/components/ATIAnalytics/canonical/index.tsx index 394b0bd4c83..f34dbc15b83 100644 --- a/src/app/components/ATIAnalytics/canonical/index.tsx +++ b/src/app/components/ATIAnalytics/canonical/index.tsx @@ -50,17 +50,22 @@ const addLiteScript = (atiPageViewUrlString: string) => { ); }; -const CanonicalATIAnalytics = ({ pageviewParams }: ATIAnalyticsProps) => { +const CanonicalATIAnalytics = ({ + pageviewParams, + reverbParams, +}: ATIAnalyticsProps) => { const { isLite } = useContext(RequestContext); const atiPageViewUrlString = getEnvConfig().SIMORGH_ATI_BASE_URL + pageviewParams; + const [reverbBeaconConfig] = useState(reverbParams); + const [atiPageViewUrl] = useState(atiPageViewUrlString); useEffect(() => { - if (!isOperaProxy()) sendBeacon(atiPageViewUrl); - }, [atiPageViewUrl]); + if (!isOperaProxy()) sendBeacon(atiPageViewUrl, reverbBeaconConfig); + }, [atiPageViewUrl, reverbBeaconConfig]); return ( <> diff --git a/src/app/components/ATIAnalytics/index.test.tsx b/src/app/components/ATIAnalytics/index.test.tsx index dc09f0381b6..b185487e641 100644 --- a/src/app/components/ATIAnalytics/index.test.tsx +++ b/src/app/components/ATIAnalytics/index.test.tsx @@ -9,6 +9,8 @@ import { setWindowValue, resetWindowValue, } from '#psammead/psammead-test-helpers/src'; +import { ServiceContext } from '#contexts/ServiceContext'; +import { ServiceConfig } from '#models/types/serviceConfig'; import styAssetData from './fixtures/storyPage.json'; import pglAssetData from './fixtures/photoGalleryPage.json'; import mapAssetData from './fixtures/mediaAssetPage.json'; @@ -1136,4 +1138,68 @@ describe('ATI Analytics Container', () => { }); }); }); + + describe('Reverb', () => { + it('should supply reverbParams when Reverb is enabled', () => { + const mockCanonical = jest.fn().mockReturnValue('canonical-return-value'); + // @ts-expect-error - we need to mock these functions to ensure tests are deterministic + canonical.default = mockCanonical; + + const { + metadata: { atiAnalytics }, + } = articleDataNews; + + // @ts-expect-error - only partial data required to manually set 'useReverb' to true + const serviceContextProps: ServiceConfig = { + atiAnalyticsAppName: 'atiAnalyticsAppName', + atiAnalyticsProducerId: 'atiAnalyticsProducerId', + service: 'pidgin', + brandName: 'brandName', + lang: 'pcm', + useReverb: true, + }; + + render( + + + , + { + ...defaultRenderProps, + atiData: atiAnalytics, + isAmp: false, + pageData: articleDataNews, + pageType: ARTICLE_PAGE, + service: 'pidgin', + isUK: true, + }, + ); + + const { reverbParams } = mockCanonical.mock.calls[0][0]; + + expect(reverbParams.params.page).toEqual({ + contentId: 'urn:bbc:optimo:c0000000001o', + contentType: 'article', + destination: 'WS_NEWS_LANGUAGES_TEST', + name: 'news.articles.c0000000001o.page', + additionalProperties: { + app_name: 'atiAnalyticsAppName', + app_type: 'responsive', + content_language: 'en-gb', + product_platform: null, + referrer_url: null, + x5: 'http%253A%252F%252Flocalhost%252F', + x8: 'simorgh', + x9: 'Article%20Headline%20for%20SEO', + x10: null, + x11: '2018-01-01T12:01:00.000Z', + x12: '2018-01-01T14:00:00.000Z', + x13: 'Royal+Wedding+2018~Duchess+of+Sussex', + x14: '2351f2b2-ce36-4f44-996d-c3c4f7f90eaa~803eaeb9-c0c3-4f1b-9a66-90efac3df2dc', + x16: '', + x17: 'Royal+Wedding+2018~Duchess+of+Sussex', + x18: false, + }, + }); + }); + }); }); diff --git a/src/app/components/ATIAnalytics/index.tsx b/src/app/components/ATIAnalytics/index.tsx index 26dcbf18730..9992f269f48 100644 --- a/src/app/components/ATIAnalytics/index.tsx +++ b/src/app/components/ATIAnalytics/index.tsx @@ -4,28 +4,40 @@ import { ServiceContext } from '../../contexts/ServiceContext'; import CanonicalATIAnalytics from './canonical'; import AmpATIAnalytics from './amp'; import { ATIProps } from './types'; -import buildATIUrl from './params'; +import { buildATIUrl, buildReverbParams } from './params'; const ATIAnalytics = ({ data, atiData }: ATIProps) => { const requestContext = useContext(RequestContext); const serviceContext = useContext(ServiceContext); const { isAmp } = requestContext; + const { useReverb } = serviceContext; - const pageviewParams = buildATIUrl({ + const urlPageViewParams = buildATIUrl({ requestContext, serviceContext, data, atiData, }) as string; - if (!pageviewParams) { + const reverbParams = useReverb + ? buildReverbParams({ + requestContext, + serviceContext, + atiData: atiData || {}, + }) + : null; + + if (!urlPageViewParams) { return null; } return isAmp ? ( - + ) : ( - + ); }; diff --git a/src/app/components/ATIAnalytics/params/buildParams/index.test.ts b/src/app/components/ATIAnalytics/params/buildParams/index.test.ts index ecdf59299b7..d6e857fc9e3 100644 --- a/src/app/components/ATIAnalytics/params/buildParams/index.test.ts +++ b/src/app/components/ATIAnalytics/params/buildParams/index.test.ts @@ -23,6 +23,7 @@ const requestContext: RequestContextProps = { const serviceContext: ServiceConfig = { atiAnalyticsAppName: 'atiAnalyticsAppName', atiAnalyticsProducerId: 'atiAnalyticsProducerId', + atiAnalyticsProducerName: 'atiAnalyticsProducerName', service: 'pidgin', lang: 'pcm', }; @@ -53,6 +54,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'pidgin', statsDestination: 'statsDestination', timePublished: undefined, @@ -149,6 +151,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: 'previousPath', producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'burmese', statsDestination: 'statsDestination', timePublished: '2023-07-13T05:03:56.214Z', @@ -287,6 +290,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: 'previousPath', producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'hausa', statsDestination: 'statsDestination', timePublished: '2023-07-11T17:42:48.771Z', @@ -379,6 +383,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'pidgin', statsDestination: 'statsDestination', timePublished: undefined, @@ -465,6 +470,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'pidgin', statsDestination: 'statsDestination', timePublished: '2023-08-01T12:00:00Z', @@ -580,6 +586,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'mundo', statsDestination: 'statsDestination', timePublished: '2023-02-10T02:00:41.000Z', @@ -694,6 +701,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'mundo', statsDestination: 'statsDestination', timePublished: '2017-09-14T14:09:14.000Z', @@ -806,6 +814,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'mundo', statsDestination: 'statsDestination', timePublished: '2016-08-07T09:21:02.000Z', @@ -913,6 +922,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: '64', + producerName: 'atiAnalyticsProducerName', service: 'news', statsDestination: 'statsDestination', timePublished: '2021-03-05T13:37:50.000Z', @@ -1042,6 +1052,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'urdu', statsDestination: 'statsDestination', timePublished: '2020-01-31T08:48:32.000Z', @@ -1127,6 +1138,7 @@ describe('implementation of buildPageATIParams and buildPageATIUrl', () => { platform: 'canonical', previousPath: undefined, producerId: 'atiAnalyticsProducerId', + producerName: 'atiAnalyticsProducerName', service: 'serbian', statsDestination: 'statsDestination', timePublished: '2018-01-19T14:09:41.000Z', diff --git a/src/app/components/ATIAnalytics/params/buildParams/index.ts b/src/app/components/ATIAnalytics/params/buildParams/index.ts index bccf8bd933c..f418bc8e0b5 100644 --- a/src/app/components/ATIAnalytics/params/buildParams/index.ts +++ b/src/app/components/ATIAnalytics/params/buildParams/index.ts @@ -1,5 +1,5 @@ import { LIBRARY_VERSION } from '../../../../lib/analyticsUtils'; -import { buildATIPageTrackPath } from '../../atiUrl'; +import { buildATIPageTrackPath, buildReverbAnalyticsModel } from '../../atiUrl'; import { ATIDataWithContexts } from '../../types'; export const buildPageATIParams = ({ @@ -9,8 +9,13 @@ export const buildPageATIParams = ({ }: ATIDataWithContexts) => { const { isUK, origin, platform, previousPath, statsDestination } = requestContext; - const { atiAnalyticsAppName, atiAnalyticsProducerId, lang, service } = - serviceContext; + const { + atiAnalyticsAppName, + atiAnalyticsProducerId, + atiAnalyticsProducerName, + lang, + service, + } = serviceContext; const { campaigns, categoryName, @@ -47,6 +52,7 @@ export const buildPageATIParams = ({ platform, previousPath, producerId: producerId || atiAnalyticsProducerId, + producerName: atiAnalyticsProducerName, service, statsDestination, timePublished, @@ -64,3 +70,12 @@ export const buildPageATIUrl = ({ buildATIPageTrackPath( buildPageATIParams({ atiData, requestContext, serviceContext }), ); + +export const buildPageReverbParams = ({ + atiData, + requestContext, + serviceContext, +}: ATIDataWithContexts) => + buildReverbAnalyticsModel( + buildPageATIParams({ atiData, requestContext, serviceContext }), + ); diff --git a/src/app/components/ATIAnalytics/params/index.ts b/src/app/components/ATIAnalytics/params/index.ts index 0702f5fa2cc..4d3c1ee3e40 100644 --- a/src/app/components/ATIAnalytics/params/index.ts +++ b/src/app/components/ATIAnalytics/params/index.ts @@ -21,7 +21,11 @@ import { AUDIO_PAGE, TV_PAGE, } from '../../../routes/utils/pageTypes'; -import { buildPageATIUrl, buildPageATIParams } from './buildParams'; +import { + buildPageATIUrl, + buildPageATIParams, + buildPageReverbParams, +} from './buildParams'; import { buildIndexPageATIParams, buildIndexPageATIUrl, @@ -32,6 +36,7 @@ import { PageData, ATIPageTrackingProps, ATIConfigurationDetailsProviders, + ReverbDetailsProviders, } from '../types'; import { PageTypes } from '../../../models/types/global'; @@ -154,6 +159,14 @@ export const buildATIUrl = ({ return null; }; +export const buildReverbParams = ({ + requestContext, + serviceContext, + atiData, +}: ReverbDetailsProviders) => { + return buildPageReverbParams({ atiData, requestContext, serviceContext }); +}; + export const buildATIEventTrackingParams = ({ requestContext, serviceContext, @@ -176,5 +189,3 @@ export const buildATIEventTrackingParams = ({ return buildParams(data as PageData, requestContext, serviceContext); }; - -export default buildATIUrl; diff --git a/src/app/components/ATIAnalytics/types.ts b/src/app/components/ATIAnalytics/types.ts index c7255c34b8a..14e4dda85a0 100644 --- a/src/app/components/ATIAnalytics/types.ts +++ b/src/app/components/ATIAnalytics/types.ts @@ -93,9 +93,16 @@ export interface ATIConfigurationDetailsProviders { atiData?: ATIData; } +export interface ReverbDetailsProviders { + requestContext: RequestContextProps; + serviceContext: ServiceConfig; + atiData: ATIData; +} + export interface ATIAnalyticsProps { baseUrl?: string; pageviewParams: string; + reverbParams?: object | null; } export interface ATIEventTrackingProps { @@ -105,12 +112,14 @@ export interface ATIEventTrackingProps { pageIdentifier?: string; platform?: Platforms; producerId?: string; + producerName?: string; service?: Services; statsDestination?: string; type?: string; advertiserID?: string; url?: string; detailedPlacement?: string; + useReverb?: boolean; experimentVariant?: string; ampExperimentName?: string; } @@ -125,6 +134,7 @@ export interface ATIPageTrackingProps { pageIdentifier?: string; pageTitle?: string | null; producerId?: string; + producerName?: string; libraryVersion?: string; platform?: Platforms; statsDestination?: string; diff --git a/src/app/contexts/EventTrackingContext/index.test.tsx b/src/app/contexts/EventTrackingContext/index.test.tsx index 47da5a6b30b..f01e86edf62 100644 --- a/src/app/contexts/EventTrackingContext/index.test.tsx +++ b/src/app/contexts/EventTrackingContext/index.test.tsx @@ -59,6 +59,7 @@ describe('Expected use', () => { pageIdentifier: 'news::pidgin.news.story.51745682.page', platform: 'canonical', producerId: '70', + producerName: 'PIDGIN', statsDestination: 'WS_NEWS_LANGUAGES_TEST', }); }); @@ -80,6 +81,7 @@ describe('Expected use', () => { pageIdentifier: 'kyrgyz.page', platform: 'canonical', producerId: '58', + producerName: 'KYRGYZ', statsDestination: 'WS_NEWS_LANGUAGES_TEST', }); }); diff --git a/src/app/contexts/EventTrackingContext/index.tsx b/src/app/contexts/EventTrackingContext/index.tsx index 4fb15232967..a6c706d44e6 100644 --- a/src/app/contexts/EventTrackingContext/index.tsx +++ b/src/app/contexts/EventTrackingContext/index.tsx @@ -104,7 +104,7 @@ export const EventTrackingContextProvider = ({ const { pageType } = requestContext; const serviceContext = useContext(ServiceContext); - const { atiAnalyticsProducerId } = serviceContext; + const { atiAnalyticsProducerId, atiAnalyticsProducerName } = serviceContext; const { enabled: eventTrackingIsEnabled } = useToggle('eventTracking'); @@ -125,12 +125,14 @@ export const EventTrackingContextProvider = ({ pageIdentifier, platform, producerId: atiAnalyticsProducerId, + producerName: atiAnalyticsProducerName, statsDestination, }; } return null; }, [ atiAnalyticsProducerId, + atiAnalyticsProducerName, atiData, data, eventTrackingIsEnabled, diff --git a/src/app/hooks/useClickTrackerHandler/index.jsx b/src/app/hooks/useClickTrackerHandler/index.jsx index 77429656dfd..92ae9d74c83 100644 --- a/src/app/hooks/useClickTrackerHandler/index.jsx +++ b/src/app/hooks/useClickTrackerHandler/index.jsx @@ -24,11 +24,16 @@ const useClickTrackerHandler = (props = {}) => { const [clicked, setClicked] = useState(false); const eventTrackingContext = useContext(EventTrackingContext); - const { pageIdentifier, platform, producerId, statsDestination } = - eventTrackingContext; + const { + pageIdentifier, + platform, + producerId, + producerName, + statsDestination, + } = eventTrackingContext; const campaignID = props?.campaignID || eventTrackingContext?.campaignID; - const { service } = useContext(ServiceContext); + const { service, useReverb } = useContext(ServiceContext); return useCallback( async event => { @@ -46,6 +51,7 @@ const useClickTrackerHandler = (props = {}) => { pageIdentifier, platform, producerId, + producerName, service, statsDestination, ].every(Boolean); @@ -84,11 +90,13 @@ const useClickTrackerHandler = (props = {}) => { pageIdentifier, platform, producerId, + producerName, service, advertiserID, statsDestination, url, detailedPlacement, + useReverb, ...(optimizelyVariation && optimizelyVariation !== 'off' && { experimentVariant: optimizelyVariation, @@ -114,6 +122,7 @@ const useClickTrackerHandler = (props = {}) => { platform, preventNavigation, producerId, + producerName, service, statsDestination, url, @@ -122,6 +131,7 @@ const useClickTrackerHandler = (props = {}) => { optimizely, optimizelyMetricNameOverride, detailedPlacement, + useReverb, ], ); }; diff --git a/src/app/hooks/useViewTracker/index.jsx b/src/app/hooks/useViewTracker/index.jsx index e5a01c4a297..d4e668100e4 100644 --- a/src/app/hooks/useViewTracker/index.jsx +++ b/src/app/hooks/useViewTracker/index.jsx @@ -27,12 +27,16 @@ const useViewTracker = (props = {}) => { const { trackingIsEnabled } = useTrackingToggle(componentName); const eventTrackingContext = useContext(EventTrackingContext); - const { pageIdentifier, platform, producerId, statsDestination } = - eventTrackingContext; - + const { + pageIdentifier, + platform, + producerId, + producerName, + statsDestination, + } = eventTrackingContext; const campaignID = props?.campaignID || eventTrackingContext?.campaignID; - const { service } = useContext(ServiceContext); + const { service, useReverb } = useContext(ServiceContext); const initObserver = async () => { if (typeof window.IntersectionObserver === 'undefined') { @@ -60,6 +64,7 @@ const useViewTracker = (props = {}) => { pageIdentifier, platform, producerId, + producerName, service, statsDestination, ].every(Boolean); @@ -98,12 +103,14 @@ const useViewTracker = (props = {}) => { pageIdentifier, platform, producerId, + producerName, service, statsDestination, type: EVENT_TYPE, advertiserID, url, detailedPlacement, + useReverb, ...(optimizelyVariation && optimizelyVariation !== 'off' && { experimentVariant: optimizelyVariation, @@ -131,6 +138,7 @@ const useViewTracker = (props = {}) => { pageIdentifier, platform, producerId, + producerName, service, statsDestination, trackingIsEnabled, @@ -140,6 +148,7 @@ const useViewTracker = (props = {}) => { optimizely, optimizelyMetricNameOverride, detailedPlacement, + useReverb, ]); return async element => { diff --git a/src/app/legacy/containers/CpsFeaturesAnalysis/index.jsx b/src/app/legacy/containers/CpsFeaturesAnalysis/index.jsx index 2203df22ca7..0884fb18a87 100644 --- a/src/app/legacy/containers/CpsFeaturesAnalysis/index.jsx +++ b/src/app/legacy/containers/CpsFeaturesAnalysis/index.jsx @@ -121,7 +121,7 @@ const PromoComponent = ({ promo, dir = 'ltr', sendOptimizelyEvents }) => { }, }; - const viewRef = useViewTracker(eventTrackingDataWithOptimizely); + const viewRef = useViewTracker(eventTrackingDataWithOptimizely.block); return (
diff --git a/src/app/legacy/containers/PageHandlers/__snapshots__/withContexts.test.jsx.snap b/src/app/legacy/containers/PageHandlers/__snapshots__/withContexts.test.jsx.snap index 7684b08b551..040bd94a784 100644 --- a/src/app/legacy/containers/PageHandlers/__snapshots__/withContexts.test.jsx.snap +++ b/src/app/legacy/containers/PageHandlers/__snapshots__/withContexts.test.jsx.snap @@ -3,7 +3,7 @@ exports[`withContexts HOC should return all context providers 1`] = `
- {"lang":"en-GB","articleAuthor":"https://www.facebook.com/bbcnews","articleTimestampPrefix":"Updated","articleTimestampSuffix":"","atiAnalyticsAppName":"news","atiAnalyticsProducerId":"64","chartbeatDomain":"bbc.co.uk","brandName":"BBC News","product":"BBC News","defaultImage":"https://static.files.bbci.co.uk/ws/simorgh-assets/public/news/images/metadata/poster-1024x576.png","defaultImageAltText":"BBC News","dir":"ltr","externalLinkText":", external","imageCaptionOffscreenText":"Image caption, ","videoCaptionOffscreenText":"Video caption, ","audioCaptionOffscreenText":"Audio caption","defaultCaptionOffscreenText":"Caption, ","imageCopyrightOffscreenText":"Image source, ","locale":"en_GB","datetimeLocale":"en-gb","service":"news","serviceName":"News","languageName":"English","twitterCreator":"@BBCNews","twitterSite":"@BBCNews","noBylinesPolicy":"https://www.bbc.com/news/help-41670342#authorexpertise","publishingPrinciples":"https://www.bbc.com/news/help-41670342","isTrustProjectParticipant":true,"script":{"atlas":{"groupA":{"fontSize":78,"lineHeight":84},"groupB":{"fontSize":96,"lineHeight":104},"groupD":{"fontSize":140,"lineHeight":148}},"elephant":{"groupA":{"fontSize":60,"lineHeight":64},"groupB":{"fontSize":78,"lineHeight":84},"groupD":{"fontSize":116,"lineHeight":124}},"imperial":{"groupA":{"fontSize":50,"lineHeight":54},"groupB":{"fontSize":64,"lineHeight":72},"groupD":{"fontSize":96,"lineHeight":104}},"royal":{"groupA":{"fontSize":40,"lineHeight":44},"groupB":{"fontSize":52,"lineHeight":60},"groupD":{"fontSize":76,"lineHeight":84}},"foolscap":{"groupA":{"fontSize":32,"lineHeight":36},"groupB":{"fontSize":40,"lineHeight":44},"groupD":{"fontSize":56,"lineHeight":60}},"canon":{"groupA":{"fontSize":28,"lineHeight":32},"groupB":{"fontSize":32,"lineHeight":36},"groupD":{"fontSize":44,"lineHeight":48}},"trafalgar":{"groupA":{"fontSize":20,"lineHeight":24},"groupB":{"fontSize":24,"lineHeight":28},"groupD":{"fontSize":32,"lineHeight":36}},"paragon":{"groupA":{"fontSize":20,"lineHeight":24},"groupB":{"fontSize":22,"lineHeight":26},"groupD":{"fontSize":28,"lineHeight":32}},"doublePica":{"groupA":{"fontSize":18,"lineHeight":22},"groupB":{"fontSize":20,"lineHeight":24},"groupD":{"fontSize":24,"lineHeight":28}},"greatPrimer":{"groupA":{"fontSize":18,"lineHeight":22},"groupB":{"fontSize":18,"lineHeight":22},"groupD":{"fontSize":20,"lineHeight":24}},"bodyCopy":{"groupA":{"fontSize":15,"lineHeight":20},"groupB":{"fontSize":16,"lineHeight":22},"groupD":{"fontSize":16,"lineHeight":22}},"pica":{"groupA":{"fontSize":15,"lineHeight":20},"groupB":{"fontSize":16,"lineHeight":20},"groupD":{"fontSize":16,"lineHeight":20}},"longPrimer":{"groupA":{"fontSize":15,"lineHeight":18},"groupB":{"fontSize":15,"lineHeight":18},"groupD":{"fontSize":14,"lineHeight":18}},"brevier":{"groupA":{"fontSize":14,"lineHeight":18},"groupB":{"fontSize":14,"lineHeight":18},"groupD":{"fontSize":13,"lineHeight":16}},"minion":{"groupA":{"fontSize":12,"lineHeight":16},"groupB":{"fontSize":12,"lineHeight":16},"groupD":{"fontSize":12,"lineHeight":16}}},"manifestPath":"/articles/manifest.json","frontPageTitle":"Home","showAdPlaceholder":false,"showRelatedTopics":true,"translations":{"ads":{"advertisementLabel":"Advertisement"},"home":"Home","currentPage":"Current page","skipLinkText":"Skip to content","relatedContent":"Related content","relatedTopics":"Related topics","navMenuText":"Sections","mediaAssetPage":{"mediaPlayer":"Media player","audioPlayer":"Audio player","videoPlayer":"Video player"},"liveExperiencePage":{"liveLabel":"Live","liveCoverage":"Live Coverage","breaking":"Breaking","postedAt":"Posted at","summary":"Summary","shareButtonText":"Share"},"downloads":{"instructions":"You can download and view today’s news.","title":"File Download"},"gist":"At a glance","error":{"404":{"statusCode":"404","title":"Page cannot be found","message":"Sorry, we're unable to bring you the page you're looking for. Please try:","solutions":["Double checking the url","Hitting the refresh button in your browser","Searching for this page using the BBC search bar"],"callToActionFirst":"Alternatively, please visit the ","callToActionLinkText":"BBC News homepage.","callToActionLast":"","callToActionLinkUrl":"https://www.bbc.com/news"},"500":{"statusCode":"500","title":"Internal server error","message":"Sorry, we're currently unable to bring you the page you're looking for. Please try:","solutions":["Hitting the refresh button in your browser","Coming back again later"],"callToActionFirst":"Alternatively, please visit the ","callToActionLinkText":"BBC News homepage.","callToActionLast":"","callToActionLinkUrl":"https://www.bbc.com/news"}},"consentBanner":{"privacy":{"title":"We've updated our Privacy and Cookies Policy","description":{"uk":{"first":"We've made some important changes to our Privacy and Cookies Policy and we want you to know what this means for you and your data.","linkText":null,"last":null,"linkUrl":null},"international":{"first":"We've made some important changes to our Privacy and Cookies Policy and we want you to know what this means for you and your data.","linkText":null,"last":null,"linkUrl":null}},"accept":"OK","reject":"Find out what's changed","rejectUrl":"https://www.bbc.co.uk/usingthebbc/privacy-policy/"},"cookie":{"amp":{"accept":"Accept data collection and continue","reject":"Reject data collection and continue","initial":{"title":"Let us know you agree to data collection on AMP","description":{"first":"We and our partners use technologies, such as ","linkText":"cookies","last":", and collect browsing data to give you the best online experience and to personalise the content and advertising shown to you. Please let us know if you agree.","linkUrl":"https://www.bbc.co.uk/usingthebbc/cookies/what-do-i-need-to-know-about-cookies/"},"manage":"Manage my settings"},"manage":{"title":"Manage consent settings on AMP pages","description":{"para1":"These settings apply to AMP pages only. You may be asked to set these preferences again when you visit non-AMP BBC pages.","para2":"The lightweight mobile page you have visited has been built using Google AMP technology.","heading2":"Strictly necessary data collection","para3":"To make our web pages work, we store some limited information on your device without your consent.","para4":{"text":"Read more about the essential information we store on your device to make our web pages work.","url":"https://www.bbc.co.uk/usingthebbc/strictly-necessary-cookies/"},"para5":"We use local storage to store your consent preferences on your device.","heading3":"Optional data collection","para6":"When you consent to data collection on AMP pages you are consenting to allow us to display personalised ads that are relevant to you when you are outside of the UK.","para7":{"text":"Read more about how we personalise ads in the BBC and our advertising partners.","url":"https://www.bbc.com/usingthebbc/cookies/how-does-the-bbc-use-cookies-for-advertising/"},"para8":"You can choose not to receive personalised ads by clicking “Reject data collection and continue” below. Please note that you will still see advertising, but it will not be personalised to you.","para9":"You can change these settings by clicking “Ad Choices / Do not sell my info” in the footer at any time."}}},"canonical":{"title":"Let us know you agree to cookies","description":{"uk":{"first":"We use ","linkText":"cookies","last":" to give you the best online experience. Please let us know if you agree to all of these cookies.","linkUrl":"https://www.bbc.co.uk/usingthebbc/cookies/what-do-i-need-to-know-about-cookies/"},"international":{"first":"We use ","linkText":"cookies","last":" to give you the best online experience. Please let us know if you agree to all of these cookies.","linkUrl":"https://www.bbc.co.uk/usingthebbc/cookies/what-do-i-need-to-know-about-cookies/"}},"accept":"Yes, I agree","reject":"No, take me to settings","rejectUrl":"https://www.bbc.co.uk/usingthebbc/cookies/how-can-i-change-my-bbc-cookie-settings/"}}},"media":{"noJs":"To play this content, please enable JavaScript, or try a different browser","contentExpired":"This content is no longer available","audio":"Audio","photogallery":"Image gallery","video":"Video","listen":"Listen","watch":"Watch","liveLabel":"LIVE","nextLabel":"NEXT","previousRadioShow":"Previous radio show","nextRadioShow":"Next radio show","duration":"Duration"},"socialEmbed":{},"featuresAnalysisTitle":"More to explore"},"mostRead":{"header":"Most read","lastUpdated":"Last updated:","numberOfItems":10,"hasMostRead":true},"radioSchedule":{"hasRadioSchedule":false},"recommendations":{"hasStoryRecommendations":false},"footer":{"trustProjectLink":{"href":"https://www.bbc.com/news/help-41670342","text":"Why you can trust the BBC"},"externalLink":{"href":"https://www.bbc.co.uk/editorialguidelines/guidance/feeds-and-links","text":"Read about our approach to external linking."},"links":[{"href":"https://www.bbc.com/terms","text":"Terms of Use"},{"href":"https://www.bbc.co.uk/aboutthebbc/","text":"About the BBC"},{"href":"https://www.bbc.com/privacy/","text":"Privacy Policy"},{"href":"https://www.bbc.com/usingthebbc/cookies/","text":"Cookies"},{"href":"https://www.bbc.com/accessibility/","text":"Accessibility Help"},{"href":"https://www.bbc.com/contact/","text":"Contact the BBC"},{"id":"COOKIE_SETTINGS","href":"#","text":"Do not share or sell my info","lang":"en-GB"}],"copyrightText":"BBC. The BBC is not responsible for the content of external sites."},"timezone":"Europe/London","navigation":[{"title":"Home","url":"/news"},{"title":"UK","url":"/news/uk"},{"title":"World","url":"/news/world"},{"title":"Business","url":"/news/business"},{"title":"Politics","url":"/news/politics"},{"title":"Tech","url":"/news/technology"},{"title":"Science","url":"/news/science_and_environment"},{"title":"Health","url":"/news/health"},{"title":"Family & Education","url":"/news/education"},{"title":"Entertainment & Arts","url":"/news/entertainment_and_arts"},{"title":"Stories","url":"/news/stories"}]} + {"lang":"en-GB","articleAuthor":"https://www.facebook.com/bbcnews","articleTimestampPrefix":"Updated","articleTimestampSuffix":"","atiAnalyticsAppName":"news","atiAnalyticsProducerId":"64","atiAnalyticsProducerName":"NEWS","chartbeatDomain":"bbc.co.uk","brandName":"BBC News","product":"BBC News","defaultImage":"https://static.files.bbci.co.uk/ws/simorgh-assets/public/news/images/metadata/poster-1024x576.png","defaultImageAltText":"BBC News","dir":"ltr","externalLinkText":", external","imageCaptionOffscreenText":"Image caption, ","videoCaptionOffscreenText":"Video caption, ","audioCaptionOffscreenText":"Audio caption","defaultCaptionOffscreenText":"Caption, ","imageCopyrightOffscreenText":"Image source, ","locale":"en_GB","datetimeLocale":"en-gb","service":"news","serviceName":"News","languageName":"English","twitterCreator":"@BBCNews","twitterSite":"@BBCNews","noBylinesPolicy":"https://www.bbc.com/news/help-41670342#authorexpertise","publishingPrinciples":"https://www.bbc.com/news/help-41670342","isTrustProjectParticipant":true,"script":{"atlas":{"groupA":{"fontSize":78,"lineHeight":84},"groupB":{"fontSize":96,"lineHeight":104},"groupD":{"fontSize":140,"lineHeight":148}},"elephant":{"groupA":{"fontSize":60,"lineHeight":64},"groupB":{"fontSize":78,"lineHeight":84},"groupD":{"fontSize":116,"lineHeight":124}},"imperial":{"groupA":{"fontSize":50,"lineHeight":54},"groupB":{"fontSize":64,"lineHeight":72},"groupD":{"fontSize":96,"lineHeight":104}},"royal":{"groupA":{"fontSize":40,"lineHeight":44},"groupB":{"fontSize":52,"lineHeight":60},"groupD":{"fontSize":76,"lineHeight":84}},"foolscap":{"groupA":{"fontSize":32,"lineHeight":36},"groupB":{"fontSize":40,"lineHeight":44},"groupD":{"fontSize":56,"lineHeight":60}},"canon":{"groupA":{"fontSize":28,"lineHeight":32},"groupB":{"fontSize":32,"lineHeight":36},"groupD":{"fontSize":44,"lineHeight":48}},"trafalgar":{"groupA":{"fontSize":20,"lineHeight":24},"groupB":{"fontSize":24,"lineHeight":28},"groupD":{"fontSize":32,"lineHeight":36}},"paragon":{"groupA":{"fontSize":20,"lineHeight":24},"groupB":{"fontSize":22,"lineHeight":26},"groupD":{"fontSize":28,"lineHeight":32}},"doublePica":{"groupA":{"fontSize":18,"lineHeight":22},"groupB":{"fontSize":20,"lineHeight":24},"groupD":{"fontSize":24,"lineHeight":28}},"greatPrimer":{"groupA":{"fontSize":18,"lineHeight":22},"groupB":{"fontSize":18,"lineHeight":22},"groupD":{"fontSize":20,"lineHeight":24}},"bodyCopy":{"groupA":{"fontSize":15,"lineHeight":20},"groupB":{"fontSize":16,"lineHeight":22},"groupD":{"fontSize":16,"lineHeight":22}},"pica":{"groupA":{"fontSize":15,"lineHeight":20},"groupB":{"fontSize":16,"lineHeight":20},"groupD":{"fontSize":16,"lineHeight":20}},"longPrimer":{"groupA":{"fontSize":15,"lineHeight":18},"groupB":{"fontSize":15,"lineHeight":18},"groupD":{"fontSize":14,"lineHeight":18}},"brevier":{"groupA":{"fontSize":14,"lineHeight":18},"groupB":{"fontSize":14,"lineHeight":18},"groupD":{"fontSize":13,"lineHeight":16}},"minion":{"groupA":{"fontSize":12,"lineHeight":16},"groupB":{"fontSize":12,"lineHeight":16},"groupD":{"fontSize":12,"lineHeight":16}}},"manifestPath":"/articles/manifest.json","frontPageTitle":"Home","showAdPlaceholder":false,"showRelatedTopics":true,"translations":{"ads":{"advertisementLabel":"Advertisement"},"home":"Home","currentPage":"Current page","skipLinkText":"Skip to content","relatedContent":"Related content","relatedTopics":"Related topics","navMenuText":"Sections","mediaAssetPage":{"mediaPlayer":"Media player","audioPlayer":"Audio player","videoPlayer":"Video player"},"liveExperiencePage":{"liveLabel":"Live","liveCoverage":"Live Coverage","breaking":"Breaking","postedAt":"Posted at","summary":"Summary","shareButtonText":"Share"},"downloads":{"instructions":"You can download and view today’s news.","title":"File Download"},"gist":"At a glance","error":{"404":{"statusCode":"404","title":"Page cannot be found","message":"Sorry, we're unable to bring you the page you're looking for. Please try:","solutions":["Double checking the url","Hitting the refresh button in your browser","Searching for this page using the BBC search bar"],"callToActionFirst":"Alternatively, please visit the ","callToActionLinkText":"BBC News homepage.","callToActionLast":"","callToActionLinkUrl":"https://www.bbc.com/news"},"500":{"statusCode":"500","title":"Internal server error","message":"Sorry, we're currently unable to bring you the page you're looking for. Please try:","solutions":["Hitting the refresh button in your browser","Coming back again later"],"callToActionFirst":"Alternatively, please visit the ","callToActionLinkText":"BBC News homepage.","callToActionLast":"","callToActionLinkUrl":"https://www.bbc.com/news"}},"consentBanner":{"privacy":{"title":"We've updated our Privacy and Cookies Policy","description":{"uk":{"first":"We've made some important changes to our Privacy and Cookies Policy and we want you to know what this means for you and your data.","linkText":null,"last":null,"linkUrl":null},"international":{"first":"We've made some important changes to our Privacy and Cookies Policy and we want you to know what this means for you and your data.","linkText":null,"last":null,"linkUrl":null}},"accept":"OK","reject":"Find out what's changed","rejectUrl":"https://www.bbc.co.uk/usingthebbc/privacy-policy/"},"cookie":{"amp":{"accept":"Accept data collection and continue","reject":"Reject data collection and continue","initial":{"title":"Let us know you agree to data collection on AMP","description":{"first":"We and our partners use technologies, such as ","linkText":"cookies","last":", and collect browsing data to give you the best online experience and to personalise the content and advertising shown to you. Please let us know if you agree.","linkUrl":"https://www.bbc.co.uk/usingthebbc/cookies/what-do-i-need-to-know-about-cookies/"},"manage":"Manage my settings"},"manage":{"title":"Manage consent settings on AMP pages","description":{"para1":"These settings apply to AMP pages only. You may be asked to set these preferences again when you visit non-AMP BBC pages.","para2":"The lightweight mobile page you have visited has been built using Google AMP technology.","heading2":"Strictly necessary data collection","para3":"To make our web pages work, we store some limited information on your device without your consent.","para4":{"text":"Read more about the essential information we store on your device to make our web pages work.","url":"https://www.bbc.co.uk/usingthebbc/strictly-necessary-cookies/"},"para5":"We use local storage to store your consent preferences on your device.","heading3":"Optional data collection","para6":"When you consent to data collection on AMP pages you are consenting to allow us to display personalised ads that are relevant to you when you are outside of the UK.","para7":{"text":"Read more about how we personalise ads in the BBC and our advertising partners.","url":"https://www.bbc.com/usingthebbc/cookies/how-does-the-bbc-use-cookies-for-advertising/"},"para8":"You can choose not to receive personalised ads by clicking “Reject data collection and continue” below. Please note that you will still see advertising, but it will not be personalised to you.","para9":"You can change these settings by clicking “Ad Choices / Do not sell my info” in the footer at any time."}}},"canonical":{"title":"Let us know you agree to cookies","description":{"uk":{"first":"We use ","linkText":"cookies","last":" to give you the best online experience. Please let us know if you agree to all of these cookies.","linkUrl":"https://www.bbc.co.uk/usingthebbc/cookies/what-do-i-need-to-know-about-cookies/"},"international":{"first":"We use ","linkText":"cookies","last":" to give you the best online experience. Please let us know if you agree to all of these cookies.","linkUrl":"https://www.bbc.co.uk/usingthebbc/cookies/what-do-i-need-to-know-about-cookies/"}},"accept":"Yes, I agree","reject":"No, take me to settings","rejectUrl":"https://www.bbc.co.uk/usingthebbc/cookies/how-can-i-change-my-bbc-cookie-settings/"}}},"media":{"noJs":"To play this content, please enable JavaScript, or try a different browser","contentExpired":"This content is no longer available","audio":"Audio","photogallery":"Image gallery","video":"Video","listen":"Listen","watch":"Watch","liveLabel":"LIVE","nextLabel":"NEXT","previousRadioShow":"Previous radio show","nextRadioShow":"Next radio show","duration":"Duration"},"socialEmbed":{},"featuresAnalysisTitle":"More to explore"},"mostRead":{"header":"Most read","lastUpdated":"Last updated:","numberOfItems":10,"hasMostRead":true},"radioSchedule":{"hasRadioSchedule":false},"recommendations":{"hasStoryRecommendations":false},"footer":{"trustProjectLink":{"href":"https://www.bbc.com/news/help-41670342","text":"Why you can trust the BBC"},"externalLink":{"href":"https://www.bbc.co.uk/editorialguidelines/guidance/feeds-and-links","text":"Read about our approach to external linking."},"links":[{"href":"https://www.bbc.com/terms","text":"Terms of Use"},{"href":"https://www.bbc.co.uk/aboutthebbc/","text":"About the BBC"},{"href":"https://www.bbc.com/privacy/","text":"Privacy Policy"},{"href":"https://www.bbc.com/usingthebbc/cookies/","text":"Cookies"},{"href":"https://www.bbc.com/accessibility/","text":"Accessibility Help"},{"href":"https://www.bbc.com/contact/","text":"Contact the BBC"},{"id":"COOKIE_SETTINGS","href":"#","text":"Do not share or sell my info","lang":"en-GB"}],"copyrightText":"BBC. The BBC is not responsible for the content of external sites."},"timezone":"Europe/London","navigation":[{"title":"Home","url":"/news"},{"title":"UK","url":"/news/uk"},{"title":"World","url":"/news/world"},{"title":"Business","url":"/news/business"},{"title":"Politics","url":"/news/politics"},{"title":"Tech","url":"/news/technology"},{"title":"Science","url":"/news/science_and_environment"},{"title":"Health","url":"/news/health"},{"title":"Family & Education","url":"/news/education"},{"title":"Entertainment & Arts","url":"/news/entertainment_and_arts"},{"title":"Stories","url":"/news/stories"}]} {"env":"live","id":"c0000000000o","isUK":true,"origin":"https://www.bbc.com","pageType":"article","derivedPageType":null,"isAmp":true,"isApp":false,"isLite":false,"isNextJs":false,"platform":"amp","statsDestination":"NEWS_PS_TEST","statsPageIdentifier":"news.articles.c0000000000o.page","statusCode":200,"previousPath":null,"variant":null,"timeOnServer":null,"showAdsBasedOnLocation":true,"showCookieBannerBasedOnCountry":true,"service":"news","pathname":"/pathname","canonicalLink":"https://www.bbc.com/pathname","ampLink":"https://www.bbc.com/pathname.amp","canonicalUkLink":"https://www.bbc.co.uk/pathname","ampUkLink":"https://www.bbc.co.uk/pathname.amp","canonicalNonUkLink":"https://www.bbc.com/pathname","ampNonUkLink":"https://www.bbc.com/pathname.amp","mvtExperiments":[{"experimentName":"foo","variation":"bar"}]} diff --git a/src/app/lib/analyticsUtils/sendBeacon/index.js b/src/app/lib/analyticsUtils/sendBeacon/index.js index 25f6d3a4afd..b52a7ae9a00 100644 --- a/src/app/lib/analyticsUtils/sendBeacon/index.js +++ b/src/app/lib/analyticsUtils/sendBeacon/index.js @@ -4,10 +4,120 @@ import { ATI_LOGGING_ERROR } from '../../logger.const'; const logger = nodeLogger(__filename); -const sendBeacon = async url => { +const setReverbPageValues = async ({ pageVars, userVars }) => { + window.bbcpage = {}; + + window.bbcpage = Object.assign(window.bbcpage, { + getName() { + return Promise.resolve(pageVars.name); + }, + getLanguage() { + return Promise.resolve(pageVars.additionalProperties.content_language); + }, + getDestination() { + return Promise.resolve(pageVars.destination); + }, + getProducer() { + return Promise.resolve(pageVars.producer); + }, + getSection() { + return Promise.resolve(''); + }, + getContentId() { + return Promise.resolve(pageVars.contentId); + }, + getContentType() { + return Promise.resolve(pageVars.contentType); + }, + getEdition() { + return Promise.resolve(''); + }, + getReferrer() { + return Promise.resolve(''); + }, + getAdditionalProperties() { + return Promise.resolve(pageVars.additionalProperties); + }, + additionalProperties: { + testDomain: 'local.ati-host.net', + trace: '', + customVars: '', + }, + }); + + window.bbcuser = { + getHashedId: () => [userVars.hashedId], + isSignedIn: () => Promise.resolve(userVars.isSignedIn), + }; +}; + +const reverbPageViews = async ({ reverbInstance }) => { + reverbInstance.viewEvent(); +}; + +const reverbLinkClick = async ({ reverbInstance, eventDetails }) => { + const { componentName, container } = eventDetails; + + return reverbInstance.userActionEvent( + 'click', + componentName, + { container }, + {}, + {}, + true, + ); +}; + +const reverbHandlers = { + pageView: reverbPageViews, + sectionView: reverbPageViews, + sectionClick: reverbLinkClick, +}; + +const callReverb = async eventDetails => { + const { eventName } = eventDetails; + + // eslint-disable-next-line no-underscore-dangle + window.__reverb.__reverbLoadedPromise.then( + async reverb => { + if (reverb.isReady()) { + await reverbHandlers[eventName]({ + reverbInstance: reverb, + eventDetails, + }); + return; + } + + reverb.initialise().then(async () => { + await reverbHandlers[eventName]({ + reverbInstance: reverb, + eventDetails, + }); + }); + }, + () => { + logger.error(ATI_LOGGING_ERROR, { + error: 'Failed to load reverb. No event sent', + }); + }, + ); +}; + +const sendBeacon = async (url, reverbBeaconConfig) => { if (onClient()) { try { - await fetch(url, { credentials: 'include' }).then(res => res.text()); + if (reverbBeaconConfig) { + const { + params: { page, user }, + eventDetails, + } = reverbBeaconConfig; + + await setReverbPageValues({ pageVars: page, userVars: user }); + + await callReverb(eventDetails); + } else { + await fetch(url, { credentials: 'include' }).then(res => res.text()); + } } catch (error) { logger.error(ATI_LOGGING_ERROR, { error, diff --git a/src/app/lib/analyticsUtils/sendBeacon/index.test.js b/src/app/lib/analyticsUtils/sendBeacon/index.test.js index d8fda53a1a8..501f94db515 100644 --- a/src/app/lib/analyticsUtils/sendBeacon/index.test.js +++ b/src/app/lib/analyticsUtils/sendBeacon/index.test.js @@ -5,6 +5,18 @@ import { ATI_LOGGING_ERROR } from '#app/lib/logger.const'; let fetchResponse; let isOnClient; +const reverbMock = { + isReady: jest.fn(), + initialise: jest.fn(() => Promise.resolve()), + viewEvent: jest.fn(), + userActionEvent: jest.fn(), +}; + +// eslint-disable-next-line no-underscore-dangle +window.__reverb = { + __reverbLoadedPromise: Promise.resolve(reverbMock), +}; + describe('sendBeacon', () => { beforeEach(() => { isOnClient = true; @@ -38,6 +50,34 @@ describe('sendBeacon', () => { expect(fetch).not.toHaveBeenCalled(); }); + describe('Reverb', () => { + const reverbConfig = { + params: { + page: 'page', + user: '1234-5678', + }, + eventDetails: { + eventName: 'pageView', + }, + }; + + it('should call Reverb viewEvent if Reverb config is passed', async () => { + const sendBeacon = require('./index').default; + + await sendBeacon('https://foobar.com', reverbConfig); + + expect(reverbMock.viewEvent).toHaveBeenCalledTimes(1); + }); + + it('should not call "fetch" if Reverb config is passed', async () => { + const sendBeacon = require('./index').default; + + await sendBeacon('https://foobar.com', reverbConfig); + + expect(fetch).not.toHaveBeenCalled(); + }); + }); + describe('when the fetch fails', () => { let error; diff --git a/src/app/lib/config/services/afaanoromoo.ts b/src/app/lib/config/services/afaanoromoo.ts index b7974603374..afd398df5de 100644 --- a/src/app/lib/config/services/afaanoromoo.ts +++ b/src/app/lib/config/services/afaanoromoo.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-afaanoromoo', atiAnalyticsProducerId: '2', + atiAnalyticsProducerName: 'AFAAN_OROMOO', chartbeatDomain: 'afaanoromoo.bbc.co.uk', brandName: 'BBC News Afaan Oromoo', product: 'BBC News', diff --git a/src/app/lib/config/services/afrique.ts b/src/app/lib/config/services/afrique.ts index 9a38c3481d1..a71051c4e3a 100644 --- a/src/app/lib/config/services/afrique.ts +++ b/src/app/lib/config/services/afrique.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-afrique', atiAnalyticsProducerId: '3', + atiAnalyticsProducerName: 'AFRIQUE', chartbeatDomain: 'afrique.bbc.co.uk', brandName: 'BBC News Afrique', product: 'BBC News', diff --git a/src/app/lib/config/services/amharic.ts b/src/app/lib/config/services/amharic.ts index 5948911d93f..df4351887c9 100644 --- a/src/app/lib/config/services/amharic.ts +++ b/src/app/lib/config/services/amharic.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-amharic', atiAnalyticsProducerId: '4', + atiAnalyticsProducerName: 'AMHARIC', chartbeatDomain: 'amharic.bbc.co.uk', brandName: 'BBC News አማርኛ', product: 'BBC News', diff --git a/src/app/lib/config/services/arabic.ts b/src/app/lib/config/services/arabic.ts index 817aa428593..337ad471d33 100644 --- a/src/app/lib/config/services/arabic.ts +++ b/src/app/lib/config/services/arabic.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-arabic', atiAnalyticsProducerId: '5', + atiAnalyticsProducerName: 'ARABIC', chartbeatDomain: 'arabic.bbc.co.uk', brandName: 'BBC News عربي', product: 'BBC News', diff --git a/src/app/lib/config/services/archive.ts b/src/app/lib/config/services/archive.ts index dfe36cb9f17..9e0c5aa1daf 100644 --- a/src/app/lib/config/services/archive.ts +++ b/src/app/lib/config/services/archive.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'archive', atiAnalyticsProducerId: '127', + atiAnalyticsProducerName: 'BBC_ARCHIVE', chartbeatDomain: 'bbc.co.uk', brandName: 'BBC Archive', product: 'BBC Archive', diff --git a/src/app/lib/config/services/azeri.ts b/src/app/lib/config/services/azeri.ts index 4d7b16a622c..9a52fdd189f 100644 --- a/src/app/lib/config/services/azeri.ts +++ b/src/app/lib/config/services/azeri.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-azeri', atiAnalyticsProducerId: '6', + atiAnalyticsProducerName: 'AZERI', chartbeatDomain: 'azeri.bbc.co.uk', brandName: 'BBC News Azərbaycanca', product: 'BBC News', diff --git a/src/app/lib/config/services/bengali.ts b/src/app/lib/config/services/bengali.ts index 51a72d47488..7184ea9609d 100644 --- a/src/app/lib/config/services/bengali.ts +++ b/src/app/lib/config/services/bengali.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-bengali', atiAnalyticsProducerId: '31', + atiAnalyticsProducerName: 'BENGALI', chartbeatDomain: 'bengali.bbc.co.uk', brandName: 'BBC News বাংলা', product: 'BBC News', diff --git a/src/app/lib/config/services/burmese.ts b/src/app/lib/config/services/burmese.ts index 22fd1aa30fe..e07da31a844 100644 --- a/src/app/lib/config/services/burmese.ts +++ b/src/app/lib/config/services/burmese.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-burmese', atiAnalyticsProducerId: '35', + atiAnalyticsProducerName: 'BURMESE', chartbeatDomain: 'burmese.bbc.co.uk', brandName: 'BBC News မြန်မာ', product: 'BBC News', diff --git a/src/app/lib/config/services/cymrufyw.ts b/src/app/lib/config/services/cymrufyw.ts index 4e9be266a66..84f30249382 100644 --- a/src/app/lib/config/services/cymrufyw.ts +++ b/src/app/lib/config/services/cymrufyw.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-cymrufyw', atiAnalyticsProducerId: '100', + atiAnalyticsProducerName: 'WALES', chartbeatDomain: 'cymrufyw.bbc.co.uk', brandName: 'BBC Cymru Fyw', product: 'BBC News', diff --git a/src/app/lib/config/services/gahuza.ts b/src/app/lib/config/services/gahuza.ts index 3487bcfcac5..b8686eee7f1 100644 --- a/src/app/lib/config/services/gahuza.ts +++ b/src/app/lib/config/services/gahuza.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-gahuza', atiAnalyticsProducerId: '40', + atiAnalyticsProducerName: 'GAHUZA', chartbeatDomain: 'gahuza.bbc.co.uk', brandName: 'BBC News Gahuza', product: 'BBC News', diff --git a/src/app/lib/config/services/gujarati.ts b/src/app/lib/config/services/gujarati.ts index 1a094106638..b112776d5c0 100644 --- a/src/app/lib/config/services/gujarati.ts +++ b/src/app/lib/config/services/gujarati.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-gujarati', atiAnalyticsProducerId: '50', + atiAnalyticsProducerName: 'GUJARATI', chartbeatDomain: 'gujarati.bbc.co.uk', brandName: 'BBC News ગુજરાતી', product: 'BBC News', diff --git a/src/app/lib/config/services/hausa.ts b/src/app/lib/config/services/hausa.ts index 75b345f2f8f..9fc7af11a34 100644 --- a/src/app/lib/config/services/hausa.ts +++ b/src/app/lib/config/services/hausa.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-hausa', atiAnalyticsProducerId: '51', + atiAnalyticsProducerName: 'HAUSA', chartbeatDomain: 'hausa.bbc.co.uk', brandName: 'BBC News Hausa', product: 'BBC News', diff --git a/src/app/lib/config/services/hindi.ts b/src/app/lib/config/services/hindi.ts index 659d092d993..808afd24548 100644 --- a/src/app/lib/config/services/hindi.ts +++ b/src/app/lib/config/services/hindi.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-hindi', atiAnalyticsProducerId: '52', + atiAnalyticsProducerName: 'HINDI', chartbeatDomain: 'hindi.bbc.co.uk', brandName: 'BBC News हिंदी', product: 'BBC News', diff --git a/src/app/lib/config/services/igbo.ts b/src/app/lib/config/services/igbo.ts index 8a8267f4db1..fc91ff94b46 100644 --- a/src/app/lib/config/services/igbo.ts +++ b/src/app/lib/config/services/igbo.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-igbo', atiAnalyticsProducerId: '53', + atiAnalyticsProducerName: 'IGBO', chartbeatDomain: 'igbo.bbc.co.uk', brandName: 'BBC News Ìgbò', product: 'BBC News', diff --git a/src/app/lib/config/services/indonesia.ts b/src/app/lib/config/services/indonesia.ts index 1b74048a858..ebf9725d812 100644 --- a/src/app/lib/config/services/indonesia.ts +++ b/src/app/lib/config/services/indonesia.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-indonesia', atiAnalyticsProducerId: '54', + atiAnalyticsProducerName: 'INDONESIAN', chartbeatDomain: 'indonesian.bbc.co.uk', // this is meant to be different to the service name brandName: 'BBC News Indonesia', product: 'BBC News', diff --git a/src/app/lib/config/services/japanese.ts b/src/app/lib/config/services/japanese.ts index 82ceb2b0462..30281394a10 100644 --- a/src/app/lib/config/services/japanese.ts +++ b/src/app/lib/config/services/japanese.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-japanese', atiAnalyticsProducerId: '56', + atiAnalyticsProducerName: 'JAPANESE', chartbeatDomain: 'japanese.bbc.co.uk', brandName: 'BBCニュース', product: 'BBC News', diff --git a/src/app/lib/config/services/korean.ts b/src/app/lib/config/services/korean.ts index 47706596d7c..dd69c356ca1 100644 --- a/src/app/lib/config/services/korean.ts +++ b/src/app/lib/config/services/korean.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '에 업데이트 됨', atiAnalyticsAppName: 'news-korean', atiAnalyticsProducerId: '57', + atiAnalyticsProducerName: 'KOREAN', chartbeatDomain: 'korean.bbc.co.uk', brandName: 'BBC News 코리아', product: 'BBC News', diff --git a/src/app/lib/config/services/kyrgyz.ts b/src/app/lib/config/services/kyrgyz.ts index 3e7318bec05..91eaab2b2a8 100644 --- a/src/app/lib/config/services/kyrgyz.ts +++ b/src/app/lib/config/services/kyrgyz.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-kyrgyz', atiAnalyticsProducerId: '58', + atiAnalyticsProducerName: 'KYRGYZ', chartbeatDomain: 'kyrgyz.bbc.co.uk', brandName: 'BBC News Кыргыз Кызматы', product: 'BBC News', diff --git a/src/app/lib/config/services/marathi.ts b/src/app/lib/config/services/marathi.ts index ab71ffa49d3..6bc2e1fcf14 100644 --- a/src/app/lib/config/services/marathi.ts +++ b/src/app/lib/config/services/marathi.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-marathi', atiAnalyticsProducerId: '59', + atiAnalyticsProducerName: 'MARATHI', chartbeatDomain: 'marathi.bbc.co.uk', brandName: 'BBC News मराठी', product: 'BBC News', diff --git a/src/app/lib/config/services/mundo.ts b/src/app/lib/config/services/mundo.ts index 2058ef98ad4..1883747803b 100644 --- a/src/app/lib/config/services/mundo.ts +++ b/src/app/lib/config/services/mundo.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-mundo', atiAnalyticsProducerId: '62', + atiAnalyticsProducerName: 'MUNDO', chartbeatDomain: 'mundo.bbc.co.uk', brandName: 'BBC News Mundo', product: 'BBC News', diff --git a/src/app/lib/config/services/naidheachdan.ts b/src/app/lib/config/services/naidheachdan.ts index 374eb830c85..162430d21e5 100644 --- a/src/app/lib/config/services/naidheachdan.ts +++ b/src/app/lib/config/services/naidheachdan.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-naidheachdan', atiAnalyticsProducerId: '79', + atiAnalyticsProducerName: 'SCOTLAND', chartbeatDomain: 'bbc.co.uk', brandName: 'BBC Naidheachdan', product: 'BBC News', diff --git a/src/app/lib/config/services/nepali.ts b/src/app/lib/config/services/nepali.ts index c890f90816a..1bb74063d29 100644 --- a/src/app/lib/config/services/nepali.ts +++ b/src/app/lib/config/services/nepali.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: 'अद्यावधिक', atiAnalyticsAppName: 'news-nepali', atiAnalyticsProducerId: '63', + atiAnalyticsProducerName: 'NEPALI', chartbeatDomain: 'nepali.bbc.co.uk', brandName: 'BBC News नेपाली', product: 'BBC News', diff --git a/src/app/lib/config/services/news.ts b/src/app/lib/config/services/news.ts index b7c8ec505c9..d26675c59de 100644 --- a/src/app/lib/config/services/news.ts +++ b/src/app/lib/config/services/news.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news', atiAnalyticsProducerId: '64', + atiAnalyticsProducerName: 'NEWS', chartbeatDomain: 'bbc.co.uk', brandName: 'BBC News', product: 'BBC News', diff --git a/src/app/lib/config/services/newsround.ts b/src/app/lib/config/services/newsround.ts index eb95bf0fa84..4f4b506d059 100644 --- a/src/app/lib/config/services/newsround.ts +++ b/src/app/lib/config/services/newsround.ts @@ -13,6 +13,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'newsround', atiAnalyticsProducerId: '65', + atiAnalyticsProducerName: 'NEWSROUND', chartbeatDomain: 'bbc.co.uk', brandName: 'CBBC Newsround', product: 'CBBC Newsround', diff --git a/src/app/lib/config/services/pashto.ts b/src/app/lib/config/services/pashto.ts index 91b3b6db007..79984fc5961 100644 --- a/src/app/lib/config/services/pashto.ts +++ b/src/app/lib/config/services/pashto.ts @@ -14,6 +14,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-pashto', atiAnalyticsProducerId: '68', + atiAnalyticsProducerName: 'PASHTO', brandName: 'BBC News پښتو', chartbeatDomain: 'pashto.bbc.co.uk', serviceLocalizedName: 'پښتو', diff --git a/src/app/lib/config/services/persian.ts b/src/app/lib/config/services/persian.ts index 4ab97d5cdf1..192037d0d8f 100644 --- a/src/app/lib/config/services/persian.ts +++ b/src/app/lib/config/services/persian.ts @@ -14,6 +14,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-persian', atiAnalyticsProducerId: '69', + atiAnalyticsProducerName: 'PERSIAN', chartbeatDomain: 'persian.bbc.co.uk', brandName: 'BBC News فارسی', serviceLocalizedName: 'فارسی', diff --git a/src/app/lib/config/services/pidgin.ts b/src/app/lib/config/services/pidgin.ts index 65c8c398b46..439516b24e2 100644 --- a/src/app/lib/config/services/pidgin.ts +++ b/src/app/lib/config/services/pidgin.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-pidgin', atiAnalyticsProducerId: '70', + atiAnalyticsProducerName: 'PIDGIN', chartbeatDomain: 'pidgin.bbc.co.uk', brandName: 'BBC News Pidgin', product: 'BBC News', diff --git a/src/app/lib/config/services/portuguese.ts b/src/app/lib/config/services/portuguese.ts index aa342b51df0..6c13d7ff310 100644 --- a/src/app/lib/config/services/portuguese.ts +++ b/src/app/lib/config/services/portuguese.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-portuguese', atiAnalyticsProducerId: '33', + atiAnalyticsProducerName: 'BRASIL', chartbeatDomain: 'brasil.bbc.co.uk', // this is meant to be different to the service name brandName: 'BBC News Brasil', product: 'BBC News', diff --git a/src/app/lib/config/services/punjabi.ts b/src/app/lib/config/services/punjabi.ts index 49a1fd2d465..e46e350ebc0 100644 --- a/src/app/lib/config/services/punjabi.ts +++ b/src/app/lib/config/services/punjabi.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-punjabi', atiAnalyticsProducerId: '73', + atiAnalyticsProducerName: 'PUNJABI', chartbeatDomain: 'punjabi.bbc.co.uk', brandName: 'BBC News ਪੰਜਾਬੀ', product: 'BBC News', diff --git a/src/app/lib/config/services/russian.ts b/src/app/lib/config/services/russian.ts index 69b8978f080..99eeaaea27d 100644 --- a/src/app/lib/config/services/russian.ts +++ b/src/app/lib/config/services/russian.ts @@ -319,6 +319,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-russian', atiAnalyticsProducerId: '75', + atiAnalyticsProducerName: 'RUSSIAN', chartbeatDomain: 'russian.bbc.co.uk', brandName: 'BBC News Русская служба', product: 'BBC News', diff --git a/src/app/lib/config/services/scotland.ts b/src/app/lib/config/services/scotland.ts index c6518022033..ee761a25e1c 100644 --- a/src/app/lib/config/services/scotland.ts +++ b/src/app/lib/config/services/scotland.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'scotland', atiAnalyticsProducerId: '79', + atiAnalyticsProducerName: 'SCOTLAND', chartbeatDomain: 'bbc.co.uk', brandName: 'BBC Scotland', product: 'BBC Scotland', diff --git a/src/app/lib/config/services/serbian.ts b/src/app/lib/config/services/serbian.ts index 1c2f0714dc1..4a77e8e3156 100644 --- a/src/app/lib/config/services/serbian.ts +++ b/src/app/lib/config/services/serbian.ts @@ -11,6 +11,7 @@ const baseServiceConfig = { articleAuthor: 'https://www.facebook.com/bbcnews', atiAnalyticsAppName: 'news-serbian', atiAnalyticsProducerId: '81', + atiAnalyticsProducerName: 'SERBIAN', chartbeatDomain: 'serbian.bbc.co.uk', product: 'BBC News', defaultImage: 'https://news.files.bbci.co.uk/ws/img/logos/og/serbian.png', diff --git a/src/app/lib/config/services/sinhala.ts b/src/app/lib/config/services/sinhala.ts index 4767fe6be05..3cc1c747a4e 100644 --- a/src/app/lib/config/services/sinhala.ts +++ b/src/app/lib/config/services/sinhala.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-sinhala', atiAnalyticsProducerId: '82', + atiAnalyticsProducerName: 'SINHALA', chartbeatDomain: 'sinhala.bbc.co.uk', brandName: 'BBC News සිංහල', product: 'BBC News', diff --git a/src/app/lib/config/services/somali.ts b/src/app/lib/config/services/somali.ts index 2df492cef85..79542cc8515 100644 --- a/src/app/lib/config/services/somali.ts +++ b/src/app/lib/config/services/somali.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-somali', atiAnalyticsProducerId: '83', + atiAnalyticsProducerName: 'SOMALI', chartbeatDomain: 'somali.bbc.co.uk', brandName: 'BBC News Somali', product: 'BBC News', diff --git a/src/app/lib/config/services/sport.ts b/src/app/lib/config/services/sport.ts index f5a22ac2c84..61506ee3237 100644 --- a/src/app/lib/config/services/sport.ts +++ b/src/app/lib/config/services/sport.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'sport', atiAnalyticsProducerId: '85', + atiAnalyticsProducerName: 'SPORT', chartbeatDomain: 'bbc.co.uk', brandName: 'BBC Sport', product: 'BBC Sport', diff --git a/src/app/lib/config/services/swahili.ts b/src/app/lib/config/services/swahili.ts index b36619ae5c6..94d80d7b22b 100644 --- a/src/app/lib/config/services/swahili.ts +++ b/src/app/lib/config/services/swahili.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-swahili', atiAnalyticsProducerId: '86', + atiAnalyticsProducerName: 'SWAHILI', chartbeatDomain: 'swahili.bbc.co.uk', brandName: 'BBC News Swahili', product: 'BBC News', diff --git a/src/app/lib/config/services/tamil.ts b/src/app/lib/config/services/tamil.ts index 44a064620ed..5fdb27a5067 100644 --- a/src/app/lib/config/services/tamil.ts +++ b/src/app/lib/config/services/tamil.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-tamil', atiAnalyticsProducerId: '87', + atiAnalyticsProducerName: 'TAMIL', chartbeatDomain: 'tamil.bbc.co.uk', brandName: 'BBC News தமிழ்', product: 'BBC News', diff --git a/src/app/lib/config/services/telugu.ts b/src/app/lib/config/services/telugu.ts index 0999df750c0..0708a6a6a61 100644 --- a/src/app/lib/config/services/telugu.ts +++ b/src/app/lib/config/services/telugu.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-telugu', atiAnalyticsProducerId: '89', + atiAnalyticsProducerName: 'TELUGU', chartbeatDomain: 'telugu.bbc.co.uk', brandName: 'BBC News తెలుగు', product: 'BBC News', diff --git a/src/app/lib/config/services/thai.ts b/src/app/lib/config/services/thai.ts index caf71f6d453..73d5dd32e56 100644 --- a/src/app/lib/config/services/thai.ts +++ b/src/app/lib/config/services/thai.ts @@ -14,6 +14,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-thai', atiAnalyticsProducerId: '90', + atiAnalyticsProducerName: 'THAI', chartbeatDomain: 'thai.bbc.co.uk', brandName: 'BBC News ไทย', product: 'BBC News', diff --git a/src/app/lib/config/services/tigrinya.ts b/src/app/lib/config/services/tigrinya.ts index 0e9d3e0b530..6f74ac82489 100644 --- a/src/app/lib/config/services/tigrinya.ts +++ b/src/app/lib/config/services/tigrinya.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-tigrinya', atiAnalyticsProducerId: '91', + atiAnalyticsProducerName: 'TIGRINYA', chartbeatDomain: 'tigrinya.bbc.co.uk', brandName: 'BBC News ትግርኛ', product: 'BBC News', diff --git a/src/app/lib/config/services/turkce.ts b/src/app/lib/config/services/turkce.ts index 8f2b21bfbb3..583780197a9 100644 --- a/src/app/lib/config/services/turkce.ts +++ b/src/app/lib/config/services/turkce.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-turkce', atiAnalyticsProducerId: '92', + atiAnalyticsProducerName: 'TURKISH', chartbeatDomain: 'turkish.bbc.co.uk', // this is meant to be different to the service name brandName: 'BBC News Türkçe', product: 'BBC News', diff --git a/src/app/lib/config/services/ukchina.ts b/src/app/lib/config/services/ukchina.ts index bb2649a14e1..3a9a0a01926 100644 --- a/src/app/lib/config/services/ukchina.ts +++ b/src/app/lib/config/services/ukchina.ts @@ -11,6 +11,7 @@ const baseServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-ukchina', atiAnalyticsProducerId: '93', + atiAnalyticsProducerName: 'UK_CHINA', chartbeatDomain: 'ukchina.bbc.co.uk', brandName: 'BBC 英伦网', product: 'BBC', diff --git a/src/app/lib/config/services/ukrainian.ts b/src/app/lib/config/services/ukrainian.ts index b9e3b5ecd73..4022affb25e 100644 --- a/src/app/lib/config/services/ukrainian.ts +++ b/src/app/lib/config/services/ukrainian.ts @@ -16,6 +16,7 @@ const baseServiceConfig = { articleTimestampPrefix: 'Оновлено: ', atiAnalyticsAppName: 'news-ukrainian', atiAnalyticsProducerId: '94', + atiAnalyticsProducerName: 'UKRAINIAN', chartbeatDomain: 'ukrainian.bbc.co.uk', brandName: 'BBC News Україна', product: 'BBC News', diff --git a/src/app/lib/config/services/urdu.ts b/src/app/lib/config/services/urdu.ts index 3290d22fdcf..992afa6e4ff 100644 --- a/src/app/lib/config/services/urdu.ts +++ b/src/app/lib/config/services/urdu.ts @@ -13,6 +13,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-urdu', atiAnalyticsProducerId: '95', + atiAnalyticsProducerName: 'URDU', chartbeatDomain: 'urdu.bbc.co.uk', brandName: 'BBC News اردو', defaultImage: 'https://news.files.bbci.co.uk/ws/img/logos/og/urdu.png', diff --git a/src/app/lib/config/services/uzbek.ts b/src/app/lib/config/services/uzbek.ts index c73b99e67c5..5c5f60f3941 100644 --- a/src/app/lib/config/services/uzbek.ts +++ b/src/app/lib/config/services/uzbek.ts @@ -11,6 +11,7 @@ const baseServiceConfig = { articleAuthor: `https://www.facebook.com/bbcnews`, atiAnalyticsAppName: 'news-uzbek', atiAnalyticsProducerId: '96', + atiAnalyticsProducerName: 'UZBEK', chartbeatDomain: 'uzbek.bbc.co.uk', product: 'BBC News', defaultImage: 'https://news.files.bbci.co.uk/ws/img/logos/og/uzbek.png', diff --git a/src/app/lib/config/services/vietnamese.ts b/src/app/lib/config/services/vietnamese.ts index 02c2c562403..c8786cde402 100644 --- a/src/app/lib/config/services/vietnamese.ts +++ b/src/app/lib/config/services/vietnamese.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-vietnamese', atiAnalyticsProducerId: '97', + atiAnalyticsProducerName: 'VIETNAMESE', chartbeatDomain: 'vietnamese.bbc.co.uk', brandName: 'BBC News Tiếng Việt', product: 'BBC News', diff --git a/src/app/lib/config/services/ws.ts b/src/app/lib/config/services/ws.ts index c84a5047ad7..202af86087c 100644 --- a/src/app/lib/config/services/ws.ts +++ b/src/app/lib/config/services/ws.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news', atiAnalyticsProducerId: '64', + atiAnalyticsProducerName: 'NEWS', chartbeatDomain: 'bbc.co.uk', brandName: 'BBC News', product: 'BBC News', diff --git a/src/app/lib/config/services/yoruba.ts b/src/app/lib/config/services/yoruba.ts index 45ed9b3f2e6..7ac2810344f 100644 --- a/src/app/lib/config/services/yoruba.ts +++ b/src/app/lib/config/services/yoruba.ts @@ -12,6 +12,7 @@ export const service: DefaultServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-yoruba', atiAnalyticsProducerId: '107', + atiAnalyticsProducerName: 'YORUBA', chartbeatDomain: 'yoruba.bbc.co.uk', brandName: 'BBC News Yorùbá', product: 'BBC News', diff --git a/src/app/lib/config/services/zhongwen.ts b/src/app/lib/config/services/zhongwen.ts index 3a446a5c9fa..6a31052ab50 100644 --- a/src/app/lib/config/services/zhongwen.ts +++ b/src/app/lib/config/services/zhongwen.ts @@ -12,6 +12,7 @@ const baseServiceConfig = { articleTimestampSuffix: '', atiAnalyticsAppName: 'news-zhongwen', atiAnalyticsProducerId: '38', + atiAnalyticsProducerName: 'CHINESE', chartbeatDomain: 'zhongwen.bbc.co.uk', brandName: 'BBC News 中文', product: 'BBC News', diff --git a/src/app/lib/utilities/getEnvConfig/index.ts b/src/app/lib/utilities/getEnvConfig/index.ts index 04c8dc94a41..e4ce70ef114 100644 --- a/src/app/lib/utilities/getEnvConfig/index.ts +++ b/src/app/lib/utilities/getEnvConfig/index.ts @@ -23,6 +23,7 @@ export const getProcessEnvAppVariables = () => ({ process.env.SIMORGH_PUBLIC_STATIC_ASSETS_ORIGIN, SIMORGH_PUBLIC_STATIC_ASSETS_PATH: process.env.SIMORGH_PUBLIC_STATIC_ASSETS_PATH, + SIMORGH_REVERB_SOURCE: process.env.SIMORGH_REVERB_SOURCE, SIMORGH_WEBVITALS_REPORTING_ENDPOINT: process.env.SIMORGH_WEBVITALS_REPORTING_ENDPOINT, SIMORGH_WEBVITALS_DEFAULT_SAMPLING_RATE: diff --git a/src/app/models/types/eventTracking.ts b/src/app/models/types/eventTracking.ts index f299ea81714..156ae525614 100644 --- a/src/app/models/types/eventTracking.ts +++ b/src/app/models/types/eventTracking.ts @@ -1,5 +1,12 @@ import { ReactSDKClient } from '@optimizely/react-sdk'; +export type ReverbClient = { + isReady: () => boolean; + initialise: () => Promise; + viewEvent: () => void; + userActionEvent: (...args: unknown[]) => void; +}; + export type EventTrackingMetadata = { componentName: string; detailedPlacement?: string; diff --git a/src/app/models/types/serviceConfig.ts b/src/app/models/types/serviceConfig.ts index ef28a24d7f2..8a9981214f4 100644 --- a/src/app/models/types/serviceConfig.ts +++ b/src/app/models/types/serviceConfig.ts @@ -42,6 +42,8 @@ export type ServiceConfig = { articleTimestampSuffix?: string; atiAnalyticsAppName: string; atiAnalyticsProducerId: string; + atiAnalyticsProducerName?: string; + useReverb?: boolean; chartbeatDomain: string; brandName: string; product: string; diff --git a/src/global.d.ts b/src/global.d.ts index f96b4eca5ef..4a9a61f0cc4 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1,5 +1,11 @@ +import { ReverbClient } from '#models/types/eventTracking'; +import { BumpType } from '#app/components/MediaLoader/types'; + declare global { interface Window { + __reverb: { + __reverbLoadedPromise: Promise; + }; requirejs: ( bumpVersion: string[], callback: (Bump: BumpType) => void, diff --git a/src/integration/utils/customResourceLoader.js b/src/integration/utils/customResourceLoader.js new file mode 100644 index 00000000000..e1c4dbc4647 --- /dev/null +++ b/src/integration/utils/customResourceLoader.js @@ -0,0 +1,14 @@ +const jsdom = require('jsdom'); +const dotenv = require('dotenv'); + +class CustomResourceLoader extends jsdom.ResourceLoader { + fetch(url, options) { + if (url === dotenv.config().parsed.SIMORGH_REVERB_SOURCE) { + return super.fetch(url, options); + } + + return null; + } +} + +module.exports = CustomResourceLoader; diff --git a/src/integration/utils/fetchDom.js b/src/integration/utils/fetchDom.js index 6b831795058..00a68be1a7c 100644 --- a/src/integration/utils/fetchDom.js +++ b/src/integration/utils/fetchDom.js @@ -8,6 +8,8 @@ dns.setDefaultResultOrder('ipv4first'); const { JSDOM } = require('jsdom'); const retry = require('retry'); +const CustomResourceLoader = require('./customResourceLoader'); + const faultTolerantDomFetch = ({ url, runScripts, headers }) => new Promise((resolve, reject) => { const oneSecond = 1000; @@ -31,7 +33,12 @@ const faultTolerantDomFetch = ({ url, runScripts, headers }) => const html = await response.text(); const dom = new JSDOM(html, { url, - ...(runScripts ? { runScripts: 'dangerously' } : {}), + ...(runScripts + ? { + runScripts: 'dangerously', + resources: new CustomResourceLoader(), + } + : {}), }); resolve(dom); diff --git a/src/server/Document/Renderers/CanonicalRenderer.tsx b/src/server/Document/Renderers/CanonicalRenderer.tsx index 62528debe55..fe44cecc7ec 100644 --- a/src/server/Document/Renderers/CanonicalRenderer.tsx +++ b/src/server/Document/Renderers/CanonicalRenderer.tsx @@ -2,7 +2,10 @@ import React from 'react'; import IfAboveIE9 from '#app/legacy/components/IfAboveIE9Comment'; import NO_JS_CLASSNAME from '#app/lib/noJs.const'; -import { getProcessEnvAppVariables } from '#app/lib/utilities/getEnvConfig'; +import { + getEnvConfig, + getProcessEnvAppVariables, +} from '#app/lib/utilities/getEnvConfig'; import serialiseForScript from '#app/lib/utilities/serialiseForScript'; import { BaseRendererProps } from './types'; @@ -35,6 +38,22 @@ export default function CanonicalRenderer({ return ( + + @@ -206,6 +222,22 @@ exports[`Document Component should render correctly 1`] = ` lang="test" > + + diff --git a/src/server/Document/component.test.jsx b/src/server/Document/component.test.jsx index e6b42b3e5b3..88300a0ae5c 100644 --- a/src/server/Document/component.test.jsx +++ b/src/server/Document/component.test.jsx @@ -2,12 +2,23 @@ import React from 'react'; import { renderToString, renderToStaticMarkup } from 'react-dom/server'; import { Helmet } from 'react-helmet'; import { JSDOM } from 'jsdom'; +import dotenv from 'dotenv'; import DocumentComponent from './component'; Helmet.canUseDOM = false; describe('Document Component', () => { + const originalProcessEnv = process.env; + + // Load environment variables into process.env to ensure CanonicalRenderer + // uses values set in the .env file in lieu of mocked values + dotenv.config(); + + afterEach(() => { + process.env = originalProcessEnv; + }); + const data = { test: 'data' }; const legacyScripts = ( <>