Skip to content

Commit

Permalink
Merge branch 'latest' into WSTEAMA-1421-create-jumpto-skeleton-component
Browse files Browse the repository at this point in the history
  • Loading branch information
holchris authored Nov 7, 2024
2 parents 8a55583 + 74e7db4 commit 79f51a8
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 11 deletions.
23 changes: 23 additions & 0 deletions src/app/components/ATIAnalytics/canonical/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { Helmet } from 'react-helmet';
import {
render,
act,
Expand Down Expand Up @@ -30,6 +31,28 @@ describe('Canonical ATI Analytics', () => {
expect(mockSendBeacon).toHaveBeenCalledWith(expectedUrl);
});

it('should render lite Helmet script when isLite is true', () => {
jest.spyOn(isOperaProxy, 'default').mockImplementation(() => false);

const expectedUrl = `${atiBaseUrl}${mockPageviewParams}`;

act(() => {
render(<CanonicalATIAnalytics pageviewParams={mockPageviewParams} />, {
isLite: true,
});
});

const helmet = Helmet.peek();

expect(helmet.scriptTags).toHaveLength(1);
expect(helmet.scriptTags[0].innerHTML).toEqual(`
var xhr = new XMLHttpRequest();
xhr.open("GET", "${expectedUrl}", true);
xhr.withCredentials = true;
xhr.send();
`);
});

it('should not send beacon when browser is Opera Mini', () => {
jest.spyOn(isOperaProxy, 'default').mockImplementation(() => true);

Expand Down
29 changes: 18 additions & 11 deletions src/app/components/ATIAnalytics/canonical/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import React, { useContext, useEffect, useState, Fragment } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { getEnvConfig } from '#app/lib/utilities/getEnvConfig';
import { RequestContext } from '#app/contexts/RequestContext';
import isOperaProxy from '#app/lib/utilities/isOperaProxy';
import { Helmet } from 'react-helmet';
import sendBeacon from '../../../lib/analyticsUtils/sendBeacon';
import { ATIAnalyticsProps } from '../types';
import sendBeaconOperaMiniScript from './sendBeaconOperaMiniScript';
import sendBeaconLite from './sendBeaconLite';

const getNoJsATIPageViewUrl = (atiPageViewUrl: string) =>
atiPageViewUrl.includes('x8=[simorgh]')
? atiPageViewUrl.replace('x8=[simorgh]', 'x8=[simorgh-nojs]')
: `${atiPageViewUrl}&x8=[simorgh-nojs]`;

const renderNoScriptTrackingPixel = (
atiPageViewUrl: string,
isLite: boolean,
) => {
const ImgPixelWrapper = isLite ? Fragment : 'noscript';

const renderNoScriptTrackingPixel = (atiPageViewUrl: string) => {
return (
<ImgPixelWrapper>
<noscript>
<img
height="1px"
width="1px"
Expand All @@ -30,7 +26,7 @@ const renderNoScriptTrackingPixel = (
style={{ position: 'absolute' }}
src={getNoJsATIPageViewUrl(atiPageViewUrl)}
/>
</ImgPixelWrapper>
</noscript>
);
};

Expand All @@ -44,6 +40,16 @@ const addOperaMiniExtremeScript = (atiPageViewUrlString: string) => {
);
};

const addLiteScript = (atiPageViewUrlString: string) => {
const script = sendBeaconLite(atiPageViewUrlString);

return (
<Helmet>
<script type="text/javascript">{script}</script>
</Helmet>
);
};

const CanonicalATIAnalytics = ({ pageviewParams }: ATIAnalyticsProps) => {
const { isLite } = useContext(RequestContext);

Expand All @@ -58,8 +64,9 @@ const CanonicalATIAnalytics = ({ pageviewParams }: ATIAnalyticsProps) => {

return (
<>
{addOperaMiniExtremeScript(atiPageViewUrlString)}
{renderNoScriptTrackingPixel(atiPageViewUrl, isLite)}
{isLite && addLiteScript(atiPageViewUrlString)}
{!isLite && addOperaMiniExtremeScript(atiPageViewUrlString)}
{renderNoScriptTrackingPixel(atiPageViewUrl)}
</>
);
};
Expand Down
35 changes: 35 additions & 0 deletions src/app/components/ATIAnalytics/canonical/sendBeaconLite.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable no-eval */
import sendBeaconLite from './sendBeaconLite';

let XMLHttpRequestSpy: jest.SpyInstance<XMLHttpRequest | undefined, []>;

describe('sendBeaconLite', () => {
const XMLHttpRequestMock: Partial<XMLHttpRequest> = {
open: jest.fn(),
withCredentials: false,
send: jest.fn(),
};

beforeEach(() => {
XMLHttpRequestSpy = jest.spyOn(window, 'XMLHttpRequest');
});

afterEach(() => {
XMLHttpRequestSpy.mockRestore();
jest.clearAllMocks();
});

it('should send beacon with XHR', () => {
XMLHttpRequestSpy.mockImplementation(
() => XMLHttpRequestMock as XMLHttpRequest,
);

eval(sendBeaconLite('https://foobar.com'));

expect(XMLHttpRequestMock.open).toHaveBeenCalledWith(
'GET',
'https://foobar.com',
true,
);
});
});
8 changes: 8 additions & 0 deletions src/app/components/ATIAnalytics/canonical/sendBeaconLite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const sendBeaconLite = (atiPageViewUrlString: string) => `
var xhr = new XMLHttpRequest();
xhr.open("GET", "${atiPageViewUrlString}", true);
xhr.withCredentials = true;
xhr.send();
`;

export default sendBeaconLite;

0 comments on commit 79f51a8

Please sign in to comment.