@faststore/core 4.3.0-dev.6 → 4.3.0-dev.8

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.
@@ -0,0 +1,192 @@
1
+ /**
2
+ * @vitest-environment jsdom
3
+ */
4
+
5
+ import { act, renderHook } from '@testing-library/react'
6
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
7
+
8
+ vi.mock('discovery.config', () => ({
9
+ __esModule: true,
10
+ default: {
11
+ api: { storeId: 'storeframework' },
12
+ },
13
+ }))
14
+
15
+ const mockFetch = vi.hoisted(() => vi.fn())
16
+ vi.mock('isomorphic-unfetch', () => ({ __esModule: true, default: mockFetch }))
17
+
18
+ import { useSetPassword } from '../../../src/sdk/account/useSetPassword'
19
+
20
+ const okResponse = (body: unknown) => ({
21
+ ok: true,
22
+ statusText: 'OK',
23
+ json: async () => body,
24
+ })
25
+
26
+ const errorResponse = (body: unknown) => ({
27
+ ok: false,
28
+ statusText: 'Bad Request',
29
+ json: async () => body,
30
+ })
31
+
32
+ const validInput = {
33
+ userEmail: 'shopper@example.com',
34
+ currentPassword: 'OldPass123',
35
+ newPassword: 'NewPass123',
36
+ }
37
+
38
+ function getSetPasswordCall() {
39
+ return mockFetch.mock.calls.find((call) =>
40
+ String(call[0]).includes('setpassword')
41
+ )
42
+ }
43
+
44
+ function getStartLoginCall() {
45
+ return mockFetch.mock.calls.find((call) =>
46
+ String(call[0]).includes('/pub/authentication/start')
47
+ )
48
+ }
49
+
50
+ describe('useSetPassword', () => {
51
+ beforeEach(() => {
52
+ mockFetch.mockReset()
53
+ })
54
+
55
+ afterEach(() => {
56
+ vi.clearAllMocks()
57
+ })
58
+
59
+ it('posts to the new authenticator setpassword route with expireSessions and an', async () => {
60
+ mockFetch
61
+ .mockResolvedValueOnce(okResponse({})) // startLogin
62
+ .mockResolvedValueOnce(okResponse({ authStatus: 'success' }))
63
+
64
+ const { result } = renderHook(() => useSetPassword('myaccount'))
65
+
66
+ await act(async () => {
67
+ await result.current.setPassword(validInput)
68
+ })
69
+
70
+ const call = getSetPasswordCall()
71
+ expect(call).toBeDefined()
72
+
73
+ const url = String(call?.[0])
74
+ expect(url).toContain(
75
+ '/api/authenticator/pub/authentication/classic/setpassword'
76
+ )
77
+ expect(url).not.toContain('/api/vtexid/')
78
+ expect(url).toContain('expireSessions=true')
79
+ expect(url).toContain('an=myaccount')
80
+ })
81
+
82
+ it('posts to the new authenticator start route with an and credentials', async () => {
83
+ mockFetch
84
+ .mockResolvedValueOnce(okResponse({})) // startLogin
85
+ .mockResolvedValueOnce(okResponse({ authStatus: 'success' }))
86
+
87
+ const { result } = renderHook(() => useSetPassword('myaccount'))
88
+
89
+ await act(async () => {
90
+ await result.current.setPassword(validInput)
91
+ })
92
+
93
+ const call = getStartLoginCall()
94
+ expect(call).toBeDefined()
95
+
96
+ const url = String(call?.[0])
97
+ expect(url).toContain('/api/authenticator/pub/authentication/start')
98
+ expect(url).not.toContain('/api/vtexid/')
99
+ expect(url).toContain('an=myaccount')
100
+
101
+ const init = call?.[1] as RequestInit
102
+ expect(init?.method).toBe('POST')
103
+ expect(init?.credentials).toBe('include')
104
+
105
+ const body = init?.body as FormData
106
+ expect(body).toBeInstanceOf(FormData)
107
+ expect(body.get('user')).toBe(validInput.userEmail)
108
+ expect(body.get('scope')).toBe('myaccount')
109
+ expect(body.get('accountName')).toBe('myaccount')
110
+ expect(body.get('returnUrl')).toBe('/')
111
+ })
112
+
113
+ it('sends a POST with credentials and the expected form-data body', async () => {
114
+ mockFetch
115
+ .mockResolvedValueOnce(okResponse({}))
116
+ .mockResolvedValueOnce(okResponse({ authStatus: 'success' }))
117
+
118
+ const { result } = renderHook(() => useSetPassword('myaccount'))
119
+
120
+ await act(async () => {
121
+ await result.current.setPassword(validInput)
122
+ })
123
+
124
+ const call = getSetPasswordCall()
125
+ const init = call?.[1] as RequestInit
126
+
127
+ expect(init?.method).toBe('POST')
128
+ expect(init?.credentials).toBe('include')
129
+
130
+ const body = init?.body as FormData
131
+ expect(body).toBeInstanceOf(FormData)
132
+ expect(body.get('login')).toBe(validInput.userEmail)
133
+ expect(body.get('currentPassword')).toBe(validInput.currentPassword)
134
+ expect(body.get('newPassword')).toBe(validInput.newPassword)
135
+ })
136
+
137
+ it('returns success when the endpoint reports authStatus success', async () => {
138
+ mockFetch
139
+ .mockResolvedValueOnce(okResponse({}))
140
+ .mockResolvedValueOnce(okResponse({ authStatus: 'success' }))
141
+
142
+ const { result } = renderHook(() => useSetPassword('myaccount'))
143
+
144
+ let outcome: { success: boolean; message: string } | undefined
145
+ await act(async () => {
146
+ outcome = await result.current.setPassword(validInput)
147
+ })
148
+
149
+ expect(outcome).toEqual({
150
+ success: true,
151
+ message: 'Password set successfully',
152
+ })
153
+ })
154
+
155
+ it('maps wrongcredentials error responses to the existing message', async () => {
156
+ mockFetch
157
+ .mockResolvedValueOnce(okResponse({}))
158
+ .mockResolvedValueOnce(errorResponse({ authStatus: 'wrongcredentials' }))
159
+
160
+ const { result } = renderHook(() => useSetPassword('myaccount'))
161
+
162
+ let outcome: { success: boolean; message: string } | undefined
163
+ await act(async () => {
164
+ outcome = await result.current.setPassword(validInput)
165
+ })
166
+
167
+ expect(outcome).toEqual({ success: false, message: 'Wrong credentials' })
168
+ })
169
+
170
+ it('falls back to config.api.storeId when accountName is missing', async () => {
171
+ mockFetch
172
+ .mockResolvedValueOnce(okResponse({}))
173
+ .mockResolvedValueOnce(okResponse({ authStatus: 'success' }))
174
+
175
+ const { result } = renderHook(() => useSetPassword())
176
+
177
+ await act(async () => {
178
+ await result.current.setPassword(validInput)
179
+ })
180
+
181
+ const setPasswordUrl = String(getSetPasswordCall()?.[0])
182
+ expect(setPasswordUrl).toContain('an=storeframework')
183
+
184
+ const startLoginCall = getStartLoginCall()
185
+ const startLoginUrl = String(startLoginCall?.[0])
186
+ expect(startLoginUrl).toContain('an=storeframework')
187
+
188
+ const startBody = (startLoginCall?.[1] as RequestInit)?.body as FormData
189
+ expect(startBody.get('scope')).toBe('storeframework')
190
+ expect(startBody.get('accountName')).toBe('storeframework')
191
+ })
192
+ })