gatsby-core-theme 30.0.104 → 30.0.105

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 CHANGED
@@ -1,3 +1,22 @@
1
+ ## [30.0.105](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/compare/v30.0.104...v30.0.105) (2024-04-03)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * added required keys to the WebPage schema ([0372ef1](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/0372ef1f55935ece04f7d2b785a926ce4f355ec6))
7
+ * breadcrumbs ([6f7f7fc](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/6f7f7fc47111c6fb6c304ac4b305adf060786798))
8
+ * fixed tests for the schema ([54d0c14](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/54d0c14f6abede9a8461d25b12e9d0332e2c6e62))
9
+ * increased test coverage ([51cb07f](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/51cb07fd0d97b01a58f9afe86ff7fdeda6a6c5fa))
10
+ * remove continue reading link from author box description ([eae0f9a](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/eae0f9a2516dc8e8bc708baba8ecafafedca0f5c))
11
+ * update breadcrumbs translations ([0289c66](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/0289c66b97801e32b885e8a3e110ec3bc43ce4c8))
12
+ * update tests ([f15a058](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/f15a0582057c413f839211e0c0107cc65bd4b448))
13
+
14
+
15
+ * Merge branch 'tm-4187-webpage-schema' into 'master' ([04ff989](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/04ff989b0fb0b43e8e1c6f7fb77be6f6cbcf38b7))
16
+ * Merge remote-tracking branch 'origin' into tm-4187-webpage-schema ([f080656](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/f080656adc8e0c9ce6bb1dcd94f6c650f329d6c7))
17
+ * Merge branch 'tm-4223-breadcrumbs' into 'master' ([a53736d](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/a53736d18d9f8dddf543f34a65893db6febc6c06))
18
+ * Merge branch 'tm-4178-author-box-changes' into 'master' ([ca1e276](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/ca1e276bb2da842e138527a0da64adffe111e923))
19
+
1
20
  ## [30.0.104](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/compare/v30.0.103...v30.0.104) (2024-04-02)
2
21
 
3
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "30.0.104",
3
+ "version": "30.0.105",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -1,14 +1,11 @@
1
1
  import React, { useContext, useRef, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { FaArrowRight } from '@react-icons/all-files/fa/FaArrowRight';
4
3
  import { translate } from '~helpers/getters';
5
4
  import styles from './author-description.module.scss';
6
- import Link from '~hooks/link';
7
5
  import { Context } from '~context/MainProvider';
8
6
 
9
7
  export default function AuthorDescription({
10
8
  author,
11
- contReadIcon = <FaArrowRight title="Right-pointing Arrow Icon" />,
12
9
  template = '',
13
10
  readMore = false,
14
11
  maximumLength = 30,
@@ -45,16 +42,6 @@ export default function AuthorDescription({
45
42
  : author?.biography,
46
43
  }}
47
44
  />
48
- {author?.profile_page_path && (
49
- <Link
50
- to={author?.profile_page_path}
51
- title={author?.name}
52
- className={`${styles.readMore || ''} author-gtm`}
53
- >
54
- {translate(translations, 'cont_read', 'continue reading')}
55
- {contReadIcon}
56
- </Link>
57
- )}
58
45
  </div>
59
46
  );
60
47
  }
@@ -66,7 +53,6 @@ AuthorDescription.propTypes = {
66
53
  expertise: PropTypes.arrayOf(PropTypes.string),
67
54
  profile_page_path: PropTypes.string,
68
55
  }).isRequired,
69
- contReadIcon: PropTypes.node,
70
56
  template: PropTypes.string,
71
57
  readMore: PropTypes.bool,
72
58
  maximumLength: PropTypes.number,
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import { imagePrettyUrl, getAltText, translate } from '~helpers/getters';
4
4
  import styles from './author-details.module.scss';
5
5
  import LazyImage from '~hooks/lazy-image';
6
+ import Link from '~hooks/link';
6
7
  import socialIcons from '../icons/socialIcons';
7
8
  import FactCheckIcon from '../../../../images/icons/fact-check';
8
9
  import { Context } from '~context/MainProvider';
@@ -29,10 +30,10 @@ export default function AuthorDetails({
29
30
  />
30
31
  )}
31
32
  <div className={styles.information || ''}>
32
- <p className={styles.name || ''}>
33
+ <Link to={author?.profile_page_path} className={`${styles.name || ''} author-gtm`}>
33
34
  <span>{author?.name}</span>
