@times-components/ts-components 1.145.1-7e7a12feaf05c514789e802bf49cadca92e6a2b9.10 → 1.145.1-840c3cbc6021aef0e28e52412d33f016c55bc0b4.1

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.
Files changed (136) hide show
  1. package/dist/components/travel-mini-cta/index.d.ts +3 -0
  2. package/dist/components/travel-mini-cta/index.js +84 -0
  3. package/dist/components/travel-mini-cta/styles.d.ts +42 -0
  4. package/dist/components/travel-mini-cta/styles.js +273 -0
  5. package/dist/components/travel-mini-cta/travel-mini-cta.stories.d.ts +110 -0
  6. package/dist/components/travel-mini-cta/travel-mini-cta.stories.js +121 -0
  7. package/dist/components/travel-mini-cta/types.d.ts +10 -0
  8. package/dist/components/{trip-cards → travel-mini-cta}/types.js +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +2 -2
  11. package/dist/utils/applyDarkMode.d.ts +1 -0
  12. package/dist/utils/applyDarkMode.js +12 -0
  13. package/dist/utils/getMediaQuery.d.ts +11 -0
  14. package/dist/utils/getMediaQuery.js +19 -0
  15. package/dist/utils/index.d.ts +2 -0
  16. package/dist/utils/index.js +3 -0
  17. package/package.json +3 -3
  18. package/rnw.js +1 -1
  19. package/src/components/travel-mini-cta/index.tsx +161 -0
  20. package/src/components/travel-mini-cta/styles.ts +336 -0
  21. package/src/components/travel-mini-cta/travel-mini-cta.stories.tsx +157 -0
  22. package/src/components/travel-mini-cta/types.ts +10 -0
  23. package/src/index.ts +1 -2
  24. package/src/utils/applyDarkMode.ts +12 -0
  25. package/src/utils/getMediaQuery.ts +25 -0
  26. package/src/utils/index.ts +2 -0
  27. package/dist/components/carousel-component/CarouselComponent.stories.d.ts +0 -1
  28. package/dist/components/carousel-component/CarouselComponent.stories.js +0 -146
  29. package/dist/components/carousel-component/CarouselItem.d.ts +0 -3
  30. package/dist/components/carousel-component/CarouselItem.js +0 -11
  31. package/dist/components/carousel-component/DefaultNavigationArrow.d.ts +0 -8
  32. package/dist/components/carousel-component/DefaultNavigationArrow.js +0 -6
  33. package/dist/components/carousel-component/DefaultPageDot.d.ts +0 -8
  34. package/dist/components/carousel-component/DefaultPageDot.js +0 -4
  35. package/dist/components/carousel-component/__tests__/CarouselComponent.test.d.ts +0 -1
  36. package/dist/components/carousel-component/__tests__/CarouselComponent.test.js +0 -163
  37. package/dist/components/carousel-component/__tests__/CarouselItem.test.d.ts +0 -1
  38. package/dist/components/carousel-component/__tests__/CarouselItem.test.js +0 -80
  39. package/dist/components/carousel-component/__tests__/DefaultNavigationArrow.test.d.ts +0 -1
  40. package/dist/components/carousel-component/__tests__/DefaultNavigationArrow.test.js +0 -62
  41. package/dist/components/carousel-component/__tests__/DefaultPageDot.test.d.ts +0 -1
  42. package/dist/components/carousel-component/__tests__/DefaultPageDot.test.js +0 -68
  43. package/dist/components/carousel-component/hooks/__tests__/useCarousel.test.d.ts +0 -1
  44. package/dist/components/carousel-component/hooks/__tests__/useCarousel.test.js +0 -459
  45. package/dist/components/carousel-component/hooks/useCarousel.d.ts +0 -2
  46. package/dist/components/carousel-component/hooks/useCarousel.js +0 -175
  47. package/dist/components/carousel-component/index.d.ts +0 -4
  48. package/dist/components/carousel-component/index.js +0 -20
  49. package/dist/components/carousel-component/styles.d.ts +0 -27
  50. package/dist/components/carousel-component/styles.js +0 -169
  51. package/dist/components/carousel-component/types.d.ts +0 -53
  52. package/dist/components/carousel-component/types.js +0 -2
  53. package/dist/components/trip-cards/SkeletonCard.d.ts +0 -6
  54. package/dist/components/trip-cards/SkeletonCard.js +0 -21
  55. package/dist/components/trip-cards/TripCard.d.ts +0 -3
  56. package/dist/components/trip-cards/TripCard.js +0 -49
  57. package/dist/components/trip-cards/TripCards.stories.d.ts +0 -1
  58. package/dist/components/trip-cards/TripCards.stories.js +0 -189
  59. package/dist/components/trip-cards/TripCardsLayout.d.ts +0 -3
  60. package/dist/components/trip-cards/TripCardsLayout.js +0 -37
  61. package/dist/components/trip-cards/__tests__/SkeletonCard.test.d.ts +0 -1
  62. package/dist/components/trip-cards/__tests__/SkeletonCard.test.js +0 -139
  63. package/dist/components/trip-cards/__tests__/TripCard.test.d.ts +0 -1
  64. package/dist/components/trip-cards/__tests__/TripCard.test.js +0 -95
  65. package/dist/components/trip-cards/__tests__/TripCardsLayout.test.d.ts +0 -1
  66. package/dist/components/trip-cards/__tests__/TripCardsLayout.test.js +0 -277
  67. package/dist/components/trip-cards/__tests__/assets.test.d.ts +0 -1
  68. package/dist/components/trip-cards/__tests__/assets.test.js +0 -165
  69. package/dist/components/trip-cards/__tests__/helpers.test.d.ts +0 -1
  70. package/dist/components/trip-cards/__tests__/helpers.test.js +0 -216
  71. package/dist/components/trip-cards/__tests__/index.test.d.ts +0 -1
  72. package/dist/components/trip-cards/__tests__/index.test.js +0 -433
  73. package/dist/components/trip-cards/__tests__/mockData.test.d.ts +0 -1
  74. package/dist/components/trip-cards/__tests__/mockData.test.js +0 -57
  75. package/dist/components/trip-cards/__tests__/skeletonStyles.test.d.ts +0 -1
  76. package/dist/components/trip-cards/__tests__/skeletonStyles.test.js +0 -194
  77. package/dist/components/trip-cards/assets/BoatIcon.d.ts +0 -1
  78. package/dist/components/trip-cards/assets/BoatIcon.js +0 -4
  79. package/dist/components/trip-cards/assets/CalendarIcon.d.ts +0 -1
  80. package/dist/components/trip-cards/assets/CalendarIcon.js +0 -4
  81. package/dist/components/trip-cards/assets/ChevronRightIcon.d.ts +0 -1
  82. package/dist/components/trip-cards/assets/ChevronRightIcon.js +0 -4
  83. package/dist/components/trip-cards/assets/LocationIcon.d.ts +0 -1
  84. package/dist/components/trip-cards/assets/LocationIcon.js +0 -4
  85. package/dist/components/trip-cards/assets/MoonIcon.d.ts +0 -1
  86. package/dist/components/trip-cards/assets/MoonIcon.js +0 -4
  87. package/dist/components/trip-cards/assets/index.d.ts +0 -6
  88. package/dist/components/trip-cards/assets/index.js +0 -7
  89. package/dist/components/trip-cards/helpers.d.ts +0 -4
  90. package/dist/components/trip-cards/helpers.js +0 -115
  91. package/dist/components/trip-cards/index.d.ts +0 -4
  92. package/dist/components/trip-cards/index.js +0 -70
  93. package/dist/components/trip-cards/mockData.d.ts +0 -3
  94. package/dist/components/trip-cards/mockData.js +0 -317
  95. package/dist/components/trip-cards/skeletonStyles.d.ts +0 -9
  96. package/dist/components/trip-cards/skeletonStyles.js +0 -37
  97. package/dist/components/trip-cards/styles.d.ts +0 -38
  98. package/dist/components/trip-cards/styles.js +0 -401
  99. package/dist/components/trip-cards/types.d.ts +0 -119
  100. package/src/components/carousel-component/CarouselComponent.stories.tsx +0 -220
  101. package/src/components/carousel-component/CarouselItem.tsx +0 -25
  102. package/src/components/carousel-component/DefaultNavigationArrow.tsx +0 -37
  103. package/src/components/carousel-component/DefaultPageDot.tsx +0 -20
  104. package/src/components/carousel-component/__tests__/CarouselComponent.test.tsx +0 -259
  105. package/src/components/carousel-component/__tests__/CarouselItem.test.tsx +0 -140
  106. package/src/components/carousel-component/__tests__/DefaultNavigationArrow.test.tsx +0 -153
  107. package/src/components/carousel-component/__tests__/DefaultPageDot.test.tsx +0 -105
  108. package/src/components/carousel-component/hooks/__tests__/useCarousel.test.ts +0 -625
  109. package/src/components/carousel-component/hooks/useCarousel.ts +0 -231
  110. package/src/components/carousel-component/index.tsx +0 -92
  111. package/src/components/carousel-component/styles.ts +0 -185
  112. package/src/components/carousel-component/types.ts +0 -62
  113. package/src/components/trip-cards/SkeletonCard.tsx +0 -62
  114. package/src/components/trip-cards/TripCard.tsx +0 -143
  115. package/src/components/trip-cards/TripCards.stories.tsx +0 -254
  116. package/src/components/trip-cards/TripCardsLayout.tsx +0 -108
  117. package/src/components/trip-cards/__tests__/SkeletonCard.test.tsx +0 -169
  118. package/src/components/trip-cards/__tests__/TripCard.test.tsx +0 -120
  119. package/src/components/trip-cards/__tests__/TripCardsLayout.test.tsx +0 -532
  120. package/src/components/trip-cards/__tests__/assets.test.tsx +0 -206
  121. package/src/components/trip-cards/__tests__/helpers.test.ts +0 -266
  122. package/src/components/trip-cards/__tests__/index.test.tsx +0 -495
  123. package/src/components/trip-cards/__tests__/mockData.test.ts +0 -67
  124. package/src/components/trip-cards/__tests__/skeletonStyles.test.tsx +0 -256
  125. package/src/components/trip-cards/assets/BoatIcon.tsx +0 -17
  126. package/src/components/trip-cards/assets/CalendarIcon.tsx +0 -17
  127. package/src/components/trip-cards/assets/ChevronRightIcon.tsx +0 -20
  128. package/src/components/trip-cards/assets/LocationIcon.tsx +0 -17
  129. package/src/components/trip-cards/assets/MoonIcon.tsx +0 -17
  130. package/src/components/trip-cards/assets/index.ts +0 -7
  131. package/src/components/trip-cards/helpers.ts +0 -150
  132. package/src/components/trip-cards/index.tsx +0 -119
  133. package/src/components/trip-cards/mockData.ts +0 -345
  134. package/src/components/trip-cards/skeletonStyles.ts +0 -46
  135. package/src/components/trip-cards/styles.ts +0 -446
  136. package/src/components/trip-cards/types.ts +0 -128
