gatsby-core-theme 44.30.1 → 44.30.3

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,17 @@
1
+ ## [44.30.3](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.30.2...v44.30.3) (2026-06-25)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add variable for height of bonus code button ([f147e4d](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/f147e4d70100a3fc9cd55e1e497cfdff7dd1f629))
7
+
8
+ ## [44.30.2](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.30.1...v44.30.2) (2026-06-24)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * fixes for notification panel ([80c7649](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/80c7649bb5650317b017c336b3b9653fa52a1042))
14
+
1
15
  ## [44.30.1](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.30.0...v44.30.1) (2026-06-22)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "44.30.1",
3
+ "version": "44.30.3",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { render, screen, fireEvent } from '@testing-library/react';
2
+ import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom/extend-expect';
4
4
  import { getListToplistItem } from '~tests/factories/modules/toplist.factory';
5
5
  import BonusesItems from '.';
@@ -25,7 +25,7 @@ const buildToplist = (overrides = {}) => ({
25
25
  describe('BonusesItems', () => {
26
26
  beforeEach(() => {
27
27
  Object.assign(navigator, {
28
- clipboard: { writeText: jest.fn() },
28
+ clipboard: { writeText: jest.fn().mockResolvedValue(undefined) },
29
29
  });
30
30
  });
31
31
 
@@ -34,7 +34,7 @@ describe('BonusesItems', () => {
34
34
  expect(screen.getByText('No new items')).toBeVisible();
35
35
  });
36
36
 
37
- test('renders bonus item with promo code and copies on click', () => {
37
+ test('renders bonus item with promo code and copies on click', async () => {
38
38
  const toplist = buildToplist();
39
39
  const { container } = render(<BonusesItems toplist={toplist} showUnread />);
40
40
 
@@ -44,7 +44,10 @@ describe('BonusesItems', () => {
44
44
  expect(screen.getByText('BONUS123')).toBeVisible();
45
45
 
46
46
  fireEvent.click(screen.getByText('BONUS123'));
47
- expect(navigator.clipboard.writeText).toHaveBeenCalledWith('BONUS123');
47
+ await waitFor(() => {
48
+ expect(navigator.clipboard.writeText).toHaveBeenCalledWith('BONUS123');
49
+ expect(screen.getByText('CODE COPIED')).toBeVisible();
50
+ });
48
51
  });
49
52
 
50
53
  test('renders bonus item without promo code row', () => {
@@ -60,4 +63,4 @@ describe('BonusesItems', () => {
60
63
  expect(container.querySelector('.bonusCodeRow')).toBeFalsy();
61
64
  expect(screen.getByText('name1 Review')).toBeVisible();
62
65
  });
63
- });
66
+ });
@@ -1,7 +1,8 @@
1
- import React from "react";
1
+ import React, { useState } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import { FaArrowRight } from "@react-icons/all-files/fa/FaArrowRight";
4
4
  import CopyIcon from "~images/icons/copyIcon";
5
+ import CheckCircleIcon from "~images/icons/check-circle";
5
6
  import LazyImage from "~hooks/lazy-image";
6
7
  import PrettyLink from "~atoms/pretty-link";
7
8
  import ReviewLink from "~atoms/review-link";
@@ -14,7 +15,7 @@ import {
14
15
  imagePrettyUrl,
15
16
  } from "~helpers/getters";
16
17
  import { getAltText } from "~helpers/image";
17
- import { getTimeAgo } from "~helpers/date-time";
18
+ import { getTimeAgo, parseSortableDate } from "~helpers/date-time";
18
19
  import { TrackingKeys } from "~constants/tracking-api";
19
20
  import VerifiedBadgeIcon from "~images/icons/verifiedBadgeIcon";
20
21
  import useTranslate from "~hooks/useTranslate/useTranslate";
@@ -29,6 +30,7 @@ const BonusItem = ({
29
30
  updatedLabel,
30
31
  hideBadges
31
32
  }) => {
33
+ const [copySuccess, setCopySuccess] = useState(false);
32
34
  const bonus = getBonusData(item, tracker);
33
35
  const oneliner = [bonus?.mainLine, bonus?.secondLine]
34
36
  .filter(Boolean)
@@ -37,14 +39,21 @@ const BonusItem = ({
37
39
  const reviewPath = item.review_link
38
40
  ? `/${item.review_link}`
39
41
  : item.path || null;
40
- const timeData = getTimeAgo(item.updated_at) || {};
42
+ const timeData = item.updated_at ? getTimeAgo(item.updated_at) : null;
41
43
  const timeKeyLabel = useTranslate(
42
- timeData.key,
43
- timeData.key?.replace(/_/g, " ")
44
+ timeData?.key,
45
+ timeData?.key?.replace(/_/g, " ")
44
46
  );
45
- const timeAgo = timeData.value
46
- ? `${updatedLabel} ${timeData.value} ${timeKeyLabel}`
47
- : "";
47
+ const foundedYear = item?.founded?.substring(0, 4);
48
+ let timeAgo = "";
49
+
50
+ if (timeData?.value) {
51
+ timeAgo = `${updatedLabel} ${timeData.value} ${timeKeyLabel}`;
52
+ } else if (foundedYear) {
53
+ // eslint-disable-next-line react-hooks/rules-of-hooks
54
+ timeAgo = `${useTranslate("founded", "Founded")} ${foundedYear}`;
55
+ }
56
+
48
57
  const hasTnc = Boolean(getOperatorTnc(item, tracker));
49
58
 
50
59
  const verifiedMonth = new Intl.DateTimeFormat("en-US", {
@@ -55,6 +64,20 @@ const BonusItem = ({
55
64
  "notification_verified_in",
56
65
  "Verified in [month]"
57
66
  ).replace("[month]", verifiedMonth);
67
+ const codeCopiedLabel = useTranslate("code_copied", "CODE COPIED");
68
+ const isBet365 = item.short_name === "bet365";
69
+
70
+ const copyToClipBoard = async (e, copyMe) => {
71
+ e.preventDefault();
72
+ e.stopPropagation();
73
+
74
+ try {
75
+ await navigator.clipboard.writeText(copyMe);
76
+ setCopySuccess(true);
77
+ } catch (err) {
78
+ setCopySuccess(false);
79
+ }
80
+ };
58
81
 
59
82
  return (
60
83
  <li className={styles.bonusItem}>
@@ -72,7 +95,7 @@ const BonusItem = ({
72
95
  width={52}
73
96
  height={52}
74
97
  alt={getAltText(item.logo, item.name)}
75
- src={imagePrettyUrl(item.logo?.filename, 52, 52)}
98
+ src={imagePrettyUrl(item.logo?.filename)}
76
99
  />
77
100
  </PrettyLink>
78
101
 
@@ -83,11 +106,30 @@ const BonusItem = ({
83
106
  <span className={styles.bonusCodeLabel}>{bonusCodeLabel}</span>
84
107
  <button
85
108
  type="button"
86
- className={styles.bonusCode}
87
- onClick={() => navigator.clipboard.writeText(promoCode)}
109
+ className={`${styles.bonusCode} ${copySuccess ? styles.bonusCodeCopied : ""}`}
110
+ onClick={(e) =>
111
+ promoCode && !isBet365 ? copyToClipBoard(e, promoCode) : undefined
112
+ }
113
+ disabled={isBet365}
88
114
  >
89
- <span>{promoCode}</span>
90
- <CopyIcon width={20} height={20} />
115
+ {!copySuccess ? (
116
+ <>
117
+ <span>{promoCode}</span>
118
+ {!isBet365 && <CopyIcon width={20} height={20} />}
119
+ </>
120
+ ) : (
121
+ <>
122
+ <span>{codeCopiedLabel}</span>
123
+ <span className={styles.bonusCodeCheckIcon}>
124
+ <CheckCircleIcon
125
+ width={20}
126
+ height={20}
127
+ bgColor="var(--notification-bonus-code-border, #20cd77)"
128
+ color="#fff"
129
+ />
130
+ </span>
131
+ </>
132
+ )}
91
133
  </button>
92
134
  </div>
93
135
  )}
@@ -138,6 +180,7 @@ BonusItem.propTypes = {
138
180
  updated_at: PropTypes.string,
139
181
  short_name: PropTypes.string,
140
182
  name: PropTypes.string,
183
+ founded: PropTypes.string,
141
184
  logo: PropTypes.shape({
142
185
  filename: PropTypes.string,
143
186
  }),
@@ -151,7 +194,11 @@ BonusItem.propTypes = {
151
194
  };
152
195
 
153
196
  const BonusesItems = ({ toplist, showUnread, hideBadges }) => {
154
- const items = toplist?.items || [];
197
+ const items = [...(toplist?.items || [])].sort(
198
+ (a, b) =>
199
+ parseSortableDate(b.updated_at || b.founded) -
200
+ parseSortableDate(a.updated_at || a.founded)
201
+ );
155
202
  const tracker =
156
203
  toplist?.toplist_bonus || toplist?.one_liner || toplist?.tracker || "main";
157
204
  const noBonuses = useTranslate("noNewUpdates", "No new items");
@@ -189,4 +236,4 @@ BonusesItems.propTypes = {
189
236
  hideBadges: PropTypes.bool
190
237
  };
191
238
 
192
- export default BonusesItems;
239
+ export default BonusesItems;
@@ -13,9 +13,17 @@ import {
13
13
  import { getAltText, getImageFilename } from "~helpers/image";
14
14
  import ArticleIcon from "../../../../../images/icons/articleIcon";
15
15
  import useTranslate from "~hooks/useTranslate/useTranslate";
16
- import { getTimeAgo } from "~helpers/date-time";
16
+ import { getTimeAgo, parseSortableDate } from "~helpers/date-time";
17
17
  import styles from "./notification-items.module.scss";
18
18
 
19
+ const getTrendingSortDate = (item) =>
20
+ parseSortableDate(
21
+ item?.manual_updated_date ||
22
+ item?.updated_at ||
23
+ item?.manual_published_date ||
24
+ item?.created_at
25
+ );
26
+
19
27
  const CategoryTag = ({ category }) => {
20
28
  const label = useTranslate(
21
29
  `category_${category.short_name}`,
@@ -28,9 +36,10 @@ const CategoryTag = ({ category }) => {
28
36
  };
29
37
 
30
38
  const CardsItems = ({ module, showUnread = false }) => {
31
- const { items } = module || {};
39
+ const items = [...(module?.items || [])].sort(
40
+ (a, b) => getTrendingSortDate(b) - getTrendingSortDate(a)
41
+ );
32
42
  const noNewUpdates = useTranslate("noNewUpdates", "No new items");
33
- const updatedLabel = useTranslate("updated", "Updated");
34
43
 
35
44
  const renderItem = (item) => {
36
45
  const isArticleOrPage = ["article", "page"].includes(item?.relation_type);
@@ -46,20 +55,20 @@ const CardsItems = ({ module, showUnread = false }) => {
46
55
  const categories = item?.categories || [];
47
56
  const description =
48
57
  subtitle || item?.short_description || item?.description || "";
49
- const timeData =
50
- getTimeAgo(
51
- item?.manual_updated_date ||
52
- item?.updated_at ||
53
- item?.manual_published_date ||
54
- item?.created_at
55
- ) || {};
56
- const timeAgo = timeData.value
57
- ? `${updatedLabel} ${timeData.value} ${useTranslate(
58
+ const dateModified = item?.manual_updated_date || item?.updated_at;
59
+ const datePublished = item?.manual_published_date || item?.created_at;
60
+ const dateString = dateModified || datePublished;
61
+ const usePublishedLabel = !dateModified && Boolean(datePublished);
62
+ const timeData = dateString ? getTimeAgo(dateString) : null;
63
+ const timeAgo = timeData?.value
64
+ ? `${useTranslate(
65
+ usePublishedLabel ? "published" : "updated",
66
+ usePublishedLabel ? "Published" : "Updated"
67
+ )} ${timeData.value} ${useTranslate(
58
68
  timeData.key,
59
69
  timeData.key?.replace(/_/g, " ")
60
70
  )}`
61
71
  : "";
62
-
63
72
  const thumbnail = img ? (
64
73
  <LazyImage
65
74
  width={40}
@@ -9,13 +9,22 @@ import LazyImage from "~hooks/lazy-image";
9
9
  import keygen from "~helpers/keygen";
10
10
  import Link from "~hooks/link";
11
11
  import useTranslate from "~hooks/useTranslate/useTranslate";
12
- import { getTimeAgo } from "~helpers/date-time";
12
+ import { getTimeAgo, parseSortableDate } from "~helpers/date-time";
13
13
  import styles from "../cards-v2/notification-items.module.scss";
14
14
 
15
+ const getTrendingSortDate = (item) =>
16
+ parseSortableDate(
17
+ item?.manual_updated_date ||
18
+ item?.updated_at ||
19
+ item?.manual_published_date ||
20
+ item?.created_at
21
+ );
22
+
15
23
  const SpotlightItems = ({ module, showUnread = false }) => {
16
- const { items } = module || {};
24
+ const items = [...(module?.items || [])].sort(
25
+ (a, b) => getTrendingSortDate(b) - getTrendingSortDate(a)
26
+ );
17
27
  const noNewUpdates = useTranslate("noNewUpdates", "No new items");
18
- const updatedLabel = useTranslate("updated", "Updated");
19
28
 
20
29
  const renderItem = (item) => {
21
30
  const img = item?.image;
@@ -25,21 +34,24 @@ const SpotlightItems = ({ module, showUnread = false }) => {
25
34
  const ribbon = item?.subtitle?.split(",")[0]?.replace("[null]", "")?.trim();
26
35
  const metaText = item?.subtitle?.split(",").slice(1).join(",").trim();
27
36
  const description = item?.short_description || item?.text || "";
28
- const timeData =
29
- getTimeAgo(
30
- item?.manual_updated_date ||
31
- item?.updated_at
32
- ) || {};
37
+ const dateModified = item?.manual_updated_date || item?.updated_at;
38
+ const datePublished = item?.manual_published_date || item?.created_at;
39
+ const dateString = dateModified || datePublished;
40
+ const usePublishedLabel = !dateModified && Boolean(datePublished);
41
+ const timeData = dateString ? getTimeAgo(dateString) : null;
33
42
  const timeKeyLabel = useTranslate(
34
- timeData.key,
35
- timeData.key?.replace(/_/g, " ")
43
+ timeData?.key,
44
+ timeData?.key?.replace(/_/g, " ")
36
45
  );
37
46
  let timeAgo = "";
38
47
 
39
- if (timeData.value) {
40
- timeAgo = `${updatedLabel} ${timeData.value} ${timeKeyLabel}`;
48
+ if (timeData?.value) {
49
+ timeAgo = `${useTranslate(
50
+ usePublishedLabel ? "published" : "updated",
51
+ usePublishedLabel ? "Published" : "Updated"
52
+ )} ${timeData.value} ${timeKeyLabel}`;
41
53
  } else if (metaText) {
42
- timeAgo = `${updatedLabel} ${metaText}`;
54
+ timeAgo = `${useTranslate("updated", "Updated")} ${metaText}`;
43
55
  }
44
56
 
45
57
  return (
@@ -116,6 +116,7 @@
116
116
  gap: 0.8rem;
117
117
  padding: 0 0 0.8rem;
118
118
  border-bottom: 1px solid var(--notification-item-border, #e3e6ef);
119
+ cursor: default;
119
120
  }
120
121
 
121
122
  .unreadDot {
@@ -135,6 +136,7 @@
135
136
  gap: 0.8rem;
136
137
  width: 100%;
137
138
  min-height: 5.2rem;
139
+ cursor: default;
138
140
  }
139
141
 
140
142
  .logo {
@@ -145,6 +147,7 @@
145
147
  height: 5.2rem;
146
148
  border: 1px solid var(--notification-logo-border, #dedede);
147
149
  border-radius: var(--notification-logo-border-radius, 0.8rem);
150
+ cursor: default;
148
151
 
149
152
  img {
150
153
  display: block;
@@ -154,6 +157,7 @@
154
157
  }
155
158
  }
156
159
 
160
+
157
161
  .bonusText {
158
162
  @include flex-direction(column);
159
163
  @include flex-align(flex-start, center);
@@ -162,6 +166,7 @@
162
166
  min-width: 0;
163
167
  gap: 0.4rem;
164
168
  padding-right: 2.4rem;
169
+ cursor: default;
165
170
  }
166
171
 
167
172
  .oneliner {
@@ -170,6 +175,7 @@
170
175
  font-weight: 700;
171
176
  line-height: 2.2rem;
172
177
  color: var(--notification-oneliner-color, #1b1b1c);
178
+ cursor: default;
173
179
  }
174
180
 
175
181
  .bonusCodeRow {
@@ -190,7 +196,7 @@
190
196
  @include flex-align(center, center);
191
197
 
192
198
  gap: 0.6rem;
193
- height: 2.4rem;
199
+ height: var(--notification-bonus-code-height, 2.4rem);
194
200
  padding: 0 0.8rem;
195
201
  border: 1px var(--notification-bonus-code-border-style, dashed)
196
202
  var(--notification-bonus-code-border, #20cd77);
@@ -211,15 +217,36 @@
211
217
 
212
218
  svg {
213
219
  flex-shrink: 0;
220
+ pointer-events: none;
214
221
  color: var(--notification-bonus-code-icon, #262629);
215
222
  }
216
223
  }
217
224
 
225
+ .bonusCodeCopied {
226
+ border-color: var(--notification-bonus-code-border, #20cd77);
227
+ }
228
+
229
+ .bonusCodeCheckIcon {
230
+ @include flex-align(center, center);
231
+
232
+ flex-shrink: 0;
233
+ width: 2rem;
234
+ height: 2rem;
235
+ pointer-events: none;
236
+
237
+ svg {
238
+ display: block;
239
+ width: 2rem;
240
+ height: 2rem;
241
+ }
242
+ }
243
+
218
244
  .meta {
219
245
  @include flex-align(center, flex-start);
220
246
 
221
247
  width: 100%;
222
248
  min-height: 1.8rem;
249
+ cursor: default;
223
250
  }
224
251
 
225
252
  .reviewLink {
@@ -230,6 +257,7 @@
230
257
  line-height: 1.8rem;
231
258
  color: var(--notification-link-color, #165af8);
232
259
  text-decoration: underline;
260
+ cursor: pointer;
233
261
  }
234
262
 
235
263
  .updated {
@@ -241,6 +269,7 @@
241
269
  color: var(--notification-meta-color, #515156);
242
270
  text-align: right;
243
271
  white-space: nowrap;
272
+ cursor: default;
244
273
  }
245
274
 
246
275
  .cta {
@@ -254,6 +283,7 @@
254
283
  background: var(--notification-cta-bg, #6e33e5);
255
284
  color: var(--notification-cta-color, #fff);
256
285
  text-decoration: none;
286
+ cursor: default;
257
287
 
258
288
  &:hover {
259
289
  background: var(--notification-cta-hover-bg, #5a28c7);
@@ -52,3 +52,11 @@ export const getTimeAgo = (dateString) => {
52
52
  }
53
53
  return { value: diffMinutes, key: diffMinutes === 1 ? "minute_ago" : "minutes_ago" };
54
54
  };
55
+
56
+ export const parseSortableDate = (dateString) => {
57
+ if (!dateString) return 0;
58
+
59
+ const time = Date.parse(String(dateString).replace(" ", "T"));
60
+
61
+ return Number.isNaN(time) ? 0 : time;
62
+ };
@@ -1,4 +1,4 @@
1
- import { formatDate, getTimeAgo } from './date-time';
1
+ import { formatDate, getTimeAgo, parseSortableDate } from './date-time';
2
2
 
3
3
  describe('Date-Time Helper', () => {
4
4
  test('formatDate()', () => {
@@ -22,4 +22,11 @@ describe('Date-Time Helper', () => {
22
22
  expect(getTimeAgo(daysAgo)).toMatchObject({ key: 'days_ago', value: 10 });
23
23
  expect(getTimeAgo(monthsAgo)).toMatchObject({ key: 'months_ago', value: 2 });
24
24
  });
25
+
26
+ test('parseSortableDate()', () => {
27
+ expect(parseSortableDate(null)).toBe(0);
28
+ expect(parseSortableDate('2025-06-01 10:00:00')).toBeGreaterThan(
29
+ parseSortableDate('2024-01-01 10:00:00')
30
+ );
31
+ });
25
32
  });
@@ -6,7 +6,7 @@ export default function CheckCircleIcon({ width = 24, height = 24, color = '#272
6
6
  <svg
7
7
  width={width}
8
8
  height={height}
9
- viewBox={`0 0 ${width} ${height}`}
9
+ viewBox="0 0 24 24"
10
10
  fill="none"
11
11
  aria-labelledby="checkCircleIcon"
12
12
  xmlns="http://www.w3.org/2000/svg"
@@ -520,6 +520,35 @@ export function shouldSavePrefilled(module = {}, siteName) {
520
520
  );
521
521
  }
522
522
 
523
+ function normalizePathForMatch(path) {
524
+ if (!path || typeof path !== "string") return "";
525
+ return path.replace(/^\/+|\/+$/g, "");
526
+ }
527
+
528
+ function getSpotlightLinkedPage(link, pagesMappedById = {}) {
529
+ if (!link || link.type !== "page") return null;
530
+
531
+ if (link.page_id && pagesMappedById[link.page_id]) {
532
+ return pagesMappedById[link.page_id];
533
+ }
534
+
535
+ const linkValue = link.value;
536
+ if (!linkValue) return null;
537
+
538
+ if (pagesMappedById[linkValue]) {
539
+ return pagesMappedById[linkValue];
540
+ }
541
+
542
+ const linkPath = normalizePathForMatch(linkValue);
543
+ if (!linkPath) return null;
544
+
545
+ return (
546
+ Object.values(pagesMappedById).find(
547
+ (page) => normalizePathForMatch(page?.path) === linkPath
548
+ ) || null
549
+ );
550
+ }
551
+
523
552
  export function processSpotlightModule(module = {}, content, relations, ribbons, previewPageID, translations, relationData, operators, games,
524
553
  pagesMappedById = {}
525
554
  ) {
@@ -543,11 +572,22 @@ export function processSpotlightModule(module = {}, content, relations, ribbons,
543
572
  games
544
573
  );
545
574
 
546
- const pageId = item?.link?.page_id;
547
- const linkedPage = pageId ? pagesMappedById[pageId] : null;
575
+ const linkedPage = getSpotlightLinkedPage(item?.link, pagesMappedById);
548
576
  if (linkedPage?.short_description) {
549
577
  item.short_description = linkedPage.short_description;
550
578
  }
579
+ if (linkedPage?.updated_at) {
580
+ item.updated_at = linkedPage.updated_at;
581
+ }
582
+ if (linkedPage?.manual_updated_date) {
583
+ item.manual_updated_date = linkedPage.manual_updated_date;
584
+ }
585
+ if (linkedPage?.created_at) {
586
+ item.created_at = linkedPage.created_at;
587
+ }
588
+ if (linkedPage?.manual_published_date) {
589
+ item.manual_published_date = linkedPage.manual_published_date;
590
+ }
551
591
  });
552
592
  }
553
593
 
@@ -11,6 +11,7 @@ import {
11
11
  shouldSavePrefilled,
12
12
  processContentModule,
13
13
  processAnchor,
14
+ processSpotlightModule,
14
15
  } from "./modules.mjs";
15
16
  import { objectsHolder } from "~tests/factories/modules/modules.factory";
16
17
  import getPageDataList from "~tests/factories/pages/list.factory";
@@ -391,4 +392,43 @@ expect(module.value.ribbons[0]).toBe("testRibbon");
391
392
 
392
393
  expect(prefilledModule.items).toHaveLength(3);
393
394
  });
395
+
396
+ test("Spotlights resolve linked page by path when page_id is missing", () => {
397
+ const linkedPage = {
398
+ ...getPageData(),
399
+ id: 123,
400
+ path: "casino-bonus/irishlucks-exclusive-bonuses-vault",
401
+ updated_at: "2024-06-10 12:00:00",
402
+ short_description: "Linked page description",
403
+ };
404
+ const module = {
405
+ mode: "image_text",
406
+ items: [
407
+ {
408
+ label: "Bonus Club",
409
+ text: "<p>Join now!</p>",
410
+ link: {
411
+ type: "page",
412
+ value: "/casino-bonus/irishlucks-exclusive-bonuses-vault",
413
+ },
414
+ },
415
+ ],
416
+ };
417
+
418
+ processSpotlightModule(
419
+ module,
420
+ {},
421
+ {},
422
+ {},
423
+ null,
424
+ {},
425
+ {},
426
+ {},
427
+ {},
428
+ { 123: linkedPage }
429
+ );
430
+
431
+ expect(module.items[0].short_description).toBe("Linked page description");
432
+ expect(module.items[0].updated_at).toBe("2024-06-10 12:00:00");
433
+ });
394
434
  });