Skip to content

Commit 38a3deb

Browse files
committed
update tests
1 parent d331562 commit 38a3deb

File tree

2 files changed

+55
-97
lines changed

2 files changed

+55
-97
lines changed

src/utils/cloudConfig.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Extends the base config with cloud sync settings
44
*/
55

6-
const DEFAULT_CLOUD_CONFIG = {
6+
export const DEFAULT_CLOUD_CONFIG = {
77
enabled: false,
88
autoSync: false,
99
syncInterval: 300000, // 5 minutes in ms

tests/unit/cloud/deviceFlow.test.js

Lines changed: 54 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,35 @@
22
* Tests for device flow authentication
33
*/
44

5-
import {
5+
import { describe, it, expect, beforeEach, jest } from '@jest/globals';
6+
7+
// Mock the API client constructor function
8+
const mockPost = jest.fn();
9+
const MockSplitmarkAPIClient = jest.fn().mockImplementation(() => ({
10+
post: mockPost,
11+
}));
12+
13+
// Mock the credentials module
14+
const mockSaveToken = jest.fn();
15+
const mockClearToken = jest.fn();
16+
17+
// Use unstable_mockModule to properly mock ES modules
18+
jest.unstable_mockModule('../../../src/cloud/api/client.js', () => ({
19+
default: MockSplitmarkAPIClient,
20+
}));
21+
22+
jest.unstable_mockModule('../../../src/cloud/storage/credentials.js', () => ({
23+
saveToken: mockSaveToken,
24+
clearToken: mockClearToken,
25+
}));
26+
27+
// Import the functions to test after mocking
28+
const {
629
initiateDeviceFlow,
730
pollDeviceToken,
831
completeDeviceFlow,
932
loginWithDeviceFlow,
10-
} from '../../../src/cloud/api/auth.js';
11-
12-
// Mock the API client
13-
jest.mock('../../../src/cloud/api/client.js', () => {
14-
return {
15-
__esModule: true,
16-
default: jest.fn().mockImplementation(() => ({
17-
post: jest.fn(),
18-
})),
19-
};
20-
});
21-
22-
// Mock credential storage
23-
jest.mock('../../../src/cloud/storage/credentials.js', () => ({
24-
saveToken: jest.fn(),
25-
}));
33+
} = await import('../../../src/cloud/api/auth.js');
2634

2735
describe('Device Flow Authentication', () => {
2836
beforeEach(() => {
@@ -31,19 +39,14 @@ describe('Device Flow Authentication', () => {
3139

3240
describe('initiateDeviceFlow', () => {
3341
it('should initiate device flow and return codes', async () => {
34-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
35-
const mockPost = jest.fn().mockResolvedValue({
36-
deviceCode: 'device_123',
37-
userCode: 'ABCD-1234',
38-
verificationUrl: 'https://splitmark.app/cli-auth',
39-
expiresIn: 600,
42+
mockPost.mockResolvedValue({
43+
device_code: 'device_123',
44+
user_code: 'ABCD-1234',
45+
verification_uri: 'https://splitmark.app/cli-auth',
46+
expires_in: 600,
4047
interval: 5,
4148
});
4249

43-
SplitmarkAPIClient.mockImplementation(() => ({
44-
post: mockPost,
45-
}));
46-
4750
const result = await initiateDeviceFlow('https://api.splitmark.app');
4851

4952
expect(result).toEqual({
@@ -56,39 +59,29 @@ describe('Device Flow Authentication', () => {
5659
});
5760

5861
expect(mockPost).toHaveBeenCalledWith(
59-
'/cli/device-code',
62+
'/auth/cli/device-code',
6063
{},
6164
{ skipAuth: true, rateLimitType: 'auth' }
6265
);
6366
});
6467

6568
it('should handle verificationUrlComplete', async () => {
66-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
67-
const mockPost = jest.fn().mockResolvedValue({
68-
deviceCode: 'device_123',
69-
userCode: 'ABCD-1234',
70-
verificationUrl: 'https://splitmark.app/cli-auth',
71-
verificationUrlComplete: 'https://splitmark.app/cli-auth?code=ABCD-1234',
72-
expiresIn: 600,
69+
mockPost.mockResolvedValue({
70+
device_code: 'device_123',
71+
user_code: 'ABCD-1234',
72+
verification_uri: 'https://splitmark.app/cli-auth',
73+
verification_uri_complete: 'https://splitmark.app/cli-auth?code=ABCD-1234',
74+
expires_in: 600,
7375
interval: 5,
7476
});
7577

76-
SplitmarkAPIClient.mockImplementation(() => ({
77-
post: mockPost,
78-
}));
79-
8078
const result = await initiateDeviceFlow('https://api.splitmark.app');
8179

8280
expect(result.verificationUrlComplete).toBe('https://splitmark.app/cli-auth?code=ABCD-1234');
8381
});
8482

8583
it('should handle API errors', async () => {
86-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
87-
const mockPost = jest.fn().mockRejectedValue(new Error('Network error'));
88-
89-
SplitmarkAPIClient.mockImplementation(() => ({
90-
post: mockPost,
91-
}));
84+
mockPost.mockRejectedValue(new Error('Network error'));
9285

9386
await expect(initiateDeviceFlow('https://api.splitmark.app')).rejects.toThrow(
9487
'Failed to initiate device flow'
@@ -98,25 +91,17 @@ describe('Device Flow Authentication', () => {
9891

9992
describe('pollDeviceToken', () => {
10093
it('should return pending when authorization is pending', async () => {
101-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
102-
const mockPost = jest.fn().mockResolvedValue({
94+
mockPost.mockResolvedValue({
10395
error: 'authorization_pending',
10496
});
10597

106-
SplitmarkAPIClient.mockImplementation(() => ({
107-
post: mockPost,
108-
}));
109-
11098
const result = await pollDeviceToken('https://api.splitmark.app', 'device_123');
11199

112100
expect(result).toEqual({ pending: true });
113101
});
114102

115103
it('should return token and user on success', async () => {
116-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
117-
const { saveToken } = require('../../../src/cloud/storage/credentials.js');
118-
119-
const mockPost = jest.fn().mockResolvedValue({
104+
mockPost.mockResolvedValue({
120105
token: 'jwt_token_123',
121106
user: {
122107
id: 'user_123',
@@ -125,10 +110,6 @@ describe('Device Flow Authentication', () => {
125110
},
126111
});
127112

128-
SplitmarkAPIClient.mockImplementation(() => ({
129-
post: mockPost,
130-
}));
131-
132113
const result = await pollDeviceToken('https://api.splitmark.app', 'device_123');
133114

134115
expect(result).toEqual({
@@ -140,33 +121,25 @@ describe('Device Flow Authentication', () => {
140121
},
141122
});
142123

143-
expect(saveToken).toHaveBeenCalledWith('jwt_token_123', expect.any(Object));
124+
expect(mockSaveToken).toHaveBeenCalledWith('jwt_token_123', expect.any(Object));
144125
});
145126

146127
it('should throw error on expired token', async () => {
147-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
148-
const mockPost = jest.fn().mockResolvedValue({
128+
mockPost.mockResolvedValue({
149129
error: 'expired_token',
150130
});
151131

152-
SplitmarkAPIClient.mockImplementation(() => ({
153-
post: mockPost,
154-
}));
155132

156133
await expect(
157134
pollDeviceToken('https://api.splitmark.app', 'device_123')
158135
).rejects.toThrow('Device code expired');
159136
});
160137

161138
it('should throw error on access denied', async () => {
162-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
163-
const mockPost = jest.fn().mockResolvedValue({
139+
mockPost.mockResolvedValue({
164140
error: 'access_denied',
165141
});
166142

167-
SplitmarkAPIClient.mockImplementation(() => ({
168-
post: mockPost,
169-
}));
170143

171144
await expect(
172145
pollDeviceToken('https://api.splitmark.app', 'device_123')
@@ -176,10 +149,10 @@ describe('Device Flow Authentication', () => {
176149

177150
describe('completeDeviceFlow', () => {
178151
it('should poll until success', async () => {
179-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
152+
const { default: SplitmarkAPIClient } = await import('../../../src/cloud/api/client.js');
180153
let callCount = 0;
181154

182-
const mockPost = jest.fn().mockImplementation(() => {
155+
mockPost.mockImplementation(() => {
183156
callCount++;
184157
if (callCount < 3) {
185158
return Promise.resolve({ error: 'authorization_pending' });
@@ -190,9 +163,6 @@ describe('Device Flow Authentication', () => {
190163
});
191164
});
192165

193-
SplitmarkAPIClient.mockImplementation(() => ({
194-
post: mockPost,
195-
}));
196166

197167
const progressUpdates = [];
198168
const onProgress = (progress) => progressUpdates.push(progress);
@@ -212,14 +182,10 @@ describe('Device Flow Authentication', () => {
212182
});
213183

214184
it('should timeout after expiration', async () => {
215-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
216-
const mockPost = jest.fn().mockResolvedValue({
185+
mockPost.mockResolvedValue({
217186
error: 'authorization_pending',
218187
});
219188

220-
SplitmarkAPIClient.mockImplementation(() => ({
221-
post: mockPost,
222-
}));
223189

224190
await expect(
225191
completeDeviceFlow(
@@ -232,15 +198,11 @@ describe('Device Flow Authentication', () => {
232198
}, 10000);
233199

234200
it('should call onProgress with correct status', async () => {
235-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
236-
const mockPost = jest.fn().mockResolvedValue({
201+
mockPost.mockResolvedValue({
237202
token: 'jwt_token_123',
238203
user: { username: 'testuser' },
239204
});
240205

241-
SplitmarkAPIClient.mockImplementation(() => ({
242-
post: mockPost,
243-
}));
244206

245207
const progressUpdates = [];
246208
const onProgress = (progress) => progressUpdates.push(progress);
@@ -264,19 +226,18 @@ describe('Device Flow Authentication', () => {
264226

265227
describe('loginWithDeviceFlow', () => {
266228
it('should complete full device flow', async () => {
267-
const SplitmarkAPIClient = require('../../../src/cloud/api/client.js').default;
268229
let requestCount = 0;
269230

270-
const mockPost = jest.fn().mockImplementation((endpoint) => {
271-
if (endpoint === '/cli/device-code') {
231+
mockPost.mockImplementation((endpoint) => {
232+
if (endpoint === '/auth/cli/device-code') {
272233
return Promise.resolve({
273-
deviceCode: 'device_123',
274-
userCode: 'ABCD-1234',
275-
verificationUrl: 'https://splitmark.app/cli-auth',
276-
expiresIn: 600,
234+
device_code: 'device_123',
235+
user_code: 'ABCD-1234',
236+
verification_uri: 'https://splitmark.app/cli-auth',
237+
expires_in: 600,
277238
interval: 0.1,
278239
});
279-
} else if (endpoint === '/cli/token') {
240+
} else if (endpoint === '/auth/cli/token') {
280241
requestCount++;
281242
if (requestCount < 2) {
282243
return Promise.resolve({ error: 'authorization_pending' });
@@ -288,9 +249,6 @@ describe('Device Flow Authentication', () => {
288249
}
289250
});
290251

291-
SplitmarkAPIClient.mockImplementation(() => ({
292-
post: mockPost,
293-
}));
294252

295253
const progressUpdates = [];
296254
const onProgress = (progress) => progressUpdates.push(progress);

0 commit comments

Comments
 (0)