@faststore/core 4.8.1-dev.0 → 4.8.1-dev.2
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-generate.log +3 -3
- package/.turbo/turbo-test.log +146 -105
- package/@generated/gql.ts +3 -3
- package/@generated/graphql.ts +4 -2
- package/@generated/persisted-documents.json +1 -1
- package/@generated/schema.graphql +4 -0
- package/CHANGELOG.md +16 -0
- package/cms/faststore/my-account/components/cms_component__accountnavigation.jsonc +10 -0
- package/cms/faststore/my-account/components/cms_component__accountorderdelivery.jsonc +80 -0
- package/cms/faststore/my-account/components/cms_component__accountorderdetails.jsonc +25 -0
- package/cms/faststore/my-account/components/cms_component__accountorderslist.jsonc +10 -0
- package/cms/faststore/my-account/components/cms_component__accountorderstatus.jsonc +90 -0
- package/cms/faststore/my-account/components/cms_component__accountordersummary.jsonc +25 -0
- package/package.json +6 -6
- package/src/components/account/Drawer/OrganizationDrawer/ContractSwitcher/ContractSwitcher.tsx +4 -6
- package/src/components/account/Drawer/OrganizationDrawer/OrganizationDrawer.tsx +18 -3
- package/src/components/account/Drawer/OrganizationDrawer/OrganizationDrawerFooter.tsx +13 -2
- package/src/components/account/Drawer/OrganizationDrawer/OrganizationDrawerHeader.tsx +1 -0
- package/src/components/account/Drawer/OrganizationDrawer/section.module.scss +7 -0
- package/src/components/account/Drawer/OrganizationSignInButton/OrganizationSignInButton.tsx +7 -9
- package/src/components/account/Menu/Menu.tsx +24 -7
- package/src/components/account/orders/ListOrders/FilterSlider/FilterFacetPendingApproval/FilterFacetPendingApproval.tsx +8 -3
- package/src/components/account/orders/ListOrders/FilterSlider/FilterSlider.tsx +1 -0
- package/src/components/account/orders/ListOrders/ListOrders.tsx +2 -2
- package/src/components/account/orders/ListOrders/listOrdersLabels.ts +4 -0
- package/src/components/account/orders/OrderDetails/BuyingPolicyAlert/BuyingPolicyAlert.tsx +45 -9
- package/src/components/account/orders/OrderDetails/DeliveryCard/DeliveryCard.tsx +14 -3
- package/src/components/account/orders/OrderDetails/DeliveryOptionAccordion/DeliveryOptionAccordion.tsx +4 -1
- package/src/components/account/orders/OrderDetails/DeliveryOptionAccordion/DeliveryOptionAccordionDeliveryInfo.tsx +14 -7
- package/src/components/account/orders/OrderDetails/DeliveryOptionAccordion/DeliveryOptionAccordionProducts.tsx +8 -5
- package/src/components/account/orders/OrderDetails/OrderDetailsHeader.tsx +5 -0
- package/src/components/account/orders/OrderDetails/StatusCard/StatusCard.tsx +26 -89
- package/src/components/account/orders/OrderDetails/StatusCard/statusCardLocalization.ts +114 -0
- package/src/components/account/orders/OrderDetails/SummaryCard/SummaryCard.tsx +2 -1
- package/src/components/account/orders/OrderDetails/SummaryCard/getOrderTotalLabel.ts +19 -0
- package/src/components/account/orders/OrderDetails/getDeliveryOptionLabel.ts +135 -0
- package/src/components/account/orders/OrderDetails/orderDetailsLabels.ts +73 -0
- package/src/components/navigation/Navbar/Navbar.tsx +17 -19
- package/src/components/navigation/Navbar/NavbarAccountArea.tsx +57 -0
- package/src/components/navigation/NavbarSlider/NavbarSlider.tsx +16 -18
- package/src/components/sections/Account/AccountOrderDelivery.tsx +3 -1
- package/src/components/sections/Account/AccountOrderDetails.tsx +16 -0
- package/src/components/sections/Account/AccountOrderStatus.tsx +27 -3
- package/src/components/sections/Account/AccountOrdersList.tsx +4 -0
- package/src/pages/api/fs/switch-contract.ts +194 -0
- package/src/pages/api/graphql.ts +108 -69
- package/src/sdk/account/accountPageContext.ts +14 -3
- package/src/sdk/account/changeContractToken.ts +19 -63
- package/src/sdk/account/clearPersistedSessionState.ts +13 -7
- package/src/sdk/account/getMyAccountRoutes.ts +2 -0
- package/src/sdk/account/useAvailableContracts.ts +1 -0
- package/src/sdk/account/useSwitchContract.ts +11 -3
- package/src/sdk/overrides/PageProvider.tsx +1 -1
- package/src/sdk/session/index.ts +2 -1
- package/src/sdk/session/isSignInAreaResolved.ts +12 -0
- package/test/components/account/ContractSwitcher.browser.test.tsx +42 -0
- package/test/components/account/Menu.browser.test.tsx +123 -0
- package/test/components/account/OrganizationDrawer.browser.test.tsx +148 -0
- package/test/components/account/OrganizationDrawerFooter.browser.test.tsx +95 -1
- package/test/components/account/OrganizationDrawerHeader.browser.test.tsx +2 -0
- package/test/components/account/OrganizationSignInButton.browser.test.tsx +49 -0
- package/test/components/account/orders/BuyingPolicyAlert.browser.test.tsx +342 -0
- package/test/components/account/orders/DeliveryCard.browser.test.tsx +36 -0
- package/test/components/account/orders/DeliveryOptionAccordion.browser.test.tsx +76 -0
- package/test/components/account/orders/DeliveryOptionAccordionDeliveryInfo.browser.test.tsx +41 -0
- package/test/components/account/orders/DeliveryOptionAccordionProducts.browser.test.tsx +35 -0
- package/test/components/account/orders/FilterFacetPendingApproval.browser.test.tsx +25 -0
- package/test/components/account/orders/StatusCard.browser.test.tsx +37 -0
- package/test/components/account/orders/StatusCard.test.ts +101 -0
- package/test/components/account/orders/SummaryCard.browser.test.tsx +59 -0
- package/test/components/account/orders/getDeliveryOptionLabel.test.ts +129 -0
- package/test/components/account/orders/getOrderTotalLabel.test.ts +35 -0
- package/test/components/account/orders/listOrdersLabels.test.ts +23 -0
- package/test/components/account/orders/orderDetailsLabels.test.ts +13 -0
- package/test/components/navigation/Navbar.browser.test.tsx +183 -0
- package/test/components/navigation/NavbarAccountArea.browser.test.tsx +115 -0
- package/test/components/navigation/NavbarSlider.browser.test.tsx +143 -0
- package/test/components/sections/Account/AccountOrderDelivery.browser.test.tsx +72 -0
- package/test/components/sections/Account/AccountOrderDetails.browser.test.tsx +151 -0
- package/test/components/sections/Account/AccountOrderStatus.browser.test.tsx +59 -0
- package/test/components/sections/Account/AccountOrdersList.browser.test.tsx +67 -0
- package/test/pages/api/graphql.test.ts +27 -1
- package/test/pages/api/switch-contract.test.ts +385 -0
- package/test/sdk/account/changeContractToken.browser.test.ts +23 -71
- package/test/sdk/account/clearPersistedSessionState.browser.test.ts +24 -0
- package/test/sdk/account/getMyAccountRoutes.test.ts +11 -1
- package/test/sdk/account/useSwitchContract.browser.test.ts +21 -0
- package/test/sdk/session/isSignInAreaResolved.test.ts +22 -0
- package/test/utils/userOrderStatus.test.ts +22 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import '@testing-library/jest-dom/vitest'
|
|
6
|
+
import { render, screen } from '@testing-library/react'
|
|
7
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
8
|
+
|
|
9
|
+
const mockUseSession = vi.hoisted(() => vi.fn())
|
|
10
|
+
const mockNavbarAccountArea = vi.hoisted(() => vi.fn())
|
|
11
|
+
const mockStoreConfig = vi.hoisted(() => ({
|
|
12
|
+
experimental: { enableFaststoreMyAccount: false },
|
|
13
|
+
localization: { enabled: false },
|
|
14
|
+
}))
|
|
15
|
+
|
|
16
|
+
vi.mock('@faststore/ui', () => ({
|
|
17
|
+
useFadeEffect: () => ({ fade: 'in', fadeOut: vi.fn() }),
|
|
18
|
+
useUI: () => ({ closeNavbar: vi.fn() }),
|
|
19
|
+
}))
|
|
20
|
+
|
|
21
|
+
vi.mock('discovery.config', () => ({ default: mockStoreConfig }))
|
|
22
|
+
|
|
23
|
+
vi.mock('src/components/navigation/NavbarLinks', () => ({
|
|
24
|
+
default: () => <nav data-testid="navbar-links" />,
|
|
25
|
+
}))
|
|
26
|
+
|
|
27
|
+
vi.mock('src/components/ui/Button', () => ({
|
|
28
|
+
ButtonSignInFallback: () => null,
|
|
29
|
+
}))
|
|
30
|
+
|
|
31
|
+
vi.mock('src/components/ui/Link', () => ({
|
|
32
|
+
default: ({ children }: { children?: React.ReactNode }) => (
|
|
33
|
+
<a href="/">{children}</a>
|
|
34
|
+
),
|
|
35
|
+
}))
|
|
36
|
+
|
|
37
|
+
vi.mock('src/components/ui/LocalizationButton', () => ({
|
|
38
|
+
default: () => <div data-testid="localization-button" />,
|
|
39
|
+
}))
|
|
40
|
+
|
|
41
|
+
vi.mock('src/components/ui/Logo', () => ({
|
|
42
|
+
default: () => <div data-testid="logo" />,
|
|
43
|
+
}))
|
|
44
|
+
|
|
45
|
+
vi.mock('../../../src/components/navigation/Navbar/NavbarAccountArea', () => ({
|
|
46
|
+
NavbarAccountArea: (props: Record<string, unknown>) => {
|
|
47
|
+
mockNavbarAccountArea(props)
|
|
48
|
+
return <div data-testid="navbar-account-area" />
|
|
49
|
+
},
|
|
50
|
+
}))
|
|
51
|
+
|
|
52
|
+
vi.mock('src/sdk/overrides/OverrideContext', () => ({
|
|
53
|
+
useOverrideComponents: () => ({
|
|
54
|
+
NavbarSlider: {
|
|
55
|
+
Component: ({ children }: React.PropsWithChildren) => (
|
|
56
|
+
<div data-testid="navbar-slider-wrapper">{children}</div>
|
|
57
|
+
),
|
|
58
|
+
props: {},
|
|
59
|
+
},
|
|
60
|
+
NavbarSliderHeader: {
|
|
61
|
+
Component: ({ children }: React.PropsWithChildren) => (
|
|
62
|
+
<header>{children}</header>
|
|
63
|
+
),
|
|
64
|
+
props: {},
|
|
65
|
+
},
|
|
66
|
+
NavbarSliderContent: {
|
|
67
|
+
Component: ({ children }: React.PropsWithChildren) => (
|
|
68
|
+
<div>{children}</div>
|
|
69
|
+
),
|
|
70
|
+
props: {},
|
|
71
|
+
},
|
|
72
|
+
NavbarSliderFooter: {
|
|
73
|
+
Component: ({ children }: React.PropsWithChildren) => (
|
|
74
|
+
<footer>{children}</footer>
|
|
75
|
+
),
|
|
76
|
+
props: {},
|
|
77
|
+
},
|
|
78
|
+
_experimentalButtonSignIn: { Component: () => null },
|
|
79
|
+
}),
|
|
80
|
+
}))
|
|
81
|
+
|
|
82
|
+
vi.mock('src/sdk/session', () => ({ useSession: mockUseSession }))
|
|
83
|
+
|
|
84
|
+
import NavbarSlider from '../../../src/components/navigation/NavbarSlider/NavbarSlider'
|
|
85
|
+
|
|
86
|
+
const baseProps = {
|
|
87
|
+
logo: {
|
|
88
|
+
src: '/logo.png',
|
|
89
|
+
alt: 'Logo',
|
|
90
|
+
link: { url: '/', title: 'Home' },
|
|
91
|
+
},
|
|
92
|
+
home: { label: 'Home' },
|
|
93
|
+
links: [],
|
|
94
|
+
region: { icon: 'MapPin', label: 'Region', shouldDisplayRegion: false },
|
|
95
|
+
signIn: {
|
|
96
|
+
button: {
|
|
97
|
+
icon: { alt: 'account', icon: 'User' },
|
|
98
|
+
label: 'Sign in',
|
|
99
|
+
myAccountLabel: 'My Account',
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
describe('NavbarSlider', () => {
|
|
105
|
+
it('resolves the sign-in area and forwards isSignInResolved=false while the session has not validated', () => {
|
|
106
|
+
mockUseSession.mockReturnValue({
|
|
107
|
+
b2b: {},
|
|
108
|
+
isSessionReady: false,
|
|
109
|
+
hasValidated: false,
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
render(<NavbarSlider {...baseProps} />)
|
|
113
|
+
|
|
114
|
+
expect(screen.getByTestId('navbar-account-area')).toBeTruthy()
|
|
115
|
+
expect(mockNavbarAccountArea).toHaveBeenCalledWith(
|
|
116
|
+
expect.objectContaining({
|
|
117
|
+
isSignInResolved: false,
|
|
118
|
+
skeletonAttr: 'data-fs-navbar-slider-signin-skeleton',
|
|
119
|
+
})
|
|
120
|
+
)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('forwards isSignInResolved=true and isOrganizationEnabled once the B2B representative session resolves', () => {
|
|
124
|
+
mockStoreConfig.experimental.enableFaststoreMyAccount = true
|
|
125
|
+
mockUseSession.mockReturnValue({
|
|
126
|
+
b2b: { isRepresentative: true },
|
|
127
|
+
isSessionReady: true,
|
|
128
|
+
hasValidated: true,
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
render(<NavbarSlider {...baseProps} />)
|
|
132
|
+
|
|
133
|
+
expect(mockNavbarAccountArea).toHaveBeenCalledWith(
|
|
134
|
+
expect.objectContaining({
|
|
135
|
+
isSignInResolved: true,
|
|
136
|
+
isOrganizationEnabled: true,
|
|
137
|
+
isRepresentative: true,
|
|
138
|
+
})
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
mockStoreConfig.experimental.enableFaststoreMyAccount = false
|
|
142
|
+
})
|
|
143
|
+
})
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import '@testing-library/jest-dom/vitest'
|
|
2
|
+
import { cleanup, render, screen } from '@testing-library/react'
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
4
|
+
|
|
5
|
+
const mockUseAccountPageData = vi.hoisted(() => vi.fn())
|
|
6
|
+
|
|
7
|
+
vi.mock('next/router', () => ({ useRouter: () => ({ locale: 'pt-BR' }) }))
|
|
8
|
+
vi.mock('src/sdk/account/accountPageContext', () => ({
|
|
9
|
+
useAccountPageData: mockUseAccountPageData,
|
|
10
|
+
}))
|
|
11
|
+
|
|
12
|
+
import AccountOrderDelivery from 'src/components/sections/Account/AccountOrderDelivery'
|
|
13
|
+
|
|
14
|
+
const order = {
|
|
15
|
+
storePreferencesData: { currencyCode: 'BRL' },
|
|
16
|
+
customFields: [],
|
|
17
|
+
deliveryOptionsData: {
|
|
18
|
+
contact: { name: 'Maria' },
|
|
19
|
+
deliveryOptions: [
|
|
20
|
+
{
|
|
21
|
+
selectedSla: 'Normal',
|
|
22
|
+
deliveryChannel: 'delivery',
|
|
23
|
+
shippingEstimate: '2bd',
|
|
24
|
+
friendlyDeliveryOptionName: 'Delivery Up to 2 business days',
|
|
25
|
+
quantityOfDifferentItems: 1,
|
|
26
|
+
total: 1100,
|
|
27
|
+
items: [],
|
|
28
|
+
address: {
|
|
29
|
+
city: 'Rio de Janeiro',
|
|
30
|
+
street: 'Rua Um',
|
|
31
|
+
postalCode: '20000-000',
|
|
32
|
+
state: 'RJ',
|
|
33
|
+
country: 'BRA',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
cleanup()
|
|
42
|
+
mockUseAccountPageData.mockReset()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
describe('AccountOrderDelivery', () => {
|
|
46
|
+
it('forwards the CMS labels to the delivery card and accordions', () => {
|
|
47
|
+
mockUseAccountPageData.mockReturnValue({ order })
|
|
48
|
+
|
|
49
|
+
render(
|
|
50
|
+
<AccountOrderDelivery
|
|
51
|
+
deliveryTitle="Entrega do pedido"
|
|
52
|
+
deliveryChannelLabel="Entrega"
|
|
53
|
+
businessDaysOtherTemplate="Em até {count} dias úteis"
|
|
54
|
+
recipientLabel="Destinatário"
|
|
55
|
+
/>
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
expect(screen.getByText('Entrega do pedido')).toBeInTheDocument()
|
|
59
|
+
expect(screen.getAllByText('Entrega Em até 2 dias úteis')).toHaveLength(2)
|
|
60
|
+
expect(screen.getByText('Destinatário')).toBeInTheDocument()
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('renders nothing when the order has no delivery data', () => {
|
|
64
|
+
mockUseAccountPageData.mockReturnValue({
|
|
65
|
+
order: { ...order, deliveryOptionsData: null },
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const { container } = render(<AccountOrderDelivery />)
|
|
69
|
+
|
|
70
|
+
expect(container).toBeEmptyDOMElement()
|
|
71
|
+
})
|
|
72
|
+
})
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import '@testing-library/jest-dom/vitest'
|
|
6
|
+
import { cleanup, render, screen } from '@testing-library/react'
|
|
7
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
8
|
+
|
|
9
|
+
const mockUseAccountPageData = vi.hoisted(() => vi.fn())
|
|
10
|
+
|
|
11
|
+
vi.mock('src/sdk/account/accountPageContext', () => ({
|
|
12
|
+
useAccountPageData: mockUseAccountPageData,
|
|
13
|
+
}))
|
|
14
|
+
|
|
15
|
+
vi.mock(
|
|
16
|
+
'src/components/account/orders/OrderDetails/OrderDetailsHeader',
|
|
17
|
+
() => ({
|
|
18
|
+
OrderDetailsHeader: ({
|
|
19
|
+
labels,
|
|
20
|
+
}: {
|
|
21
|
+
labels: Record<string, string | undefined>
|
|
22
|
+
}) => (
|
|
23
|
+
<div data-testid="order-details-header">
|
|
24
|
+
<span data-testid="reject-modal-title">{labels.rejectModalTitle}</span>
|
|
25
|
+
<span data-testid="reject-modal-message">
|
|
26
|
+
{labels.rejectModalMessage}
|
|
27
|
+
</span>
|
|
28
|
+
<span data-testid="reject-modal-confirm">
|
|
29
|
+
{labels.rejectModalConfirmText}
|
|
30
|
+
</span>
|
|
31
|
+
<span data-testid="approve-success-toast">
|
|
32
|
+
{labels.approveSuccessToast}
|
|
33
|
+
</span>
|
|
34
|
+
<span data-testid="approve-error-toast">
|
|
35
|
+
{labels.approveErrorToast}
|
|
36
|
+
</span>
|
|
37
|
+
<span data-testid="reject-success-toast">
|
|
38
|
+
{labels.rejectSuccessToast}
|
|
39
|
+
</span>
|
|
40
|
+
<span data-testid="reject-error-toast">{labels.rejectErrorToast}</span>
|
|
41
|
+
<span data-testid="pending-further-approvals-alert">
|
|
42
|
+
{labels.pendingFurtherApprovalsAlert}
|
|
43
|
+
</span>
|
|
44
|
+
</div>
|
|
45
|
+
),
|
|
46
|
+
})
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
import AccountOrderDetails from 'src/components/sections/Account/AccountOrderDetails'
|
|
50
|
+
import { defaultOrderDetailsHeaderLabels } from 'src/components/account/orders/OrderDetails/orderDetailsLabels'
|
|
51
|
+
|
|
52
|
+
const order = { orderId: '123' }
|
|
53
|
+
|
|
54
|
+
afterEach(cleanup)
|
|
55
|
+
|
|
56
|
+
describe('AccountOrderDetails', () => {
|
|
57
|
+
it('forwards the default English reject modal labels when the CMS has no override', () => {
|
|
58
|
+
mockUseAccountPageData.mockReturnValueOnce({ order })
|
|
59
|
+
|
|
60
|
+
render(<AccountOrderDetails />)
|
|
61
|
+
|
|
62
|
+
expect(screen.getByTestId('reject-modal-title')).toHaveTextContent(
|
|
63
|
+
defaultOrderDetailsHeaderLabels.rejectModalTitle
|
|
64
|
+
)
|
|
65
|
+
expect(screen.getByTestId('reject-modal-message').textContent).toBe(
|
|
66
|
+
defaultOrderDetailsHeaderLabels.rejectModalMessage
|
|
67
|
+
)
|
|
68
|
+
expect(screen.getByTestId('reject-modal-confirm')).toHaveTextContent(
|
|
69
|
+
defaultOrderDetailsHeaderLabels.rejectModalConfirmText
|
|
70
|
+
)
|
|
71
|
+
expect(screen.getByTestId('approve-success-toast')).toHaveTextContent(
|
|
72
|
+
defaultOrderDetailsHeaderLabels.approveSuccessToast
|
|
73
|
+
)
|
|
74
|
+
expect(screen.getByTestId('approve-error-toast')).toHaveTextContent(
|
|
75
|
+
defaultOrderDetailsHeaderLabels.approveErrorToast
|
|
76
|
+
)
|
|
77
|
+
expect(screen.getByTestId('reject-success-toast')).toHaveTextContent(
|
|
78
|
+
defaultOrderDetailsHeaderLabels.rejectSuccessToast
|
|
79
|
+
)
|
|
80
|
+
expect(screen.getByTestId('reject-error-toast')).toHaveTextContent(
|
|
81
|
+
defaultOrderDetailsHeaderLabels.rejectErrorToast
|
|
82
|
+
)
|
|
83
|
+
expect(
|
|
84
|
+
screen.getByTestId('pending-further-approvals-alert')
|
|
85
|
+
).toHaveTextContent(
|
|
86
|
+
defaultOrderDetailsHeaderLabels.pendingFurtherApprovalsAlert
|
|
87
|
+
)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('forwards CMS-provided reject modal labels to the order details header', () => {
|
|
91
|
+
mockUseAccountPageData.mockReturnValueOnce({ order })
|
|
92
|
+
|
|
93
|
+
render(
|
|
94
|
+
<AccountOrderDetails
|
|
95
|
+
rejectModalTitle="Rejeitar solicitação de aprovação"
|
|
96
|
+
rejectModalMessage="Você está rejeitando a política {policy}."
|
|
97
|
+
rejectModalConfirmText="Confirmar rejeição"
|
|
98
|
+
/>
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
expect(screen.getByTestId('reject-modal-title')).toHaveTextContent(
|
|
102
|
+
'Rejeitar solicitação de aprovação'
|
|
103
|
+
)
|
|
104
|
+
expect(screen.getByTestId('reject-modal-message')).toHaveTextContent(
|
|
105
|
+
'Você está rejeitando a política {policy}.'
|
|
106
|
+
)
|
|
107
|
+
expect(screen.getByTestId('reject-modal-confirm')).toHaveTextContent(
|
|
108
|
+
'Confirmar rejeição'
|
|
109
|
+
)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('forwards CMS-provided buying policy toast labels to the order details header', () => {
|
|
113
|
+
mockUseAccountPageData.mockReturnValueOnce({ order })
|
|
114
|
+
|
|
115
|
+
render(
|
|
116
|
+
<AccountOrderDetails
|
|
117
|
+
approveSuccessToast="Política {policy} aprovada com sucesso."
|
|
118
|
+
approveErrorToast="Não foi possível aprovar a política."
|
|
119
|
+
rejectSuccessToast="Política {policy} rejeitada. Pedido negado."
|
|
120
|
+
rejectErrorToast="Não foi possível rejeitar a política."
|
|
121
|
+
pendingFurtherApprovalsAlert="Sua aprovação foi registrada. O pedido ainda aguarda outras aprovações."
|
|
122
|
+
/>
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
expect(screen.getByTestId('approve-success-toast')).toHaveTextContent(
|
|
126
|
+
'Política {policy} aprovada com sucesso.'
|
|
127
|
+
)
|
|
128
|
+
expect(screen.getByTestId('approve-error-toast')).toHaveTextContent(
|
|
129
|
+
'Não foi possível aprovar a política.'
|
|
130
|
+
)
|
|
131
|
+
expect(screen.getByTestId('reject-success-toast')).toHaveTextContent(
|
|
132
|
+
'Política {policy} rejeitada. Pedido negado.'
|
|
133
|
+
)
|
|
134
|
+
expect(screen.getByTestId('reject-error-toast')).toHaveTextContent(
|
|
135
|
+
'Não foi possível rejeitar a política.'
|
|
136
|
+
)
|
|
137
|
+
expect(
|
|
138
|
+
screen.getByTestId('pending-further-approvals-alert')
|
|
139
|
+
).toHaveTextContent(
|
|
140
|
+
'Sua aprovação foi registrada. O pedido ainda aguarda outras aprovações.'
|
|
141
|
+
)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('renders nothing when the page data has no order', () => {
|
|
145
|
+
mockUseAccountPageData.mockReturnValueOnce({ order: null })
|
|
146
|
+
|
|
147
|
+
const { container } = render(<AccountOrderDetails />)
|
|
148
|
+
|
|
149
|
+
expect(container).toBeEmptyDOMElement()
|
|
150
|
+
})
|
|
151
|
+
})
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import '@testing-library/jest-dom/vitest'
|
|
2
|
+
import { cleanup, render, screen } from '@testing-library/react'
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
4
|
+
|
|
5
|
+
const mockUseAccountPageData = vi.hoisted(() => vi.fn())
|
|
6
|
+
|
|
7
|
+
vi.mock('next/router', () => ({ useRouter: () => ({ locale: 'pt-BR' }) }))
|
|
8
|
+
vi.mock('src/sdk/account/accountPageContext', () => ({
|
|
9
|
+
useAccountPageData: mockUseAccountPageData,
|
|
10
|
+
}))
|
|
11
|
+
|
|
12
|
+
import AccountOrderStatus from 'src/components/sections/Account/AccountOrderStatus'
|
|
13
|
+
|
|
14
|
+
const order = {
|
|
15
|
+
status: 'payment-approved',
|
|
16
|
+
creationDate: '2026-08-05T18:30:00.000Z',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
afterEach(cleanup)
|
|
20
|
+
|
|
21
|
+
describe('AccountOrderStatus', () => {
|
|
22
|
+
it('renders the timeline with the default labels', () => {
|
|
23
|
+
mockUseAccountPageData.mockReturnValueOnce({ order })
|
|
24
|
+
|
|
25
|
+
render(<AccountOrderStatus />)
|
|
26
|
+
|
|
27
|
+
expect(screen.getByText('Status')).toBeInTheDocument()
|
|
28
|
+
expect(screen.getByText('Order placed')).toBeInTheDocument()
|
|
29
|
+
expect(screen.getByText('Handling order')).toBeInTheDocument()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('forwards the CMS labels to the status card', () => {
|
|
33
|
+
mockUseAccountPageData.mockReturnValueOnce({ order })
|
|
34
|
+
|
|
35
|
+
render(
|
|
36
|
+
<AccountOrderStatus
|
|
37
|
+
statusTitle="Status do pedido"
|
|
38
|
+
orderPlacedStep="Pedido realizado"
|
|
39
|
+
approvedStep="Aprovado"
|
|
40
|
+
handlingStep="Em separação"
|
|
41
|
+
shipOrderStep="Enviar pedido"
|
|
42
|
+
/>
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
expect(screen.getByText('Status do pedido')).toBeInTheDocument()
|
|
46
|
+
expect(screen.getByText('Pedido realizado')).toBeInTheDocument()
|
|
47
|
+
expect(screen.getByText('Aprovado')).toBeInTheDocument()
|
|
48
|
+
expect(screen.getByText('Em separação')).toBeInTheDocument()
|
|
49
|
+
expect(screen.getByText('Enviar pedido')).toBeInTheDocument()
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('renders nothing when the page data has no order', () => {
|
|
53
|
+
mockUseAccountPageData.mockReturnValueOnce({ order: null })
|
|
54
|
+
|
|
55
|
+
const { container } = render(<AccountOrderStatus />)
|
|
56
|
+
|
|
57
|
+
expect(container).toBeEmptyDOMElement()
|
|
58
|
+
})
|
|
59
|
+
})
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import '@testing-library/jest-dom/vitest'
|
|
2
|
+
import { cleanup, render } from '@testing-library/react'
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
4
|
+
|
|
5
|
+
import type { ListOrdersProps } from 'src/components/account/orders/ListOrders/ListOrders'
|
|
6
|
+
|
|
7
|
+
const mockUseAccountPageData = vi.hoisted(() => vi.fn())
|
|
8
|
+
const mockListOrders = vi.hoisted(() =>
|
|
9
|
+
vi.fn((_props: ListOrdersProps) => null)
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
vi.mock('src/sdk/account/accountPageContext', () => ({
|
|
13
|
+
useAccountPageData: mockUseAccountPageData,
|
|
14
|
+
}))
|
|
15
|
+
vi.mock('src/components/account/orders/ListOrders', () => ({
|
|
16
|
+
ListOrders: mockListOrders,
|
|
17
|
+
}))
|
|
18
|
+
|
|
19
|
+
import AccountOrdersList from 'src/components/sections/Account/AccountOrdersList'
|
|
20
|
+
|
|
21
|
+
const pageData = {
|
|
22
|
+
listOrders: { list: [] },
|
|
23
|
+
total: 0,
|
|
24
|
+
perPage: 10,
|
|
25
|
+
filters: {
|
|
26
|
+
page: 1,
|
|
27
|
+
status: [],
|
|
28
|
+
dateInitial: '',
|
|
29
|
+
dateFinal: '',
|
|
30
|
+
text: '',
|
|
31
|
+
clientEmail: '',
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
cleanup()
|
|
37
|
+
mockListOrders.mockClear()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
describe('AccountOrdersList', () => {
|
|
41
|
+
it('forwards the default filter group labels', () => {
|
|
42
|
+
mockUseAccountPageData.mockReturnValueOnce(pageData)
|
|
43
|
+
|
|
44
|
+
render(<AccountOrdersList />)
|
|
45
|
+
|
|
46
|
+
expect(mockListOrders.mock.calls[0][0].labels).toMatchObject({
|
|
47
|
+
statusFilterLabel: 'Status',
|
|
48
|
+
orderDateFilterLabel: 'Order Date',
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('forwards the CMS filter group labels', () => {
|
|
53
|
+
mockUseAccountPageData.mockReturnValueOnce(pageData)
|
|
54
|
+
|
|
55
|
+
render(
|
|
56
|
+
<AccountOrdersList
|
|
57
|
+
statusFilterLabel="Situação"
|
|
58
|
+
orderDateFilterLabel="Data do pedido"
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
expect(mockListOrders.mock.calls[0][0].labels).toMatchObject({
|
|
63
|
+
statusFilterLabel: 'Situação',
|
|
64
|
+
orderDateFilterLabel: 'Data do pedido',
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
})
|
|
@@ -18,12 +18,13 @@ vi.mock('../../../src/server', () => ({
|
|
|
18
18
|
|
|
19
19
|
const mockedExecute = vi.mocked(execute)
|
|
20
20
|
|
|
21
|
-
const createResponse = () => {
|
|
21
|
+
const createResponse = ({ headersSent = false } = {}) => {
|
|
22
22
|
const res = {
|
|
23
23
|
status: vi.fn().mockReturnThis(),
|
|
24
24
|
setHeader: vi.fn().mockReturnThis(),
|
|
25
25
|
send: vi.fn().mockReturnThis(),
|
|
26
26
|
end: vi.fn().mockReturnThis(),
|
|
27
|
+
headersSent,
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
return res as unknown as NextApiResponse & typeof res
|
|
@@ -122,6 +123,7 @@ describe('/api/graphql error status propagation', () => {
|
|
|
122
123
|
expect(res.status).toHaveBeenCalledWith(500)
|
|
123
124
|
expect(res.end).toHaveBeenCalled()
|
|
124
125
|
expect(res.send).not.toHaveBeenCalled()
|
|
126
|
+
expect(res.setHeader).toHaveBeenCalledWith('cache-control', 'no-store')
|
|
125
127
|
})
|
|
126
128
|
|
|
127
129
|
it('exposes type, status and message in the body outside production', async () => {
|
|
@@ -168,6 +170,15 @@ describe('/api/graphql error status propagation', () => {
|
|
|
168
170
|
|
|
169
171
|
expect(res.status).toHaveBeenCalledWith(404)
|
|
170
172
|
})
|
|
173
|
+
|
|
174
|
+
it('sets cache-control: no-store on error responses so a bare 404/410 is not cached by intermediaries', async () => {
|
|
175
|
+
mockExecuteWithErrors([maskedError(new NotFoundError('missing'))])
|
|
176
|
+
|
|
177
|
+
const res = createResponse()
|
|
178
|
+
await handler(createRequest(), res)
|
|
179
|
+
|
|
180
|
+
expect(res.setHeader).toHaveBeenCalledWith('cache-control', 'no-store')
|
|
181
|
+
})
|
|
171
182
|
})
|
|
172
183
|
|
|
173
184
|
describe('/api/graphql request handling', () => {
|
|
@@ -200,6 +211,21 @@ describe('/api/graphql request handling', () => {
|
|
|
200
211
|
|
|
201
212
|
expect(res.status).toHaveBeenCalledWith(status)
|
|
202
213
|
expect(res.end).toHaveBeenCalled()
|
|
214
|
+
expect(res.setHeader).toHaveBeenCalledWith('cache-control', 'no-store')
|
|
203
215
|
}
|
|
204
216
|
)
|
|
217
|
+
|
|
218
|
+
it('skips the cache-control header when headers were already sent', async () => {
|
|
219
|
+
mockedExecute.mockRejectedValue(new Error('boom after flush'))
|
|
220
|
+
|
|
221
|
+
const res = createResponse({ headersSent: true })
|
|
222
|
+
await handler(createRequest(), res)
|
|
223
|
+
|
|
224
|
+
expect(res.setHeader).not.toHaveBeenCalledWith(
|
|
225
|
+
'cache-control',
|
|
226
|
+
expect.anything()
|
|
227
|
+
)
|
|
228
|
+
expect(res.status).toHaveBeenCalledWith(500)
|
|
229
|
+
expect(res.end).toHaveBeenCalled()
|
|
230
|
+
})
|
|
205
231
|
})
|