@incodetech/core 2.0.0-alpha.2 → 2.0.0-alpha.4
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/dist/OpenViduLogger-BdPfiZO6.esm.js +3 -0
- package/dist/OpenViduLogger-CQyDxBvM.esm.js +803 -0
- package/dist/{addEvent-1Mi5CEiq.esm.js → addEvent-9v4w5iO-.esm.js} +1 -1
- package/dist/email.d.ts +1 -1
- package/dist/email.esm.js +2 -2
- package/dist/{endpoints-D_pUMaqA.esm.js → endpoints-Dn1t57hJ.esm.js} +8 -3
- package/dist/flow.d.ts +3 -3
- package/dist/flow.esm.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +2 -2
- package/dist/{lib-CyIAFRfr.esm.js → lib-Bu9XGMBW.esm.js} +1 -800
- package/dist/{permissionServices-CVR0Pq38.esm.js → permissionServices-CCpxd8le.esm.js} +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/phone.esm.js +2 -2
- package/dist/selfie.d.ts +5 -4
- package/dist/selfie.esm.js +27 -10
- package/package.json +4 -1
- package/.turbo/turbo-build.log +0 -33
- package/.turbo/turbo-coverage.log +0 -22
- package/.turbo/turbo-format.log +0 -6
- package/.turbo/turbo-lint$colon$fix.log +0 -77
- package/.turbo/turbo-lint.log +0 -95
- package/.turbo/turbo-test.log +0 -870
- package/.turbo/turbo-typecheck.log +0 -5
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -221
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -210
- package/coverage/src/camera/cameraService.ts.html +0 -580
- package/coverage/src/camera/cameraServices.ts.html +0 -163
- package/coverage/src/camera/cameraStateMachine.ts.html +0 -877
- package/coverage/src/camera/index.html +0 -146
- package/coverage/src/email/emailActor.ts.html +0 -130
- package/coverage/src/email/emailManager.ts.html +0 -1366
- package/coverage/src/email/emailStateMachine.ts.html +0 -1186
- package/coverage/src/email/index.html +0 -146
- package/coverage/src/flow/flowActor.ts.html +0 -124
- package/coverage/src/flow/flowAnalyzer.ts.html +0 -196
- package/coverage/src/flow/flowManager.ts.html +0 -790
- package/coverage/src/flow/flowServices.ts.html +0 -124
- package/coverage/src/flow/flowStateMachine.ts.html +0 -631
- package/coverage/src/flow/index.html +0 -221
- package/coverage/src/flow/moduleLoader.ts.html +0 -304
- package/coverage/src/flow/orchestratedFlowManager.ts.html +0 -778
- package/coverage/src/flow/orchestratedFlowStateMachine.ts.html +0 -1060
- package/coverage/src/http/api.ts.html +0 -355
- package/coverage/src/http/endpoints.ts.html +0 -136
- package/coverage/src/http/index.html +0 -131
- package/coverage/src/index.html +0 -116
- package/coverage/src/phone/index.html +0 -146
- package/coverage/src/phone/phoneActor.ts.html +0 -130
- package/coverage/src/phone/phoneManager.ts.html +0 -1459
- package/coverage/src/phone/phoneStateMachine.ts.html +0 -1351
- package/coverage/src/recordings/index.html +0 -116
- package/coverage/src/recordings/recordingsRepository.ts.html +0 -229
- package/coverage/src/selfie/index.html +0 -191
- package/coverage/src/selfie/selfieActor.ts.html +0 -136
- package/coverage/src/selfie/selfieErrorUtils.ts.html +0 -283
- package/coverage/src/selfie/selfieManager.ts.html +0 -988
- package/coverage/src/selfie/selfieStateMachine.ts.html +0 -2497
- package/coverage/src/selfie/selfieUploadService.ts.html +0 -328
- package/coverage/src/selfie/types.ts.html +0 -394
- package/coverage/src/setup.ts.html +0 -598
- package/src/camera/cameraActor.ts +0 -21
- package/src/camera/cameraService.test.ts +0 -437
- package/src/camera/cameraService.ts +0 -165
- package/src/camera/cameraServices.test.ts +0 -66
- package/src/camera/cameraServices.ts +0 -26
- package/src/camera/cameraStateMachine.test.ts +0 -602
- package/src/camera/cameraStateMachine.ts +0 -264
- package/src/camera/index.ts +0 -5
- package/src/camera/types.ts +0 -17
- package/src/device/getBrowser.ts +0 -31
- package/src/device/getDeviceClass.ts +0 -29
- package/src/device/index.ts +0 -2
- package/src/email/__mocks__/emailMocks.ts +0 -59
- package/src/email/emailActor.ts +0 -15
- package/src/email/emailManager.test.ts +0 -573
- package/src/email/emailManager.ts +0 -427
- package/src/email/emailServices.ts +0 -66
- package/src/email/emailStateMachine.test.ts +0 -741
- package/src/email/emailStateMachine.ts +0 -367
- package/src/email/index.ts +0 -39
- package/src/email/types.ts +0 -60
- package/src/events/addEvent.ts +0 -20
- package/src/events/types.ts +0 -7
- package/src/flow/__mocks__/flowMocks.ts +0 -84
- package/src/flow/flowActor.ts +0 -13
- package/src/flow/flowAnalyzer.test.ts +0 -266
- package/src/flow/flowAnalyzer.ts +0 -37
- package/src/flow/flowCompletionService.ts +0 -21
- package/src/flow/flowManager.test.ts +0 -560
- package/src/flow/flowManager.ts +0 -235
- package/src/flow/flowServices.test.ts +0 -109
- package/src/flow/flowServices.ts +0 -13
- package/src/flow/flowStateMachine.test.ts +0 -334
- package/src/flow/flowStateMachine.ts +0 -182
- package/src/flow/index.ts +0 -21
- package/src/flow/moduleLoader.test.ts +0 -136
- package/src/flow/moduleLoader.ts +0 -73
- package/src/flow/orchestratedFlowManager.test.ts +0 -240
- package/src/flow/orchestratedFlowManager.ts +0 -231
- package/src/flow/orchestratedFlowStateMachine.test.ts +0 -199
- package/src/flow/orchestratedFlowStateMachine.ts +0 -325
- package/src/flow/types.ts +0 -434
- package/src/http/__mocks__/api.ts +0 -88
- package/src/http/api.test.ts +0 -231
- package/src/http/api.ts +0 -90
- package/src/http/endpoints.ts +0 -17
- package/src/index.ts +0 -33
- package/src/permissions/index.ts +0 -2
- package/src/permissions/permissionServices.ts +0 -31
- package/src/permissions/types.ts +0 -3
- package/src/phone/__mocks__/phoneMocks.ts +0 -71
- package/src/phone/index.ts +0 -39
- package/src/phone/phoneActor.ts +0 -15
- package/src/phone/phoneManager.test.ts +0 -393
- package/src/phone/phoneManager.ts +0 -458
- package/src/phone/phoneServices.ts +0 -98
- package/src/phone/phoneStateMachine.test.ts +0 -918
- package/src/phone/phoneStateMachine.ts +0 -422
- package/src/phone/types.ts +0 -83
- package/src/recordings/recordingsRepository.test.ts +0 -87
- package/src/recordings/recordingsRepository.ts +0 -48
- package/src/recordings/streamingEvents.ts +0 -10
- package/src/selfie/__mocks__/selfieMocks.ts +0 -26
- package/src/selfie/index.ts +0 -14
- package/src/selfie/selfieActor.ts +0 -17
- package/src/selfie/selfieErrorUtils.test.ts +0 -116
- package/src/selfie/selfieErrorUtils.ts +0 -66
- package/src/selfie/selfieManager.test.ts +0 -297
- package/src/selfie/selfieManager.ts +0 -301
- package/src/selfie/selfieServices.ts +0 -362
- package/src/selfie/selfieStateMachine.test.ts +0 -283
- package/src/selfie/selfieStateMachine.ts +0 -804
- package/src/selfie/selfieUploadService.test.ts +0 -90
- package/src/selfie/selfieUploadService.ts +0 -81
- package/src/selfie/types.ts +0 -103
- package/src/session/index.ts +0 -5
- package/src/session/sessionService.ts +0 -78
- package/src/setup.test.ts +0 -61
- package/src/setup.ts +0 -171
- package/tsconfig.json +0 -13
- package/tsdown.config.ts +0 -22
- package/vitest.config.ts +0 -37
- package/vitest.setup.ts +0 -135
- /package/dist/{Manager-6BwbaI_H.d.ts → Manager-BGfxEmyv.d.ts} +0 -0
- /package/dist/{StateMachine-7c1gcu94.d.ts → StateMachine-DRE1oH2B.d.ts} +0 -0
- /package/dist/{types-tq1ypYSL.d.ts → types-kWlqshfM.d.ts} +0 -0
- /package/dist/{warmup-Dr7OcFND.d.ts → warmup-CEJTfxQr.d.ts} +0 -0
|
@@ -1,573 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { mockEmailConfig, mockEmailConfigNoOtp } from './__mocks__/emailMocks';
|
|
3
|
-
import { createEmailManager, type EmailState } from './emailManager';
|
|
4
|
-
|
|
5
|
-
// Mock the email services - using same pattern as phone tests
|
|
6
|
-
vi.mock('./emailServices', () => ({
|
|
7
|
-
fetchEmail: vi.fn().mockResolvedValue({ email: 'user@example.com' }),
|
|
8
|
-
addEmail: vi.fn().mockResolvedValue({ success: true }),
|
|
9
|
-
sendEmailOtp: vi.fn().mockResolvedValue(undefined),
|
|
10
|
-
verifyEmailOtp: vi.fn().mockResolvedValue({ success: true }),
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
// Mock the events module
|
|
14
|
-
vi.mock('../events/addEvent', () => ({
|
|
15
|
-
addEvent: vi.fn().mockResolvedValue(undefined),
|
|
16
|
-
}));
|
|
17
|
-
|
|
18
|
-
describe('createEmailManager', () => {
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
vi.clearAllMocks();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
describe('Initial state', () => {
|
|
24
|
-
it('should create an email manager with all API methods', () => {
|
|
25
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
26
|
-
|
|
27
|
-
expect(manager).toBeDefined();
|
|
28
|
-
expect(manager.getState).toBeDefined();
|
|
29
|
-
expect(manager.subscribe).toBeDefined();
|
|
30
|
-
expect(manager.stop).toBeDefined();
|
|
31
|
-
expect(manager.load).toBeDefined();
|
|
32
|
-
expect(manager.setEmail).toBeDefined();
|
|
33
|
-
expect(manager.submit).toBeDefined();
|
|
34
|
-
expect(manager.submitOtp).toBeDefined();
|
|
35
|
-
expect(manager.resendOtp).toBeDefined();
|
|
36
|
-
expect(manager.back).toBeDefined();
|
|
37
|
-
expect(manager.reset).toBeDefined();
|
|
38
|
-
|
|
39
|
-
manager.stop();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should start in idle state', () => {
|
|
43
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
44
|
-
|
|
45
|
-
expect(manager.getState()).toEqual({ status: 'idle' });
|
|
46
|
-
|
|
47
|
-
manager.stop();
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe('Headless email flow without OTP', () => {
|
|
52
|
-
it('should transition through email flow states', async () => {
|
|
53
|
-
const manager = createEmailManager({ config: mockEmailConfigNoOtp });
|
|
54
|
-
const states: EmailState[] = [];
|
|
55
|
-
|
|
56
|
-
manager.subscribe((state) => states.push(state));
|
|
57
|
-
|
|
58
|
-
// Load the manager
|
|
59
|
-
manager.load();
|
|
60
|
-
|
|
61
|
-
// Wait for inputting state
|
|
62
|
-
await vi.waitFor(() => {
|
|
63
|
-
expect(manager.getState().status).toBe('inputting');
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Verify we reached inputting
|
|
67
|
-
expect(states.some((s) => s.status === 'inputting')).toBe(true);
|
|
68
|
-
|
|
69
|
-
// Set email and submit
|
|
70
|
-
manager.setEmail('user@example.com', true);
|
|
71
|
-
manager.submit();
|
|
72
|
-
|
|
73
|
-
// Wait for any progression past inputting
|
|
74
|
-
await vi.waitFor(
|
|
75
|
-
() => {
|
|
76
|
-
const status = manager.getState().status;
|
|
77
|
-
return (
|
|
78
|
-
status === 'submitting' ||
|
|
79
|
-
status === 'success' ||
|
|
80
|
-
status === 'error'
|
|
81
|
-
);
|
|
82
|
-
},
|
|
83
|
-
{ timeout: 2000 },
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
manager.stop();
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
describe('Headless email flow with OTP', () => {
|
|
91
|
-
it('should reach awaitingOtp state after email submission', async () => {
|
|
92
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
93
|
-
|
|
94
|
-
manager.load();
|
|
95
|
-
|
|
96
|
-
await vi.waitFor(() => {
|
|
97
|
-
expect(manager.getState().status).toBe('inputting');
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Set email - must be marked as valid
|
|
101
|
-
manager.setEmail('user@example.com', true);
|
|
102
|
-
|
|
103
|
-
// Small delay to ensure state update
|
|
104
|
-
await vi.waitFor(() => {
|
|
105
|
-
manager.submit();
|
|
106
|
-
return true;
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Wait for OTP states
|
|
110
|
-
await vi.waitFor(
|
|
111
|
-
() => {
|
|
112
|
-
const status = manager.getState().status;
|
|
113
|
-
return (
|
|
114
|
-
status === 'submitting' ||
|
|
115
|
-
status === 'sendingOtp' ||
|
|
116
|
-
status === 'awaitingOtp' ||
|
|
117
|
-
status === 'success'
|
|
118
|
-
);
|
|
119
|
-
},
|
|
120
|
-
{ timeout: 2000 },
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
manager.stop();
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should verify OTP and reach success', async () => {
|
|
127
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
128
|
-
|
|
129
|
-
manager.load();
|
|
130
|
-
|
|
131
|
-
await vi.waitFor(() => {
|
|
132
|
-
expect(manager.getState().status).toBe('inputting');
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
manager.setEmail('user@example.com', true);
|
|
136
|
-
manager.submit();
|
|
137
|
-
|
|
138
|
-
await vi.waitFor(
|
|
139
|
-
() => {
|
|
140
|
-
const status = manager.getState().status;
|
|
141
|
-
return status === 'awaitingOtp';
|
|
142
|
-
},
|
|
143
|
-
{ timeout: 2000 },
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
manager.submitOtp('ABC123');
|
|
147
|
-
|
|
148
|
-
await vi.waitFor(
|
|
149
|
-
() => {
|
|
150
|
-
const status = manager.getState().status;
|
|
151
|
-
return status === 'success' || status === 'verifyingOtp';
|
|
152
|
-
},
|
|
153
|
-
{ timeout: 2000 },
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
manager.stop();
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('should handle back navigation from OTP screen', async () => {
|
|
160
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
161
|
-
|
|
162
|
-
manager.load();
|
|
163
|
-
|
|
164
|
-
await vi.waitFor(() => {
|
|
165
|
-
expect(manager.getState().status).toBe('inputting');
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
manager.setEmail('user@example.com', true);
|
|
169
|
-
manager.submit();
|
|
170
|
-
|
|
171
|
-
await vi.waitFor(() => {
|
|
172
|
-
expect(manager.getState().status).toBe('awaitingOtp');
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
manager.back();
|
|
176
|
-
|
|
177
|
-
await vi.waitFor(() => {
|
|
178
|
-
expect(manager.getState().status).toBe('inputting');
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
manager.stop();
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
describe('api.load()', () => {
|
|
186
|
-
it('should transition through loading states', async () => {
|
|
187
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
188
|
-
|
|
189
|
-
manager.load();
|
|
190
|
-
|
|
191
|
-
// Should eventually reach inputting
|
|
192
|
-
await vi.waitFor(() => {
|
|
193
|
-
expect(manager.getState().status).toBe('inputting');
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
manager.stop();
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
describe('api.setEmail()', () => {
|
|
201
|
-
it('should update email in context', async () => {
|
|
202
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
203
|
-
|
|
204
|
-
manager.load();
|
|
205
|
-
|
|
206
|
-
await vi.waitFor(() => {
|
|
207
|
-
expect(manager.getState().status).toBe('inputting');
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
manager.setEmail('user@example.com', true);
|
|
211
|
-
|
|
212
|
-
// Email is stored in context but not exposed in state
|
|
213
|
-
// The important thing is the action doesn't error
|
|
214
|
-
expect(manager.getState().status).toBe('inputting');
|
|
215
|
-
|
|
216
|
-
manager.stop();
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
describe('api.reset()', () => {
|
|
221
|
-
it('should not reset from inputting state (RESET not handled there)', async () => {
|
|
222
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
223
|
-
|
|
224
|
-
manager.load();
|
|
225
|
-
|
|
226
|
-
await vi.waitFor(() => {
|
|
227
|
-
expect(manager.getState().status).toBe('inputting');
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
manager.reset();
|
|
231
|
-
|
|
232
|
-
// RESET is only handled in success/error states
|
|
233
|
-
expect(manager.getState().status).toBe('inputting');
|
|
234
|
-
|
|
235
|
-
manager.stop();
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
describe('subscribe()', () => {
|
|
240
|
-
it('should notify subscribers of state changes', async () => {
|
|
241
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
242
|
-
const states: EmailState[] = [];
|
|
243
|
-
|
|
244
|
-
manager.subscribe((state) => states.push(state));
|
|
245
|
-
|
|
246
|
-
manager.load();
|
|
247
|
-
|
|
248
|
-
await vi.waitFor(() => {
|
|
249
|
-
expect(manager.getState().status).toBe('inputting');
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
expect(states.length).toBeGreaterThan(0);
|
|
253
|
-
expect(states.some((s) => s.status === 'inputting')).toBe(true);
|
|
254
|
-
|
|
255
|
-
manager.stop();
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('should return unsubscribe function', async () => {
|
|
259
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
260
|
-
const listener = vi.fn();
|
|
261
|
-
|
|
262
|
-
const unsubscribe = manager.subscribe(listener);
|
|
263
|
-
|
|
264
|
-
manager.load();
|
|
265
|
-
|
|
266
|
-
await vi.waitFor(() => {
|
|
267
|
-
expect(manager.getState().status).toBe('inputting');
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
const callCountAfterLoad = listener.mock.calls.length;
|
|
271
|
-
|
|
272
|
-
unsubscribe();
|
|
273
|
-
|
|
274
|
-
manager.setEmail('user@example.com', true);
|
|
275
|
-
|
|
276
|
-
// Should not have been called after unsubscribe
|
|
277
|
-
expect(listener.mock.calls.length).toBe(callCountAfterLoad);
|
|
278
|
-
|
|
279
|
-
manager.stop();
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
describe('Error handling', () => {
|
|
284
|
-
it('should handle email submission errors', async () => {
|
|
285
|
-
const { addEmail } = await import('./emailServices');
|
|
286
|
-
vi.mocked(addEmail).mockRejectedValueOnce(new Error('Network error'));
|
|
287
|
-
|
|
288
|
-
const manager = createEmailManager({ config: mockEmailConfigNoOtp });
|
|
289
|
-
|
|
290
|
-
manager.load();
|
|
291
|
-
|
|
292
|
-
await vi.waitFor(() => {
|
|
293
|
-
expect(manager.getState().status).toBe('inputting');
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
manager.setEmail('user@example.com', true);
|
|
297
|
-
manager.submit();
|
|
298
|
-
|
|
299
|
-
await vi.waitFor(() => {
|
|
300
|
-
const state = manager.getState();
|
|
301
|
-
// Should either show error in inputting state or error state
|
|
302
|
-
return state.status === 'inputting' || state.status === 'error';
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
manager.stop();
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
describe('Headless API usage', () => {
|
|
310
|
-
it('exposes all methods needed for headless integration', () => {
|
|
311
|
-
// This test documents the headless API surface
|
|
312
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
313
|
-
|
|
314
|
-
// Manager provides these methods for headless usage:
|
|
315
|
-
expect(typeof manager.load).toBe('function');
|
|
316
|
-
expect(typeof manager.setEmail).toBe('function');
|
|
317
|
-
expect(typeof manager.submit).toBe('function');
|
|
318
|
-
expect(typeof manager.submitOtp).toBe('function');
|
|
319
|
-
expect(typeof manager.resendOtp).toBe('function');
|
|
320
|
-
expect(typeof manager.back).toBe('function');
|
|
321
|
-
expect(typeof manager.reset).toBe('function');
|
|
322
|
-
expect(typeof manager.getState).toBe('function');
|
|
323
|
-
expect(typeof manager.subscribe).toBe('function');
|
|
324
|
-
expect(typeof manager.stop).toBe('function');
|
|
325
|
-
|
|
326
|
-
manager.stop();
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
it('can track state changes via subscribe', async () => {
|
|
330
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
331
|
-
const stateHistory: string[] = [];
|
|
332
|
-
|
|
333
|
-
// Subscribe to track all state changes
|
|
334
|
-
manager.subscribe((state) => {
|
|
335
|
-
stateHistory.push(state.status);
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
manager.load();
|
|
339
|
-
|
|
340
|
-
await vi.waitFor(() => {
|
|
341
|
-
expect(manager.getState().status).toBe('inputting');
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
// Verify we captured state transitions
|
|
345
|
-
expect(stateHistory.length).toBeGreaterThan(0);
|
|
346
|
-
expect(stateHistory.includes('inputting')).toBe(true);
|
|
347
|
-
|
|
348
|
-
manager.stop();
|
|
349
|
-
});
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
describe('mapState coverage', () => {
|
|
353
|
-
it('should map loadingPrefill state correctly', async () => {
|
|
354
|
-
const configWithPrefill = { ...mockEmailConfig, prefill: true };
|
|
355
|
-
const manager = createEmailManager({ config: configWithPrefill });
|
|
356
|
-
const states: EmailState[] = [];
|
|
357
|
-
|
|
358
|
-
manager.subscribe((state) => states.push(state));
|
|
359
|
-
manager.load();
|
|
360
|
-
|
|
361
|
-
// Should pass through loadingPrefill
|
|
362
|
-
await vi.waitFor(() => {
|
|
363
|
-
expect(manager.getState().status).toBe('inputting');
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
expect(states.some((s) => s.status === 'loadingPrefill')).toBe(true);
|
|
367
|
-
|
|
368
|
-
manager.stop();
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
it('should map submitting state correctly', async () => {
|
|
372
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
373
|
-
const states: EmailState[] = [];
|
|
374
|
-
|
|
375
|
-
manager.subscribe((state) => states.push(state));
|
|
376
|
-
manager.load();
|
|
377
|
-
|
|
378
|
-
await vi.waitFor(() => {
|
|
379
|
-
expect(manager.getState().status).toBe('inputting');
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
manager.setEmail('user@example.com', true);
|
|
383
|
-
manager.submit();
|
|
384
|
-
|
|
385
|
-
await vi.waitFor(() => {
|
|
386
|
-
const status = manager.getState().status;
|
|
387
|
-
return status !== 'inputting';
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
expect(states.some((s) => s.status === 'submitting')).toBe(true);
|
|
391
|
-
|
|
392
|
-
manager.stop();
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
it('should map sendingOtp state correctly', async () => {
|
|
396
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
397
|
-
const states: EmailState[] = [];
|
|
398
|
-
|
|
399
|
-
manager.subscribe((state) => states.push(state));
|
|
400
|
-
manager.load();
|
|
401
|
-
|
|
402
|
-
await vi.waitFor(() => {
|
|
403
|
-
expect(manager.getState().status).toBe('inputting');
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
manager.setEmail('user@example.com', true);
|
|
407
|
-
manager.submit();
|
|
408
|
-
|
|
409
|
-
await vi.waitFor(() => {
|
|
410
|
-
expect(manager.getState().status).toBe('awaitingOtp');
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
expect(states.some((s) => s.status === 'sendingOtp')).toBe(true);
|
|
414
|
-
|
|
415
|
-
manager.stop();
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
it('should map awaitingOtp state with correct properties', async () => {
|
|
419
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
420
|
-
|
|
421
|
-
manager.load();
|
|
422
|
-
|
|
423
|
-
await vi.waitFor(() => {
|
|
424
|
-
expect(manager.getState().status).toBe('inputting');
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
manager.setEmail('user@example.com', true);
|
|
428
|
-
manager.submit();
|
|
429
|
-
|
|
430
|
-
await vi.waitFor(() => {
|
|
431
|
-
expect(manager.getState().status).toBe('awaitingOtp');
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
const state = manager.getState();
|
|
435
|
-
if (state.status === 'awaitingOtp') {
|
|
436
|
-
expect(typeof state.resendTimer).toBe('number');
|
|
437
|
-
expect(typeof state.canResend).toBe('boolean');
|
|
438
|
-
expect(typeof state.attemptsRemaining).toBe('number');
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
manager.stop();
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
it('should map verifyingOtp state correctly', async () => {
|
|
445
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
446
|
-
const states: EmailState[] = [];
|
|
447
|
-
|
|
448
|
-
manager.subscribe((state) => states.push(state));
|
|
449
|
-
manager.load();
|
|
450
|
-
|
|
451
|
-
await vi.waitFor(() => {
|
|
452
|
-
expect(manager.getState().status).toBe('inputting');
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
manager.setEmail('user@example.com', true);
|
|
456
|
-
manager.submit();
|
|
457
|
-
|
|
458
|
-
await vi.waitFor(() => {
|
|
459
|
-
expect(manager.getState().status).toBe('awaitingOtp');
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
manager.submitOtp('ABC123');
|
|
463
|
-
|
|
464
|
-
await vi.waitFor(() => {
|
|
465
|
-
expect(manager.getState().status).toBe('success');
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
expect(states.some((s) => s.status === 'verifyingOtp')).toBe(true);
|
|
469
|
-
|
|
470
|
-
manager.stop();
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
it('should map otpError state with correct properties', async () => {
|
|
474
|
-
const { verifyEmailOtp } = await import('./emailServices');
|
|
475
|
-
vi.mocked(verifyEmailOtp).mockResolvedValueOnce({ success: false });
|
|
476
|
-
|
|
477
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
478
|
-
|
|
479
|
-
manager.load();
|
|
480
|
-
|
|
481
|
-
await vi.waitFor(() => {
|
|
482
|
-
expect(manager.getState().status).toBe('inputting');
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
manager.setEmail('user@example.com', true);
|
|
486
|
-
manager.submit();
|
|
487
|
-
|
|
488
|
-
await vi.waitFor(() => {
|
|
489
|
-
expect(manager.getState().status).toBe('awaitingOtp');
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
manager.submitOtp('WRONG');
|
|
493
|
-
|
|
494
|
-
await vi.waitFor(() => {
|
|
495
|
-
expect(manager.getState().status).toBe('otpError');
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
const state = manager.getState();
|
|
499
|
-
if (state.status === 'otpError') {
|
|
500
|
-
expect(typeof state.error).toBe('string');
|
|
501
|
-
expect(typeof state.attemptsRemaining).toBe('number');
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
manager.stop();
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
it('should map inputting state with prefilled email', async () => {
|
|
508
|
-
const configWithPrefill = { ...mockEmailConfig, prefill: true };
|
|
509
|
-
const manager = createEmailManager({ config: configWithPrefill });
|
|
510
|
-
|
|
511
|
-
manager.load();
|
|
512
|
-
|
|
513
|
-
await vi.waitFor(() => {
|
|
514
|
-
expect(manager.getState().status).toBe('inputting');
|
|
515
|
-
});
|
|
516
|
-
|
|
517
|
-
const state = manager.getState();
|
|
518
|
-
if (state.status === 'inputting') {
|
|
519
|
-
expect(state.prefilledEmail).toBe('user@example.com');
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
manager.stop();
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
it('should map success state correctly', async () => {
|
|
526
|
-
const manager = createEmailManager({ config: mockEmailConfigNoOtp });
|
|
527
|
-
|
|
528
|
-
manager.load();
|
|
529
|
-
|
|
530
|
-
await vi.waitFor(() => {
|
|
531
|
-
expect(manager.getState().status).toBe('inputting');
|
|
532
|
-
});
|
|
533
|
-
|
|
534
|
-
manager.setEmail('user@example.com', true);
|
|
535
|
-
manager.submit();
|
|
536
|
-
|
|
537
|
-
await vi.waitFor(() => {
|
|
538
|
-
expect(manager.getState().status).toBe('success');
|
|
539
|
-
});
|
|
540
|
-
|
|
541
|
-
expect(manager.getState()).toEqual({ status: 'success' });
|
|
542
|
-
|
|
543
|
-
manager.stop();
|
|
544
|
-
});
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
describe('api.setOtpCode()', () => {
|
|
548
|
-
it('should set OTP code without submitting', async () => {
|
|
549
|
-
const manager = createEmailManager({ config: mockEmailConfig });
|
|
550
|
-
|
|
551
|
-
manager.load();
|
|
552
|
-
|
|
553
|
-
await vi.waitFor(() => {
|
|
554
|
-
expect(manager.getState().status).toBe('inputting');
|
|
555
|
-
});
|
|
556
|
-
|
|
557
|
-
manager.setEmail('user@example.com', true);
|
|
558
|
-
manager.submit();
|
|
559
|
-
|
|
560
|
-
await vi.waitFor(() => {
|
|
561
|
-
expect(manager.getState().status).toBe('awaitingOtp');
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
// setOtpCode should not trigger verification
|
|
565
|
-
manager.setOtpCode('ABC123');
|
|
566
|
-
|
|
567
|
-
// Should still be in awaitingOtp
|
|
568
|
-
expect(manager.getState().status).toBe('awaitingOtp');
|
|
569
|
-
|
|
570
|
-
manager.stop();
|
|
571
|
-
});
|
|
572
|
-
});
|
|
573
|
-
});
|