diff --git a/src/app/containers/FrontPage/index.test.jsx b/src/app/containers/FrontPage/index.test.jsx
index 422ee31cf8f..56c596f4e0d 100644
--- a/src/app/containers/FrontPage/index.test.jsx
+++ b/src/app/containers/FrontPage/index.test.jsx
@@ -18,6 +18,16 @@ const defaultProps = {
data: { status: 200 },
};
+jest.mock('../PageHandlers/withContexts', () => Component => {
+ const DataContainer = props => (
+
+
+
+ );
+
+ return DataContainer;
+});
+
jest.mock('../PageHandlers/withPageWrapper', () => Component => {
const PageWrapperContainer = props => (
diff --git a/src/app/contexts/UserContext/Chartbeat/index.jsx b/src/app/contexts/UserContext/Chartbeat/index.jsx
new file mode 100644
index 00000000000..897083c6e6a
--- /dev/null
+++ b/src/app/contexts/UserContext/Chartbeat/index.jsx
@@ -0,0 +1,27 @@
+import React, { useContext } from 'react';
+import useToggle from '../../../containers/Toggle/useToggle';
+import CanonicalChartbeatBeacon from '../../../containers/ChartbeatAnalytics/canonical';
+import { RequestContext } from '../../RequestContext';
+import { canonicalChartbeatPropTypes } from '../../../models/propTypes/chartbeatAnalytics';
+
+const Chartbeat = ({ config }) => {
+ const { enabled } = useToggle('chartbeatAnalytics');
+ const { platform } = useContext(RequestContext);
+ const isAmp = platform === 'amp';
+
+ if (!enabled || !config || isAmp) {
+ return null;
+ }
+
+ return ;
+};
+
+Chartbeat.propTypes = {
+ config: canonicalChartbeatPropTypes,
+};
+
+Chartbeat.defaultProps = {
+ config: null,
+};
+
+export default Chartbeat;
diff --git a/src/app/contexts/UserContext/index.jsx b/src/app/contexts/UserContext/index.jsx
index 9159a35b84d..bbe95f9af3f 100644
--- a/src/app/contexts/UserContext/index.jsx
+++ b/src/app/contexts/UserContext/index.jsx
@@ -1,19 +1,27 @@
import React, { useState } from 'react';
import { node } from 'prop-types';
import { getCookiePolicy, personalisationEnabled } from './cookies';
+import Chartbeat from './Chartbeat';
export const UserContext = React.createContext({});
export const UserContextProvider = ({ children }) => {
const [cookiePolicy, setCookiePolicy] = useState(getCookiePolicy());
+ const [chartbeatConfig, sendCanonicalChartbeatBeacon] = useState(null);
const value = {
cookiePolicy,
+ sendCanonicalChartbeatBeacon,
updateCookiePolicy: () => setCookiePolicy(getCookiePolicy()),
personalisationEnabled: personalisationEnabled(cookiePolicy),
};
- return {children};
+ return (
+
+
+ {children}
+
+ );
};
UserContextProvider.propTypes = {
diff --git a/src/app/contexts/UserContext/index.test.jsx b/src/app/contexts/UserContext/index.test.jsx
index 211fbfb3877..32e7b080981 100644
--- a/src/app/contexts/UserContext/index.test.jsx
+++ b/src/app/contexts/UserContext/index.test.jsx
@@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
import { UserContext, UserContextProvider } from '.';
import { getCookiePolicy, personalisationEnabled } from './cookies';
+import * as chartbeat from './Chartbeat';
jest.mock('react', () => {
const original = jest.requireActual('react');
@@ -17,6 +18,9 @@ jest.mock('./cookies', () => ({
personalisationEnabled: jest.fn(),
}));
+const mockChartbeat = jest.fn().mockReturnValue('chartbeat');
+chartbeat.default = mockChartbeat;
+
const DummyComponent = () => {
useContext(UserContext);
return null;
@@ -39,7 +43,7 @@ describe('UserContext', () => {
jest.clearAllMocks();
});
- it('should provide cookie values and state function', () => {
+ it('should provide cookie values, state function and render chartbeat', () => {
act(() => {
ReactDOM.render(, container);
});
@@ -51,6 +55,14 @@ describe('UserContext', () => {
cookiePolicy: '111',
personalisationEnabled: true,
updateCookiePolicy: expect.any(Function),
+ sendCanonicalChartbeatBeacon: expect.any(Function),
});
+ expect(mockChartbeat).toHaveBeenCalledTimes(1);
+ expect(mockChartbeat).toHaveBeenCalledWith(
+ {
+ config: null,
+ },
+ {},
+ );
});
});
diff --git a/src/app/models/propTypes/chartbeatAnalytics/index.js b/src/app/models/propTypes/chartbeatAnalytics/index.js
new file mode 100644
index 00000000000..d54cf179f17
--- /dev/null
+++ b/src/app/models/propTypes/chartbeatAnalytics/index.js
@@ -0,0 +1,23 @@
+import { string, shape, number, bool, oneOf, oneOfType } from 'prop-types';
+
+const baseChartbeatPropTypes = {
+ domain: string.isRequired,
+ sections: string.isRequired,
+ uid: number.isRequired,
+ title: string.isRequired,
+ virtualReferrer: oneOfType([string, oneOf([null])]),
+ idSync: shape({
+ bbc_hid: string,
+ }),
+};
+
+export const canonicalChartbeatPropTypes = shape({
+ ...baseChartbeatPropTypes,
+ type: string.isRequired,
+ useCanonical: bool.isRequired,
+});
+
+export const ampChartbeatPropTypes = shape({
+ ...baseChartbeatPropTypes,
+ contentType: string.isRequired,
+});