@akinon/next 1.93.0-rc.49 → 1.93.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +36 -1260
  2. package/__tests__/next-config.test.ts +10 -1
  3. package/bin/pz-prebuild.js +1 -0
  4. package/components/accordion.tsx +5 -20
  5. package/components/file-input.tsx +3 -65
  6. package/components/input.tsx +0 -2
  7. package/components/link.tsx +12 -16
  8. package/components/modal.tsx +16 -32
  9. package/components/plugin-module.tsx +3 -35
  10. package/components/selected-payment-option-view.tsx +0 -11
  11. package/data/client/checkout.ts +4 -25
  12. package/data/server/category.ts +28 -48
  13. package/data/server/flatpage.ts +12 -16
  14. package/data/server/landingpage.ts +12 -16
  15. package/data/server/list.ts +13 -23
  16. package/data/server/product.ts +39 -66
  17. package/data/server/special-page.ts +12 -16
  18. package/data/urls.ts +2 -7
  19. package/hocs/server/with-segment-defaults.tsx +2 -5
  20. package/hooks/use-localization.ts +3 -2
  21. package/instrumentation/node.ts +13 -15
  22. package/jest.config.js +1 -7
  23. package/lib/cache.ts +0 -2
  24. package/middlewares/checkout-provider.ts +1 -1
  25. package/middlewares/complete-gpay.ts +2 -6
  26. package/middlewares/complete-masterpass.ts +2 -7
  27. package/middlewares/default.ts +183 -232
  28. package/middlewares/index.ts +1 -3
  29. package/middlewares/locale.ts +1 -9
  30. package/middlewares/redirection-payment.ts +2 -6
  31. package/middlewares/saved-card-redirection.ts +2 -7
  32. package/middlewares/three-d-redirection.ts +2 -7
  33. package/middlewares/url-redirection.ts +15 -9
  34. package/package.json +3 -3
  35. package/plugins.d.ts +0 -10
  36. package/plugins.js +1 -4
  37. package/redux/middlewares/checkout.ts +2 -15
  38. package/redux/reducers/checkout.ts +1 -9
  39. package/sentry/index.ts +17 -54
  40. package/types/commerce/order.ts +0 -1
  41. package/types/index.ts +1 -42
  42. package/utils/app-fetch.ts +2 -7
  43. package/utils/index.ts +10 -34
  44. package/utils/redirect.ts +6 -31
  45. package/with-pz-config.js +5 -1
  46. package/__tests__/redirect.test.ts +0 -758
  47. package/api/image-proxy.ts +0 -75
  48. package/api/similar-product-list.ts +0 -84
  49. package/api/similar-products.ts +0 -120
  50. package/data/server/basket.ts +0 -72
  51. package/hooks/use-loyalty-availability.ts +0 -21
  52. package/middlewares/wallet-complete-redirection.ts +0 -203
  53. package/utils/redirect-ignore.ts +0 -35
