@faststore/core 4.10.1-dev.0 → 4.10.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.
- package/.turbo/turbo-test.log +152 -144
- package/CHANGELOG.md +4 -2
- package/package.json +6 -6
- package/src/server/content/service.ts +70 -21
- package/test/server/content/service.test.ts +241 -2
package/.turbo/turbo-test.log
CHANGED
|
@@ -7,26 +7,34 @@
|
|
|
7
7
|
|
|
8
8
|
Not implemented: navigation to another Document
|
|
9
9
|
Not implemented: navigation to another Document
|
|
10
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/ui/useScrollRestoration.browser.test.ts [2m([22m[2m43 tests[22m[2m)[22m[33m
|
|
10
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/ui/useScrollRestoration.browser.test.ts [2m([22m[2m43 tests[22m[2m)[22m[33m 1184[2mms[22m[39m
|
|
11
11
|
Browserslist: browsers data (caniuse-lite) is 8 months old. Please run:
|
|
12
12
|
npx update-browserslist-db@latest
|
|
13
13
|
Why you should do it regularly: https://github.com/browserslist/update-db#readme
|
|
14
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/cards/MyAccountListCards.browser.test.tsx [2m([22m[2m16 tests[22m[2m)[22m[33m
|
|
15
|
-
[33m[2m✓[22m[39m shows the tab bar and renders Personal cards by default [33m
|
|
16
|
-
[33m[2m✓[22m[39m paginates when there are more than 25 cards [33m
|
|
17
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/ContractSwitcher.browser.test.tsx [2m([22m[2m22 tests[22m[2m)[22m[33m
|
|
18
|
-
[33m[2m✓[22m[39m shows
|
|
19
|
-
|
|
20
|
-
[33m[2m✓[22m[39m
|
|
21
|
-
[33m[2m✓[22m[39m
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
14
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/cards/MyAccountListCards.browser.test.tsx [2m([22m[2m16 tests[22m[2m)[22m[33m 2807[2mms[22m[39m
|
|
15
|
+
[33m[2m✓[22m[39m shows the tab bar and renders Personal cards by default [33m 1154[2mms[22m[39m
|
|
16
|
+
[33m[2m✓[22m[39m paginates when there are more than 25 cards [33m 432[2mms[22m[39m
|
|
17
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/ContractSwitcher.browser.test.tsx [2m([22m[2m22 tests[22m[2m)[22m[33m 4137[2mms[22m[39m
|
|
18
|
+
[33m[2m✓[22m[39m shows a loading state while contracts load [33m 332[2mms[22m[39m
|
|
19
|
+
[33m[2m✓[22m[39m shows an error state when the list fails to load [33m 944[2mms[22m[39m
|
|
20
|
+
[33m[2m✓[22m[39m requires selecting a contract before Confirm is enabled, then switches (REQ-03) [33m 521[2mms[22m[39m
|
|
21
|
+
[33m[2m✓[22m[39m keeps Confirm disabled until a different contract is selected [33m 319[2mms[22m[39m
|
|
22
|
+
[33m[2m✓[22m[39m keeps Confirm disabled when switching is unavailable [33m 388[2mms[22m[39m
|
|
23
|
+
[33m[2m✓[22m[39m keeps Confirm disabled when the selected contract is filtered out [33m 365[2mms[22m[39m
|
|
24
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/BuyingPolicyAlert.browser.test.tsx [2m([22m[2m13 tests[22m[2m)[22m[33m 2904[2mms[22m[39m
|
|
25
|
+
[33m[2m✓[22m[39m opens the reject confirmation modal with the default English copy [33m 1018[2mms[22m[39m
|
|
26
|
+
[33m[2m✓[22m[39m opens the reject confirmation modal with CMS-provided labels [33m 307[2mms[22m[39m
|
|
27
|
+
[33m[2m✓[22m[39m shows the default English toast when a policy is rejected [33m 369[2mms[22m[39m
|
|
28
|
+
[33m[2m✓[22m[39m shows the CMS-provided error toast when rejecting a policy fails [33m 338[2mms[22m[39m
|
|
29
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/RichText/RichText.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[33m 389[2mms[22m[39m
|
|
30
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawer.browser.test.tsx [2m([22m[2m10 tests[22m[2m)[22m[33m 1914[2mms[22m[39m
|
|
31
|
+
[33m[2m✓[22m[39m renders the menu view with contract details and manage footer [33m 1093[2mms[22m[39m
|
|
32
|
+
[33m[2m✓[22m[39m opens the contract switcher and returns to the menu on back [33m 338[2mms[22m[39m
|
|
33
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/CartRecommendationShelf/CartRecommendationShelf.browser.test.tsx [2m([22m[2m13 tests[22m[2m)[22m[33m 301[2mms[22m[39m
|
|
34
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/localization/useBindingSelector.browser.test.tsx [2m([22m[2m9 tests[22m[2m)[22m[32m 66[2mms[22m[39m
|
|
35
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
36
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/ProductGallery/GalleryPageHeightLock.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m 80[2mms[22m[39m
|
|
37
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/recommendations/useRecommendationShelf.browser.test.tsx [2m([22m[2m12 tests[22m[2m)[22m[32m 79[2mms[22m[39m
|
|
30
38
|
[90mstderr[2m | test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx
|
|
31
39
|
[22m[39mError in optimistic validation: TypeError: Failed to parse URL from /api/graphql?operationName=ValidateCartMutation&operationHash=3c71b0d3fc2bade14df68abfa271858beb361b12
|
|
32
40
|
[90m at node:internal/deps/undici/undici:16416:13[39m
|
|
@@ -56,10 +64,10 @@ Browserslist: browsers data (caniuse-lite) is 8 months old. Please run:
|
|
|
56
64
|
[90mstderr[2m | test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx[2m > [22m[2mRecommendationShelf[2m > [22m[2mrenders nothing when there is an error
|
|
57
65
|
[22m[39mError fetching recommendations [90mundefined[39m boom for campaign vrn:recommendations:acc:rec-top-items-v2:campaign-1
|
|
58
66
|
|
|
59
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
60
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/CartSidebar/CartSidebar.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
61
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/getInitialSession.browser.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m
|
|
62
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderDetails.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
67
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/RecommendationShelf/RecommendationShelf.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m 121[2mms[22m[39m
|
|
68
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/CartSidebar/CartSidebar.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 79[2mms[22m[39m
|
|
69
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/getInitialSession.browser.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 21[2mms[22m[39m
|
|
70
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderDetails.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 72[2mms[22m[39m
|
|
63
71
|
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mposts the password and redirects to the requested return path
|
|
64
72
|
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
65
73
|
|
|
@@ -97,7 +105,6 @@ act(() => {
|
|
|
97
105
|
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
98
106
|
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
99
107
|
|
|
100
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/Navbar.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 44[2mms[22m[39m
|
|
101
108
|
[90mstderr[2m | test/pages/password-protection.browser.test.tsx[2m > [22m[2mPasswordProtectionLogin[2m > [22m[2mdefaults returnTo to root and shows API validation errors
|
|
102
109
|
[22m[39mWarning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
|
|
103
110
|
|
|
@@ -290,10 +297,10 @@ act(() => {
|
|
|
290
297
|
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
|
|
291
298
|
at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
|
|
292
299
|
|
|
293
|
-
[32m✓[39m [30m[46m browser [49m[39m test/pages/password-protection.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m
|
|
294
|
-
[33m[2m✓[22m[39m renders the password protection form [33m
|
|
295
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
296
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
300
|
+
[32m✓[39m [30m[46m browser [49m[39m test/pages/password-protection.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m 757[2mms[22m[39m
|
|
301
|
+
[33m[2m✓[22m[39m renders the password protection form [33m 318[2mms[22m[39m
|
|
302
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/Navbar.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 64[2mms[22m[39m
|
|
303
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerFooter.browser.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[33m 513[2mms[22m[39m
|
|
297
304
|
[90mstderr[2m | test/components/cms/RenderSections.browser.test.tsx
|
|
298
305
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
299
306
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -302,8 +309,10 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
302
309
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
303
310
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
304
311
|
|
|
305
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
306
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
312
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/useSwitchContract.browser.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 40[2mms[22m[39m
|
|
313
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/NavbarSlider.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 43[2mms[22m[39m
|
|
314
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/cms/RenderSections.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 70[2mms[22m[39m
|
|
315
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/Menu.browser.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[33m 334[2mms[22m[39m
|
|
307
316
|
[90mstderr[2m | test/sdk/localization/store-url.browser.test.ts
|
|
308
317
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
309
318
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -312,15 +321,14 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
312
321
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
313
322
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
314
323
|
|
|
315
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/
|
|
316
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
317
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
318
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
319
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
320
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
321
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
322
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/changeContractToken.browser.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m
|
|
323
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/CartRecommendationShelf/CartRecommendationProductCard.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 46[2mms[22m[39m
|
|
324
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/useAvailableContracts.browser.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 27[2mms[22m[39m
|
|
325
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/localization/store-url.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
326
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/templates/SearchPage/SearchWrapper.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 30[2mms[22m[39m
|
|
327
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/recommendations/useRecommendationShelf.sessionFallback.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 135[2mms[22m[39m
|
|
328
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountListQuotes.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 144[2mms[22m[39m
|
|
329
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/navigation/NavbarAccountArea.browser.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 65[2mms[22m[39m
|
|
330
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/CartRecommendationShelf/CartRecommendationProductCard.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 49[2mms[22m[39m
|
|
331
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/changeContractToken.browser.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 24[2mms[22m[39m
|
|
324
332
|
[90mstderr[2m | test/components/account/doLogout.browser.test.ts
|
|
325
333
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
326
334
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -329,9 +337,9 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
329
337
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
330
338
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
331
339
|
|
|
332
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/doLogout.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
333
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/LocalizationButton.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
334
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerHeader.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[
|
|
340
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/doLogout.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 24[2mms[22m[39m
|
|
341
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/ui/LocalizationButton.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 71[2mms[22m[39m
|
|
342
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationDrawerHeader.browser.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[33m 408[2mms[22m[39m
|
|
335
343
|
[90mstderr[2m | test/sdk/account/clearPersistedSessionState.browser.test.ts
|
|
336
344
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
337
345
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -340,14 +348,15 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
340
348
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
341
349
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
342
350
|
|
|
343
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/clearPersistedSessionState.browser.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
344
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
345
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/
|
|
346
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderStatus.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
347
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/region/useRegion.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
348
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountListCards.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
349
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrdersList.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
350
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/SummaryCard.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
351
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/clearPersistedSessionState.browser.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 24[2mms[22m[39m
|
|
352
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryOptionAccordion.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 97[2mms[22m[39m
|
|
353
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderDelivery.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 110[2mms[22m[39m
|
|
354
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrderStatus.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 133[2mms[22m[39m
|
|
355
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/region/useRegion.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 26[2mms[22m[39m
|
|
356
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountListCards.browser.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 88[2mms[22m[39m
|
|
357
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/sections/Account/AccountOrdersList.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 24[2mms[22m[39m
|
|
358
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/SummaryCard.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 117[2mms[22m[39m
|
|
359
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/OrganizationSignInButton.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 213[2mms[22m[39m
|
|
351
360
|
[90mstderr[2m | test/sdk/session/sessionStore.browser.test.ts
|
|
352
361
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
353
362
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -356,9 +365,8 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
356
365
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
357
366
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
358
367
|
|
|
359
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
360
|
-
[32m✓[39m [30m[46m browser [49m[39m test/
|
|
361
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryOptionAccordionDeliveryInfo.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
368
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/sessionStore.browser.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
369
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryOptionAccordionDeliveryInfo.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 39[2mms[22m[39m
|
|
362
370
|
[90mstderr[2m | test/sdk/session/validateSession.browser.test.ts
|
|
363
371
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
364
372
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -367,13 +375,14 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
367
375
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
368
376
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
369
377
|
|
|
370
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/validateSession.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
371
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/StatusCard.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
372
|
-
[32m✓[39m [30m[46m browser [49m[39m test/utils/isLocalHost.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
373
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
374
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/
|
|
375
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/
|
|
376
|
-
[32m✓[39m [30m[46m browser [49m[39m test/components/skeletons/ProductGridSkeleton.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
378
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/validateSession.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
379
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/StatusCard.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 120[2mms[22m[39m
|
|
380
|
+
[32m✓[39m [30m[46m browser [49m[39m test/utils/isLocalHost.browser.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
381
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 3[2mms[22m[39m
|
|
382
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryOptionAccordionProducts.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 36[2mms[22m[39m
|
|
383
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/DeliveryCard.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 53[2mms[22m[39m
|
|
384
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/skeletons/ProductGridSkeleton.browser.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 34[2mms[22m[39m
|
|
385
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/bindingPaths.test.ts [2m([22m[2m71 tests[22m[2m)[22m[32m 30[2mms[22m[39m
|
|
377
386
|
[90mstderr[2m | test/sdk/account/refreshToken.browser.test.ts
|
|
378
387
|
[22m[39mError in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
|
|
379
388
|
at waitForSessionValidated [90m(/home/runner/work/faststore/faststore/packages/core/[39msrc/sdk/cart/waitForSessionValidated.ts:16:32[90m)[39m
|
|
@@ -382,12 +391,13 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
382
391
|
at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:357:23)
|
|
383
392
|
[90m at processTicksAndRejections (node:internal/process/task_queues:103:5)[39m
|
|
384
393
|
|
|
385
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
386
|
-
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/refreshToken.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
387
|
-
[32m✓[39m [30m[
|
|
388
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/switch-contract.test.ts [2m([22m[2m25 tests[22m[2m)[22m[32m
|
|
389
|
-
[32m✓[39m [30m[
|
|
390
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
394
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/password-protection-service.test.ts [2m([22m[2m22 tests[22m[2m)[22m[32m 40[2mms[22m[39m
|
|
395
|
+
[32m✓[39m [30m[46m browser [49m[39m test/sdk/account/refreshToken.browser.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
396
|
+
[32m✓[39m [30m[46m browser [49m[39m test/components/account/orders/FilterFacetPendingApproval.browser.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 248[2mms[22m[39m
|
|
397
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/switch-contract.test.ts [2m([22m[2m25 tests[22m[2m)[22m[32m 72[2mms[22m[39m
|
|
398
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/content/service.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m 28[2mms[22m[39m
|
|
399
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/useBindingSelector.test.tsx [2m([22m[2m22 tests[22m[2m)[22m[32m 12[2mms[22m[39m
|
|
400
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/match-url.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
391
401
|
[90mstderr[2m | test/sdk/deliveryPromise/provider.effect.test.tsx[2m > [22m[2mDeliveryPromiseProvider pickup fetch[2m > [22m[2mclears the loading flag after a failed request and retries on the next update
|
|
392
402
|
[22m[39mFailed to fetch pickup points: Error: network
|
|
393
403
|
at [90m/home/runner/work/faststore/faststore/packages/core/[39mtest/sdk/deliveryPromise/provider.effect.test.tsx:250:30
|
|
@@ -414,13 +424,13 @@ This ensures that you're testing the behavior the user would see in the browser.
|
|
|
414
424
|
at trace (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/vitest@4.0.18_@opentelemetry+api@1.9.0_@types+node@20.19.13_jiti@2.6.1_jsdom@27.4.0_sas_13be941c57d55f08f06eeaf1c180ddfe/node_modules/[4mvitest[24m/dist/chunks/test.B8ej_ZHS.js:239:21)
|
|
415
425
|
at runTest (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/@vitest+runner@4.0.18/node_modules/[4m@vitest/runner[24m/dist/index.js:1653:12)
|
|
416
426
|
|
|
417
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/provider.effect.test.tsx [2m([22m[2m9 tests[22m[2m)[22m[32m
|
|
418
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
419
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
427
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/provider.effect.test.tsx [2m([22m[2m9 tests[22m[2m)[22m[32m 84[2mms[22m[39m
|
|
428
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/unlock.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m 147[2mms[22m[39m
|
|
429
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/syncSalesChannelFromOrderForm.test.ts [2m([22m[2m14 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
430
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/bindingSelector.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 11[2mms[22m[39m
|
|
420
431
|
[90mstderr[2m | test/components/search/SearchInputComponent.test.tsx
|
|
421
432
|
[22m[39mWarning: forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?
|
|
422
433
|
|
|
423
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/syncSalesChannelFromOrderForm.test.ts [2m([22m[2m14 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
424
434
|
[90mstderr[2m | test/components/search/SearchInputComponent.test.tsx[2m > [22m[2mSearchInput (OES integration)[2m > [22m[2mrenders without crashing
|
|
425
435
|
[22m[39mWarning: React does not recognize the `visibleDropdown` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `visibledropdown` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
|
|
426
436
|
at div
|
|
@@ -481,24 +491,23 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
481
491
|
at Suspense
|
|
482
492
|
at Wrapper (/home/runner/work/faststore/faststore/packages/core/test/components/search/SearchInputComponent.test.tsx:106:20)
|
|
483
493
|
|
|
484
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInputComponent.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
485
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
486
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotesTable.test.tsx [2m([22m[2m15 tests[22m[2m)[22m[33m 325[2mms[22m[39m
|
|
487
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/search/useSearchHistory.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 32[2mms[22m[39m
|
|
494
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInputComponent.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 74[2mms[22m[39m
|
|
495
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotesTable.test.tsx [2m([22m[2m15 tests[22m[2m)[22m[33m 416[2mms[22m[39m
|
|
488
496
|
[90mstderr[2m | test/pages/pvt/account/cards/index.test.ts[2m > [22m[2mCards page getServerSideProps[2m > [22m[2mredirects to /pvt/account/403 when the query fails with 401/403
|
|
489
497
|
[22m[39m{ extensions: { status: [33m401[39m } }
|
|
490
498
|
|
|
491
499
|
[90mstderr[2m | test/pages/pvt/account/cards/index.test.ts[2m > [22m[2mCards page getServerSideProps[2m > [22m[2mrenders the error state (no redirect) when the query fails with a non-auth status
|
|
492
500
|
[22m[39m{ extensions: { status: [33m502[39m } }
|
|
493
501
|
|
|
494
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/pvt/account/cards/index.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
495
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
496
|
-
|
|
497
|
-
[33m[2m✓[22m[39m navigates
|
|
498
|
-
|
|
499
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
500
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
501
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
502
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/pvt/account/cards/index.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 12[2mms[22m[39m
|
|
503
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/search/useSearchHistory.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 40[2mms[22m[39m
|
|
504
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountListQuotes.test.tsx [2m([22m[2m11 tests[22m[2m)[22m[33m 839[2mms[22m[39m
|
|
505
|
+
[33m[2m✓[22m[39m navigates with the search term on blur [33m 361[2mms[22m[39m
|
|
506
|
+
[33m[2m✓[22m[39m navigates without a label param when the search is cleared [33m 361[2mms[22m[39m
|
|
507
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/quoteFilters.test.ts [2m([22m[2m26 tests[22m[2m)[22m[32m 42[2mms[22m[39m
|
|
508
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/cookieCacheBusting.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 16[2mms[22m[39m
|
|
509
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/productJsonLd.test.ts [2m([22m[2m36 tests[22m[2m)[22m[32m 17[2mms[22m[39m
|
|
510
|
+
[32m✓[39m [30m[43m node [49m[39m test/experimental/myAccountCmsServerSideProps.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
502
511
|
[90mstderr[2m | test/pages/api/graphql.test.ts[2m > [22m[2m/api/graphql error status propagation[2m > [22m[2mpropagates the upstream 400 from a wrapped BadRequestError instead of 500
|
|
503
512
|
[22m[39mGraphql execution returned with error: [
|
|
504
513
|
{
|
|
@@ -608,77 +617,76 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
|
|
|
608
617
|
at trace (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/vitest@4.0.18_@opentelemetry+api@1.9.0_@types+node@20.19.13_jiti@2.6.1_jsdom@27.4.0_sas_13be941c57d55f08f06eeaf1c180ddfe/node_modules/[4mvitest[24m/dist/chunks/test.B8ej_ZHS.js:239:21)
|
|
609
618
|
at runTest (file:///home/runner/work/faststore/faststore/node_modules/[4m.pnpm[24m/@vitest+runner@4.0.18/node_modules/[4m@vitest/runner[24m/dist/index.js:1653:12)
|
|
610
619
|
|
|
611
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m19 tests[22m[2m)[22m[32m
|
|
612
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m
|
|
613
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
620
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/graphql.test.ts [2m([22m[2m19 tests[22m[2m)[22m[32m 29[2mms[22m[39m
|
|
621
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/clearCookies.test.ts [2m([22m[2m20 tests[22m[2m)[22m[32m 30[2mms[22m[39m
|
|
622
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/multipleTemplates.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
614
623
|
[90mstderr[2m | test/sdk/account/useSetPassword.test.ts[2m > [22m[2museSetPassword[2m > [22m[2mmaps wrongcredentials error responses to the existing message
|
|
615
624
|
[22m[39mSet password request failed: Bad Request
|
|
616
625
|
|
|
617
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
618
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryOperation.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
626
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/useSetPassword.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 49[2mms[22m[39m
|
|
627
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryOperation.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 45[2mms[22m[39m
|
|
619
628
|
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/localizeRedirectDestination.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
620
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/
|
|
621
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/
|
|
622
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
623
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
624
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesSelectedTags.test.tsx [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
625
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/redirects/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m
|
|
626
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryUpload.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m
|
|
627
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
628
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
629
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/getDeliveryOptionLabel.test.ts [2m([22m[2m21 tests[22m[2m)[22m[32m
|
|
630
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/graphql/retryPolicy.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m
|
|
631
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/cms/myAccountDefaultSections.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m
|
|
632
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/productJsonLdRendering.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
633
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/trustedForwardedHost.test.ts [2m([22m[2m27 tests[22m[2m)[22m[32m
|
|
634
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
635
|
-
|
|
636
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
637
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
638
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
639
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
640
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
641
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
642
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
643
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
644
|
-
|
|
645
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
646
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
647
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/
|
|
648
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
649
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
650
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
651
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
652
|
-
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
629
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesStatusSelector.test.tsx [2m([22m[2m14 tests[22m[2m)[22m[32m 130[2mms[22m[39m
|
|
630
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesFilterSlider.test.tsx [2m([22m[2m8 tests[22m[2m)[22m[32m 191[2mms[22m[39m
|
|
631
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/getMyAccountRoutes.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
632
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/localization/hreflang.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
633
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuotesSelectedTags.test.tsx [2m([22m[2m10 tests[22m[2m)[22m[32m 125[2mms[22m[39m
|
|
634
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/redirects/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 46[2mms[22m[39m
|
|
635
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntryUpload.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 50[2mms[22m[39m
|
|
636
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderEntry.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 51[2mms[22m[39m
|
|
637
|
+
[32m✓[39m [30m[43m node [49m[39m test/proxy.localization.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 73[2mms[22m[39m
|
|
638
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/getDeliveryOptionLabel.test.ts [2m([22m[2m21 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
639
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/graphql/retryPolicy.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 24[2mms[22m[39m
|
|
640
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/cms/myAccountDefaultSections.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
641
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/productJsonLdRendering.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 15[2mms[22m[39m
|
|
642
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/trustedForwardedHost.test.ts [2m([22m[2m27 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
643
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[33m 1067[2mms[22m[39m
|
|
644
|
+
[33m[2m✓[22m[39m should handle options and execute [33m 493[2mms[22m[39m
|
|
645
|
+
[32m✓[39m [30m[43m node [49m[39m test/proxy.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 21[2mms[22m[39m
|
|
646
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/useStartRecommendationSession.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 52[2mms[22m[39m
|
|
647
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/webops-api.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 16[2mms[22m[39m
|
|
648
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/localization/store-url.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
649
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/StatusCard.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 37[2mms[22m[39m
|
|
650
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/orderEntry/useOrderFormItems.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 45[2mms[22m[39m
|
|
651
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/queries.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 14[2mms[22m[39m
|
|
652
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/cart/waitForSessionValidated.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 12[2mms[22m[39m
|
|
653
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/refreshToken.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
654
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/cms/global.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
655
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/provider.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
656
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/auth/useAuth.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
657
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/getRequestHostname.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
658
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/Layout.test.tsx [2m([22m[2m6 tests[22m[2m)[22m[32m 78[2mms[22m[39m
|
|
659
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/rootSpan.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 38[2mms[22m[39m
|
|
660
|
+
[32m✓[39m [30m[43m node [49m[39m test/pages/api/preview.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
653
661
|
[32m✓[39m [30m[43m node [49m[39m test/components/search/SearchInput.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 9[2mms[22m[39m
|
|
654
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/validateSessionRefreshToken.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
655
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/vrn.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m
|
|
656
|
-
[32m✓[39m [30m[43m node [49m[39m test/server/cms/index.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
662
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/validateSessionRefreshToken.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
663
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/vrn.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
664
|
+
[32m✓[39m [30m[43m node [49m[39m test/server/cms/index.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
665
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/region/useRegion.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 29[2mms[22m[39m
|
|
657
666
|
[32m✓[39m [30m[43m node [49m[39m test/utils/retry.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 13[2mms[22m[39m
|
|
658
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
659
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
660
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
661
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
662
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
663
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/useRecommendations.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
664
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
665
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
666
|
-
[32m✓[39m [30m[43m node [49m[39m test/utils/isLocalHost.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
667
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuoteStatusBadge.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 26[2mms[22m[39m
|
|
667
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/getB2BSessionClaims.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
668
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/userOrderStatus.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
669
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/useRecommendationUserId.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 193[2mms[22m[39m
|
|
670
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/unlockResponse.test.ts [2m([22m[2m11 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
671
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/OrganizationDrawerBody.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 47[2mms[22m[39m
|
|
672
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/recommendations/useRecommendations.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
673
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/deliveryPromise/reducer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
674
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/isLocalHost.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
668
675
|
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/toSessionInput.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
669
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/
|
|
670
|
-
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/
|
|
671
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
672
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
673
|
-
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/isSignInAreaResolved.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
674
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
675
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
676
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
677
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
678
|
-
[32m✓[39m [30m[43m node [49m[39m test/
|
|
676
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/quotes/MyAccountQuoteStatusBadge.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 54[2mms[22m[39m
|
|
677
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/getOrderTotalLabel.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
678
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/listOrdersLabels.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 3[2mms[22m[39m
|
|
679
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/getCookie.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
680
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/session/isSignInAreaResolved.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
681
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/auth/ProfileChallenge.test.tsx [2m([22m[2m3 tests[22m[2m)[22m[32m 43[2mms[22m[39m
|
|
682
|
+
[32m✓[39m [30m[43m node [49m[39m test/utils/filterChannel.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
683
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/analytics/utils.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
|
684
|
+
[32m✓[39m [30m[43m node [49m[39m test/instrumentation.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
685
|
+
[32m✓[39m [30m[43m node [49m[39m test/components/account/orders/orderDetailsLabels.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
686
|
+
[32m✓[39m [30m[43m node [49m[39m test/sdk/account/clearPersistedSessionState.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 12[2mms[22m[39m
|
|
679
687
|
|
|
680
688
|
[2m Test Files [22m [1m[32m135 passed[39m[22m[90m (135)[39m
|
|
681
|
-
[2m Tests [22m [1m[
|
|
682
|
-
[2m Start at [22m
|
|
683
|
-
[2m Duration [22m
|
|
689
|
+
[2m Tests [22m [1m[32m1076 passed[39m[22m[90m (1076)[39m
|
|
690
|
+
[2m Start at [22m 19:21:02
|
|
691
|
+
[2m Duration [22m 63.77s[2m (transform 15.47s, setup 0ms, import 57.20s, tests 23.12s, environment 78.69s)[22m
|
|
684
692
|
|
package/CHANGELOG.md
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [4.10.1
|
|
6
|
+
## [4.10.1](https://github.com/vtex/faststore/compare/v4.10.0...v4.10.1) (2026-10-23)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **core:** cache Content Platform template list across page generations ([#3542](https://github.com/vtex/faststore/issues/3542)) ([ab44199](https://github.com/vtex/faststore/commit/ab441997841b5f47b4dcc65d82fdfbb03fb579f2)), closes [#3384](https://github.com/vtex/faststore/issues/3384)
|
|
9
11
|
|
|
10
12
|
# [4.10.0](https://github.com/vtex/faststore/compare/v4.10.0-dev.1...v4.10.0) (2026-10-15)
|
|
11
13
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "4.10.1
|
|
3
|
+
"version": "4.10.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -71,11 +71,11 @@
|
|
|
71
71
|
"style-loader": "^3.3.1",
|
|
72
72
|
"swr": "^2.2.5",
|
|
73
73
|
"use-sync-external-store": "^1.6.0",
|
|
74
|
-
"@faststore/api": "4.10.1
|
|
75
|
-
"@faststore/
|
|
76
|
-
"@faststore/
|
|
77
|
-
"@faststore/sdk": "4.10.1
|
|
78
|
-
"@faststore/
|
|
74
|
+
"@faststore/api": "4.10.1",
|
|
75
|
+
"@faststore/lighthouse": "4.10.1",
|
|
76
|
+
"@faststore/ui": "4.10.1",
|
|
77
|
+
"@faststore/sdk": "4.10.1",
|
|
78
|
+
"@faststore/diagnostics": "4.10.1"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@cypress/code-coverage": "^3.12.1",
|
|
@@ -19,15 +19,27 @@ import { isBranchPreview, isContentPlatformSource } from './utils'
|
|
|
19
19
|
|
|
20
20
|
type ContentResult = ContentData | (ContentEntry & PageContentType)
|
|
21
21
|
|
|
22
|
+
type ContentListCacheEntry = {
|
|
23
|
+
expiresAt: number
|
|
24
|
+
promise: Promise<{ data: ContentResult[] }>
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
const OPTIONAL_CONTENT_TYPES = [
|
|
23
28
|
'globalHeaderSections',
|
|
24
29
|
'globalFooterSections',
|
|
25
30
|
] as const
|
|
31
|
+
|
|
32
|
+
// Bounds how stale the template list can get in long-lived processes (ISR);
|
|
33
|
+
// a CMS publish already triggers a new build.
|
|
34
|
+
const CONTENT_LIST_CACHE_TTL_MS = 5 * 60 * 1000
|
|
35
|
+
|
|
26
36
|
export class ContentService {
|
|
27
37
|
private readonly clientCP = new ClientCP({
|
|
28
38
|
tenant: config.api.storeId,
|
|
29
39
|
})
|
|
30
40
|
|
|
41
|
+
private readonly contentListCache = new Map<string, ContentListCacheEntry>()
|
|
42
|
+
|
|
31
43
|
async getSingleContent<T extends ContentData>(
|
|
32
44
|
params: ContentParams
|
|
33
45
|
): Promise<T> {
|
|
@@ -46,29 +58,12 @@ export class ContentService {
|
|
|
46
58
|
|
|
47
59
|
if (isContentPlatformSource()) {
|
|
48
60
|
const serviceParams = this.convertOptionsToParams(options)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
let scroll: string | undefined
|
|
53
|
-
let pages = 0
|
|
54
|
-
|
|
55
|
-
do {
|
|
56
|
-
const result = await this.clientCP.listEntries(serviceParams, scroll)
|
|
57
|
-
allEntries.push(...result.entries)
|
|
58
|
-
const next = result.scroll ?? undefined
|
|
59
|
-
if (next && next === scroll) break
|
|
60
|
-
scroll = next
|
|
61
|
-
} while (scroll && ++pages < MAX_PAGES)
|
|
62
|
-
|
|
63
|
-
if (pages >= MAX_PAGES) {
|
|
64
|
-
console.warn('listEntries pagination hit MAX_PAGES cap', serviceParams)
|
|
61
|
+
|
|
62
|
+
if (options.isPreview) {
|
|
63
|
+
return this.listAndFillEntries(serviceParams, true)
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
return this.
|
|
68
|
-
allEntries,
|
|
69
|
-
serviceParams,
|
|
70
|
-
options.isPreview
|
|
71
|
-
)
|
|
66
|
+
return this.getCachedContentList(serviceParams)
|
|
72
67
|
}
|
|
73
68
|
return getCMSPage(options.cmsOptions)
|
|
74
69
|
}
|
|
@@ -136,6 +131,60 @@ export class ContentService {
|
|
|
136
131
|
}
|
|
137
132
|
}
|
|
138
133
|
|
|
134
|
+
private getCachedContentList(
|
|
135
|
+
serviceParams: EntryPathParams
|
|
136
|
+
): Promise<{ data: ContentResult[] }> {
|
|
137
|
+
// listEntries only depends on these fields; the page slug must stay out of the key.
|
|
138
|
+
const { accountName, storeId, contentType, locale } = serviceParams
|
|
139
|
+
const key = JSON.stringify([accountName, storeId, contentType, locale])
|
|
140
|
+
|
|
141
|
+
const cached = this.contentListCache.get(key)
|
|
142
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
143
|
+
return cached.promise
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const promise = this.listAndFillEntries(serviceParams, false).catch(
|
|
147
|
+
(err: unknown) => {
|
|
148
|
+
if (this.contentListCache.get(key)?.promise === promise) {
|
|
149
|
+
this.contentListCache.delete(key)
|
|
150
|
+
}
|
|
151
|
+
throw err
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
this.contentListCache.set(key, {
|
|
156
|
+
expiresAt: Date.now() + CONTENT_LIST_CACHE_TTL_MS,
|
|
157
|
+
promise,
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
return promise
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private async listAndFillEntries(
|
|
164
|
+
serviceParams: EntryPathParams,
|
|
165
|
+
isPreview: boolean
|
|
166
|
+
): Promise<{ data: (ContentEntry & PageContentType)[] }> {
|
|
167
|
+
// TODO: This should be temporary until the cp data-plane have a search engine.
|
|
168
|
+
const MAX_PAGES = 25
|
|
169
|
+
const allEntries: ContentEntry[] = []
|
|
170
|
+
let scroll: string | undefined
|
|
171
|
+
let pages = 0
|
|
172
|
+
|
|
173
|
+
do {
|
|
174
|
+
const result = await this.clientCP.listEntries(serviceParams, scroll)
|
|
175
|
+
allEntries.push(...result.entries)
|
|
176
|
+
const next = result.scroll ?? undefined
|
|
177
|
+
if (next && next === scroll) break
|
|
178
|
+
scroll = next
|
|
179
|
+
} while (scroll && ++pages < MAX_PAGES)
|
|
180
|
+
|
|
181
|
+
if (pages >= MAX_PAGES) {
|
|
182
|
+
console.warn('listEntries pagination hit MAX_PAGES cap', serviceParams)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return this.fillEntriesWithData(allEntries, serviceParams, isPreview)
|
|
186
|
+
}
|
|
187
|
+
|
|
139
188
|
private async fillEntriesWithData(
|
|
140
189
|
entries: ContentEntry[],
|
|
141
190
|
serviceParams: EntryPathParams,
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import type { EntryPathParams } from '@vtex/client-cp'
|
|
2
|
-
import { describe, expect, it } from 'vitest'
|
|
1
|
+
import type { ContentEntry, EntryPathParams } from '@vtex/client-cp'
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
3
|
|
|
4
4
|
import { ContentService } from '../../../src/server/content/service'
|
|
5
5
|
import type {
|
|
6
6
|
ContentOptions,
|
|
7
7
|
ContentParams,
|
|
8
8
|
} from '../../../src/server/content/types'
|
|
9
|
+
import type * as ContentUtils from '../../../src/server/content/utils'
|
|
10
|
+
import { isContentPlatformSource } from '../../../src/server/content/utils'
|
|
11
|
+
|
|
12
|
+
vi.mock('../../../src/server/content/utils', async (importOriginal) => {
|
|
13
|
+
const actual = await importOriginal<typeof ContentUtils>()
|
|
14
|
+
return {
|
|
15
|
+
...actual,
|
|
16
|
+
isContentPlatformSource: vi.fn(actual.isContentPlatformSource),
|
|
17
|
+
}
|
|
18
|
+
})
|
|
9
19
|
|
|
10
20
|
type ContentServiceInternals = {
|
|
11
21
|
createContentOptions: (params: ContentParams) => ContentOptions
|
|
@@ -15,6 +25,59 @@ type ContentServiceInternals = {
|
|
|
15
25
|
const getServiceInternals = (service: ContentService) =>
|
|
16
26
|
service as unknown as ContentServiceInternals
|
|
17
27
|
|
|
28
|
+
const NOT_FOUND = 'Request failed with status code 404'
|
|
29
|
+
|
|
30
|
+
const entryData: Record<string, Record<string, unknown>> = {
|
|
31
|
+
generic: { sections: [{ name: 'Generic' }] },
|
|
32
|
+
collection: {
|
|
33
|
+
settings: { template: { value: '/colecao' } },
|
|
34
|
+
sections: [{ name: 'Collection' }],
|
|
35
|
+
},
|
|
36
|
+
other: {
|
|
37
|
+
settings: { template: { value: '/outra' } },
|
|
38
|
+
sections: [{ name: 'Other' }],
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const toEntry = (id: string) => ({ id, name: id }) as ContentEntry
|
|
43
|
+
|
|
44
|
+
function createFakeClientCP(pages: string[][]) {
|
|
45
|
+
return {
|
|
46
|
+
listEntries: vi.fn(async (_params: EntryPathParams, scroll?: string) => {
|
|
47
|
+
const index = scroll ? Number(scroll) : 0
|
|
48
|
+
return {
|
|
49
|
+
entries: pages[index].map(toEntry),
|
|
50
|
+
scroll: index + 1 < pages.length ? String(index + 1) : null,
|
|
51
|
+
}
|
|
52
|
+
}),
|
|
53
|
+
getEntry: vi.fn(async ({ entryId }: EntryPathParams) => ({
|
|
54
|
+
...entryData[entryId as string],
|
|
55
|
+
})),
|
|
56
|
+
previewEntryById: vi.fn(async ({ entryId }: EntryPathParams) => ({
|
|
57
|
+
...entryData[entryId as string],
|
|
58
|
+
})),
|
|
59
|
+
getEntryBySlug: vi.fn(
|
|
60
|
+
async (_params: EntryPathParams): Promise<Record<string, unknown>> => {
|
|
61
|
+
throw new Error(NOT_FOUND)
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
previewEntryBySlug: vi.fn(
|
|
65
|
+
async (_params: EntryPathParams): Promise<Record<string, unknown>> => {
|
|
66
|
+
throw new Error(NOT_FOUND)
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function createServiceWithClient(
|
|
73
|
+
pages: string[][] = [['generic', 'collection', 'other']]
|
|
74
|
+
) {
|
|
75
|
+
const service = new ContentService()
|
|
76
|
+
const clientCP = createFakeClientCP(pages)
|
|
77
|
+
Object.defineProperty(service, 'clientCP', { value: clientCP })
|
|
78
|
+
return { service, clientCP }
|
|
79
|
+
}
|
|
80
|
+
|
|
18
81
|
describe('ContentService', () => {
|
|
19
82
|
describe('convertOptionsToParams', () => {
|
|
20
83
|
it('maps a flat SEO slug filter to the client-cp slug param', () => {
|
|
@@ -95,4 +158,180 @@ describe('ContentService', () => {
|
|
|
95
158
|
expect('locale' in options.cmsOptions).toBe(false)
|
|
96
159
|
})
|
|
97
160
|
})
|
|
161
|
+
|
|
162
|
+
describe('Content Platform template list cache', () => {
|
|
163
|
+
const FIVE_MINUTES = 5 * 60 * 1000
|
|
164
|
+
|
|
165
|
+
beforeEach(() => {
|
|
166
|
+
vi.mocked(isContentPlatformSource).mockReturnValue(true)
|
|
167
|
+
vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
afterEach(() => {
|
|
171
|
+
vi.mocked(isContentPlatformSource).mockReset()
|
|
172
|
+
vi.restoreAllMocks()
|
|
173
|
+
vi.useRealTimers()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('shares one list and entry fetch across concurrent PLPs with different slugs', async () => {
|
|
177
|
+
const { service, clientCP } = createServiceWithClient()
|
|
178
|
+
|
|
179
|
+
const [collectionPage, otherPage, unknownPage] = await Promise.all([
|
|
180
|
+
service.getPlpContent({ slug: 'colecao/camisetas' }, []),
|
|
181
|
+
service.getPlpContent({ slug: 'outra' }, []),
|
|
182
|
+
service.getPlpContent({ slug: 'nao-existe' }, []),
|
|
183
|
+
])
|
|
184
|
+
|
|
185
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(1)
|
|
186
|
+
expect(clientCP.getEntry).toHaveBeenCalledTimes(3)
|
|
187
|
+
expect(collectionPage.sections).toEqual([{ name: 'Collection' }])
|
|
188
|
+
expect(otherPage.sections).toEqual([{ name: 'Other' }])
|
|
189
|
+
expect(unknownPage.sections).toEqual([{ name: 'Generic' }])
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('reuses the cached list within the TTL', async () => {
|
|
193
|
+
const { service, clientCP } = createServiceWithClient()
|
|
194
|
+
|
|
195
|
+
await service.getPlpContent({ slug: 'colecao' }, [])
|
|
196
|
+
await service.getPlpContent({ slug: 'outra' }, [])
|
|
197
|
+
|
|
198
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(1)
|
|
199
|
+
expect(clientCP.getEntry).toHaveBeenCalledTimes(3)
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('still prefers a direct slug match over the cached list', async () => {
|
|
203
|
+
const { service, clientCP } = createServiceWithClient()
|
|
204
|
+
await service.getPlpContent({ slug: 'colecao' }, [])
|
|
205
|
+
|
|
206
|
+
clientCP.getEntryBySlug.mockResolvedValueOnce({
|
|
207
|
+
sections: [{ name: 'Direct' }],
|
|
208
|
+
})
|
|
209
|
+
const page = await service.getPlpContent({ slug: 'colecao' }, [])
|
|
210
|
+
|
|
211
|
+
expect(page.sections).toEqual([{ name: 'Direct' }])
|
|
212
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(1)
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('consumes every scroll page once', async () => {
|
|
216
|
+
const { service, clientCP } = createServiceWithClient([
|
|
217
|
+
['generic'],
|
|
218
|
+
['collection'],
|
|
219
|
+
['other'],
|
|
220
|
+
])
|
|
221
|
+
|
|
222
|
+
await Promise.all([
|
|
223
|
+
service.getMultipleContent({ contentType: 'plp' }),
|
|
224
|
+
service.getMultipleContent({ contentType: 'plp' }),
|
|
225
|
+
])
|
|
226
|
+
const { data } = await service.getMultipleContent({ contentType: 'plp' })
|
|
227
|
+
|
|
228
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(3)
|
|
229
|
+
expect(
|
|
230
|
+
clientCP.listEntries.mock.calls.map(([, scroll]) => scroll)
|
|
231
|
+
).toEqual([undefined, '1', '2'])
|
|
232
|
+
expect(data.map((entry) => entry.id)).toEqual([
|
|
233
|
+
'generic',
|
|
234
|
+
'collection',
|
|
235
|
+
'other',
|
|
236
|
+
])
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
it('keeps separate entries per content type', async () => {
|
|
240
|
+
const { service, clientCP } = createServiceWithClient()
|
|
241
|
+
|
|
242
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
243
|
+
await service.getMultipleContent({ contentType: 'pdp' })
|
|
244
|
+
await service.getMultipleContent({ contentType: 'pdp' })
|
|
245
|
+
|
|
246
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
247
|
+
expect(
|
|
248
|
+
clientCP.listEntries.mock.calls.map(([params]) => params.contentType)
|
|
249
|
+
).toEqual(['plp', 'pdp'])
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('keeps separate entries per locale', async () => {
|
|
253
|
+
const { service, clientCP } = createServiceWithClient()
|
|
254
|
+
|
|
255
|
+
await service.getMultipleContent({ contentType: 'plp', locale: 'pt-BR' })
|
|
256
|
+
await service.getMultipleContent({ contentType: 'plp', locale: 'en-US' })
|
|
257
|
+
await service.getMultipleContent({ contentType: 'plp', locale: 'pt-BR' })
|
|
258
|
+
|
|
259
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
260
|
+
expect(
|
|
261
|
+
clientCP.listEntries.mock.calls.map(([params]) => params.locale)
|
|
262
|
+
).toEqual(['pt-BR', 'en-US'])
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
it('bypasses the cache for previews', async () => {
|
|
266
|
+
const { service, clientCP } = createServiceWithClient()
|
|
267
|
+
const previewParams: ContentParams = {
|
|
268
|
+
contentType: 'plp',
|
|
269
|
+
previewData: {
|
|
270
|
+
contentType: 'plp',
|
|
271
|
+
documentId: 'collection',
|
|
272
|
+
versionId: 'version-1',
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
277
|
+
await service.getMultipleContent(previewParams)
|
|
278
|
+
await service.getMultipleContent(previewParams)
|
|
279
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
280
|
+
|
|
281
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(3)
|
|
282
|
+
expect(clientCP.getEntry).toHaveBeenCalledTimes(3)
|
|
283
|
+
expect(clientCP.previewEntryById).toHaveBeenCalledTimes(6)
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
it('does not cache failures', async () => {
|
|
287
|
+
const { service, clientCP } = createServiceWithClient()
|
|
288
|
+
const error = new Error('Request failed with status code 500')
|
|
289
|
+
clientCP.listEntries.mockRejectedValueOnce(error)
|
|
290
|
+
|
|
291
|
+
await expect(
|
|
292
|
+
service.getMultipleContent({ contentType: 'plp' })
|
|
293
|
+
).rejects.toBe(error)
|
|
294
|
+
const { data } = await service.getMultipleContent({ contentType: 'plp' })
|
|
295
|
+
|
|
296
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
297
|
+
expect(data).toHaveLength(3)
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
it('does not let a late failure evict a newer fetch', async () => {
|
|
301
|
+
vi.useFakeTimers()
|
|
302
|
+
const { service, clientCP } = createServiceWithClient()
|
|
303
|
+
let rejectFirst: (err: Error) => void = () => {}
|
|
304
|
+
clientCP.listEntries.mockImplementationOnce(
|
|
305
|
+
() =>
|
|
306
|
+
new Promise((_, reject) => {
|
|
307
|
+
rejectFirst = reject
|
|
308
|
+
})
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
const first = service.getMultipleContent({ contentType: 'plp' })
|
|
312
|
+
const firstResult = expect(first).rejects.toThrow('late failure')
|
|
313
|
+
vi.advanceTimersByTime(FIVE_MINUTES)
|
|
314
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
315
|
+
|
|
316
|
+
rejectFirst(new Error('late failure'))
|
|
317
|
+
await firstResult
|
|
318
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
319
|
+
|
|
320
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
it('fetches the list again after the TTL', async () => {
|
|
324
|
+
vi.useFakeTimers()
|
|
325
|
+
const { service, clientCP } = createServiceWithClient()
|
|
326
|
+
|
|
327
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
328
|
+
vi.advanceTimersByTime(FIVE_MINUTES - 1)
|
|
329
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
330
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(1)
|
|
331
|
+
|
|
332
|
+
vi.advanceTimersByTime(1)
|
|
333
|
+
await service.getMultipleContent({ contentType: 'plp' })
|
|
334
|
+
expect(clientCP.listEntries).toHaveBeenCalledTimes(2)
|
|
335
|
+
})
|
|
336
|
+
})
|
|
98
337
|
})
|