34
35
  <FactCheckIcon width={verifiedIconWidth} height={verifiedIconHeight} color="#457BF9" />
35
- </p>
36
+ </Link>
36
37
  <div className={styles.ribbonAndExpert}>
37
38
  {author?.author_title && <p className={styles.title || ''}>{author?.author_title}</p>}
38
39
  {author?.ribbon_label && ribbon && (
@@ -87,6 +88,7 @@ AuthorDetails.propTypes = {
87
88
  ribbon_label: PropTypes.string,
88
89
  experience: PropTypes.string,
89
90
  pages_count: PropTypes.string,
91
+ profile_page_path: PropTypes.string,
90
92
  }),
91
93
  width: PropTypes.number,
92
94
  height: PropTypes.number,
@@ -14,7 +14,6 @@ describe('author box component', () => {
14
14
  expect(getByText('Casino Specialist')).toBeTruthy();
15
15
  expect(container.querySelectorAll('.contactLinks a')).toBeTruthy();
16
16
  expect(container.querySelectorAll('.socialIcons a')).toBeTruthy();
17
- expect(getByText('continue reading')).toBeTruthy();
18
17
  });
19
18
 
20
19
  test('render with read more ', async () => {
@@ -14,7 +14,6 @@ describe('author box component', () => {
14
14
  expect(getByText('Casino Specialist')).toBeTruthy();
15
15
  expect(container.querySelectorAll('.contactLinks a')).toBeTruthy();
16
16
  expect(container.querySelectorAll('.socialIcons a')).toBeTruthy();
17
- expect(getByText('continue reading')).toBeTruthy();
18
17
  });
19
18
 
20
19
  test('render with read more ', async () => {
@@ -14,7 +14,6 @@ describe('author box component', () => {
14
14
  expect(getByText('Casino Specialist')).toBeTruthy();
15
15
  expect(container.querySelectorAll('.contactLinks a')).toBeTruthy();
16
16
  expect(container.querySelectorAll('.socialIcons a')).toBeTruthy();
17
- expect(getByText('continue reading')).toBeTruthy();
18
17
  });
19
18
 
20
19
  test('render with read more ', async () => {
@@ -54,13 +54,7 @@ describe('Show Breadcrumbs in a page', () => {
54
54
  expect(getByText('Home').getAttribute('href')).toEqual('/');
55
55
  expect(getByText('Alternative title')).toBeTruthy();
56
56
  });
57
- test('Translation for Home available', () => {
58
- const page = {
59
- template: 'operator_review',
60
- };
61
- const { getByText } = renderComponent(page);
62
- expect(getByText('Sample Casino')).toBeTruthy();
63
- });
57
+
64
58
  test('Page category available', () => {
65
59
  const page = {
66
60
  categories: [
@@ -5,7 +5,7 @@ import Link from '~hooks/link';
5
5
 
6
6
  import styles from './breadcrumbs.module.scss';
7
7
  import keygen from '~helpers/keygen';
8
- import { translate } from '~helpers/getters';
8
+ import { getHomeBreadcrumbs } from '~helpers/getters';
9
9
  import { Context } from '~context/MainProvider';
10
10
 
11
11
  function Breadcrumbs({ page, separator = <span> / </span>, markets }) {
@@ -19,13 +19,8 @@ function Breadcrumbs({ page, separator = <span> / </span>, markets }) {
19
19
  return <></>;
20
20
  }
21
21
  const isPPC = page?.template === 'ppc';
22
- const home = translate(
23
- translations,
24
- page.categories?.length
25
- ? `home_${page.template}_${page.categories[0].short_name}`
26
- : `home_${page.template}`,
27
- translate(translations, 'Home', 'Home')
28
- );
22
+
23
+ const home = getHomeBreadcrumbs(page, translations);
29
24
 
30
25
  return (
31
26
  <ol className={styles.breadcrumbs || ''}>
@@ -74,6 +69,7 @@ Breadcrumbs.propTypes = {
74
69
  vanity_label: PropTypes.string,
75
70
  translations: PropTypes.shape({}),
76
71
  template: PropTypes.string,
72
+ type: PropTypes.string,
77
73
  categories: PropTypes.arrayOf({
78
74
  short_name: PropTypes.string,
79
75
  }),
@@ -359,6 +359,19 @@ export function translate(translations, key, defaultValue = '') {
359
359
  return defaultValue;
360
360
  }
361
361
 
362
+ export function getHomeBreadcrumbs(page, translations) {
363
+ const home = translate(
364
+ translations,
365
+ (page.categories?.length > 0 &&
366
+ translations[`home_${page.template}_${page.categories[0].short_name}`] !== undefined)
367
+ ? `home_${page.template}_${page.categories[0].short_name}`
368
+ : `home_${page.type}`,
369
+ translate(translations, 'Home', 'Home')
370
+ );
371
+
372
+ return home;
373
+ }
374
+
362
375
  // This part of the code, help us to add operator related to the page as the first item in the comparison table automatically
363
376
  // example: if we are on the operator review page(Rizk) that should be first in the comparison table
364
377
  // First, we check if we have that item in the array, if that item is in the array, we check its position
@@ -266,6 +266,56 @@ describe('Getters Helper', () => {
266
266
  expect(Getters.translate(object, 'foo', 'bar')).toEqual('bar');
267
267
  });
268
268
 
269
+ test('getHomeBreadcrumbs() with categories', () => {
270
+ const page = {
271
+ categories: [{ short_name: 'category1' }],
272
+ template: 'template1',
273
+ type: 'type1',
274
+ };
275
+ const translations = {
276
+ home_template1_category1: 'Template 1 Category 1 Home',
277
+ Home: 'Home',
278
+ };
279
+ expect(Getters.getHomeBreadcrumbs(page, translations)).toEqual('Template 1 Category 1 Home');
280
+ });
281
+
282
+ test('getHomeBreadcrumbs() with categories but with no category translations', () => {
283
+ const page = {
284
+ categories: [{ short_name: 'category2' }, { short_name: 'category1' }],
285
+ template: 'template1',
286
+ type: 'type1',
287
+ };
288
+ const translations = {
289
+ home_type1_category1: 'Template 1 Category 1 Home',
290
+ home_type1: 'Template 1',
291
+ Home: 'Home',
292
+ };
293
+ expect(Getters.getHomeBreadcrumbs(page, translations)).toEqual('Template 1');
294
+ });
295
+
296
+ test('getHomeBreadcrumbs() without categories', () => {
297
+ const page = {
298
+ categories: [],
299
+ type: 'type1',
300
+ };
301
+ const translations = {
302
+ home_type1: 'Type 1 Home',
303
+ Home: 'Home',
304
+ };
305
+ expect(Getters.getHomeBreadcrumbs(page, translations)).toEqual('Type 1 Home');
306
+ });
307
+
308
+ test('getHomeBreadcrumbs() with missing translation', () => {
309
+ const page = {
310
+ categories: [],
311
+ type: 'type2',
312
+ };
313
+ const translations = {
314
+ Home: 'Home',
315
+ };
316
+ expect(Getters.getHomeBreadcrumbs(page, translations)).toEqual('Home');
317
+ });
318
+
269
319
  const module = {
270
320
  items: [
271
321
  {
@@ -318,7 +318,7 @@ export default {
318
318
  }
319
319
 
320
320
  // add reviewer object to page
321
- if (page.reviewer_id !== null && Object.values(data.authors).length) {
321
+ if (page.reviewer_id !== null && data.authors[page.reviewer_id]) {
322
322
  transformedPages[market][pageType][index].reviewer = data.authors[page.reviewer_id];
323
323
  }
324
324
 
@@ -185,7 +185,26 @@ export function webPageSchema(page, pageImage) {
185
185
  url: `${process.env.GATSBY_SITE_URL}`,
186
186
  inLanguage: getLanguage(page?.language),
187
187
  },
188
- author: {
188
+ reviewedBy: page?.reviewer_id
189
+ ? {
190
+ '@type': 'Person',
191
+ name: page?.reviewer?.name,
192
+ jobTitle: page?.reviewer?.author_title,
193
+ image: page?.reviewer?.image_object?.url,
194
+ email: page?.reviewer?.email_address,
195
+ nationality: {
196
+ '@type': 'Country',
197
+ name: page?.reviewer?.country?.name,
198
+ },
199
+
200
+ knowsAbout: page?.reviewer?.knows_abouts?.map((item) => ({
201
+ '@type': item?.type,
202
+ name: item?.name,
203
+ sameAs: item?.links.map((link) => link?.link).filter((link) => link),
204
+ })),
205
+ }
206
+ : '',
207
+ publisher: {
189
208
  '@type': 'Organization',
190
209
  name: page?.siteSchema?.site_name || '',
191
210
  alternateName: page?.siteSchema?.alias_site_name || '',
@@ -207,6 +226,23 @@ export function webPageSchema(page, pageImage) {
207
226
  .filter((socialLink) => socialLink),
208
227
  ...(page?.knowsAbout ? { knowsAbout: page?.knowsAbout } : {}),
209
228
  },
229
+ author: {
230
+ '@type': 'Person',
231
+ name: page?.author?.name,
232
+ jobTitle: page?.author?.author_title,
233
+ image: page?.author?.image_object?.url,
234
+ email: page?.author?.email_address,
235
+ nationality: {
236
+ '@type': 'Country',
237
+ name: page?.author?.country?.name,
238
+ },
239
+
240
+ knowsAbout: page?.author?.knows_abouts?.map((item) => ({
241
+ '@type': item?.type,
242
+ name: item?.name,
243
+ sameAs: item?.links.map((link) => link?.link).filter((link) => link),
244
+ })),
245
+ },
210
246
  };
211
247
  if (speakAbleModules.length > 0) {
212
248
  schema['@speakAbleModules'] = speakAbleModules.map((module) => JSON.parse(module));
@@ -285,6 +321,7 @@ export function templateSchemas(page, pageImage) {
285
321
  '@type': 'Person',
286
322
  name: page.author?.name?.substring(0, 100),
287
323
  url: getUrl(page.author?.profile_page_path || '/'),
324
+ ...(page?.author?.knowsAbout ? { knowsAbout: page?.author?.knowsAbout } : {}),
288
325
  },
289
326
  publisher: {
290
327
  '@type': 'Organization',
@@ -118,18 +118,75 @@ describe('Schema Helper', () => {
118
118
  created_at: '01/01/01',
119
119
  updated_at: '02/02/02',
120
120
  seo_keywords: ['keyword_a', 'keyword_b'],
121
- authors: [
122
- {
123
- profile_page_path: 'author_a/author_page',
124
- email_address: 'email_a@email.com',
125
- name: 'Author_A',
121
+ author: {
122
+ profile_page_path: 'author_a/author_page',
123
+ email_address: 'email_a@email.com',
124
+ name: 'Author_A',
125
+ image_object: {
126
+ url: 'author_image.jpg',
126
127
  },
127
- {
128
- profile_page_path: 'author_b/author_page',
129
- email_address: 'email_b@email.com',
130
- name: 'Author_B',
128
+ knows_abouts: [
129
+ {
130
+ '@type': 'Thing',
131
+ name: 'Ireland',
132
+ links: [
133
+ {
134
+ link: 'www.test.com',
135
+ },
136
+ {
137
+ link: 'www.test2.com',
138
+ },
139
+ ],
140
+ },
141
+ {
142
+ '@type': 'Thing',
143
+ name: 'South Africa',
144
+ links: [
145
+ {
146
+ link: 'www.test.com',
147
+ },
148
+ {
149
+ link: 'www.test2.com',
150
+ },
151
+ ],
152
+ },
153
+ ],
154
+ },
155
+ reviewer_id: 112,
156
+ reviewer: {
157
+ profile_page_path: 'reviewer_a/author_page',
158
+ email_address: 'email_a@email.com',
159
+ name: 'Reviewer_A',
160
+ image_object: {
161
+ url: 'reviewer_image.jpg',
131
162
  },
132
- ],
163
+ knows_abouts: [
164
+ {
165
+ '@type': 'Thing',
166
+ name: 'Ireland',
167
+ links: [
168
+ {
169
+ link: 'www.test.com',
170
+ },
171
+ {
172
+ link: 'www.test2.com',
173
+ },
174
+ ],
175
+ },
176
+ {
177
+ '@type': 'Thing',
178
+ name: 'South Africa',
179
+ links: [
180
+ {
181
+ link: 'www.test.com',
182
+ },
183
+ {
184
+ link: 'www.test2.com',
185
+ },
186
+ ],
187
+ },
188
+ ],
189
+ },
133
190
  siteSchema: {
134
191
  site_name: 'Site Name',
135
192
  alias_site_name: 'Alias Site Name',
@@ -151,56 +208,26 @@ describe('Schema Helper', () => {
151
208
  expect(json.inLanguage).toEqual('site_lang');
152
209
  expect(json.datePublished).toEqual('01/01/01');
153
210
  expect(json.dateModified).toEqual('02/02/02');
154
-
155
211
  expect(Object.prototype.toString.call(json.isPartOf)).toEqual('[object Object]');
156
212
  expect(json.isPartOf['@type']).toEqual('WebSite');
157
213
  expect(json.isPartOf['@id']).toEqual(`${process.env.GATSBY_SITE_URL}#website`);
158
214
  expect(json.isPartOf.url).toEqual(`${process.env.GATSBY_SITE_URL}`);
159
215
  expect(json.isPartOf.inLanguage).toEqual('site_lang');
160
-
161
216
  expect(Object.prototype.toString.call(json.primaryImageOfPage)).toEqual('[object Object]');
162
217
  expect(json.primaryImageOfPage['@type']).toEqual('ImageObject');
163
218
  expect(json.primaryImageOfPage['@id']).toEqual(`${getUrl('web_page')}#primaryimage`);
164
219
  expect(json.primaryImageOfPage.url).toEqual(pageImage);
165
220
  expect(json.primaryImageOfPage.inLanguage).toEqual('site_lang');
166
-
167
221
  expect(Object.prototype.toString.call(json.author)).toEqual('[object Object]');
168
- expect(json.author['@type']).toEqual('Organization');
169
- expect(json.author.name).toEqual('Site Name');
170
- expect(json.author.alternateName).toEqual('Alias Site Name');
171
- expect(json.author.foundingDate).toEqual('01/02/03');
172
- expect(json.author.publishingPrinciples).toEqual(undefined);
173
-
174
- expect(Object.prototype.toString.call(json.author.logo)).toEqual('[object Object]');
175
- expect(json.author.logo['@type']).toEqual('ImageObject');
176
- expect(json.author.logo.url).toEqual(pageImage);
177
-
178
- expect(Object.prototype.toString.call(json.author.contactPoint)).toEqual('[object Array]');
179
- expect(json.author.contactPoint).toHaveLength(2);
180
- expect(Object.prototype.toString.call(json.author.contactPoint[0])).toEqual('[object Object]');
181
- expect(Object.prototype.toString.call(json.author.contactPoint[1])).toEqual('[object Object]');
182
- expect(json.author.contactPoint[0]['@type']).toEqual('ContactPoint');
183
- expect(json.author.contactPoint[1]['@type']).toEqual('ContactPoint');
184
- expect(json.author.contactPoint[0].contactType).toEqual('Author');
185
- expect(json.author.contactPoint[1].contactType).toEqual('Author');
186
- expect(json.author.contactPoint[0].url).toEqual(`${getUrl('/')}author_a/author_page`);
187
- expect(json.author.contactPoint[1].url).toEqual(`${getUrl('/')}author_b/author_page`);
188
- expect(json.author.contactPoint[0].name).toEqual('Author_A');
189
- expect(json.author.contactPoint[1].name).toEqual('Author_B');
190
- expect(json.author.contactPoint[0].email).toEqual('email_a@email.com');
191
- expect(json.author.contactPoint[1].email).toEqual('email_b@email.com');
192
-
193
- expect(Object.prototype.toString.call(json.author.sameAs)).toEqual('[object Array]');
194
- expect(json.author.sameAs).toHaveLength(3);
195
- expect(json.author.sameAs[0]).toEqual('author_linkedin');
196
- expect(json.author.sameAs[1]).toEqual('author_spotify');
197
- expect(json.author.sameAs[2]).toEqual('author_wikipedia');
198
- expect(json.author.knowsAbout).toEqual(undefined);
199
-
200
- expect(Object.prototype.toString.call(json.keywords)).toEqual('[object Array]');
201
- expect(json.keywords).toHaveLength(2);
202
- expect(json.keywords[0]).toEqual('keyword_a');
203
- expect(json.keywords[1]).toEqual('keyword_b');
222
+ expect(json.author['@type']).toEqual('Person');
223
+ expect(json.author.image).toEqual('author_image.jpg');
224
+ expect(Object.prototype.toString.call(json.author.knowsAbout)).toEqual('[object Array]');
225
+ expect(json.author.knowsAbout).toHaveLength(2);
226
+ expect(Object.prototype.toString.call(json.reviewedBy)).toEqual('[object Object]');
227
+ expect(json.reviewedBy['@type']).toEqual('Person');
228
+ expect(json.reviewedBy.image).toEqual('reviewer_image.jpg');
229
+ expect(Object.prototype.toString.call(json.reviewedBy.knowsAbout)).toEqual('[object Array]');
230
+ expect(json.reviewedBy.knowsAbout).toHaveLength(2);
204
231
  });
205
232
 
206
233
  test('organizationSchema()', () => {