gatsby-core-theme 2.2.6 → 5.0.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 +145 -0
- package/__mocks__/gatsby.js +16 -4
- package/gatsby-node.esm.js +12 -15
- package/jest.config.js +8 -1
- package/package.json +1 -1
- package/src/components/app.js +1 -17
- package/src/components/atoms/author/author.test.js +12 -5
- package/src/components/atoms/author-box/index.js +8 -6
- package/src/components/atoms/breadcrumbs/breadcrumbs.test.js +8 -0
- package/src/components/atoms/carousel/pagination-item/pagination-item.test.js +18 -3
- package/src/components/atoms/collapse/collapse.test.js +10 -0
- package/src/components/atoms/collapse/index.js +3 -1
- package/src/components/atoms/content-box/content-box.test.js +9 -6
- package/src/components/atoms/content-box/index.js +13 -12
- package/src/components/atoms/custom-select/index.js +31 -30
- package/src/components/atoms/disclaimer/disclaimer.test.js +16 -1
- package/src/components/atoms/iframe/iframe.module.scss +3 -0
- package/src/components/atoms/iframe/iframe.test.js +6 -0
- package/src/components/atoms/iframe/index.js +1 -1
- package/src/components/atoms/image/image.test.js +19 -6
- package/src/components/atoms/image/index.js +2 -4
- package/src/components/atoms/info-grid/index.js +10 -12
- package/src/components/atoms/label/index.js +2 -2
- package/src/components/atoms/label/label.test.js +4 -0
- package/src/components/atoms/module-title/index.js +9 -9
- package/src/components/atoms/module-title/module-title.test.js +76 -0
- package/src/components/atoms/open-graph/open-graph.test.js +34 -5
- package/src/components/atoms/operator-cta/operator-cta.test.js +26 -3
- package/src/components/atoms/scroll-to-top/scroll-to-top.test.js +6 -0
- package/src/components/atoms/search/autocomplete/operator.js +1 -1
- package/src/components/atoms/sitemap/index.js +1 -1
- package/src/components/atoms/spotlights/index.js +59 -54
- package/src/components/atoms/spotlights/spotlights.module.scss +25 -37
- package/src/components/atoms/spotlights/spotlights.test.js +13 -15
- package/src/components/molecules/carousel/default-slide/index.js +3 -1
- package/src/components/molecules/content/content.test.js +127 -0
- package/src/components/molecules/content/index.js +0 -1
- package/src/components/molecules/header/header.test.js +6 -0
- package/src/components/molecules/main/main.test.js +48 -12
- package/src/components/molecules/menu/menu.test.js +27 -0
- package/src/components/molecules/module/module.test.js +134 -0
- package/src/components/molecules/operator-banner/operator-banner.test.js +7 -1
- package/src/components/molecules/pagination/pagination-with-midpoints.module.scss +48 -49
- package/src/components/molecules/slider/index.js +6 -0
- package/src/components/organisms/anchor/index.js +14 -11
- package/src/components/organisms/carousel/index.js +16 -3
- package/src/components/organisms/cookie-consent/cookie-consent.test.js +7 -1
- package/src/components/organisms/form/form.test.js +21 -0
- package/src/components/organisms/form/index.js +5 -1
- package/src/components/organisms/navigation/index.js +9 -1
- package/src/components/organisms/search/index.js +0 -1
- package/src/components/organisms/toplist/list/index.js +1 -1
- package/src/components/organisms/toplist/list/list.test.js +30 -0
- package/src/components/pages/body/index.js +22 -5
- package/src/components/pages/tracker/index.js +1 -1
- package/src/constants/settings.js +1 -1
- package/src/helpers/getters.js +10 -6
- package/src/helpers/getters.test.js +1 -3
- package/src/helpers/processor/common.test.js +7 -1
- package/src/helpers/processor/index.js +2 -3
- package/src/helpers/processor/index.test.js +21 -0
- package/src/helpers/schema.js +14 -6
- package/src/helpers/schema.test.js +17 -14
- package/src/hooks/gatsby-img/index.js +1 -1
- package/src/hooks/lazy-image/index.js +23 -11
- package/src/hooks/lazy-image/lazy-image.test.js +39 -0
- package/src/hooks/lazy-picture/index.js +1 -1
- package/src/hooks/link/link.test.js +42 -1
- package/src/hooks/tabs/tab/tab.test.js +41 -0
- package/src/styles/utils/variables/_main.scss +3 -1
- package/tests/envVars.js +1 -1
- package/tests/factories/modules/content.factory.js +6 -3
- package/tests/factories/modules/modules.factory.js +152 -0
- package/tests/factories/modules/schema.factory.js +87 -0
- package/tests/factories/pages/list.factory.js +2 -1
- package/tests/factories/pages/pages.factory.js +192 -0
- package/tests/factories/sections/header.factory.js +8 -2
- package/src/components/atoms/logo/index.js +0 -36
- package/src/components/atoms/logo/logo.module.scss +0 -4
- package/src/components/atoms/logo/logo.stories.js +0 -57
- package/src/components/atoms/logo/logo.test.js +0 -30
- package/src/components/molecules/section/index.js +0 -24
- package/src/components/molecules/section/section.test.js +0 -16
- package/src/components/molecules/sidebar/index.js +0 -25
- package/src/components/molecules/sidebar/sidebar.module.scss +0 -3
- package/src/components/molecules/sidebar/sidebar.test.js +0 -30
|
@@ -6,15 +6,25 @@ import Slide from '~molecules/carousel/default-slide';
|
|
|
6
6
|
import keygen from '~helpers/keygen';
|
|
7
7
|
import styles from './carousel.module.scss';
|
|
8
8
|
|
|
9
|
-
const Carousel = ({
|
|
9
|
+
const Carousel = ({
|
|
10
|
+
page = {},
|
|
11
|
+
module = {},
|
|
12
|
+
settings = {},
|
|
13
|
+
CustomSlideComponent,
|
|
14
|
+
gtmClass = '',
|
|
15
|
+
}) => (
|
|
10
16
|
<div className={styles.carouselContainer}>
|
|
11
17
|
<Slider {...settings} gtmClass={gtmClass}>
|
|
12
|
-
{module.items.map((item) => (
|
|
18
|
+
{module.items.map((item, index) => (
|
|
13
19
|
<div key={keygen()} className={styles.carouselItem}>
|
|
14
20
|
{CustomSlideComponent !== undefined ? (
|
|
15
21
|
<CustomSlideComponent item={item} gtmClass={gtmClass} />
|
|
16
22
|
) : (
|
|
17
|
-
<Slide
|
|
23
|
+
<Slide
|
|
24
|
+
slideTitle={`${page.title}-carousel-${index + 1}`}
|
|
25
|
+
item={item}
|
|
26
|
+
gtmClass={gtmClass}
|
|
27
|
+
/>
|
|
18
28
|
)}
|
|
19
29
|
</div>
|
|
20
30
|
))}
|
|
@@ -23,6 +33,9 @@ const Carousel = ({ module = {}, settings = {}, CustomSlideComponent, gtmClass =
|
|
|
23
33
|
);
|
|
24
34
|
|
|
25
35
|
Carousel.propTypes = {
|
|
36
|
+
page: PropTypes.shape({
|
|
37
|
+
title: PropTypes.string,
|
|
38
|
+
}),
|
|
26
39
|
module: PropTypes.shape({
|
|
27
40
|
items: PropTypes.arrayOf(
|
|
28
41
|
PropTypes.shape({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { navigate } from 'gatsby';
|
|
2
3
|
import { render, cleanup, fireEvent } from '@testing-library/react';
|
|
3
4
|
import '@testing-library/jest-dom/extend-expect';
|
|
4
5
|
|
|
@@ -21,12 +22,17 @@ const setUp = () => {
|
|
|
21
22
|
return { container, getByText };
|
|
22
23
|
};
|
|
23
24
|
describe('cookie consent component', () => {
|
|
24
|
-
test('Children', () => {
|
|
25
|
+
test('Children and declineButton', () => {
|
|
25
26
|
const { container, getByText } = setUp();
|
|
27
|
+
|
|
26
28
|
expect(container.querySelectorAll('div.cookieConsent')).toHaveLength(1);
|
|
29
|
+
|
|
27
30
|
expect(container.querySelectorAll('p')).toHaveLength(1);
|
|
28
31
|
expect(container.querySelectorAll('b')).toHaveLength(1);
|
|
29
32
|
expect(getByText('cookie test')).toBeTruthy();
|
|
33
|
+
const declineButton = getByText('Decline Me');
|
|
34
|
+
fireEvent.click(declineButton);
|
|
35
|
+
expect(navigate).toHaveBeenCalled();
|
|
30
36
|
});
|
|
31
37
|
test('Buttons', () => {
|
|
32
38
|
const { container, getByText } = setUp();
|
|
@@ -29,10 +29,13 @@ describe('Form Component', () => {
|
|
|
29
29
|
test('on change', async () => {
|
|
30
30
|
render(<Form hasButton type="contact" submitUrl="https://submit-form.com" />);
|
|
31
31
|
const input = document.querySelector('input[type="text"]');
|
|
32
|
+
const messageInput = document.querySelector('textarea');
|
|
32
33
|
|
|
33
34
|
await waitFor(() => {
|
|
34
35
|
fireEvent.change(input, { target: { value: 'Mohsen' } });
|
|
36
|
+
fireEvent.change(messageInput, { target: { value: 'EKKK' } });
|
|
35
37
|
expect(input.value).toBe('Mohsen');
|
|
38
|
+
expect(messageInput.value).toBe('EKKK');
|
|
36
39
|
}, 3000);
|
|
37
40
|
});
|
|
38
41
|
|
|
@@ -52,6 +55,24 @@ describe('Form Component', () => {
|
|
|
52
55
|
});
|
|
53
56
|
expect(ApiCall).toHaveBeenCalled();
|
|
54
57
|
});
|
|
58
|
+
|
|
59
|
+
test('handle submit with filled fields', async () => {
|
|
60
|
+
const { container } = render(
|
|
61
|
+
<Form hasButton disabled={false} type="newsletter" submitUrl="https://submit-form.com" />
|
|
62
|
+
);
|
|
63
|
+
const nameInput = document.querySelector('input[type="text"]');
|
|
64
|
+
const emailInput = document.querySelector('input[type="email"]');
|
|
65
|
+
|
|
66
|
+
await waitFor(() => {
|
|
67
|
+
fireEvent.change(nameInput, { target: { value: 'Val' } });
|
|
68
|
+
fireEvent.change(emailInput, { target: { value: 'ejk@sl.com' } });
|
|
69
|
+
|
|
70
|
+
expect(nameInput.value).toBe('Val');
|
|
71
|
+
}, 3000);
|
|
72
|
+
|
|
73
|
+
const formElement = container.querySelector('form');
|
|
74
|
+
fireEvent.submit(formElement);
|
|
75
|
+
});
|
|
55
76
|
});
|
|
56
77
|
afterEach(() => {
|
|
57
78
|
cleanup();
|
|
@@ -12,6 +12,7 @@ const FormComponent = ({
|
|
|
12
12
|
submitUrl = '',
|
|
13
13
|
hasButton = true,
|
|
14
14
|
buttonLabel = 'Submit',
|
|
15
|
+
disabled = true,
|
|
15
16
|
}) => {
|
|
16
17
|
const recaptchaRef = useRef();
|
|
17
18
|
const [state, setState] = useState({
|
|
@@ -19,7 +20,7 @@ const FormComponent = ({
|
|
|
19
20
|
success: false,
|
|
20
21
|
failed: false,
|
|
21
22
|
isValid: true,
|
|
22
|
-
isDisabled:
|
|
23
|
+
isDisabled: disabled,
|
|
23
24
|
name: '',
|
|
24
25
|
email: '',
|
|
25
26
|
message: '',
|
|
@@ -43,7 +44,9 @@ const FormComponent = ({
|
|
|
43
44
|
}
|
|
44
45
|
const handleSubmit = (e) => {
|
|
45
46
|
e.preventDefault();
|
|
47
|
+
|
|
46
48
|
const { name, email, message, isDisabled } = state;
|
|
49
|
+
|
|
47
50
|
if (
|
|
48
51
|
name === '' ||
|
|
49
52
|
email === '' ||
|
|
@@ -171,5 +174,6 @@ FormComponent.propTypes = {
|
|
|
171
174
|
submitUrl: PropTypes.string.isRequired,
|
|
172
175
|
hasButton: PropTypes.bool,
|
|
173
176
|
buttonLabel: PropTypes.string,
|
|
177
|
+
disabled: PropTypes.bool,
|
|
174
178
|
};
|
|
175
179
|
export default FormComponent;
|
|
@@ -33,6 +33,7 @@ const Navigation = ({
|
|
|
33
33
|
},
|
|
34
34
|
sticky = true,
|
|
35
35
|
template,
|
|
36
|
+
children,
|
|
36
37
|
customStyles,
|
|
37
38
|
}) => {
|
|
38
39
|
const navRef = useRef(React.createRef());
|
|
@@ -69,7 +70,12 @@ const Navigation = ({
|
|
|
69
70
|
to="/"
|
|
70
71
|
onClick={onClickHandler}
|
|
71
72
|
>
|
|
72
|
-
<img
|
|
73
|
+
<img
|
|
74
|
+
alt={process.env.GATSBY_SITE_NAME}
|
|
75
|
+
src={logo}
|
|
76
|
+
width={logoWidth}
|
|
77
|
+
height={logoHeight}
|
|
78
|
+
/>
|
|
73
79
|
</Link>
|
|
74
80
|
{showMenu && (
|
|
75
81
|
<>
|
|
@@ -85,6 +91,7 @@ const Navigation = ({
|
|
|
85
91
|
)}
|
|
86
92
|
</NavigationProvider>
|
|
87
93
|
</nav>
|
|
94
|
+
{children}
|
|
88
95
|
</ConditionalWrapper>
|
|
89
96
|
);
|
|
90
97
|
};
|
|
@@ -110,6 +117,7 @@ Navigation.propTypes = {
|
|
|
110
117
|
searchIcon: PropTypes.string,
|
|
111
118
|
hasSearch: PropTypes.bool,
|
|
112
119
|
menu: PropTypes.string,
|
|
120
|
+
children: PropTypes.node,
|
|
113
121
|
options: PropTypes.shape({
|
|
114
122
|
mobile: PropTypes.shape({
|
|
115
123
|
animation: PropTypes.string,
|
|
@@ -11,7 +11,6 @@ import styles from './search.module.scss';
|
|
|
11
11
|
|
|
12
12
|
const SearchForm = ({ className, searchIcon, iconWidth = 24, iconHeight = 24 }) => {
|
|
13
13
|
const { showSearch, setShowSearch, setShowMenu, showMenu } = useContext(NavigationContext);
|
|
14
|
-
|
|
15
14
|
const Search = showSearch ? loadable(() => import('~molecules/search')) : <></>;
|
|
16
15
|
const Operator = showSearch ? (
|
|
17
16
|
loadable(() => import('~atoms/search/autocomplete/operator'))
|
|
@@ -88,7 +88,7 @@ List.propTypes = {
|
|
|
88
88
|
one_liner: PropTypes.string,
|
|
89
89
|
}),
|
|
90
90
|
CustomRow: PropTypes.func,
|
|
91
|
-
hasLoadMoreButton: PropTypes.
|
|
91
|
+
hasLoadMoreButton: PropTypes.string,
|
|
92
92
|
initItemsCount: PropTypes.string,
|
|
93
93
|
loadItemsCount: PropTypes.string,
|
|
94
94
|
pageTemplate: PropTypes.string,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, cleanup, fireEvent } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
4
|
+
import { getListToplistItem } from '~tests/factories/modules/toplist.factory';
|
|
5
|
+
|
|
6
|
+
import List from '.';
|
|
7
|
+
|
|
8
|
+
describe('List', () => {
|
|
9
|
+
test('render list with Load more', () => {
|
|
10
|
+
const { container, getByText } = render(
|
|
11
|
+
<List
|
|
12
|
+
toplist={{ items: getListToplistItem(15) }}
|
|
13
|
+
loadItemsCount="5"
|
|
14
|
+
initItemsCount="5"
|
|
15
|
+
hasLoadMoreButton="1"
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
expect(getByText('Load More')).toBeTruthy();
|
|
19
|
+
const button = container.querySelector('button');
|
|
20
|
+
fireEvent.click(button);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('render list without Load more', () => {
|
|
24
|
+
const { container } = render(<List toplist={{ items: getListToplistItem(5) }} />);
|
|
25
|
+
expect(container.querySelector('button')).toBeFalsy();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
cleanup();
|
|
30
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable no-useless-concat */
|
|
2
|
+
/* eslint-disable no-restricted-globals */
|
|
3
|
+
import React, { useEffect } from 'react';
|
|
2
4
|
import PropTypes from 'prop-types';
|
|
3
|
-
import loadable from '@loadable/component';
|
|
4
5
|
import { getSection } from '~helpers/getters';
|
|
5
6
|
import Header from '~molecules/header';
|
|
6
7
|
import Main from '~molecules/main';
|
|
@@ -17,16 +18,32 @@ function Body({ pageContext, children }) {
|
|
|
17
18
|
const main = getBodySection('main');
|
|
18
19
|
const navigation = getBodySection('navigation');
|
|
19
20
|
const footer = getBodySection('footer');
|
|
20
|
-
const sidebar = getBodySection('sidebar');
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!process.env.CANARY_TOKEN) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (
|
|
28
|
+
document.domain !== `prelive.${process.env.GATSBY_SITE_NAME}` ||
|
|
29
|
+
document.domain !== process.env.GATSBY_SITE_NAME ||
|
|
30
|
+
document.domain !== `www.${process.env.GATSBY_SITE_NAME}`
|
|
31
|
+
) {
|
|
32
|
+
const l = location.href;
|
|
33
|
+
const r = document.referrer;
|
|
34
|
+
const img = new Image();
|
|
35
|
+
img.src = `${'http://canarytokens.com/' + `[${process.env.CANARY_TOKEN}].jpg?l=`}${encodeURI(
|
|
36
|
+
l
|
|
37
|
+
)}&r=${encodeURI(r)}`;
|
|
38
|
+
}
|
|
39
|
+
}, []);
|
|
40
|
+
|
|
23
41
|
return (
|
|
24
42
|
<>
|
|
25
43
|
{navigation && <Navigation template={template} section={navigation} />}
|
|
26
44
|
{!is404 && <Header section={pageContext} />}
|
|
27
45
|
{main && !children && <Main section={main} pageContext={pageContext} />}
|
|
28
46
|
{children && <main>{children}</main>}
|
|
29
|
-
{Sidebar && <Sidebar section={sidebar} />}
|
|
30
47
|
<ScrollToTop />
|
|
31
48
|
<Footer template={template} section={footer} />
|
|
32
49
|
<CookieConsent />
|
|
@@ -6,8 +6,8 @@ export default {
|
|
|
6
6
|
},
|
|
7
7
|
keep_page_extra_fields: {
|
|
8
8
|
operator: {
|
|
9
|
-
'Irishluck.ie': true, // needed for card background image
|
|
10
9
|
'norskespilleautomater.com': true, // needed for inoperative / placeholder fields
|
|
10
|
+
'Irishluck.ie': true, // needed for card background image
|
|
11
11
|
'playcasino.co.za': true,
|
|
12
12
|
},
|
|
13
13
|
article: {
|
package/src/helpers/getters.js
CHANGED
|
@@ -90,6 +90,15 @@ export function image(filename, width, height, fit = 'cover') {
|
|
|
90
90
|
return `${cloudFrontUrl}/${Buffer.from(imageRequest).toString('base64')}`;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
export function getImageFilename(src) {
|
|
94
|
+
const srcArr = src?.substring(src?.lastIndexOf('/') + 1)?.split('.');
|
|
95
|
+
if (!srcArr.length) {
|
|
96
|
+
return '';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return srcArr[0];
|
|
100
|
+
}
|
|
101
|
+
|
|
93
102
|
export function getImageExtension(filename) {
|
|
94
103
|
return filename && filename.split('.').pop();
|
|
95
104
|
}
|
|
@@ -126,12 +135,7 @@ export function getPageImage(page) {
|
|
|
126
135
|
return page.relation.thumbnail_filename;
|
|
127
136
|
}
|
|
128
137
|
}
|
|
129
|
-
if (page.type === '
|
|
130
|
-
if (page.banner) {
|
|
131
|
-
return imagePrettyUrl(page.banner);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
if (['operator', 'software_provider'].includes(page.type) && page.relation.logo) {
|
|
138
|
+
if (page.type === 'software_provider' && page.relation.logo) {
|
|
135
139
|
return imagePrettyUrl(page.relation.logo);
|
|
136
140
|
}
|
|
137
141
|
if (page.banner) {
|
|
@@ -20,9 +20,7 @@ describe('Getters Helper', () => {
|
|
|
20
20
|
|
|
21
21
|
test('getPageTitle()', () => {
|
|
22
22
|
window.location.search = 's=hello';
|
|
23
|
-
expect(Getters.getPageTitle({ path: 's' })).toEqual(
|
|
24
|
-
'You searched for hello - norskespilleautomater.com'
|
|
25
|
-
);
|
|
23
|
+
expect(Getters.getPageTitle({ path: 's' })).toEqual('You searched for hello - Irishluck.ie');
|
|
26
24
|
});
|
|
27
25
|
|
|
28
26
|
test('getExtraField()', () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { groupBy, removeDuplicates } from './common';
|
|
1
|
+
import { groupBy, removeDuplicates, clonePageForCards } from './common';
|
|
2
2
|
import getPageDataList from '~tests/factories/pages/list.factory';
|
|
3
3
|
|
|
4
4
|
describe('Common Helper', () => {
|
|
@@ -18,4 +18,10 @@ describe('Common Helper', () => {
|
|
|
18
18
|
const filtered = removeDuplicates(array, 'id');
|
|
19
19
|
expect(filtered).toHaveLength(2);
|
|
20
20
|
});
|
|
21
|
+
|
|
22
|
+
test('ClonePageForCards', () => {
|
|
23
|
+
const data = getPageDataList(2);
|
|
24
|
+
const result = clonePageForCards(data, 'comparison_table');
|
|
25
|
+
expect(result?.relation?.bonus?.deposit_methods).toBeFalsy();
|
|
26
|
+
});
|
|
21
27
|
});
|
|
@@ -55,7 +55,7 @@ export function processSitemapPages(pages, markets) {
|
|
|
55
55
|
return pageListByMarket;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
function transform(response) {
|
|
58
|
+
export function transform(response) {
|
|
59
59
|
const transformed = {};
|
|
60
60
|
Object.keys(response.site_markets).forEach((siteMarket) => {
|
|
61
61
|
const language = siteMarket.split('_')[1];
|
|
@@ -74,7 +74,7 @@ function transform(response) {
|
|
|
74
74
|
return transformed;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
function processSections(sections, skipPost = false) {
|
|
77
|
+
export function processSections(sections, skipPost = false) {
|
|
78
78
|
Object.keys(sections).forEach((sectionKey) => {
|
|
79
79
|
if (skipPost && sectionKey.includes('post_main')) {
|
|
80
80
|
return;
|
|
@@ -96,7 +96,6 @@ function processSections(sections, skipPost = false) {
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
});
|
|
99
|
-
|
|
100
99
|
return sections;
|
|
101
100
|
}
|
|
102
101
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { transform, processExtraFields } from './index';
|
|
2
|
+
import pages from '~tests/factories/pages/pages.factory.js';
|
|
3
|
+
|
|
4
|
+
describe('Index Processor', () => {
|
|
5
|
+
test('Transform', () => {
|
|
6
|
+
const results = transform(pages);
|
|
7
|
+
expect(results?.za_en?.page).toBeTruthy();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('processExtraFields', () => {
|
|
11
|
+
const extraFields = {
|
|
12
|
+
logos: { value: 339, type: 'default' },
|
|
13
|
+
};
|
|
14
|
+
processExtraFields(extraFields);
|
|
15
|
+
expect(extraFields?.logos).toBe(339);
|
|
16
|
+
});
|
|
17
|
+
test('processExtraFields null', () => {
|
|
18
|
+
const result = processExtraFields(false);
|
|
19
|
+
expect(result).toBeFalsy();
|
|
20
|
+
});
|
|
21
|
+
});
|
package/src/helpers/schema.js
CHANGED
|
@@ -98,10 +98,11 @@ export function generateSchemaObject(schema) {
|
|
|
98
98
|
}, {});
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
export function breadcrumbsSchema(breadcrumbs) {
|
|
101
|
+
export function breadcrumbsSchema(breadcrumbs, path) {
|
|
102
102
|
const schema = {
|
|
103
103
|
'@context': 'https://schema.org',
|
|
104
104
|
'@type': 'BreadcrumbList',
|
|
105
|
+
'@id': `${getUrl(path)}#breadcrumblist`,
|
|
105
106
|
itemListElement: breadcrumbs.map((breadcrumb, index) => ({
|
|
106
107
|
'@type': 'ListItem',
|
|
107
108
|
name: breadcrumb.path,
|
|
@@ -177,6 +178,7 @@ export function organizationSchema(page, pageImage) {
|
|
|
177
178
|
const schema = {
|
|
178
179
|
'@context': 'https://schema.org',
|
|
179
180
|
'@type': 'Organization',
|
|
181
|
+
'@id': `${getUrl(page.path)}#organization`,
|
|
180
182
|
url: process.env.GATSBY_SITE_URL,
|
|
181
183
|
name: page.siteSchema?.site_name,
|
|
182
184
|
logo: pageImage,
|
|
@@ -188,13 +190,14 @@ export function organizationSchema(page, pageImage) {
|
|
|
188
190
|
return JSON.stringify(generateSchemaObject(schema));
|
|
189
191
|
}
|
|
190
192
|
|
|
191
|
-
export function moduleSchemas(modules) {
|
|
192
|
-
const schema = modules.map((module) => {
|
|
193
|
+
export function moduleSchemas(modules, path) {
|
|
194
|
+
const schema = modules.map((module, index) => {
|
|
193
195
|
switch (module.name) {
|
|
194
196
|
case 'faq': {
|
|
195
197
|
const moduleSchema = {
|
|
196
198
|
'@context': 'https://schema.org',
|
|
197
199
|
'@type': 'FAQPage',
|
|
200
|
+
'@id': `${getUrl(path)}#faqpage${index === 0 ? '' : index}`,
|
|
198
201
|
mainEntity: module.items?.map((item) => ({
|
|
199
202
|
'@type': 'Question',
|
|
200
203
|
acceptedAnswer: {
|
|
@@ -233,7 +236,7 @@ export function templateSchemas(page, pageImage) {
|
|
|
233
236
|
page.siteInfo?.site_name ||
|
|
234
237
|
process.env.GATSBY_SITE_NAME,
|
|
235
238
|
logo:
|
|
236
|
-
`${process.env.IMAGE_CDN_URL}/${page.siteInfo
|
|
239
|
+
(page.siteInfo?.site_logo && `${process.env.IMAGE_CDN_URL}/${page.siteInfo.site_logo}`) ||
|
|
237
240
|
page.featured_image_object?.url ||
|
|
238
241
|
pageImage,
|
|
239
242
|
},
|
|
@@ -243,6 +246,7 @@ export function templateSchemas(page, pageImage) {
|
|
|
243
246
|
const schema = {
|
|
244
247
|
'@context': 'https://schema.org',
|
|
245
248
|
'@type': 'Article',
|
|
249
|
+
'@id': `${getUrl(page.path)}#article`,
|
|
246
250
|
url: getUrl(page.path),
|
|
247
251
|
headline: page.title,
|
|
248
252
|
datePublished: page.created_at,
|
|
@@ -260,6 +264,7 @@ export function templateSchemas(page, pageImage) {
|
|
|
260
264
|
const schema = {
|
|
261
265
|
'@context': 'https://schema.org',
|
|
262
266
|
'@type': 'Review',
|
|
267
|
+
'@id': `${getUrl(page.path)}#review`,
|
|
263
268
|
name: page.relation?.name || '',
|
|
264
269
|
reviewBody: page.extra_fields?.operator_summary || '',
|
|
265
270
|
itemReviewed: {
|
|
@@ -284,6 +289,7 @@ export function templateSchemas(page, pageImage) {
|
|
|
284
289
|
const schema = {
|
|
285
290
|
'@context': 'https://schema.org',
|
|
286
291
|
'@type': 'VideoGame',
|
|
292
|
+
'@id': `${getUrl(page.path)}#videogame`,
|
|
287
293
|
url: getUrl(page.path),
|
|
288
294
|
name: page.relation?.name || '',
|
|
289
295
|
description: page.extra_fields?.game_summary || '',
|
|
@@ -319,12 +325,14 @@ export function schemaGenerator(page = {}, pageImage) {
|
|
|
319
325
|
// Page Schema
|
|
320
326
|
page.seo_json_schema,
|
|
321
327
|
// Breadcrumbs Schema
|
|
322
|
-
page.breadcrumbs?.length ? breadcrumbsSchema(page.breadcrumbs) : null,
|
|
328
|
+
page.breadcrumbs?.length ? breadcrumbsSchema(page.breadcrumbs, page.path) : null,
|
|
323
329
|
// Modules Schemas
|
|
324
330
|
webPageSchema(page, pageImage),
|
|
325
331
|
organizationSchema(page, pageImage),
|
|
326
332
|
templateSchemas(page, pageImage),
|
|
327
|
-
...(page.sections?.main?.modules
|
|
333
|
+
...(page.sections?.main?.modules
|
|
334
|
+
? moduleSchemas(page.sections.main.modules, page.path)
|
|
335
|
+
: [null]),
|
|
328
336
|
];
|
|
329
337
|
|
|
330
338
|
return jsonSchema;
|
|
@@ -99,12 +99,12 @@ describe('Schema Helper', () => {
|
|
|
99
99
|
expect(json.author.foundingDate).toEqual('01/02/03');
|
|
100
100
|
if (isIL || isNSA) {
|
|
101
101
|
expect(json.author.publishingPrinciples).toEqual(
|
|
102
|
-
|
|
103
|
-
? 'https://www.
|
|
104
|
-
: 'https://www.
|
|
102
|
+
isNSA
|
|
103
|
+
? 'https://www.norskespilleautomater.com/om-oss/prinsipper'
|
|
104
|
+
: 'https://www.irishluck.ie/editorial-principles'
|
|
105
105
|
);
|
|
106
106
|
} else {
|
|
107
|
-
expect(json.author.publishingPrinciples).toEqual(
|
|
107
|
+
expect(json.author.publishingPrinciples).toEqual(null);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
expect(Object.prototype.toString.call(json.author.logo)).toEqual('[object Object]');
|
|
@@ -175,16 +175,19 @@ describe('Schema Helper', () => {
|
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
test('moduleSchemas(faq)', () => {
|
|
178
|
-
const output = Schema.moduleSchemas(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
178
|
+
const output = Schema.moduleSchemas(
|
|
179
|
+
[
|
|
180
|
+
{
|
|
181
|
+
name: 'faq',
|
|
182
|
+
items: [
|
|
183
|
+
{ answer: 'Answer A', question: 'Question A' },
|
|
184
|
+
{ answer: 'Answer B', question: 'Question B' },
|
|
185
|
+
{ answer: 'Answer C', question: 'Question C' },
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
'/'
|
|
190
|
+
)[0];
|
|
188
191
|
|
|
189
192
|
const json = parseCheckSchema(output);
|
|
190
193
|
expect(json['@type']).toEqual('FAQPage');
|
|
@@ -10,7 +10,7 @@ export default function LazyImage({
|
|
|
10
10
|
style = {},
|
|
11
11
|
className,
|
|
12
12
|
src = '#',
|
|
13
|
-
alt = '',
|
|
13
|
+
alt = 'missing alt',
|
|
14
14
|
defaultImg,
|
|
15
15
|
loading = 'lazy',
|
|
16
16
|
}) {
|
|
@@ -54,16 +54,28 @@ export default function LazyImage({
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
return (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
<>
|
|
58
|
+
<img
|
|
59
|
+
src={src}
|
|
60
|
+
loading={loading}
|
|
61
|
+
className={className}
|
|
62
|
+
height={height}
|
|
63
|
+
width={width}
|
|
64
|
+
alt={alt}
|
|
65
|
+
style={style}
|
|
66
|
+
onError={() => setErrorImage(true)}
|
|
67
|
+
/>
|
|
68
|
+
<noscript>
|
|
69
|
+
<img
|
|
70
|
+
src={src}
|
|
71
|
+
className={className}
|
|
72
|
+
height={height}
|
|
73
|
+
width={width}
|
|
74
|
+
alt={alt}
|
|
75
|
+
style={style}
|
|
76
|
+
/>
|
|
77
|
+
</noscript>
|
|
78
|
+
</>
|
|
67
79
|
);
|
|
68
80
|
}
|
|
69
81
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, cleanup } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
4
|
+
import LazyImage from '.';
|
|
5
|
+
|
|
6
|
+
describe('LazyImage function', () => {
|
|
7
|
+
test('LazyImage defaultImg', () => {
|
|
8
|
+
const { container } = render(
|
|
9
|
+
<LazyImage
|
|
10
|
+
src={null}
|
|
11
|
+
defaultImg={<img src="https://cdn.irishluck.ie/jackpot-village-logo-9.png" alt="test" />}
|
|
12
|
+
/>
|
|
13
|
+
);
|
|
14
|
+
expect(container.querySelector('img')).toBeTruthy();
|
|
15
|
+
expect(container.querySelector('img')).toHaveAttribute(
|
|
16
|
+
'src',
|
|
17
|
+
'https://cdn.irishluck.ie/jackpot-village-logo-9.png'
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('LazyImage mock function inisNativeImageLazyLoadingSupported', () => {
|
|
22
|
+
// eslint-disable-next-line global-require
|
|
23
|
+
const func = require('../../helpers/device-detect');
|
|
24
|
+
func.isNativeImageLazyLoadingSupported = jest.fn(() => true);
|
|
25
|
+
const { container } = render(
|
|
26
|
+
<LazyImage src="https://cdn.irishluck.ie/jackpot-village-logo-9.png" />
|
|
27
|
+
);
|
|
28
|
+
expect(container.querySelector('img')).toBeTruthy();
|
|
29
|
+
expect(container.querySelector('img')).toHaveAttribute(
|
|
30
|
+
'src',
|
|
31
|
+
'https://cdn.irishluck.ie/jackpot-village-logo-9.png'
|
|
32
|
+
);
|
|
33
|
+
expect(container.querySelector('img')).toHaveAttribute('loading', 'lazy');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
cleanup();
|
|
39
|
+
});
|