From 00f9388165cddb257c1940cb98eb64baf023a1ae Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Fri, 4 Oct 2024 12:01:12 +0100 Subject: [PATCH 01/21] adjusts withOptimizelyProvider usage --- src/app/pages/ArticlePage/index.tsx | 7 ++-- src/app/pages/utils/applyBasicPageHandlers.js | 26 +++++++++----- .../utils/applyBasicPageHandlers.test.js | 36 +++++++++++++++++++ 3 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/app/pages/utils/applyBasicPageHandlers.test.js diff --git a/src/app/pages/ArticlePage/index.tsx b/src/app/pages/ArticlePage/index.tsx index 1e48edc5215..3b18c81fe25 100644 --- a/src/app/pages/ArticlePage/index.tsx +++ b/src/app/pages/ArticlePage/index.tsx @@ -1,7 +1,6 @@ -import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; import ArticlePage from './ArticlePage'; import applyBasicPageHandlers from '../utils/applyBasicPageHandlers'; -const OptimizelyArticle = withOptimizelyProvider(ArticlePage); - -export default applyBasicPageHandlers(OptimizelyArticle); +export default applyBasicPageHandlers(ArticlePage, { + applyOptimizely: true, +}); diff --git a/src/app/pages/utils/applyBasicPageHandlers.js b/src/app/pages/utils/applyBasicPageHandlers.js index 63a9075195c..9ec2995b25e 100644 --- a/src/app/pages/utils/applyBasicPageHandlers.js +++ b/src/app/pages/utils/applyBasicPageHandlers.js @@ -4,12 +4,22 @@ import withPageWrapper from '#containers/PageHandlers/withPageWrapper'; import withError from '#containers/PageHandlers/withError'; import withData from '#containers/PageHandlers/withData'; import withHashChangeHandler from '#containers/PageHandlers/withHashChangeHandler'; +import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; -export default component => - pipe( - withData, - withError, - withPageWrapper, - withContexts, - withHashChangeHandler, - )(component); +export default (component, { applyOptimizely = false } = {}) => + applyOptimizely + ? pipe( + withData, + withError, + withPageWrapper, + withContexts, + withHashChangeHandler, + withOptimizelyProvider, + )(component) + : pipe( + withData, + withError, + withPageWrapper, + withContexts, + withHashChangeHandler, + )(component); diff --git a/src/app/pages/utils/applyBasicPageHandlers.test.js b/src/app/pages/utils/applyBasicPageHandlers.test.js new file mode 100644 index 00000000000..e66aaced538 --- /dev/null +++ b/src/app/pages/utils/applyBasicPageHandlers.test.js @@ -0,0 +1,36 @@ +import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; +import applyBasicPageHandlers from './applyBasicPageHandlers'; + +jest.mock('#app/legacy/containers/PageHandlers/withOptimizelyProvider'); + +describe('applyBasicPageHandlers', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should have called the withOptimizelyProvider function if applyOptimizely is true', () => { + const component = jest.fn(); + const applyOptimizely = true; + + applyBasicPageHandlers(component, { applyOptimizely }); + + expect(withOptimizelyProvider).toHaveBeenCalled(); + }); + + it('should not call the withOptimizelyProvider function if applyOptimizely is false', () => { + const component = jest.fn(); + const applyOptimizely = false; + + applyBasicPageHandlers(component, { applyOptimizely }); + + expect(withOptimizelyProvider).not.toHaveBeenCalled(); + }); + + it('should not call the withOptimizelyProvider function if applyOptimizely is not provided', () => { + const component = jest.fn(); + + applyBasicPageHandlers(component); + + expect(withOptimizelyProvider).not.toHaveBeenCalled(); + }); +}); From 219fd9d23ad3fdf214247fd45b474748db214d4d Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 10:18:11 +0100 Subject: [PATCH 02/21] adds extra test case --- .../utils/applyBasicPageHandlers.test.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/app/pages/utils/applyBasicPageHandlers.test.js b/src/app/pages/utils/applyBasicPageHandlers.test.js index e66aaced538..bac29b0272a 100644 --- a/src/app/pages/utils/applyBasicPageHandlers.test.js +++ b/src/app/pages/utils/applyBasicPageHandlers.test.js @@ -1,11 +1,23 @@ import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; +import * as pipe from 'ramda/src/pipe'; import applyBasicPageHandlers from './applyBasicPageHandlers'; +jest.mock('ramda/src/pipe', () => { + const originalModule = jest.requireActual('ramda/src/pipe'); + + return { + __esModule: true, + ...originalModule, + default: originalModule, + }; +}); + jest.mock('#app/legacy/containers/PageHandlers/withOptimizelyProvider'); describe('applyBasicPageHandlers', () => { beforeEach(() => { jest.clearAllMocks(); + jest.resetModules(); }); it('should have called the withOptimizelyProvider function if applyOptimizely is true', () => { @@ -33,4 +45,17 @@ describe('applyBasicPageHandlers', () => { expect(withOptimizelyProvider).not.toHaveBeenCalled(); }); + + it('should call pipe with withOptimizelyProvider as the last argument if applyOptimizely is true', () => { + const component = jest.fn(); + const applyOptimizely = true; + const pipeMock = jest.spyOn(pipe, 'default'); + + applyBasicPageHandlers(component, { applyOptimizely }); + + const args = pipeMock.mock.calls[0]; + const lastArg = args[args.length - 1]; + + expect(lastArg).toEqual(withOptimizelyProvider); + }); }); From 6206a1e909ca0e0c2c021e89f626292e881748e1 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 10:28:11 +0100 Subject: [PATCH 03/21] adds check to have been called once --- src/app/pages/utils/applyBasicPageHandlers.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/pages/utils/applyBasicPageHandlers.test.js b/src/app/pages/utils/applyBasicPageHandlers.test.js index bac29b0272a..77efceb0c69 100644 --- a/src/app/pages/utils/applyBasicPageHandlers.test.js +++ b/src/app/pages/utils/applyBasicPageHandlers.test.js @@ -57,5 +57,6 @@ describe('applyBasicPageHandlers', () => { const lastArg = args[args.length - 1]; expect(lastArg).toEqual(withOptimizelyProvider); + expect(withOptimizelyProvider).toHaveBeenCalledTimes(1); }); }); From 598104ced53f3b530b190c0438b92414531aac99 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 12:38:04 +0100 Subject: [PATCH 04/21] moves cookie ckns_mvt setter logic to user context --- src/app/contexts/UserContext/index.test.tsx | 70 +++++++++++++++++++ src/app/contexts/UserContext/index.tsx | 19 +++++ .../getOptimizelyUserId/index.js | 24 ------- .../getOptimizelyUserId/index.test.js | 33 --------- .../withOptimizelyProvider/index.jsx | 7 +- .../withOptimizelyProvider/index.test.jsx | 50 +++++++++++-- 6 files changed, 138 insertions(+), 65 deletions(-) delete mode 100644 src/app/legacy/containers/PageHandlers/withOptimizelyProvider/getOptimizelyUserId/index.js delete mode 100644 src/app/legacy/containers/PageHandlers/withOptimizelyProvider/getOptimizelyUserId/index.test.js diff --git a/src/app/contexts/UserContext/index.test.tsx b/src/app/contexts/UserContext/index.test.tsx index 7f99b9018a3..a12ff15105f 100644 --- a/src/app/contexts/UserContext/index.test.tsx +++ b/src/app/contexts/UserContext/index.test.tsx @@ -1,5 +1,8 @@ import React, { useContext } from 'react'; import { render } from '@testing-library/react'; +import Cookie from 'js-cookie'; +import * as onClient from '#app/lib/utilities/onClient'; +import * as isOperaProxy from '#app/lib/utilities/isOperaProxy'; import { UserContext, UserContextProvider } from '.'; import { getCookiePolicy, personalisationEnabled } from './cookies'; import * as chartbeat from './Chartbeat'; @@ -61,4 +64,71 @@ describe('UserContext', () => { {}, ); }); + describe('ckns_mvt cookie', () => { + const cookieSetterSpy = jest.spyOn(Cookie, 'set'); + const cookieGetterSpy = jest.spyOn(Cookie, 'get'); + const isOperaProxySpy = jest.spyOn(isOperaProxy, 'default'); + const onClientSpy = jest.spyOn(onClient, 'default'); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should call cookie logic when not opera mini and is on client', () => { + onClientSpy.mockImplementationOnce(() => true as unknown as Location); + isOperaProxySpy.mockImplementationOnce(() => false); + + render(); + + expect(cookieGetterSpy).toHaveBeenCalled(); + }); + + it('should not call cookie logic when on opera mini and is on client', () => { + onClientSpy.mockImplementationOnce(() => true as unknown as Location); + isOperaProxySpy.mockImplementationOnce(() => true); + + render(); + + expect(cookieGetterSpy).not.toHaveBeenCalled(); + }); + + it('should not call cookie logic when not on opera mini and is not on client', () => { + onClientSpy.mockImplementationOnce(() => false); + isOperaProxySpy.mockImplementationOnce(() => false); + + render(); + + expect(cookieGetterSpy).not.toHaveBeenCalled(); + }); + + it('should not set cookie when ckns_mvt cookie exists', () => { + onClientSpy.mockImplementationOnce(() => true as unknown as Location); + isOperaProxySpy.mockImplementationOnce(() => false); + // @ts-expect-error This should be able to be mocked as a string or undefined + cookieGetterSpy.mockImplementationOnce(() => 'foo'); + + render(); + + expect(cookieSetterSpy).not.toHaveBeenCalled(); + }); + + it('should set cookie when no ckns_mvt cookie exists', () => { + const uuidRegex = + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + onClientSpy.mockImplementationOnce(() => true as unknown as Location); + isOperaProxySpy.mockImplementationOnce(() => false); + // @ts-expect-error This should be able to be mocked as a string or undefined + cookieGetterSpy.mockImplementationOnce(() => undefined); + + render(); + + const [[cookieName, cookieValue, cookieOptions]] = + cookieSetterSpy.mock.calls; + + expect(cookieValue).toMatch(uuidRegex); + expect(cookieName).toEqual('ckns_mvt'); + expect(cookieOptions).toEqual({ expires: 365, path: '/', secure: true }); + expect(cookieSetterSpy).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/src/app/contexts/UserContext/index.tsx b/src/app/contexts/UserContext/index.tsx index 7febc7431b0..fbe7ee61260 100644 --- a/src/app/contexts/UserContext/index.tsx +++ b/src/app/contexts/UserContext/index.tsx @@ -5,6 +5,10 @@ import React, { SetStateAction, useMemo, } from 'react'; +import { v4 as uuid } from 'uuid'; +import Cookie from 'js-cookie'; +import onClient from '#app/lib/utilities/onClient'; +import isOperaProxy from '#app/lib/utilities/isOperaProxy'; import { getCookiePolicy, personalisationEnabled } from './cookies'; import Chartbeat from './Chartbeat'; @@ -19,10 +23,25 @@ export const UserContext = React.createContext( {} as UserContextProps, ); +const cknsMvtCookie = () => { + const cookieName = 'ckns_mvt'; + const cookieValue = Cookie.get(cookieName); + + if (!cookieValue) { + const cookieUuid = uuid(); + const expires = 365; + Cookie.set(cookieName, cookieUuid, { expires, path: '/', secure: true }); + } +}; + export const UserContextProvider = ({ children }: PropsWithChildren) => { const [cookiePolicy, setCookiePolicy] = useState(getCookiePolicy()); const [chartbeatConfig, sendCanonicalChartbeatBeacon] = useState(null); + if (onClient() && !isOperaProxy()) { + cknsMvtCookie(); + } + const value = useMemo( () => ({ cookiePolicy, diff --git a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/getOptimizelyUserId/index.js b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/getOptimizelyUserId/index.js deleted file mode 100644 index 8dbd0809c1f..00000000000 --- a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/getOptimizelyUserId/index.js +++ /dev/null @@ -1,24 +0,0 @@ -import onClient from '#lib/utilities/onClient'; -import isOperaProxy from '#lib/utilities/isOperaProxy'; -import { v4 as uuid } from 'uuid'; -import Cookie from 'js-cookie'; - -const getOptimizelyUserId = () => { - // Users accessing the site on opera "extreme data saving mode" have the pages rendered by an intermediate service - // Attempting to track these users is just tracking that proxy, causing all opera mini visitors to have the same id - if (!onClient() || isOperaProxy()) return null; - - const cookieName = 'ckns_mvt'; - const cookieValue = Cookie.get(cookieName); - const expires = 365; // expires in 12 Months - - if (!cookieValue) { - const cookieUuid = uuid(); - Cookie.set(cookieName, cookieUuid, { expires, path: '/', secure: true }); - return cookieUuid; - } - - return cookieValue; -}; - -export default getOptimizelyUserId; diff --git a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/getOptimizelyUserId/index.test.js b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/getOptimizelyUserId/index.test.js deleted file mode 100644 index 5d4e499c883..00000000000 --- a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/getOptimizelyUserId/index.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import Cookie from 'js-cookie'; -import getOptimizelyUserId from './index'; - -describe('getOptimizelyUserId', () => { - const cookieSetterSpy = jest.spyOn(Cookie, 'set'); - - afterEach(() => { - jest.clearAllMocks(); - Cookie.remove('ckns_mvt'); - }); - - it('should return the optimizely user id if the cookie exists', () => { - Cookie.set('ckns_mvt', 'random-uuid'); - - const optimizelyUserId = getOptimizelyUserId(); - - expect(optimizelyUserId).toEqual('random-uuid'); - }); - - it('should create and return optimizely user id if it does not exist', () => { - const uuidRegex = - /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; - const optimizelyUserId = getOptimizelyUserId(); - const [[cookieName, cookieValue, cookieOptions]] = - cookieSetterSpy.mock.calls; - - expect(optimizelyUserId).toMatch(uuidRegex); - expect(cookieName).toEqual('ckns_mvt'); - expect(cookieValue).toEqual(optimizelyUserId); - expect(cookieOptions).toEqual({ expires: 365, path: '/', secure: true }); - expect(cookieSetterSpy).toHaveBeenCalledTimes(1); - }); -}); diff --git a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx index fc7c142e29b..374058c8cfa 100644 --- a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx +++ b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx @@ -8,8 +8,9 @@ import isLive from '#lib/utilities/isLive'; import onClient from '#lib/utilities/onClient'; import { GEL_GROUP_3_SCREEN_WIDTH_MAX } from '#psammead/gel-foundations/src/breakpoints'; import { getEnvConfig } from '#app/lib/utilities/getEnvConfig'; +import Cookie from 'js-cookie'; +import isOperaProxy from '#app/lib/utilities/isOperaProxy'; import { ServiceContext } from '../../../../contexts/ServiceContext'; -import getOptimizelyUserId from './getOptimizelyUserId'; // 004_brasil_recommendations_experiment const isCypress = onClient() && window.Cypress; @@ -32,10 +33,10 @@ const withOptimizelyProvider = Component => { let mobile; const getUserId = () => { - if (disableOptimizely) { + if (disableOptimizely || isOperaProxy() || !onClient()) { return null; } - return getOptimizelyUserId(); + return Cookie.get('ckns_mvt') ?? null; }; if (onClient()) { diff --git a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.test.jsx b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.test.jsx index 5b0f45b5d92..8e98ddbb22c 100644 --- a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.test.jsx +++ b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.test.jsx @@ -1,14 +1,30 @@ import React, { useMemo } from 'react'; import * as optimizelyReactSdk from '@optimizely/react-sdk'; import { render } from '@testing-library/react'; +import Cookie from 'js-cookie'; import latin from '../../../../components/ThemeProvider/fontScripts/latin'; import { ServiceContext } from '../../../../contexts/ServiceContext'; import withOptimizelyProvider from '.'; -const optimizelyProviderSpy = jest.spyOn( - optimizelyReactSdk.OptimizelyProvider.prototype, - 'render', -); +// const optimizelyProviderSpy = jest.spyOn( +// optimizelyReactSdk.OptimizelyProvider, +// 'default', +// ); + +// jest.mock('@optimizely/react-sdk', () => ({ + +// })); + +// jest.mock('../myModule', () => { +// // Require the original module to not be mocked... +// const originalModule = jest.requireActual('../myModule'); + +// return { +// __esModule: true, // Use it when dealing with esModules +// ...originalModule, +// getRandom: jest.fn(() => 10), +// }; +// }); const props = { bbcOrigin: 'https://www.bbc.com', @@ -44,8 +60,32 @@ const TestComponent = () => { describe('withOptimizelyProvider HOC', () => { it('should enrich the component with the Optimizely API', () => { + const optimizelyProviderRenderSpy = jest.spyOn( + optimizelyReactSdk.OptimizelyProvider.prototype, + 'render', + ); + + render(); + + expect(optimizelyProviderRenderSpy).toHaveBeenCalledTimes(1); + }); + + it('should return undefined when ckns_mvt is fetched with Cookie.get', () => { + const cookieGetterSpy = jest.spyOn(Cookie, 'get'); + + render(); + + expect(cookieGetterSpy).toHaveBeenCalledWith('ckns_mvt'); + expect(cookieGetterSpy).toHaveReturnedWith(undefined); + }); + + it('should return the correct ckns_mvt cookie value from Cookie.get', () => { + const cookieGetterSpy = jest.spyOn(Cookie, 'get'); + Cookie.set('ckns_mvt', 'random-uuid'); + render(); - expect(optimizelyProviderSpy).toHaveBeenCalledTimes(1); + expect(cookieGetterSpy).toHaveBeenCalledWith('ckns_mvt'); + expect(cookieGetterSpy).toHaveReturnedWith('random-uuid'); }); }); From 8d7697e910f185641647dbbc2f051eba4e7f293d Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 14:08:23 +0100 Subject: [PATCH 05/21] fixes order of userId check --- .../containers/PageHandlers/withOptimizelyProvider/index.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx index 374058c8cfa..719efa0702e 100644 --- a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx +++ b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx @@ -33,7 +33,7 @@ const withOptimizelyProvider = Component => { let mobile; const getUserId = () => { - if (disableOptimizely || isOperaProxy() || !onClient()) { + if (disableOptimizely || !onClient() || isOperaProxy()) { return null; } return Cookie.get('ckns_mvt') ?? null; @@ -50,6 +50,8 @@ const withOptimizelyProvider = Component => { } } + console.log(getUserId()); + return ( Date: Mon, 7 Oct 2024 14:24:03 +0100 Subject: [PATCH 06/21] adjust applyBasicPageHandlers api --- src/app/pages/ArticlePage/index.tsx | 3 +- src/app/pages/utils/applyBasicPageHandlers.js | 27 +++++-------- .../utils/applyBasicPageHandlers.test.js | 39 +++---------------- 3 files changed, 16 insertions(+), 53 deletions(-) diff --git a/src/app/pages/ArticlePage/index.tsx b/src/app/pages/ArticlePage/index.tsx index 3b18c81fe25..ddf850c2783 100644 --- a/src/app/pages/ArticlePage/index.tsx +++ b/src/app/pages/ArticlePage/index.tsx @@ -1,6 +1,7 @@ +import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; import ArticlePage from './ArticlePage'; import applyBasicPageHandlers from '../utils/applyBasicPageHandlers'; export default applyBasicPageHandlers(ArticlePage, { - applyOptimizely: true, + lastHandler: withOptimizelyProvider, }); diff --git a/src/app/pages/utils/applyBasicPageHandlers.js b/src/app/pages/utils/applyBasicPageHandlers.js index 9ec2995b25e..4fc98cad9e7 100644 --- a/src/app/pages/utils/applyBasicPageHandlers.js +++ b/src/app/pages/utils/applyBasicPageHandlers.js @@ -4,22 +4,13 @@ import withPageWrapper from '#containers/PageHandlers/withPageWrapper'; import withError from '#containers/PageHandlers/withError'; import withData from '#containers/PageHandlers/withData'; import withHashChangeHandler from '#containers/PageHandlers/withHashChangeHandler'; -import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; -export default (component, { applyOptimizely = false } = {}) => - applyOptimizely - ? pipe( - withData, - withError, - withPageWrapper, - withContexts, - withHashChangeHandler, - withOptimizelyProvider, - )(component) - : pipe( - withData, - withError, - withPageWrapper, - withContexts, - withHashChangeHandler, - )(component); +export default (component, { lastHandler = Component => Component } = {}) => + pipe( + withData, + withError, + withPageWrapper, + withContexts, + withHashChangeHandler, + lastHandler, + )(component); diff --git a/src/app/pages/utils/applyBasicPageHandlers.test.js b/src/app/pages/utils/applyBasicPageHandlers.test.js index 77efceb0c69..4e29dff2028 100644 --- a/src/app/pages/utils/applyBasicPageHandlers.test.js +++ b/src/app/pages/utils/applyBasicPageHandlers.test.js @@ -1,4 +1,3 @@ -import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; import * as pipe from 'ramda/src/pipe'; import applyBasicPageHandlers from './applyBasicPageHandlers'; @@ -12,51 +11,23 @@ jest.mock('ramda/src/pipe', () => { }; }); -jest.mock('#app/legacy/containers/PageHandlers/withOptimizelyProvider'); - describe('applyBasicPageHandlers', () => { beforeEach(() => { jest.clearAllMocks(); jest.resetModules(); }); - it('should have called the withOptimizelyProvider function if applyOptimizely is true', () => { - const component = jest.fn(); - const applyOptimizely = true; - - applyBasicPageHandlers(component, { applyOptimizely }); - - expect(withOptimizelyProvider).toHaveBeenCalled(); - }); - - it('should not call the withOptimizelyProvider function if applyOptimizely is false', () => { - const component = jest.fn(); - const applyOptimizely = false; - - applyBasicPageHandlers(component, { applyOptimizely }); - - expect(withOptimizelyProvider).not.toHaveBeenCalled(); - }); - - it('should not call the withOptimizelyProvider function if applyOptimizely is not provided', () => { - const component = jest.fn(); - - applyBasicPageHandlers(component); - - expect(withOptimizelyProvider).not.toHaveBeenCalled(); - }); - - it('should call pipe with withOptimizelyProvider as the last argument if applyOptimizely is true', () => { + it('should call pipe with function as the last argument when passed via lastFunction', () => { const component = jest.fn(); - const applyOptimizely = true; + const mockLastFunction = jest.fn(); const pipeMock = jest.spyOn(pipe, 'default'); - applyBasicPageHandlers(component, { applyOptimizely }); + applyBasicPageHandlers(component, { lastHandler: mockLastFunction }); const args = pipeMock.mock.calls[0]; const lastArg = args[args.length - 1]; - expect(lastArg).toEqual(withOptimizelyProvider); - expect(withOptimizelyProvider).toHaveBeenCalledTimes(1); + expect(lastArg).toEqual(mockLastFunction); + expect(mockLastFunction).toHaveBeenCalledTimes(1); }); }); From f3aafd46088b4df0bab1f17e93198ee86b98ff8a Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 14:36:59 +0100 Subject: [PATCH 07/21] updates readme --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cb332712401..359d0a93031 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Each render is passed through a set of HOC's (Higher Order Components) to enhanc - withData - withHashChangeHandler -With a selection of page types passed through withOptimizelyProvider, currently [Article](https://github.com/bbc/simorgh/blob/latest/src/app/pages/ArticlePage/index.jsx) and [Story](https://github.com/bbc/simorgh/blob/latest/src/app/pages/StoryPage/index.jsx) pages. +With a selection of page types passed through withOptimizelyProvider, that enables usage of Optimizely in the selected page types. #### withVariant @@ -97,6 +97,20 @@ The withHashChangeHandler HOC is a wrapper applied to all pages that checks for The withOptimizelyProvider HOC returns components that have been enhanced with access to an Optimizely client, that is used to run our A/B testing. This is done to limit bundle sizes, as we seperate some of our bundles by page type, that means if we're only running A/B testing on certain page types, we can prevent polluting page type bundles with the weight of the SDK library we use for Optimizely. +This should be used by using the `lastFunction` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is set within the user context, so the withOptimizelyProvider HOC needs to be applied after the withContexts HOC, so the `ckns_mvt` is availible to be used on first time visits to be used as the Optimizely User Id + +Example for Article page: +```jsx +import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; +import ArticlePage from './ArticlePage'; +import applyBasicPageHandlers from '../utils/applyBasicPageHandlers'; + +export default applyBasicPageHandlers(ArticlePage, { + lastHandler: withOptimizelyProvider, +}); + +``` + ### Adding a new Page type When adding a new page type there are several parts required. From 119e7adb6fa780d4466a6837dcff50c875997065 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 14:39:16 +0100 Subject: [PATCH 08/21] removes test comments --- .../withOptimizelyProvider/index.test.jsx | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.test.jsx b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.test.jsx index 8e98ddbb22c..e0d4a640f52 100644 --- a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.test.jsx +++ b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.test.jsx @@ -6,26 +6,6 @@ import latin from '../../../../components/ThemeProvider/fontScripts/latin'; import { ServiceContext } from '../../../../contexts/ServiceContext'; import withOptimizelyProvider from '.'; -// const optimizelyProviderSpy = jest.spyOn( -// optimizelyReactSdk.OptimizelyProvider, -// 'default', -// ); - -// jest.mock('@optimizely/react-sdk', () => ({ - -// })); - -// jest.mock('../myModule', () => { -// // Require the original module to not be mocked... -// const originalModule = jest.requireActual('../myModule'); - -// return { -// __esModule: true, // Use it when dealing with esModules -// ...originalModule, -// getRandom: jest.fn(() => 10), -// }; -// }); - const props = { bbcOrigin: 'https://www.bbc.com', id: 'c0000000000o', From 4e2f19cfba85f1de32e17c5b27ef06d94e4531e7 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 14:42:17 +0100 Subject: [PATCH 09/21] readme updates --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 359d0a93031..046fc0eacf2 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The withHashChangeHandler HOC is a wrapper applied to all pages that checks for The withOptimizelyProvider HOC returns components that have been enhanced with access to an Optimizely client, that is used to run our A/B testing. This is done to limit bundle sizes, as we seperate some of our bundles by page type, that means if we're only running A/B testing on certain page types, we can prevent polluting page type bundles with the weight of the SDK library we use for Optimizely. -This should be used by using the `lastFunction` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is set within the user context, so the withOptimizelyProvider HOC needs to be applied after the withContexts HOC, so the `ckns_mvt` is availible to be used on first time visits to be used as the Optimizely User Id +This should be used by using the `lastFunction` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/blob/598104ced53f3b530b190c0438b92414531aac99/src/app/contexts/UserContext/index.tsx#L33), so the withOptimizelyProvider HOC needs to be applied after the [withContexts](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is availible to be used on first time visits to be used as the Optimizely User Id Example for Article page: ```jsx From e7d13b530cab11240ca64a9ee75af2997297751a Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 14:50:06 +0100 Subject: [PATCH 10/21] removes console log --- .../containers/PageHandlers/withOptimizelyProvider/index.jsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx index 719efa0702e..c7ae3f7d17f 100644 --- a/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx +++ b/src/app/legacy/containers/PageHandlers/withOptimizelyProvider/index.jsx @@ -50,8 +50,6 @@ const withOptimizelyProvider = Component => { } } - console.log(getUserId()); - return ( Date: Mon, 7 Oct 2024 15:20:54 +0100 Subject: [PATCH 11/21] rearranges pipe --- src/app/pages/ArticlePage/index.tsx | 5 ++++- src/app/pages/utils/applyBasicPageHandlers.js | 7 +++++-- .../pages/utils/applyBasicPageHandlers.test.js | 17 +++++++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/app/pages/ArticlePage/index.tsx b/src/app/pages/ArticlePage/index.tsx index 116c11b5248..6ffed3641db 100644 --- a/src/app/pages/ArticlePage/index.tsx +++ b/src/app/pages/ArticlePage/index.tsx @@ -1,4 +1,7 @@ +import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; import ArticlePage from './ArticlePage'; import applyBasicPageHandlers from '../utils/applyBasicPageHandlers'; -export default applyBasicPageHandlers(ArticlePage); +export default applyBasicPageHandlers(ArticlePage, { + handlerBeforeContexts: withOptimizelyProvider, +}); diff --git a/src/app/pages/utils/applyBasicPageHandlers.js b/src/app/pages/utils/applyBasicPageHandlers.js index 4fc98cad9e7..c9a1f81bf67 100644 --- a/src/app/pages/utils/applyBasicPageHandlers.js +++ b/src/app/pages/utils/applyBasicPageHandlers.js @@ -5,12 +5,15 @@ import withError from '#containers/PageHandlers/withError'; import withData from '#containers/PageHandlers/withData'; import withHashChangeHandler from '#containers/PageHandlers/withHashChangeHandler'; -export default (component, { lastHandler = Component => Component } = {}) => +export default ( + component, + { handlerBeforeContexts = Component => Component } = {}, +) => pipe( withData, withError, withPageWrapper, + handlerBeforeContexts, withContexts, withHashChangeHandler, - lastHandler, )(component); diff --git a/src/app/pages/utils/applyBasicPageHandlers.test.js b/src/app/pages/utils/applyBasicPageHandlers.test.js index 4e29dff2028..2c2d1210aae 100644 --- a/src/app/pages/utils/applyBasicPageHandlers.test.js +++ b/src/app/pages/utils/applyBasicPageHandlers.test.js @@ -1,4 +1,5 @@ import * as pipe from 'ramda/src/pipe'; +import WithContexts from '#app/legacy/containers/PageHandlers/withContexts'; import applyBasicPageHandlers from './applyBasicPageHandlers'; jest.mock('ramda/src/pipe', () => { @@ -17,17 +18,21 @@ describe('applyBasicPageHandlers', () => { jest.resetModules(); }); - it('should call pipe with function as the last argument when passed via lastFunction', () => { + it('should call pipe with function as the argument before the withContexts argument when passed via handlerBeforeContexts', () => { const component = jest.fn(); - const mockLastFunction = jest.fn(); + const mockBeforeContextsFunction = jest.fn(); const pipeMock = jest.spyOn(pipe, 'default'); - applyBasicPageHandlers(component, { lastHandler: mockLastFunction }); + applyBasicPageHandlers(component, { + handlerBeforeContexts: mockBeforeContextsFunction, + }); const args = pipeMock.mock.calls[0]; - const lastArg = args[args.length - 1]; + const beforeContextsFunctionArg = args[3]; + const WithContextsFunctionArg = args[4]; - expect(lastArg).toEqual(mockLastFunction); - expect(mockLastFunction).toHaveBeenCalledTimes(1); + expect(beforeContextsFunctionArg).toEqual(mockBeforeContextsFunction); + expect(WithContextsFunctionArg).toEqual(WithContexts); + expect(mockBeforeContextsFunction).toHaveBeenCalledTimes(1); }); }); From 6cc12a1d755abc2c213d6ad707ebaee96f78665b Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 15:22:21 +0100 Subject: [PATCH 12/21] updates readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 046fc0eacf2..f485fc5e6a2 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The withHashChangeHandler HOC is a wrapper applied to all pages that checks for The withOptimizelyProvider HOC returns components that have been enhanced with access to an Optimizely client, that is used to run our A/B testing. This is done to limit bundle sizes, as we seperate some of our bundles by page type, that means if we're only running A/B testing on certain page types, we can prevent polluting page type bundles with the weight of the SDK library we use for Optimizely. -This should be used by using the `lastFunction` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/blob/598104ced53f3b530b190c0438b92414531aac99/src/app/contexts/UserContext/index.tsx#L33), so the withOptimizelyProvider HOC needs to be applied after the [withContexts](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is availible to be used on first time visits to be used as the Optimizely User Id +This should be used by using the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/blob/598104ced53f3b530b190c0438b92414531aac99/src/app/contexts/UserContext/index.tsx#L33), so the withOptimizelyProvider HOC needs to be applied in the correct order alongside [withContexts](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is availible to be used on first time visits to be used as the Optimizely User Id Example for Article page: ```jsx From 1e34a1131e7e739cf1eaae317f1ebfb56706cb27 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 15:25:28 +0100 Subject: [PATCH 13/21] updates links --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f485fc5e6a2..1ea8c431fea 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The withHashChangeHandler HOC is a wrapper applied to all pages that checks for The withOptimizelyProvider HOC returns components that have been enhanced with access to an Optimizely client, that is used to run our A/B testing. This is done to limit bundle sizes, as we seperate some of our bundles by page type, that means if we're only running A/B testing on certain page types, we can prevent polluting page type bundles with the weight of the SDK library we use for Optimizely. -This should be used by using the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/blob/598104ced53f3b530b190c0438b92414531aac99/src/app/contexts/UserContext/index.tsx#L33), so the withOptimizelyProvider HOC needs to be applied in the correct order alongside [withContexts](https://github.com/bbc/simorgh/blob/d559889a551202f0b9ad8d6ce2a94d31ecfad6a5/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is availible to be used on first time visits to be used as the Optimizely User Id +This should be used by using the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/tree/latest/src/app/contexts/UserContext/index.tsx#L33), so the withOptimizelyProvider HOC needs to be applied in the correct order alongside [withContexts](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is availible to be used on first time visits to be used as the Optimizely User Id Example for Article page: ```jsx From 84ab860d71fa7dc366c9da659484b80426996d39 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Mon, 7 Oct 2024 16:08:27 +0100 Subject: [PATCH 14/21] updates failing test --- src/app/components/ATIAnalytics/canonical/index.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/components/ATIAnalytics/canonical/index.test.tsx b/src/app/components/ATIAnalytics/canonical/index.test.tsx index 0e39adbd742..33b404b057d 100644 --- a/src/app/components/ATIAnalytics/canonical/index.test.tsx +++ b/src/app/components/ATIAnalytics/canonical/index.test.tsx @@ -31,7 +31,7 @@ describe('Canonical ATI Analytics', () => { }); it('should not send beacon when browser is Opera Mini', () => { - jest.spyOn(isOperaProxy, 'default').mockImplementationOnce(() => true); + jest.spyOn(isOperaProxy, 'default').mockImplementation(() => true); act(() => { render(); From 0999ce6447ed7c6051faae63af8618a01efbd758 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Tue, 8 Oct 2024 08:30:04 +0100 Subject: [PATCH 15/21] Update README.md Co-authored-by: Karina Thomas <58214768+karinathomasbbc@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ea8c431fea..1424ef9ab4f 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The withHashChangeHandler HOC is a wrapper applied to all pages that checks for The withOptimizelyProvider HOC returns components that have been enhanced with access to an Optimizely client, that is used to run our A/B testing. This is done to limit bundle sizes, as we seperate some of our bundles by page type, that means if we're only running A/B testing on certain page types, we can prevent polluting page type bundles with the weight of the SDK library we use for Optimizely. -This should be used by using the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/tree/latest/src/app/contexts/UserContext/index.tsx#L33), so the withOptimizelyProvider HOC needs to be applied in the correct order alongside [withContexts](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is availible to be used on first time visits to be used as the Optimizely User Id +This should be used by using the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/tree/latest/src/app/contexts/UserContext/index.tsx#L33), so the `withOptimizelyProvider` HOC needs to be applied in the correct order alongside [withContexts](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is available on first time visits and set as the Optimizely User Id Example for Article page: ```jsx From e528410c945e9f47c04c84a33b3f7f20b949c3ff Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Tue, 8 Oct 2024 08:33:21 +0100 Subject: [PATCH 16/21] Update README.md Co-authored-by: Karina Thomas <58214768+karinathomasbbc@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1424ef9ab4f..c3807814fbb 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ import ArticlePage from './ArticlePage'; import applyBasicPageHandlers from '../utils/applyBasicPageHandlers'; export default applyBasicPageHandlers(ArticlePage, { - lastHandler: withOptimizelyProvider, + handlerBeforeContexts: withOptimizelyProvider, }); ``` From 98aaa6a389ab4a5f5ee0d798daa041366d71fe32 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Tue, 8 Oct 2024 08:36:31 +0100 Subject: [PATCH 17/21] Update src/app/contexts/UserContext/index.test.tsx Co-authored-by: Karina Thomas <58214768+karinathomasbbc@users.noreply.github.com> --- src/app/contexts/UserContext/index.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/contexts/UserContext/index.test.tsx b/src/app/contexts/UserContext/index.test.tsx index a12ff15105f..bf9df761234 100644 --- a/src/app/contexts/UserContext/index.test.tsx +++ b/src/app/contexts/UserContext/index.test.tsx @@ -101,7 +101,7 @@ describe('UserContext', () => { expect(cookieGetterSpy).not.toHaveBeenCalled(); }); - it('should not set cookie when ckns_mvt cookie exists', () => { + it('should not set cookie when ckns_mvt cookie already exists', () => { onClientSpy.mockImplementationOnce(() => true as unknown as Location); isOperaProxySpy.mockImplementationOnce(() => false); // @ts-expect-error This should be able to be mocked as a string or undefined From 624087d91fcfbf4214d3ae21128add99d3f922ed Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Tue, 8 Oct 2024 08:46:43 +0100 Subject: [PATCH 18/21] updates test to be more explicit with ckns_mvt --- src/app/contexts/UserContext/index.test.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/contexts/UserContext/index.test.tsx b/src/app/contexts/UserContext/index.test.tsx index bf9df761234..50adc967449 100644 --- a/src/app/contexts/UserContext/index.test.tsx +++ b/src/app/contexts/UserContext/index.test.tsx @@ -72,6 +72,7 @@ describe('UserContext', () => { beforeEach(() => { jest.clearAllMocks(); + Cookie.remove('ckns_mvt'); }); it('should call cookie logic when not opera mini and is on client', () => { @@ -104,11 +105,12 @@ describe('UserContext', () => { it('should not set cookie when ckns_mvt cookie already exists', () => { onClientSpy.mockImplementationOnce(() => true as unknown as Location); isOperaProxySpy.mockImplementationOnce(() => false); - // @ts-expect-error This should be able to be mocked as a string or undefined - cookieGetterSpy.mockImplementationOnce(() => 'foo'); + Cookie.set('ckns_mvt', 'foo'); + cookieSetterSpy.mockClear(); render(); + expect(cookieGetterSpy).toHaveReturnedWith('foo'); expect(cookieSetterSpy).not.toHaveBeenCalled(); }); From 7a392d592d6394c3ac75aaca9c093b1c43119aaa Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Tue, 8 Oct 2024 08:51:27 +0100 Subject: [PATCH 19/21] updates readme for added clarity --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c3807814fbb..cfb8b0e2d08 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The withHashChangeHandler HOC is a wrapper applied to all pages that checks for The withOptimizelyProvider HOC returns components that have been enhanced with access to an Optimizely client, that is used to run our A/B testing. This is done to limit bundle sizes, as we seperate some of our bundles by page type, that means if we're only running A/B testing on certain page types, we can prevent polluting page type bundles with the weight of the SDK library we use for Optimizely. -This should be used by using the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/tree/latest/src/app/contexts/UserContext/index.tsx#L33), so the `withOptimizelyProvider` HOC needs to be applied in the correct order alongside [withContexts](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is available on first time visits and set as the Optimizely User Id +withOptimizelyProvider should be added as the value to the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/tree/latest/src/app/contexts/UserContext/index.tsx#L33), so the `withOptimizelyProvider` HOC needs to be applied in the correct order alongside [withContexts](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is available on first time visits and set as the Optimizely User ID, along with attributes such as service used for determining when Optimizely should enable an experiment. Example for Article page: ```jsx From 041beb77ea1348292b1278f4b4d37a017a2772ff Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Tue, 8 Oct 2024 08:55:34 +0100 Subject: [PATCH 20/21] more readme updates --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cfb8b0e2d08..1fb01f94b7b 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The withHashChangeHandler HOC is a wrapper applied to all pages that checks for The withOptimizelyProvider HOC returns components that have been enhanced with access to an Optimizely client, that is used to run our A/B testing. This is done to limit bundle sizes, as we seperate some of our bundles by page type, that means if we're only running A/B testing on certain page types, we can prevent polluting page type bundles with the weight of the SDK library we use for Optimizely. -withOptimizelyProvider should be added as the value to the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/tree/latest/src/app/contexts/UserContext/index.tsx#L33), so the `withOptimizelyProvider` HOC needs to be applied in the correct order alongside [withContexts](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC, so the `ckns_mvt` is available on first time visits and set as the Optimizely User ID, along with attributes such as service used for determining when Optimizely should enable an experiment. +withOptimizelyProvider should be added as the value of the `handlerBeforeContexts` object key within [applyBasicPageHandlers.js](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L8), as the `ckns_mvt` is [set within the UserContext](https://github.com/bbc/simorgh/tree/latest/src/app/contexts/UserContext/index.tsx#L33), so the `withOptimizelyProvider` HOC needs to be applied in the correct order alongside the [withContexts](https://github.com/bbc/simorgh/tree/latest/src/app/pages/utils/applyBasicPageHandlers.js#L13) HOC. This makes the `ckns_mvt` available on first time visits to pass into the `OptimizelyProvider`, along with attributes such as `service`, which is used for determining when Optimizely should enable an experiment. Example for Article page: ```jsx From 9fc0d50825ee70a368ca2945a35da190f97f3be4 Mon Sep 17 00:00:00 2001 From: Harvey Peachey Date: Tue, 8 Oct 2024 08:57:45 +0100 Subject: [PATCH 21/21] removes optimizely from article pages as no testing is happening --- src/app/pages/ArticlePage/index.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/app/pages/ArticlePage/index.tsx b/src/app/pages/ArticlePage/index.tsx index 6ffed3641db..116c11b5248 100644 --- a/src/app/pages/ArticlePage/index.tsx +++ b/src/app/pages/ArticlePage/index.tsx @@ -1,7 +1,4 @@ -import withOptimizelyProvider from '#app/legacy/containers/PageHandlers/withOptimizelyProvider'; import ArticlePage from './ArticlePage'; import applyBasicPageHandlers from '../utils/applyBasicPageHandlers'; -export default applyBasicPageHandlers(ArticlePage, { - handlerBeforeContexts: withOptimizelyProvider, -}); +export default applyBasicPageHandlers(ArticlePage);