@@ -1,495 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, waitFor } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
- import { TripCards } from '../index';
5
- import { TripCardsElement } from '../types';
6
- import * as mockDataModule from '../mockData';
7
-
8
- global.fetch = jest.fn();
9
-
10
- describe('TripCards', () => {
11
- const mockCards = [
12
- {
13
- cruise_id: '1',
14
- image: 'image1.jpg',
15
- headline: 'Mock Cruise 1',
16
- date: 'Jan 2024',
17
- duration: '7 nights',
18
- route: 'Route 1',
19
- ship: 'Ship 1',
20
- price: '£1000',
21
- original_price: undefined,
22
- logo: 'logo1.png',
23
- logo_url: 'https://example.com',
24
- cta_url: 'link1',
25
- cta_text: 'View'
26
- },
27
- {
28
- cruise_id: '2',
29
- image: 'image2.jpg',
30
- headline: 'Mock Cruise 2',
31
- date: 'Feb 2024',
32
- duration: '14 nights',
33
- route: 'Route 2',
34
- ship: 'Ship 2',
35
- price: '£2000',
36
- original_price: undefined,
37
- logo: 'logo2.png',
38
- logo_url: 'https://example.com',
39
- cta_url: 'link2',
40
- cta_text: 'View'
41
- },
42
- {
43
- cruise_id: '3',
44
- image: 'image3.jpg',
45
- headline: 'Mock Cruise 3',
46
- date: 'Mar 2024',
47
- duration: '10 nights',
48
- route: 'Route 3',
49
- ship: 'Ship 3',
50
- price: '£1500',
51
- original_price: undefined,
52
- logo: 'logo3.png',
53
- logo_url: 'https://example.com',
54
- cta_url: 'link3',
55
- cta_text: 'View'
56
- }
57
- ];
58
-
59
- const mockElement: TripCardsElement = {
60
- title: 'Test Cruises',
61
- description: 'Test Description',
62
- tripcards: btoa(JSON.stringify([1, 2, 3])),
63
- titleurl: 'https://example.com'
64
- };
65
-
66
- beforeEach(() => {
67
- jest.clearAllMocks();
68
- jest
69
- .spyOn(mockDataModule, 'getMockTripCards')
70
- .mockImplementation((count?: number) => {
71
- return count ? mockCards.slice(0, count) : mockCards;
72
- });
73
- Object.defineProperty(window, 'innerWidth', {
74
- writable: true,
75
- configurable: true,
76
- value: 1024
77
- });
78
- });
79
-
80
- describe('Mock Data Mode', () => {
81
- it('renders cards when useMockData is true', async () => {
82
- render(<TripCards element={mockElement} useMockData={true} />);
83
-
84
- await waitFor(() => {
85
- expect(screen.getByText('Mock Cruise 1')).toBeInTheDocument();
86
- expect(screen.getByText('Mock Cruise 2')).toBeInTheDocument();
87
- });
88
- });
89
-
90
- it('renders title and description', async () => {
91
- render(<TripCards element={mockElement} useMockData={true} />);
92
-
93
- await waitFor(() => {
94
- expect(screen.getByText('Test Cruises')).toBeInTheDocument();
95
- expect(screen.getByText('Test Description')).toBeInTheDocument();
96
- });
97
- });
98
-
99
- it('respects the number of IDs', async () => {
100
- render(<TripCards element={mockElement} useMockData={true} />);
101
-
102
- await waitFor(() => {
103
- expect(mockDataModule.getMockTripCards).toHaveBeenCalledWith(3);
104
- });
105
- });
106
- });
107
-
108
- describe('Error Handling', () => {
109
- it('returns null when no IDs are provided', async () => {
110
- const emptyElement: TripCardsElement = {
111
- title: 'Test',
112
- description: 'Test',
113
- tripcards: '',
114
- titleurl: undefined
115
- };
116
-
117
- const { container } = render(<TripCards element={emptyElement} />);
118
-
119
- await waitFor(() => {
120
- expect(container.firstChild).toBeNull();
121
- });
122
- });
123
-
124
- it('returns null when fetch fails', async () => {
125
- (global.fetch as jest.Mock).mockRejectedValue(new Error('Network error'));
126
-
127
- const { container } = render(<TripCards element={mockElement} />);
128
-
129
- await waitFor(() => {
130
- expect(container.firstChild).toBeNull();
131
- });
132
- });
133
-
134
- it('returns null when response is not ok', async () => {
135
- (global.fetch as jest.Mock).mockResolvedValue({
136
- ok: false,
137
- status: 404
138
- });
139
-
140
- const { container } = render(<TripCards element={mockElement} />);
141
-
142
- await waitFor(() => {
143
- expect(container.firstChild).toBeNull();
144
- });
145
- });
146
-
147
- it('returns null when API response format is invalid', async () => {
148
- (global.fetch as jest.Mock).mockResolvedValue({
149
- ok: true,
150
- json: async () => ({ invalid: 'data' })
151
- });
152
-
153
- const { container } = render(<TripCards element={mockElement} />);
154
-
155
- await waitFor(() => {
156
- expect(container.firstChild).toBeNull();
157
- });
158
- });
159
- });
160
-
161
- describe('API Data Fetching', () => {
162
- it('fetches and displays cruise data from API', async () => {
163
- const mockApiResponse = {
164
- results: [
165
- {
166
- post_id: 1,
167
- cruise_id: 1,
168
- cruise_title: 'API Cruise 1',
169
- cruise_line: {
170
- name: 'API Line',
171
- link: 'http://line.com',
172
- logo: 'logo.png'
173
- },
174
- ship: {
175
- name: 'API Ship',
176
- link: 'http://ship.com',
177
- image: 'api-image1.jpg'
178
- },
179
- departs: '2026-03-01',
180
- ends: '2026-03-11',
181
- date_label: 'March 2024',
182
- destination: ['Port 1', 'Port 3'],
183
- duration: 10,
184
- itinerary: ['Port 1', 'Port 2', 'Port 3'],
185
- prices: {
186
- cheapest_price: 1500,
187
- inside: 1500,
188
- outside: 1800,
189
- balcony: 2000,
190
- suite: 2500
191
- },
192
- was_prices: {
193
- inside: 2000,
194
- outside: 2200,
195
- balcony: 2500,
196
- suite: 3000
197
- },
198
- link: 'api-link',
199
- campaigns: ['Special'],
200
- extras: {
201
- date: 'March 2024',
202
- duration: '10 nights',
203
- destination: 'Mediterranean',
204
- info: 'Additional info'
205
- }
206
- },
207
- {
208
- post_id: 2,
209
- cruise_id: 2,
210
- cruise_title: 'API Cruise 2',
211
- cruise_line: {
212
- name: 'API Line',
213
- link: 'http://line.com',
214
- logo: 'logo.png'
215
- },
216
- ship: {
217
- name: 'API Ship 2',
218
- link: 'http://ship.com',
219
- image: 'api-image2.jpg'
220
- },
221
- departs: '2026-04-01',
222
- ends: '2026-04-11',
223
- date_label: 'April 2024',
224
- destination: ['Port 2', 'Port 4'],
225
- duration: 10,
226
- itinerary: ['Port 2', 'Port 3', 'Port 4'],
227
- prices: {
228
- cheapest_price: 1600,
229
- inside: 1600,
230
- outside: 1900,
231
- balcony: 2100,
232
- suite: 2600
233
- },
234
- was_prices: {
235
- inside: 0,
236
- outside: 0,
237
- balcony: 0,
238
- suite: 0
239
- },
240
- link: 'api-link2',
241
- campaigns: [],
242
- extras: {
243
- date: 'April 2024',
244
- duration: '10 nights',
245
- destination: 'Caribbean',
246
- info: 'Additional info'
247
- }
248
- },
249
- {
250
- post_id: 3,
251
- cruise_id: 3,
252
- cruise_title: 'API Cruise 3',
253
- cruise_line: {
254
- name: 'API Line',
255
- link: 'http://line.com',
256
- logo: 'logo.png'
257
- },
258
- ship: {
259
- name: 'API Ship 3',
260
- link: 'http://ship.com',
261
- image: 'api-image3.jpg'
262
- },
263
- departs: '2026-05-01',
264
- ends: '2026-05-11',
265
- date_label: 'May 2024',
266
- destination: ['Port 3', 'Port 5'],
267
- duration: 10,
268
- itinerary: ['Port 3', 'Port 4', 'Port 5'],
269
- prices: {
270
- cheapest_price: 1700,
271
- inside: 1700,
272
- outside: 2000,
273
- balcony: 2200,
274
- suite: 2700
275
- },
276
- was_prices: {
277
- inside: 2100,
278
- outside: 2400,
279
- balcony: 2600,
280
- suite: 3100
281
- },
282
- link: 'api-link3',
283
- campaigns: [],
284
- extras: {
285
- date: 'May 2024',
286
- duration: '10 nights',
287
- destination: 'Alaska',
288
- info: 'Additional info'
289
- }
290
- }
291
- ]
292
- };
293
-
294
- (global.fetch as jest.Mock).mockResolvedValue({
295
- ok: true,
296
- json: async () => mockApiResponse
297
- });
298
-
299
- render(<TripCards element={mockElement} />);
300
-
301
- await waitFor(() => {
302
- expect(screen.getByText('API Cruise 1')).toBeInTheDocument();
303
- });
304
- });
305
-
306
- it('sends correct request to API', async () => {
307
- const mockApiResponse = {
308
- results: mockCards.map((card, index) => ({
309
- post_id: index + 1,
310
- cruise_id: parseInt(card.cruise_id, 10),
311
- cruise_title: card.headline,
312
- cruise_line: {
313
- name: 'Test Line',
314
- link: card.logo_url,
315
- logo: card.logo
316
- },
317
- ship: {
318
- name: card.ship,
319
- link: 'http://ship.com',
320
- image: card.image
321
- },
322
- departs: '2026-01-01',
323
- ends: '2026-01-11',
324
- date_label: card.date,
325
- destination: ['Test Port'],
326
- duration: 10,
327
- itinerary: ['Port 1', 'Port 2', 'Port 3'],
328
- prices: {
329
- cheapest_price: 1500,
330
- inside: 1500,
331
- outside: 1800,
332
- balcony: 2000,
333
- suite: 2500
334
- },
335
- was_prices: {
336
- inside: 0,
337
- outside: 0,
338
- balcony: 0,
339
- suite: 0
340
- },
341
- link: card.cta_url,
342
- campaigns: [],
343
- extras: {
344
- date: card.date,
345
- duration: card.duration,
346
- destination: 'Test',
347
- info: 'Info'
348
- }
349
- }))
350
- };
351
-
352
- (global.fetch as jest.Mock).mockResolvedValue({
353
- ok: true,
354
- json: async () => mockApiResponse
355
- });
356
-
357
- render(<TripCards element={mockElement} />);
358
-
359
- await waitFor(() => {
360
- expect(global.fetch).toHaveBeenCalledWith(
361
- 'https://www.staging-thetimes.com/holidays/wp-admin/admin-ajax.php',
362
- expect.objectContaining({
363
- method: 'POST',
364
- body: expect.any(FormData)
365
- })
366
- );
367
- });
368
- });
369
- });
370
-
371
- describe('Layout', () => {
372
- it('uses static grid for exactly 2 cards', async () => {
373
- const twoCardElement: TripCardsElement = {
374
- ...mockElement,
375
- tripcards: btoa(JSON.stringify([1, 2]))
376
- };
377
-
378
- render(<TripCards element={twoCardElement} useMockData={true} />);
379
-
380
- await waitFor(() => {
381
- expect(screen.getByText('Mock Cruise 1')).toBeInTheDocument();
382
- });
383
-
384
- expect(screen.queryByLabelText('Previous items')).not.toBeInTheDocument();
385
- });
386
-
387
- it('uses carousel for more than 2 cards', async () => {
388
- const threeCards = [
389
- ...mockCards,
390
- {
391
- cruise_id: '3',
392
- image: 'image3.jpg',
393
- headline: 'Mock Cruise 3',
394
- date: 'Mar 2024',
395
- duration: '21 nights',
396
- route: 'Route 3',
397
- ship: 'Ship 3',
398
- price: '£3000',
399
- original_price: undefined,
400
- logo: 'logo3.png',
401
- logo_url: 'https://example.com',
402
- cta_url: 'link3',
403
- cta_text: 'View'
404
- }
405
- ];
406
-
407
- jest
408
- .spyOn(mockDataModule, 'getMockTripCards')
409
- .mockReturnValue(threeCards);
410
-
411
- render(<TripCards element={mockElement} useMockData={true} />);
412
-
413
- await waitFor(() => {
414
- expect(screen.getByText('Mock Cruise 1')).toBeInTheDocument();
415
- expect(screen.getByLabelText('Previous items')).toBeInTheDocument();
416
- expect(screen.getByLabelText('Next items')).toBeInTheDocument();
417
- });
418
- });
419
- });
420
-
421
- describe('Responsive Behavior', () => {
422
- it('handles window resize', () => {
423
- const { unmount } = render(
424
- <TripCards element={mockElement} useMockData={true} />
425
- );
426
-
427
- const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
428
-
429
- unmount();
430
-
431
- expect(removeEventListenerSpy).toHaveBeenCalledWith(
432
- 'resize',
433
- expect.any(Function)
434
- );
435
- });
436
- });
437
-
438
- describe('Props', () => {
439
- it('renders empty title when not provided', async () => {
440
- const elementWithoutTitle: TripCardsElement = {
441
- ...mockElement,
442
- title: undefined
443
- };
444
-
445
- render(<TripCards element={elementWithoutTitle} useMockData={true} />);
446
-
447
- await waitFor(() => {
448
- const titleElement = screen.getByTestId('trip-cards-title');
449
- expect(titleElement).toBeInTheDocument();
450
- expect(titleElement).toBeEmptyDOMElement();
451
- });
452
- });
453
-
454
- it('renders empty description when not provided', async () => {
455
- const elementWithoutDesc: TripCardsElement = {
456
- ...mockElement,
457
- description: undefined
458
- };
459
-
460
- render(<TripCards element={elementWithoutDesc} useMockData={true} />);
461
-
462
- await waitFor(() => {
463
- const descElement = screen.getByTestId('trip-cards-subtitle');
464
- expect(descElement).toBeInTheDocument();
465
- expect(descElement).toBeEmptyDOMElement();
466
- });
467
- });
468
-
469
- it('renders title link when provided', async () => {
470
- render(<TripCards element={mockElement} useMockData={true} />);
471
-
472
- await waitFor(() => {
473
- const link = screen.getByTestId('title-link');
474
- expect(link).toHaveAttribute('href', 'https://example.com');
475
- expect(link).toHaveAttribute('target', '_blank');
476
- });
477
- });
478
-
479
- it('does not render title link when not provided', async () => {
480
- const elementWithoutLink: TripCardsElement = {
481
- ...mockElement,
482
- titleurl: undefined
483
- };
484
-
485
- render(<TripCards element={elementWithoutLink} useMockData={true} />);
486
-
487
- await waitFor(() => {
488
- expect(screen.getByText('Mock Cruise 1')).toBeInTheDocument();
489
- });
490
-
491
- const links = screen.getAllByRole('link');
492
- expect(links.length).toBeGreaterThan(0);
493
- });
494
- });
495
- });
@@ -1,67 +0,0 @@
1
- import { getMockTripCards, mockApiResults } from '../mockData';
2
-
3
- describe('mockData', () => {
4
- describe('mockApiResults', () => {
5
- it('contains 6 cruise results', () => {
6
- expect(mockApiResults).toHaveLength(6);
7
- });
8
-
9
- it('each result has required fields', () => {
10
- mockApiResults.forEach(result => {
11
- expect(result).toHaveProperty('cruise_id');
12
- expect(result).toHaveProperty('cruise_title');
13
- expect(result).toHaveProperty('cruise_line');
14
- expect(result).toHaveProperty('ship');
15
- expect(result).toHaveProperty('prices');
16
- expect(result).toHaveProperty('was_prices');
17
- expect(result).toHaveProperty('extras');
18
- });
19
- });
20
-
21
- it('extras object contains required fields', () => {
22
- mockApiResults.forEach(result => {
23
- expect(result.extras).toHaveProperty('date');
24
- expect(result.extras).toHaveProperty('duration');
25
- expect(result.extras).toHaveProperty('destination');
26
- expect(result.extras).toHaveProperty('info');
27
- });
28
- });
29
- });
30
-
31
- describe('getMockTripCards', () => {
32
- it('returns all transformed cards when no count specified', () => {
33
- const cards = getMockTripCards();
34
-
35
- expect(cards).toHaveLength(6);
36
- });
37
-
38
- it('returns specified number of cards', () => {
39
- const cards = getMockTripCards(3);
40
-
41
- expect(cards).toHaveLength(3);
42
- });
43
-
44
- it('returns transformed TripCardApiData objects', () => {
45
- const cards = getMockTripCards(1);
46
-
47
- expect(cards[0]).toHaveProperty('cruise_id');
48
- expect(cards[0]).toHaveProperty('image');
49
- expect(cards[0]).toHaveProperty('headline');
50
- expect(cards[0]).toHaveProperty('date');
51
- expect(cards[0]).toHaveProperty('duration');
52
- expect(cards[0]).toHaveProperty('route');
53
- expect(cards[0]).toHaveProperty('ship');
54
- expect(cards[0]).toHaveProperty('price');
55
- expect(cards[0]).toHaveProperty('logo');
56
- expect(cards[0]).toHaveProperty('logo_url');
57
- expect(cards[0]).toHaveProperty('cta_url');
58
- expect(cards[0]).toHaveProperty('cta_text');
59
- });
60
-
61
- it('cruise_id is converted to string', () => {
62
- const cards = getMockTripCards(1);
63
-
64
- expect(typeof cards[0].cruise_id).toBe('string');
65
- });
66
- });
67
- });