@@ -1,758 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
-
4
- interface Locale {
5
- value: string;
6
- label: string;
7
- localePath?: string;
8
- apiValue?: string;
9
- rtl?: boolean;
10
- }
11
-
12
- const mockNextRedirect = jest.fn();
13
- const mockHeaders = jest.fn();
14
- const mockCookies = jest.fn();
15
-
16
- function findBaseDir() {
17
- const insideNodeModules = __dirname.includes('node_modules');
18
-
19
- if (insideNodeModules) {
20
- return path.resolve(__dirname, '../../../../');
21
- } else {
22
- return path.resolve(__dirname, '../../../apps/projectzeronext');
23
- }
24
- }
25
-
26
- jest.mock(
27
- '@theme/routes',
28
- () => ({
29
- ROUTES: {
30
- AUTH: '/auth',
31
- BASKET: '/basket',
32
- ACCOUNT_ORDERS: '/account/orders'
33
- }
34
- }),
35
- { virtual: true }
36
- );
37
-
38
- jest.mock('next/navigation', () => ({
39
- redirect: mockNextRedirect,
40
- RedirectType: {
41
- replace: 'replace',
42
- push: 'push'
43
- }
44
- }));
45
-
46
- jest.mock('next/headers', () => ({
47
- headers: () => mockHeaders(),
48
- cookies: () => mockCookies()
49
- }));
50
-
51
- const mockServerVariables = {
52
- locale: 'en' as string | undefined
53
- };
54
-
55
- jest.mock('@akinon/next/utils/server-variables', () => ({
56
- ServerVariables: mockServerVariables
57
- }));
58
-
59
- jest.mock('@akinon/next/utils', () => ({
60
- urlLocaleMatcherRegex: /^\/(?:tr)(?=\/|$)/
61
- }));
62
-
63
- const mockSettings = {
64
- localization: {
65
- defaultLocaleValue: 'en',
66
- localeUrlStrategy: 'hide-default-locale',
67
- locales: [
68
- { value: 'en', label: 'EN' },
69
- { value: 'tr', label: 'TR' }
70
- ]
71
- }
72
- };
73
-
74
- jest.mock('settings', () => mockSettings, { virtual: true });
75
-
76
- describe('Redirect utility functional tests', () => {
77
- let redirect: any;
78
- let getUrlPathWithLocale: any;
79
- let LocaleUrlStrategy: any;
80
- let actualSettings: any;
81
-
82
- beforeAll(async () => {
83
- try {
84
- const baseDir = findBaseDir();
85
- const settingsPath = path.resolve(baseDir, 'src/settings.js');
86
- actualSettings = require(settingsPath);
87
-
88
- Object.assign(mockSettings.localization, actualSettings.localization);
89
-
90
- const nonDefaultLocales = actualSettings.localization.locales
91
- .filter(
92
- (locale: Locale) =>
93
- locale.value !== actualSettings.localization.defaultLocaleValue
94
- )
95
- .map((locale: Locale) => locale.value);
96
- if (nonDefaultLocales.length > 0) {
97
- jest.doMock('@akinon/next/utils', () => ({
98
- urlLocaleMatcherRegex: new RegExp(
99
- `^\\/(${nonDefaultLocales.join('|')})(?=\\/|$)`
100
- )
101
- }));
102
- } else {
103
- jest.doMock('@akinon/next/utils', () => ({
104
- urlLocaleMatcherRegex: /^\/(?!.*)/
105
- }));
106
- console.log('No non-default locales found, using empty regex');
107
- }
108
- } catch (error) {
109
- console.warn(
110
- 'Could not load actual settings, using default mock settings'
111
- );
112
-
113
- jest.doMock('@akinon/next/utils', () => ({
114
- urlLocaleMatcherRegex: /^\/(?!.*)/
115
- }));
116
- console.log('Using fallback empty regex (no locale matching)');
117
- }
118
-
119
- const localizationModule = await import('@akinon/next/localization');
120
- LocaleUrlStrategy = localizationModule.LocaleUrlStrategy;
121
-
122
- const redirectModule = await import('@akinon/next/utils/redirect');
123
- redirect = redirectModule.redirect;
124
-
125
- const localizationUtilsModule = await import(
126
- '@akinon/next/utils/localization'
127
- );
128
- getUrlPathWithLocale = localizationUtilsModule.getUrlPathWithLocale;
129
- });
130
-
131
- beforeEach(() => {
132
- jest.clearAllMocks();
133
- process.env.NEXT_PUBLIC_URL = 'https://example.com';
134
-
135
- mockServerVariables.locale =
136
- actualSettings?.localization?.defaultLocaleValue || 'en';
137
-
138
- mockCookies.mockReturnValue({
139
- get: jest.fn().mockReturnValue(undefined)
140
- });
141
-
142
- mockHeaders.mockReturnValue(new Map());
143
- });
144
-
145
- describe('getUrlPathWithLocale functional tests', () => {
146
- describe('Dynamic behavior based on actual settings', () => {
147
- it('should work correctly with project localeUrlStrategy', () => {
148
- const defaultLocale =
149
- actualSettings?.localization?.defaultLocaleValue || 'en';
150
- const strategy =
151
- actualSettings?.localization?.localeUrlStrategy ||
152
- LocaleUrlStrategy.HideDefaultLocale;
153
- const locales = actualSettings?.localization?.locales || [
154
- { value: 'en', label: 'EN' },
155
- { value: 'tr', label: 'TR' }
156
- ];
157
-
158
- const result1 = getUrlPathWithLocale('/login', defaultLocale);
159
-
160
- const nonDefaultLocale = locales.find(
161
- (locale: Locale) => locale.value !== defaultLocale
162
- );
163
- const result2 = nonDefaultLocale
164
- ? getUrlPathWithLocale('/login', nonDefaultLocale.value)
165
- : null;
166
-
167
- const result3 = getUrlPathWithLocale('/login', undefined);
168
-
169
- if (strategy === LocaleUrlStrategy.HideDefaultLocale) {
170
- expect(result1).toBe('/login');
171
- if (result2 && nonDefaultLocale) {
172
- expect(result2).toBe(`/${nonDefaultLocale.value}/login`);
173
- }
174
- expect(result3).toBe('/login');
175
- } else if (strategy === LocaleUrlStrategy.ShowAllLocales) {
176
- expect(result1).toBe(`/${defaultLocale}/login`);
177
- if (result2 && nonDefaultLocale) {
178
- expect(result2).toBe(`/${nonDefaultLocale.value}/login`);
179
- }
180
- expect(result3).toBe(`/${defaultLocale}/login`);
181
- } else if (strategy === LocaleUrlStrategy.HideAllLocales) {
182
- expect(result1).toBe('/login');
183
- if (result2) {
184
- expect(result2).toBe('/login');
185
- }
186
- expect(result3).toBe('/login');
187
- } else if (strategy === LocaleUrlStrategy.Subdomain) {
188
- expect(result1).toBe('/login');
189
- if (result2) {
190
- expect(result2).toBe('/login');
191
- }
192
- expect(result3).toBe('/login');
193
- }
194
- });
195
-
196
- it('should handle complex paths correctly with project settings', () => {
197
- const defaultLocale =
198
- actualSettings?.localization?.defaultLocaleValue || 'en';
199
- const locales = actualSettings?.localization?.locales || [
200
- { value: 'en', label: 'EN' },
201
- { value: 'tr', label: 'TR' }
202
- ];
203
- const strategy =
204
- actualSettings?.localization?.localeUrlStrategy ||
205
- LocaleUrlStrategy.HideDefaultLocale;
206
-
207
- const complexPath = '/account/orders/123';
208
- const nonDefaultLocale = locales.find(
209
- (locale: Locale) => locale.value !== defaultLocale
210
- );
211
-
212
- const result1 = getUrlPathWithLocale(complexPath, defaultLocale);
213
- const result2 = nonDefaultLocale
214
- ? getUrlPathWithLocale(complexPath, nonDefaultLocale.value)
215
- : null;
216
-
217
- if (strategy === LocaleUrlStrategy.HideDefaultLocale) {
218
- expect(result1).toBe(complexPath);
219
- if (result2 && nonDefaultLocale) {
220
- expect(result2).toBe(`/${nonDefaultLocale.value}${complexPath}`);
221
- }
222
- } else if (strategy === LocaleUrlStrategy.ShowAllLocales) {
223
- expect(result1).toBe(`/${defaultLocale}${complexPath}`);
224
- if (result2 && nonDefaultLocale) {
225
- expect(result2).toBe(`/${nonDefaultLocale.value}${complexPath}`);
226
- }
227
- }
228
- });
229
-
230
- it('should handle query parameters correctly', () => {
231
- const defaultLocale =
232
- actualSettings?.localization?.defaultLocaleValue || 'en';
233
- const locales = actualSettings?.localization?.locales || [
234
- { value: 'en', label: 'EN' },
235
- { value: 'tr', label: 'TR' }
236
- ];
237
- const strategy =
238
- actualSettings?.localization?.localeUrlStrategy ||
239
- LocaleUrlStrategy.HideDefaultLocale;
240
-
241
- const pathWithQuery = '/search?q=test';
242
- const nonDefaultLocale = locales.find(
243
- (locale: Locale) => locale.value !== defaultLocale
244
- );
245
-
246
- const result1 = getUrlPathWithLocale(pathWithQuery, defaultLocale);
247
- const result2 = nonDefaultLocale
248
- ? getUrlPathWithLocale(pathWithQuery, nonDefaultLocale.value)
249
- : null;
250
-
251
- if (strategy === LocaleUrlStrategy.HideDefaultLocale) {
252
- expect(result1).toBe(pathWithQuery);
253
- if (result2 && nonDefaultLocale) {
254
- expect(result2).toBe(`/${nonDefaultLocale.value}${pathWithQuery}`);
255
- }
256
- } else if (strategy === LocaleUrlStrategy.ShowAllLocales) {
257
- expect(result1).toBe(`/${defaultLocale}${pathWithQuery}`);
258
- if (result2 && nonDefaultLocale) {
259
- expect(result2).toBe(`/${nonDefaultLocale.value}${pathWithQuery}`);
260
- }
261
- }
262
- });
263
- });
264
- });
265
-
266
- describe('URL locale matcher regex behavior', () => {
267
- it('should match non-default locale prefixes based on project settings', () => {
268
- const defaultLocale =
269
- actualSettings?.localization?.defaultLocaleValue || 'en';
270
- const locales = actualSettings?.localization?.locales || [
271
- { value: 'en', label: 'EN' },
272
- { value: 'tr', label: 'TR' }
273
- ];
274
-
275
- const nonDefaultLocales = locales
276
- .filter((locale: Locale) => locale.value !== defaultLocale)
277
- .map((locale: Locale) => locale.value);
278
-
279
- const urlLocaleMatcherRegex = new RegExp(
280
- `^\\/(${nonDefaultLocales.join('|')})(?=\\/|$)`
281
- );
282
-
283
- nonDefaultLocales.forEach((locale: string) => {
284
- expect(urlLocaleMatcherRegex.test(`/${locale}/profile`)).toBe(true);
285
- expect(urlLocaleMatcherRegex.test(`/${locale}`)).toBe(true);
286
- });
287
-
288
- expect(urlLocaleMatcherRegex.test(`/${defaultLocale}/profile`)).toBe(
289
- false
290
- );
291
- expect(urlLocaleMatcherRegex.test('/profile')).toBe(false);
292
- });
293
-
294
- it('should handle callback URL extraction correctly with project locales', () => {
295
- const defaultLocale =
296
- actualSettings?.localization?.defaultLocaleValue || 'en';
297
- const locales = actualSettings?.localization?.locales || [
298
- { value: 'en', label: 'EN' },
299
- { value: 'tr', label: 'TR' }
300
- ];
301
-
302
- const nonDefaultLocales = locales
303
- .filter((locale: Locale) => locale.value !== defaultLocale)
304
- .map((locale: Locale) => locale.value);
305
-
306
- const urlLocaleMatcherRegex = new RegExp(
307
- `^\\/(${nonDefaultLocales.join('|')})(?=\\/|$)`
308
- );
309
-
310
- const testPaths = [
311
- ...nonDefaultLocales.map((locale: string) => ({
312
- input: `/${locale}/profile`,
313
- expected: '/profile'
314
- })),
315
- { input: '/profile', expected: '/profile' },
316
- {
317
- input: `/${defaultLocale}/profile`,
318
- expected: `/${defaultLocale}/profile`
319
- }
320
- ];
321
-
322
- testPaths.forEach(({ input, expected }) => {
323
- const result = input.replace(urlLocaleMatcherRegex, '');
324
- expect(result).toBe(expected);
325
- });
326
- });
327
- });
328
-
329
- describe('redirect function behavior', () => {
330
- describe('Default locale strategy tests', () => {
331
- beforeEach(() => {
332
- const defaultLocale =
333
- actualSettings?.localization?.defaultLocaleValue || 'en';
334
- mockServerVariables.locale = defaultLocale;
335
- });
336
-
337
- it('should redirect with correct URL for default locale', () => {
338
- mockHeaders.mockReturnValue(
339
- new Map([['pz-url', 'https://example.com/profile']])
340
- );
341
-
342
- redirect('/login');
343
-
344
- expect(mockNextRedirect).toHaveBeenCalledWith(
345
- '/login?callbackUrl=/profile'
346
- );
347
- });
348
-
349
- it('should redirect with locale handling for non-default locale', () => {
350
- const locales = actualSettings?.localization?.locales || [
351
- { value: 'en', label: 'EN' },
352
- { value: 'tr', label: 'TR' }
353
- ];
354
- const defaultLocale =
355
- actualSettings?.localization?.defaultLocaleValue || 'en';
356
- const nonDefaultLocale = locales.find(
357
- (locale: Locale) => locale.value !== defaultLocale
358
- );
359
-
360
- if (nonDefaultLocale) {
361
- mockServerVariables.locale = nonDefaultLocale.value;
362
- mockHeaders.mockReturnValue(
363
- new Map([
364
- [
365
- 'pz-url',
366
- `https://example.com/${nonDefaultLocale.value}/profile`
367
- ]
368
- ])
369
- );
370
-
371
- redirect('/login');
372
-
373
- expect(mockNextRedirect).toHaveBeenCalledWith(
374
- `/${nonDefaultLocale.value}/login?callbackUrl=/profile`
375
- );
376
- } else {
377
- expect(true).toBe(true);
378
- }
379
- });
380
-
381
- it('should extract callback URL correctly removing locale prefix', () => {
382
- const locales = actualSettings?.localization?.locales || [
383
- { value: 'en', label: 'EN' },
384
- { value: 'tr', label: 'TR' }
385
- ];
386
- const defaultLocale =
387
- actualSettings?.localization?.defaultLocaleValue || 'en';
388
- const nonDefaultLocale = locales.find(
389
- (locale: Locale) => locale.value !== defaultLocale
390
- );
391
-
392
- if (nonDefaultLocale) {
393
- mockServerVariables.locale = nonDefaultLocale.value;
394
- mockHeaders.mockReturnValue(
395
- new Map([
396
- [
397
- 'pz-url',
398
- `https://example.com/${nonDefaultLocale.value}/dashboard/settings`
399
- ]
400
- ])
401
- );
402
-
403
- redirect('/auth');
404
-
405
- expect(mockNextRedirect).toHaveBeenCalledWith(
406
- `/${nonDefaultLocale.value}/auth?callbackUrl=/dashboard/settings`
407
- );
408
- } else {
409
- expect(true).toBe(true);
410
- }
411
- });
412
-
413
- it('should handle RTL or additional locale correctly if available', () => {
414
- const locales = actualSettings?.localization?.locales || [
415
- { value: 'en', label: 'EN' },
416
- { value: 'tr', label: 'TR' }
417
- ];
418
- const defaultLocale =
419
- actualSettings?.localization?.defaultLocaleValue || 'en';
420
- const rtlLocale = locales.find(
421
- (locale: Locale) =>
422
- locale.value !== defaultLocale && locale.value !== 'tr'
423
- );
424
-
425
- if (rtlLocale) {
426
- mockServerVariables.locale = rtlLocale.value;
427
- mockHeaders.mockReturnValue(
428
- new Map([
429
- ['pz-url', `https://example.com/${rtlLocale.value}/products/123`]
430
- ])
431
- );
432
-
433
- redirect('/checkout');
434
-
435
- expect(mockNextRedirect).toHaveBeenCalledWith(
436
- `/${rtlLocale.value}/checkout?callbackUrl=/products/123`
437
- );
438
- } else {
439
- const nonDefaultLocale = locales.find(
440
- (locale: Locale) => locale.value !== defaultLocale
441
- );
442
- if (nonDefaultLocale) {
443
- mockServerVariables.locale = nonDefaultLocale.value;
444
- mockHeaders.mockReturnValue(
445
- new Map([
446
- [
447
- 'pz-url',
448
- `https://example.com/${nonDefaultLocale.value}/products/123`
449
- ]
450
- ])
451
- );
452
-
453
- redirect('/checkout');
454
-
455
- expect(mockNextRedirect).toHaveBeenCalledWith(
456
- `/${nonDefaultLocale.value}/checkout?callbackUrl=/products/123`
457
- );
458
- } else {
459
- expect(true).toBe(true);
460
- }
461
- }
462
- });
463
-
464
- it('should preserve complex callback URLs', () => {
465
- mockServerVariables.locale = 'tr';
466
- mockHeaders.mockReturnValue(
467
- new Map([
468
- ['pz-url', 'https://example.com/tr/account/orders/123/details']
469
- ])
470
- );
471
-
472
- redirect('/auth/login');
473
-
474
- expect(mockNextRedirect).toHaveBeenCalledWith(
475
- '/tr/auth/login?callbackUrl=/account/orders/123/details'
476
- );
477
- });
478
- });
479
-
480
- describe('Redirect type handling', () => {
481
- beforeEach(() => {
482
- mockHeaders.mockReturnValue(
483
- new Map([['pz-url', 'https://example.com/profile']])
484
- );
485
- });
486
-
487
- it('should pass RedirectType when provided', () => {
488
- const { RedirectType } = require('next/navigation');
489
-
490
- redirect('/login', RedirectType.replace);
491
-
492
- expect(mockNextRedirect).toHaveBeenCalledTimes(1);
493
- const [redirectUrl, type] = mockNextRedirect.mock.calls[0];
494
- expect(redirectUrl).toContain('/login');
495
- expect(type).toBe(RedirectType.replace);
496
- });
497
-
498
- it('should call redirect without type when not provided', () => {
499
- redirect('/login');
500
-
501
- expect(mockNextRedirect).toHaveBeenCalledTimes(1);
502
- const args = mockNextRedirect.mock.calls[0];
503
- expect(args.length).toBe(1);
504
- });
505
- });
506
-
507
- describe('Error handling and edge cases', () => {
508
- it('should handle missing pz-url header with env fallback', () => {
509
- mockHeaders.mockReturnValue(new Map());
510
- process.env.NEXT_PUBLIC_URL = 'https://fallback.com/some/path';
511
-
512
- redirect('/login');
513
-
514
- expect(mockNextRedirect).toHaveBeenCalledWith(
515
- '/login?callbackUrl=/some/path'
516
- );
517
- });
518
-
519
- it('should handle completely missing URL sources gracefully', () => {
520
- mockHeaders.mockReturnValue(new Map());
521
- const originalEnv = process.env.NEXT_PUBLIC_URL;
522
- delete process.env.NEXT_PUBLIC_URL;
523
-
524
- expect(() => {
525
- redirect('/login');
526
- }).toThrow('Invalid URL');
527
-
528
- process.env.NEXT_PUBLIC_URL = originalEnv;
529
- });
530
-
531
- it('should handle undefined locale gracefully', () => {
532
- mockServerVariables.locale = undefined;
533
- mockHeaders.mockReturnValue(
534
- new Map([['pz-url', 'https://example.com/profile']])
535
- );
536
-
537
- // Should not throw error, should handle gracefully
538
- expect(() => {
539
- redirect('/login');
540
- }).not.toThrow();
541
-
542
- expect(mockNextRedirect).toHaveBeenCalledWith(
543
- '/login?callbackUrl=/profile'
544
- );
545
- });
546
-
547
- it('should handle invalid locale gracefully', () => {
548
- mockServerVariables.locale = 'invalid-locale';
549
- mockHeaders.mockReturnValue(
550
- new Map([['pz-url', 'https://example.com/profile']])
551
- );
552
-
553
- // Should not throw error, should handle gracefully
554
- expect(() => {
555
- redirect('/login');
556
- }).not.toThrow();
557
-
558
- expect(mockNextRedirect).toHaveBeenCalledWith(
559
- '/login?callbackUrl=/profile'
560
- );
561
- });
562
-
563
- it('should preserve query parameters in callback URL', () => {
564
- mockHeaders.mockReturnValue(
565
- new Map([
566
- ['pz-url', 'https://example.com/profile?tab=settings&view=list']
567
- ])
568
- );
569
-
570
- redirect('/login');
571
-
572
- expect(mockNextRedirect).toHaveBeenCalledWith(
573
- '/login?callbackUrl=/profile?tab=settings&view=list'
574
- );
575
- });
576
-
577
- it('should strip fragments from callback URL (expected behavior)', () => {
578
- mockHeaders.mockReturnValue(
579
- new Map([['pz-url', 'https://example.com/profile#section']])
580
- );
581
-
582
- redirect('/login');
583
-
584
- expect(mockNextRedirect).toHaveBeenCalledWith(
585
- '/login?callbackUrl=/profile'
586
- );
587
- });
588
-
589
- it('should handle URL with both query params and fragments (fragments stripped)', () => {
590
- mockHeaders.mockReturnValue(
591
- new Map([['pz-url', 'https://example.com/profile?tab=orders#recent']])
592
- );
593
-
594
- redirect('/auth');
595
-
596
- expect(mockNextRedirect).toHaveBeenCalledWith(
597
- '/auth?callbackUrl=/profile?tab=orders'
598
- );
599
- });
600
- });
601
- });
602
-
603
- describe('Integration scenarios', () => {
604
- it('should handle complete flow with non-default locale and complex path', () => {
605
- const locales = actualSettings?.localization?.locales || [
606
- { value: 'en', label: 'EN' },
607
- { value: 'tr', label: 'TR' }
608
- ];
609
- const defaultLocale =
610
- actualSettings?.localization?.defaultLocaleValue || 'en';
611
- const nonDefaultLocale = locales.find(
612
- (locale: Locale) => locale.value !== defaultLocale
613
- );
614
-
615
- if (nonDefaultLocale) {
616
- mockServerVariables.locale = nonDefaultLocale.value;
617
- mockHeaders.mockReturnValue(
618
- new Map([
619
- [
620
- 'pz-url',
621
- `https://example.com/${nonDefaultLocale.value}/account/orders/123`
622
- ]
623
- ])
624
- );
625
-
626
- redirect('/auth/login');
627
-
628
- expect(mockNextRedirect).toHaveBeenCalledWith(
629
- `/${nonDefaultLocale.value}/auth/login?callbackUrl=/account/orders/123`
630
- );
631
- } else {
632
- expect(true).toBe(true);
633
- }
634
- });
635
-
636
- it('should handle additional locale with deep nested paths if available', () => {
637
- const locales = actualSettings?.localization?.locales || [
638
- { value: 'en', label: 'EN' },
639
- { value: 'tr', label: 'TR' }
640
- ];
641
- const defaultLocale =
642
- actualSettings?.localization?.defaultLocaleValue || 'en';
643
- const additionalLocale = locales.find(
644
- (locale: Locale) =>
645
- locale.value !== defaultLocale && locale.value !== 'tr'
646
- );
647
-
648
- if (additionalLocale) {
649
- mockServerVariables.locale = additionalLocale.value;
650
- mockHeaders.mockReturnValue(
651
- new Map([
652
- [
653
- 'pz-url',
654
- `https://example.com/${additionalLocale.value}/products/category/electronics/item/456`
655
- ]
656
- ])
657
- );
658
-
659
- redirect('/auth');
660
-
661
- expect(mockNextRedirect).toHaveBeenCalledWith(
662
- `/${additionalLocale.value}/auth?callbackUrl=/products/category/electronics/item/456`
663
- );
664
- } else {
665
- const nonDefaultLocale = locales.find(
666
- (locale: Locale) => locale.value !== defaultLocale
667
- );
668
- if (nonDefaultLocale) {
669
- mockServerVariables.locale = nonDefaultLocale.value;
670
- mockHeaders.mockReturnValue(
671
- new Map([
672
- [
673
- 'pz-url',
674
- `https://example.com/${nonDefaultLocale.value}/products/category/electronics/item/456`
675
- ]
676
- ])
677
- );
678
-
679
- redirect('/auth');
680
-
681
- expect(mockNextRedirect).toHaveBeenCalledWith(
682
- `/${nonDefaultLocale.value}/auth?callbackUrl=/products/category/electronics/item/456`
683
- );
684
- } else {
685
- expect(true).toBe(true);
686
- }
687
- }
688
- });
689
-
690
- it('should handle default locale with no prefix in callback', () => {
691
- const defaultLocale =
692
- actualSettings?.localization?.defaultLocaleValue || 'en';
693
- mockServerVariables.locale = defaultLocale;
694
- mockHeaders.mockReturnValue(
695
- new Map([['pz-url', 'https://example.com/checkout/payment']])
696
- );
697
-
698
- redirect('/auth/login');
699
-
700
- expect(mockNextRedirect).toHaveBeenCalledWith(
701
- '/auth/login?callbackUrl=/checkout/payment'
702
- );
703
- });
704
-
705
- it('should handle complex URLs with mixed locale scenarios', () => {
706
- const locales = actualSettings?.localization?.locales || [
707
- { value: 'en', label: 'EN' },
708
- { value: 'tr', label: 'TR' }
709
- ];
710
- const defaultLocale =
711
- actualSettings?.localization?.defaultLocaleValue || 'en';
712
- const nonDefaultLocale = locales.find(
713
- (locale: Locale) => locale.value !== defaultLocale
714
- );
715
-
716
- if (nonDefaultLocale) {
717
- mockServerVariables.locale = nonDefaultLocale.value;
718
- mockHeaders.mockReturnValue(
719
- new Map([
720
- [
721
- 'pz-url',
722
- `https://subdomain.example.com/${nonDefaultLocale.value}/user/dashboard?section=profile&tab=settings#preferences`
723
- ]
724
- ])
725
- );
726
-
727
- redirect('/verify-account');
728
-
729
- expect(mockNextRedirect).toHaveBeenCalledWith(
730
- `/${nonDefaultLocale.value}/verify-account?callbackUrl=/user/dashboard?section=profile&tab=settings`
731
- );
732
- } else {
733
- expect(true).toBe(true);
734
- }
735
- });
736
- });
737
-
738
- it('should verify redirect utility file exists and has expected structure', () => {
739
- const baseDir = findBaseDir();
740
- const insideNodeModules = __dirname.includes('node_modules');
741
-
742
- let redirectFilePath;
743
- if (insideNodeModules) {
744
- redirectFilePath = path.resolve(__dirname, '../utils/redirect.ts');
745
- } else {
746
- redirectFilePath = path.resolve(
747
- baseDir,
748
- '../../packages/akinon-next/utils/redirect.ts'
749
- );
750
- }
751
-
752
- const redirectFileContent = fs.readFileSync(redirectFilePath, 'utf8');
753
-
754
- expect(redirectFileContent.includes('export const redirect')).toBe(true);
755
- expect(redirectFileContent.includes('getUrlPathWithLocale')).toBe(true);
756
- expect(redirectFileContent.includes('callbackUrl')).toBe(true);
757
- });
758
- });