@newskit-render/core 1.66.0 → 1.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +133 -0
- package/README.md +16 -0
- package/__tests__/pages/[articleSlug].test.tsx +1 -55
- package/__tests__/pages/__snapshots__/home.test.tsx.snap +657 -626
- package/__tests__/pages/__snapshots__/relatedArticles.test.tsx.snap +651 -0
- package/__tests__/pages/relatedArticles.test.tsx +23 -11
- package/components/article/__tests__/__snapshots__/index.test.tsx.snap +1091 -1060
- package/components/footer/index.tsx +1 -1
- package/components/header/banner-messages.ts +45 -0
- package/components/header/index.tsx +31 -287
- package/components/header/navigation-links.ts +20 -0
- package/components/layout/LayoutTemplate.tsx +4 -1
- package/config/__tests__/index.test.ts +53 -0
- package/config/environment.ts +67 -0
- package/config/index.ts +2 -85
- package/config/multiTenancy.ts +12 -0
- package/{app-context → context/app-context}/AppContext.test.tsx +7 -3
- package/{app-context/AppContext.tsx → context/app-context/index.tsx} +5 -1
- package/context/index.tsx +2 -0
- package/context/multi-tenancy/MultiTenancy.test.tsx +47 -0
- package/context/multi-tenancy/index.tsx +31 -0
- package/css/index.ts +224 -0
- package/cypress/support/commands.js +8 -4
- package/helpers/__tests__/createThemeDropdownObject.test.ts +3 -3
- package/helpers/__tests__/getRecommendation.test.ts +62 -0
- package/helpers/createThemeDropdownObject.ts +3 -3
- package/helpers/getRecommendations.ts +29 -0
- package/helpers/global-types.ts +8 -0
- package/{__tests__/pages/mocks.ts → helpers/mocks/getRecommendationsMock.ts} +2 -6
- package/helpers/multiTenancy.ts +19 -0
- package/jest.config.js +1 -2
- package/package.json +11 -9
- package/pages/[section]/[articleId]/[articleSlug].tsx +17 -10
- package/pages/[section]/[articleId]/relatedArticles.tsx +49 -40
- package/pages/_app.tsx +42 -257
- package/pages/account/cancellation/index.tsx +1 -1
- package/pages/account/edit/[field].tsx +1 -1
- package/pages/account/index.tsx +1 -1
- package/pages/account/newsletters-and-alerts/index.tsx +1 -1
- package/pages/account/payment/index.tsx +1 -1
- package/pages/account/subscription-and-billing/index.tsx +1 -1
- package/pages/api/auth/[...nextauth].ts +5 -1
- package/pages/api/recommendations/[...slug].ts +21 -0
- package/pages/checkout/account-creation/index.tsx +1 -1
- package/pages/checkout/payment-details/index.tsx +1 -1
- package/pages/help-hub/[id]/index.tsx +22 -9
- package/pages/help-hub/index.tsx +22 -9
- package/pages/help-hub/results.tsx +24 -0
- package/theme/strings/demo.ts +1 -0
- package/theme/strings/index.ts +1 -0
- package/components/header/index.test.tsx +0 -73
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
import { UncompiledTheme } from 'newskit'
|
|
3
3
|
import { sharedTheme } from '@newskit-render/shared-components'
|
|
4
|
+
import { useMultiTenancy } from '../multi-tenancy'
|
|
5
|
+
import { themesMap } from '../../config'
|
|
4
6
|
|
|
5
7
|
type AppContextType = {
|
|
6
8
|
theme: UncompiledTheme
|
|
@@ -12,7 +14,9 @@ const AppContext = React.createContext({
|
|
|
12
14
|
} as AppContextType)
|
|
13
15
|
|
|
14
16
|
const AppContextProvider = ({ children }: { children: JSX.Element }) => {
|
|
15
|
-
const
|
|
17
|
+
const { tenant } = useMultiTenancy()
|
|
18
|
+
const tenantTheme = themesMap[tenant]
|
|
19
|
+
const [theme, setTheme] = useState(tenantTheme)
|
|
16
20
|
|
|
17
21
|
return (
|
|
18
22
|
<AppContext.Provider value={{ theme, setTheme }}>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from 'react-dom'
|
|
3
|
+
import { timesTheme } from '@newskit-render/shared-components'
|
|
4
|
+
import { Publisher } from '@newskit-render/api'
|
|
5
|
+
import { AppContext, AppContextProvider } from '../app-context'
|
|
6
|
+
import MultiTenancyProvider, { useMultiTenancy } from '.'
|
|
7
|
+
|
|
8
|
+
const container = document.createElement('div')
|
|
9
|
+
document.body.appendChild(container)
|
|
10
|
+
|
|
11
|
+
const TestComponent = ({ mockFunction }) => {
|
|
12
|
+
const accountData = useMultiTenancy()
|
|
13
|
+
mockFunction(accountData)
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe('Multi-Tenancy context', () => {
|
|
18
|
+
it('should select the correct theme based on the tenant', () => {
|
|
19
|
+
render(
|
|
20
|
+
<MultiTenancyProvider tenant={Publisher.TIMES}>
|
|
21
|
+
<AppContextProvider>
|
|
22
|
+
<AppContext.Consumer>
|
|
23
|
+
{({ theme }) => <div>{JSON.stringify(theme)}</div>}
|
|
24
|
+
</AppContext.Consumer>
|
|
25
|
+
</AppContextProvider>
|
|
26
|
+
</MultiTenancyProvider>,
|
|
27
|
+
container
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
expect(container.textContent).toBe(JSON.stringify(timesTheme))
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should receive proper context', () => {
|
|
34
|
+
const mockFunction = jest.fn()
|
|
35
|
+
render(
|
|
36
|
+
<MultiTenancyProvider tenant={Publisher.DEMO}>
|
|
37
|
+
<TestComponent mockFunction={mockFunction} />
|
|
38
|
+
</MultiTenancyProvider>,
|
|
39
|
+
container
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
expect(mockFunction).toHaveBeenCalledWith({
|
|
43
|
+
tenant: Publisher.DEMO,
|
|
44
|
+
getTenantString: expect.any(Function),
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React, { createContext, useContext } from 'react'
|
|
2
|
+
import get from 'lodash.get'
|
|
3
|
+
import { Publisher } from '@newskit-render/api'
|
|
4
|
+
import { translationsMap } from '../../config'
|
|
5
|
+
|
|
6
|
+
export interface MultiTenancyContextProps {
|
|
7
|
+
tenant?: Publisher
|
|
8
|
+
getTenantString?: (key: string, defaultValue?: string) => string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const MultiTenancyContext = createContext<MultiTenancyContextProps>({})
|
|
12
|
+
|
|
13
|
+
const MultiTenancyProvider: React.FC<MultiTenancyContextProps> = ({
|
|
14
|
+
tenant,
|
|
15
|
+
children,
|
|
16
|
+
}) => (
|
|
17
|
+
<MultiTenancyContext.Provider
|
|
18
|
+
value={{
|
|
19
|
+
tenant,
|
|
20
|
+
getTenantString: (key: string, defaultValue: string = ''): string => {
|
|
21
|
+
const data = translationsMap[tenant]
|
|
22
|
+
return get(data, key, defaultValue)
|
|
23
|
+
},
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
26
|
+
{children}
|
|
27
|
+
</MultiTenancyContext.Provider>
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
export const useMultiTenancy = () => useContext(MultiTenancyContext)
|
|
31
|
+
export default MultiTenancyProvider
|
package/css/index.ts
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { css } from 'newskit'
|
|
2
|
+
|
|
3
|
+
export const GlobalStyling = css`
|
|
4
|
+
@font-face {
|
|
5
|
+
font-family: GillSansMTStd-Medium;
|
|
6
|
+
src: url('/fonts/GillSansMTStd-Medium.otf');
|
|
7
|
+
}
|
|
8
|
+
@font-face {
|
|
9
|
+
font-family: TimesModern-Bold;
|
|
10
|
+
src: url('/fonts/TimesDigital-Bold.ttf') format('truetype');
|
|
11
|
+
}
|
|
12
|
+
@font-face {
|
|
13
|
+
font-family: TimesModern-Regular;
|
|
14
|
+
src: url('/fonts/TimesDigital-Regular.ttf') format('truetype');
|
|
15
|
+
}
|
|
16
|
+
@font-face {
|
|
17
|
+
font-family: TimesDigitalW04-Regular;
|
|
18
|
+
src: url('/fonts/TimesDigitalW04-Regular.ttf') format('truetype');
|
|
19
|
+
}
|
|
20
|
+
@font-face {
|
|
21
|
+
font-family: Montserrat;
|
|
22
|
+
src: url('/fonts/Montserrat-Regular.ttf') format('truetype');
|
|
23
|
+
}
|
|
24
|
+
@font-face {
|
|
25
|
+
font-family: TheSun-Bold;
|
|
26
|
+
src: url('/fonts/TheSun-Bold.ttf') format('truetype');
|
|
27
|
+
}
|
|
28
|
+
@font-face {
|
|
29
|
+
font-family: TheSun-HeavyNarrow;
|
|
30
|
+
src: url('/fonts/TheSun-HeavyNarrow.ttf') format('truetype');
|
|
31
|
+
}
|
|
32
|
+
@font-face {
|
|
33
|
+
font-family: TheSun-Regular;
|
|
34
|
+
src: url('/fonts/TheSun-Regular.ttf') format('truetype');
|
|
35
|
+
}
|
|
36
|
+
@font-face {
|
|
37
|
+
font-family: TheSun-Medium;
|
|
38
|
+
src: url('/fonts/TheSun-Medium.ttf') format('truetype');
|
|
39
|
+
}
|
|
40
|
+
@font-face {
|
|
41
|
+
font-family: 'DM Sans';
|
|
42
|
+
src: url('/fonts/dmsans-regular-webfont.woff2') format('woff2'),
|
|
43
|
+
url('/fonts/dmsans-regular-webfont.woff') format('woff');
|
|
44
|
+
font-style: normal;
|
|
45
|
+
font-weight: 400;
|
|
46
|
+
font-display: swap;
|
|
47
|
+
}
|
|
48
|
+
@font-face {
|
|
49
|
+
font-family: 'DM Sans';
|
|
50
|
+
src: url('/fonts/dmsans-italic-webfont.woff2') format('woff2'),
|
|
51
|
+
url('/fonts/dmsans-italic-webfont.woff') format('woff');
|
|
52
|
+
font-style: italic;
|
|
53
|
+
font-weight: 400;
|
|
54
|
+
font-display: swap;
|
|
55
|
+
}
|
|
56
|
+
@font-face {
|
|
57
|
+
font-family: 'DM Sans';
|
|
58
|
+
src: url('/fonts/dmsans-medium-webfont.woff2') format('woff2'),
|
|
59
|
+
url('/fonts/dmsans-medium-webfont.woff') format('woff');
|
|
60
|
+
font-style: normal;
|
|
61
|
+
font-weight: 500;
|
|
62
|
+
font-display: swap;
|
|
63
|
+
}
|
|
64
|
+
@font-face {
|
|
65
|
+
font-family: 'DM Sans';
|
|
66
|
+
src: url('/fonts/dmsans-mediumitalic-webfont.woff2') format('woff2'),
|
|
67
|
+
url('/fonts/dmsans-mediumitalic-webfont.woff') format('woff');
|
|
68
|
+
font-style: italic;
|
|
69
|
+
font-weight: 500;
|
|
70
|
+
font-display: swap;
|
|
71
|
+
}
|
|
72
|
+
@font-face {
|
|
73
|
+
font-family: 'DM Sans';
|
|
74
|
+
src: url('/fonts/dmsans-bold-webfont.woff2') format('woff2'),
|
|
75
|
+
url('/fonts/dmsans-bold-webfont.woff') format('woff');
|
|
76
|
+
font-style: normal;
|
|
77
|
+
font-weight: 700;
|
|
78
|
+
font-display: swap;
|
|
79
|
+
}
|
|
80
|
+
@font-face {
|
|
81
|
+
font-family: 'DM Sans';
|
|
82
|
+
src: url('/fonts/dmsans-bolditalic-webfont.woff2') format('woff2'),
|
|
83
|
+
url('/fonts/dmsans-bolditalic-webfont.woff') format('woff');
|
|
84
|
+
font-style: italic;
|
|
85
|
+
font-weight: 700;
|
|
86
|
+
font-display: swap;
|
|
87
|
+
}
|
|
88
|
+
@font-face {
|
|
89
|
+
font-family: 'Poppins';
|
|
90
|
+
src: url('/fonts/poppins-bold-webfont.woff2') format('woff2'),
|
|
91
|
+
url('/fonts/poppins-bold-webfont.woff') format('woff');
|
|
92
|
+
font-weight: 700;
|
|
93
|
+
font-style: normal;
|
|
94
|
+
}
|
|
95
|
+
@font-face {
|
|
96
|
+
font-family: 'Poppins';
|
|
97
|
+
src: url('/fonts/poppins-bolditalic-webfont.woff2') format('woff2'),
|
|
98
|
+
url('/fonts/poppins-bolditalic-webfont.woff') format('woff');
|
|
99
|
+
font-weight: normal;
|
|
100
|
+
font-style: italic;
|
|
101
|
+
}
|
|
102
|
+
@font-face {
|
|
103
|
+
font-family: 'Poppins';
|
|
104
|
+
src: url('/fonts/poppins-extrabold-webfont.woff2') format('woff2'),
|
|
105
|
+
url('/fonts/poppins-extrabold-webfont.woff') format('woff');
|
|
106
|
+
font-weight: 800;
|
|
107
|
+
font-style: normal;
|
|
108
|
+
}
|
|
109
|
+
@font-face {
|
|
110
|
+
font-family: 'Poppins';
|
|
111
|
+
src: url('/fonts/poppins-extrabolditalic-webfont.woff2') format('woff2'),
|
|
112
|
+
url('/fonts/poppins-extrabolditalic-webfont.woff') format('woff');
|
|
113
|
+
font-weight: 800;
|
|
114
|
+
font-style: italic;
|
|
115
|
+
}
|
|
116
|
+
@font-face {
|
|
117
|
+
font-family: 'Poppins';
|
|
118
|
+
src: url('/fonts/poppins-italic-webfont.woff2') format('woff2'),
|
|
119
|
+
url('/fonts/poppins-italic-webfont.woff') format('woff');
|
|
120
|
+
font-weight: 400;
|
|
121
|
+
font-style: italic;
|
|
122
|
+
}
|
|
123
|
+
@font-face {
|
|
124
|
+
font-family: 'Poppins';
|
|
125
|
+
src: url('/fonts/poppins-light-webfont.woff2') format('woff2'),
|
|
126
|
+
url('/fonts/poppins-light-webfont.woff') format('woff');
|
|
127
|
+
font-weight: 300;
|
|
128
|
+
font-style: normal;
|
|
129
|
+
}
|
|
130
|
+
@font-face {
|
|
131
|
+
font-family: 'Poppins';
|
|
132
|
+
src: url('/fonts/poppins-lightitalic-webfont.woff2') format('woff2'),
|
|
133
|
+
url('/fonts/poppins-lightitalic-webfont.woff') format('woff');
|
|
134
|
+
font-weight: 300;
|
|
135
|
+
font-style: italic;
|
|
136
|
+
}
|
|
137
|
+
@font-face {
|
|
138
|
+
font-family: 'Poppins';
|
|
139
|
+
src: url('/fonts/poppins-medium-webfont.woff2') format('woff2'),
|
|
140
|
+
url('/fonts/poppins-medium-webfont.woff') format('woff');
|
|
141
|
+
font-weight: 500;
|
|
142
|
+
font-style: normal;
|
|
143
|
+
}
|
|
144
|
+
@font-face {
|
|
145
|
+
font-family: 'Poppins';
|
|
146
|
+
src: url('/fonts/poppins-mediumitalic-webfont.woff2') format('woff2'),
|
|
147
|
+
url('/fonts/poppins-mediumitalic-webfont.woff') format('woff');
|
|
148
|
+
font-weight: 500;
|
|
149
|
+
font-style: italic;
|
|
150
|
+
}
|
|
151
|
+
@font-face {
|
|
152
|
+
font-family: 'Poppins';
|
|
153
|
+
src: url('/fonts/poppins-regular-webfont.woff2') format('woff2'),
|
|
154
|
+
url('/fonts/poppins-regular-webfont.woff') format('woff');
|
|
155
|
+
font-weight: 400;
|
|
156
|
+
font-style: normal;
|
|
157
|
+
}
|
|
158
|
+
@font-face {
|
|
159
|
+
font-family: 'Poppins';
|
|
160
|
+
src: url('/fonts/poppins-semibold-webfont.woff2') format('woff2'),
|
|
161
|
+
url('/fonts/poppins-semibold-webfont.woff') format('woff');
|
|
162
|
+
font-weight: 600;
|
|
163
|
+
font-style: normal;
|
|
164
|
+
}
|
|
165
|
+
@font-face {
|
|
166
|
+
font-family: 'Poppins';
|
|
167
|
+
src: url('/fonts/poppins-semibolditalic-webfont.woff2') format('woff2'),
|
|
168
|
+
url('/fonts/poppins-semibolditalic-webfont.woff') format('woff');
|
|
169
|
+
font-weight: 600;
|
|
170
|
+
font-style: italic;
|
|
171
|
+
}
|
|
172
|
+
@font-face {
|
|
173
|
+
font-family: 'DM Mono';
|
|
174
|
+
src: url('/fonts/dmmono-medium.woff2') format('woff2'),
|
|
175
|
+
url('/fonts/dmmono-medium.woff') format('woff');
|
|
176
|
+
font-style: normal;
|
|
177
|
+
font-weight: 500;
|
|
178
|
+
font-display: swap;
|
|
179
|
+
}
|
|
180
|
+
@font-face {
|
|
181
|
+
font-family: 'Bitter';
|
|
182
|
+
src: url('/fonts/bitter-regular.woff2') format('woff2'),
|
|
183
|
+
url('/fonts/bitter-regular.woff') format('woff');
|
|
184
|
+
font-style: normal;
|
|
185
|
+
font-weight: 400;
|
|
186
|
+
font-display: swap;
|
|
187
|
+
}
|
|
188
|
+
@font-face {
|
|
189
|
+
font-family: 'Bitter';
|
|
190
|
+
src: url('/fonts/bitter-medium.woff2') format('woff2'),
|
|
191
|
+
url('/fonts/bitter-medium.woff') format('woff');
|
|
192
|
+
font-style: normal;
|
|
193
|
+
font-weight: 500;
|
|
194
|
+
font-display: swap;
|
|
195
|
+
}
|
|
196
|
+
@font-face {
|
|
197
|
+
font-family: 'Bitter';
|
|
198
|
+
src: url('/fonts/bitter-mediumitalic.woff2') format('woff2'),
|
|
199
|
+
url('/fonts/bitter-mediumitalic.woff') format('woff');
|
|
200
|
+
font-style: italic;
|
|
201
|
+
font-weight: 500;
|
|
202
|
+
font-display: swap;
|
|
203
|
+
}
|
|
204
|
+
@font-face {
|
|
205
|
+
font-family: 'Bitter';
|
|
206
|
+
src: url('/fonts/bitter-semibold.woff2') format('woff2'),
|
|
207
|
+
url('/fonts/bitter-semibold.woff') format('woff');
|
|
208
|
+
font-style: normal;
|
|
209
|
+
font-weight: 600;
|
|
210
|
+
font-display: swap;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
html,
|
|
214
|
+
body {
|
|
215
|
+
padding: 0;
|
|
216
|
+
margin: 0;
|
|
217
|
+
font-family: 'Noto Sans', -apple-system, BlinkMacSystemFont, Segoe UI,
|
|
218
|
+
Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
|
|
219
|
+
sans-serif;
|
|
220
|
+
}
|
|
221
|
+
* {
|
|
222
|
+
box-sizing: border-box;
|
|
223
|
+
}
|
|
224
|
+
`
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
//Note: Check periodically if these consent cookie values exprire
|
|
2
|
+
const nuktSPConsentValue = 'JABCDEFGHI'
|
|
3
|
+
const consentUUIDValue = 'ff8ac797-02c4-4fb4-81f2-22f8ba2e8723_8'
|
|
4
|
+
|
|
1
5
|
Cypress.Commands.add('mockConsentAndVisit', (url) => {
|
|
2
|
-
cy.setCookie('nukt_sp_consent',
|
|
3
|
-
cy.setCookie('consentUUID',
|
|
6
|
+
cy.setCookie('nukt_sp_consent', nuktSPConsentValue)
|
|
7
|
+
cy.setCookie('consentUUID', consentUUIDValue)
|
|
4
8
|
cy.visit(url)
|
|
5
9
|
})
|
|
6
10
|
|
|
7
11
|
Cypress.Commands.add('mockConsent', () => {
|
|
8
|
-
cy.setCookie('nukt_sp_consent',
|
|
9
|
-
cy.setCookie('consentUUID',
|
|
12
|
+
cy.setCookie('nukt_sp_consent', nuktSPConsentValue)
|
|
13
|
+
cy.setCookie('consentUUID', consentUUIDValue)
|
|
10
14
|
})
|
|
11
15
|
|
|
12
16
|
const userMap = {
|
|
@@ -13,17 +13,17 @@ describe('createThemeDropdownObject', () => {
|
|
|
13
13
|
},
|
|
14
14
|
clientNavigationLogos: {
|
|
15
15
|
'The-Sun': {
|
|
16
|
-
src: 'navigationPrimary-brandMark-sun.svg',
|
|
16
|
+
src: '/MyAccount/navigationPrimary-brandMark-sun.svg',
|
|
17
17
|
width: '115px',
|
|
18
18
|
top: '0',
|
|
19
19
|
},
|
|
20
20
|
'Virgin-Radio': {
|
|
21
|
-
src: 'navigationPrimary-brandMark-vr.svg',
|
|
21
|
+
src: '/MyAccount/navigationPrimary-brandMark-vr.svg',
|
|
22
22
|
width: '150px',
|
|
23
23
|
top: '0',
|
|
24
24
|
},
|
|
25
25
|
'The-Times': {
|
|
26
|
-
src: 'navigationPrimary-brandMark-times.svg',
|
|
26
|
+
src: '/MyAccount/navigationPrimary-brandMark-times.svg',
|
|
27
27
|
width: '150px',
|
|
28
28
|
top: '0',
|
|
29
29
|
},
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getRecommendations, fetcher } from '../getRecommendations'
|
|
2
|
+
import { recomendationsMock } from '../mocks/getRecommendationsMock'
|
|
3
|
+
|
|
4
|
+
jest.mock('../getRecommendations', () => {
|
|
5
|
+
return {
|
|
6
|
+
fetcher: jest.fn().mockImplementationOnce(() => {
|
|
7
|
+
return recomendationsMock
|
|
8
|
+
}),
|
|
9
|
+
getRecommendations: jest.fn().mockImplementationOnce(() => {
|
|
10
|
+
return recomendationsMock
|
|
11
|
+
}),
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
jest.mock('@newskit-render/standalone-components', () => {
|
|
15
|
+
return {
|
|
16
|
+
recommendationsProvider: jest.fn().mockResolvedValueOnce([
|
|
17
|
+
{
|
|
18
|
+
href:
|
|
19
|
+
'https://www.thesun.co.uk/wp-content/uploads/2022/03/image-656eaa885d.jpg?strip=all&w=600&h=338&crop=1',
|
|
20
|
+
tag: 'FOOT ON THE GAZ',
|
|
21
|
+
text:
|
|
22
|
+
'Bale considering short deal with new club before RETIRING after World Cup',
|
|
23
|
+
title: 'FOOT ON THE GAZ',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
href:
|
|
27
|
+
'https://www.thesun.co.uk/wp-content/uploads/2022/03/image-a21f115694-1.jpg?strip=all&w=600&h=338&crop=1',
|
|
28
|
+
tag: 'TOUGH TIMES',
|
|
29
|
+
text:
|
|
30
|
+
'I only made £5k last year - I sold £801k villa for cash, says Claire Sweeney',
|
|
31
|
+
title: 'TOUGH TIMES',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
href: null,
|
|
35
|
+
tag: 'TOUGH TIMES',
|
|
36
|
+
text:
|
|
37
|
+
'I only made £5k last year - I sold £801k villa for cash, says Claire Sweeney',
|
|
38
|
+
title: 'TOUGH TIMES',
|
|
39
|
+
},
|
|
40
|
+
]),
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('getRecommendations function', () => {
|
|
45
|
+
it('should return recomendations', async () => {
|
|
46
|
+
const result = await getRecommendations({
|
|
47
|
+
articleId: 'test-1',
|
|
48
|
+
publisher: 'nukapi',
|
|
49
|
+
userId: 'user-1',
|
|
50
|
+
})
|
|
51
|
+
expect(result).toEqual(recomendationsMock)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
describe('fetcher function', () => {
|
|
55
|
+
it('should retun json object', async () => {
|
|
56
|
+
const result = await fetcher({
|
|
57
|
+
url: 'http://localhost:3000',
|
|
58
|
+
args: { articleId: 'test-2' },
|
|
59
|
+
})
|
|
60
|
+
expect(result).toEqual(recomendationsMock)
|
|
61
|
+
})
|
|
62
|
+
})
|
|
@@ -15,17 +15,17 @@ const clientHeaderImages = {
|
|
|
15
15
|
|
|
16
16
|
const clientNavigationLogos = {
|
|
17
17
|
'The-Sun': {
|
|
18
|
-
src: 'navigationPrimary-brandMark-sun.svg',
|
|
18
|
+
src: '/MyAccount/navigationPrimary-brandMark-sun.svg',
|
|
19
19
|
width: '115px',
|
|
20
20
|
top: '0',
|
|
21
21
|
},
|
|
22
22
|
'Virgin-Radio': {
|
|
23
|
-
src: 'navigationPrimary-brandMark-vr.svg',
|
|
23
|
+
src: '/MyAccount/navigationPrimary-brandMark-vr.svg',
|
|
24
24
|
width: '150px',
|
|
25
25
|
top: '0',
|
|
26
26
|
},
|
|
27
27
|
'The-Times': {
|
|
28
|
-
src: 'navigationPrimary-brandMark-times.svg',
|
|
28
|
+
src: '/MyAccount/navigationPrimary-brandMark-times.svg',
|
|
29
29
|
width: '150px',
|
|
30
30
|
top: '0',
|
|
31
31
|
},
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Fetcher } from 'swr'
|
|
2
|
+
import {
|
|
3
|
+
recommendationsProvider,
|
|
4
|
+
Article,
|
|
5
|
+
} from '@newskit-render/standalone-components'
|
|
6
|
+
|
|
7
|
+
interface Recommendations {
|
|
8
|
+
publisher: string
|
|
9
|
+
articleId: string
|
|
10
|
+
userId?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const fetcher: Fetcher<Article[]> = async (url): Promise<Article[]> => {
|
|
14
|
+
const res = await fetch(url)
|
|
15
|
+
return res.json()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const getRecommendations = async ({
|
|
19
|
+
articleId,
|
|
20
|
+
publisher,
|
|
21
|
+
userId,
|
|
22
|
+
}: Recommendations): Promise<Article[]> => {
|
|
23
|
+
const recommendations = await recommendationsProvider({
|
|
24
|
+
articleId,
|
|
25
|
+
publisher,
|
|
26
|
+
userId,
|
|
27
|
+
})
|
|
28
|
+
return recommendations
|
|
29
|
+
}
|
package/helpers/global-types.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
test.skip('Workaround', () => 1)
|
|
4
|
-
|
|
5
|
-
export const mockArticles: Article[] = [
|
|
1
|
+
export const recomendationsMock = [
|
|
6
2
|
{
|
|
7
3
|
href:
|
|
8
4
|
'https://www.thesun.co.uk/wp-content/uploads/2022/03/image-656eaa885d.jpg?strip=all&w=600&h=338&crop=1',
|
|
@@ -24,6 +20,6 @@ export const mockArticles: Article[] = [
|
|
|
24
20
|
tag: 'TOUGH TIMES',
|
|
25
21
|
text:
|
|
26
22
|
'I only made £5k last year - I sold £801k villa for cash, says Claire Sweeney',
|
|
27
|
-
title: 'TOUGH
|
|
23
|
+
title: 'TOUGH TIME',
|
|
28
24
|
},
|
|
29
25
|
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Publisher } from '@newskit-render/api'
|
|
2
|
+
|
|
3
|
+
const demoTenantRegex = /(newskit-render|localhost)/
|
|
4
|
+
const timesTenantRegex = /times/
|
|
5
|
+
|
|
6
|
+
const isDemoTenant = (host: string) => demoTenantRegex.test(host)
|
|
7
|
+
const isTimesTenant = (host: string) => timesTenantRegex.test(host)
|
|
8
|
+
|
|
9
|
+
export const getTenant = (host: string): Publisher => {
|
|
10
|
+
switch (true) {
|
|
11
|
+
case isTimesTenant(host):
|
|
12
|
+
return Publisher.TIMES
|
|
13
|
+
case isDemoTenant(host):
|
|
14
|
+
return Publisher.DEMO
|
|
15
|
+
|
|
16
|
+
default:
|
|
17
|
+
return Publisher.DEMO
|
|
18
|
+
}
|
|
19
|
+
}
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newskit-render/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.68.0",
|
|
4
4
|
"description": "Newskit Render - Core package",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -33,24 +33,26 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@apollo/client": "3.4.16",
|
|
36
|
-
"@newskit-render/api": "^0.
|
|
37
|
-
"@newskit-render/auth": "^0.
|
|
38
|
-
"@newskit-render/checkout": "^0.
|
|
36
|
+
"@newskit-render/api": "^0.34.0",
|
|
37
|
+
"@newskit-render/auth": "^0.42.0",
|
|
38
|
+
"@newskit-render/checkout": "^0.44.0",
|
|
39
39
|
"@newskit-render/feature-flags": "^0.22.0",
|
|
40
|
-
"@newskit-render/feed": "^0.
|
|
41
|
-
"@newskit-render/my-account": "^0.
|
|
42
|
-
"@newskit-render/shared-components": "^0.
|
|
43
|
-
"@newskit-render/standalone-components": "^0.
|
|
40
|
+
"@newskit-render/feed": "^0.23.0",
|
|
41
|
+
"@newskit-render/my-account": "^0.174.0",
|
|
42
|
+
"@newskit-render/shared-components": "^0.61.0",
|
|
43
|
+
"@newskit-render/standalone-components": "^0.21.0",
|
|
44
44
|
"@newskit-render/validation": "^0.48.0",
|
|
45
45
|
"cross-fetch": "3.1.5",
|
|
46
46
|
"graphql": "15.6.0",
|
|
47
|
+
"lodash.get": "4.4.2",
|
|
47
48
|
"newrelic": "7.1.0",
|
|
48
49
|
"newskit": "5.4.5",
|
|
49
50
|
"next": "12.1.0",
|
|
50
51
|
"react": "17.0.2",
|
|
51
52
|
"react-dom": "17.0.2",
|
|
52
53
|
"react-helmet": "6.1.0",
|
|
53
|
-
"react-hook-form": "7.8.4"
|
|
54
|
+
"react-hook-form": "7.8.4",
|
|
55
|
+
"swr": "1.3.0"
|
|
54
56
|
},
|
|
55
57
|
"devDependencies": {
|
|
56
58
|
"@apollo/react-testing": "4.0.0",
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
+
import useSWR from 'swr'
|
|
2
3
|
import newrelic from 'newrelic'
|
|
3
4
|
import {
|
|
4
5
|
createApolloClient,
|
|
5
6
|
ClientTypes,
|
|
6
7
|
getAcsCookie,
|
|
7
|
-
Publisher,
|
|
8
8
|
} from '@newskit-render/api'
|
|
9
9
|
import { UserData } from '@newskit-render/my-account'
|
|
10
|
-
import {
|
|
11
|
-
recommendationsProvider,
|
|
12
|
-
Article,
|
|
13
|
-
} from '@newskit-render/standalone-components'
|
|
10
|
+
import { Article } from '@newskit-render/standalone-components'
|
|
14
11
|
import { GET_UNIVERSAL_ARTICLE } from '../../../queries'
|
|
15
12
|
import ArticlePage, { UniversalArticle } from '../../../components/article'
|
|
16
13
|
import { fetchUser } from '../../../helpers/getUser'
|
|
@@ -21,6 +18,7 @@ import {
|
|
|
21
18
|
twitterUsername as configTwitterUsername,
|
|
22
19
|
gscId as configGscId,
|
|
23
20
|
} from '../../../config'
|
|
21
|
+
import { fetcher } from '../../../helpers/getRecommendations'
|
|
24
22
|
|
|
25
23
|
export type ArticleSlug = {
|
|
26
24
|
universalArticle: UniversalArticle
|
|
@@ -29,8 +27,9 @@ export type ArticleSlug = {
|
|
|
29
27
|
siteHost: string
|
|
30
28
|
gscId?: string
|
|
31
29
|
user?: UserData
|
|
32
|
-
|
|
30
|
+
articleId: string
|
|
33
31
|
}
|
|
32
|
+
|
|
34
33
|
const Article: React.FC<ArticleSlug> = ({
|
|
35
34
|
universalArticle,
|
|
36
35
|
articleURL,
|
|
@@ -38,8 +37,17 @@ const Article: React.FC<ArticleSlug> = ({
|
|
|
38
37
|
siteHost,
|
|
39
38
|
gscId,
|
|
40
39
|
user,
|
|
41
|
-
|
|
40
|
+
articleId,
|
|
42
41
|
}) => {
|
|
42
|
+
let userId
|
|
43
|
+
if (typeof window !== 'undefined') {
|
|
44
|
+
userId = window?.utag?.data['cp.utag_main_v_id']
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { data: recommendations = [] } = useSWR<Article[]>(
|
|
48
|
+
`/api/recommendations/${articleId}/${userId}`,
|
|
49
|
+
fetcher
|
|
50
|
+
)
|
|
43
51
|
const highlitedArticles = recommendations.slice(0, 4)
|
|
44
52
|
const relatedArticles = recommendations.slice(4, 12)
|
|
45
53
|
|
|
@@ -71,12 +79,11 @@ export async function getServerSideProps(context) {
|
|
|
71
79
|
`Article: /${section}/${articleId}/${articleSlug}`
|
|
72
80
|
)
|
|
73
81
|
|
|
74
|
-
const [{ data },
|
|
82
|
+
const [{ data }, user] = await Promise.all([
|
|
75
83
|
apolloClient.query({
|
|
76
84
|
query: GET_UNIVERSAL_ARTICLE,
|
|
77
85
|
variables: { publisher: 'DEMO', id: articleId },
|
|
78
86
|
}),
|
|
79
|
-
await recommendationsProvider({ articleId, publisher: Publisher.SUN_UK }),
|
|
80
87
|
await fetchUser(acsCookie, ACCOUNT_QUERY_URL),
|
|
81
88
|
])
|
|
82
89
|
|
|
@@ -89,8 +96,8 @@ export async function getServerSideProps(context) {
|
|
|
89
96
|
siteHost: configSiteHost || '',
|
|
90
97
|
gscId: configGscId || '',
|
|
91
98
|
showAds: true,
|
|
92
|
-
recommendations,
|
|
93
99
|
user,
|
|
100
|
+
articleId,
|
|
94
101
|
},
|
|
95
102
|
}
|
|
96
103
|
}
|