Skip to content

Commit dfa5a01

Browse files
feat: add tests for login handler
1 parent d94fd0f commit dfa5a01

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2+
import { handleLoginAndFetchToken } from '../auth/login-handler.js';
3+
import * as errorUtils from '../../../utils/error.js';
4+
import { RedoclyOAuthClient } from '../../../auth/oauth-client.js';
5+
import { logger } from '@redocly/openapi-core';
6+
7+
vi.mock('../../../auth/oauth-client.js');
8+
vi.mock('../../../reunite/api/index.js', () => ({
9+
getReuniteUrl: vi.fn(() => 'https://www.test.com'),
10+
}));
11+
12+
describe('handleLoginAndFetchToken', () => {
13+
const mockConfig = {
14+
resolvedConfig: {
15+
residency: 'us',
16+
},
17+
} as any;
18+
19+
let mockOAuthClient: any;
20+
21+
beforeEach(() => {
22+
mockOAuthClient = {
23+
getAccessToken: vi.fn(),
24+
login: vi.fn(),
25+
};
26+
vi.mocked(RedoclyOAuthClient).mockImplementation(() => mockOAuthClient);
27+
vi.spyOn(logger, 'info').mockImplementation(() => {});
28+
vi.spyOn(logger, 'warn').mockImplementation(() => {});
29+
vi.spyOn(logger, 'error').mockImplementation(() => {});
30+
vi.spyOn(errorUtils, 'exitWithError').mockImplementation(() => {
31+
throw new Error('exitWithError called');
32+
});
33+
});
34+
35+
afterEach(() => {
36+
vi.restoreAllMocks();
37+
});
38+
39+
it('should return existing access token when available', async () => {
40+
const testToken = 'existing-token';
41+
mockOAuthClient.getAccessToken.mockResolvedValue(testToken);
42+
43+
const result = await handleLoginAndFetchToken(mockConfig, false);
44+
45+
expect(result).toBe(testToken);
46+
expect(mockOAuthClient.getAccessToken).toHaveBeenCalledTimes(1);
47+
expect(mockOAuthClient.login).not.toHaveBeenCalled();
48+
});
49+
50+
it('should log info when verbose is enabled and token exists', async () => {
51+
const testToken = 'existing-token';
52+
mockOAuthClient.getAccessToken.mockResolvedValue(testToken);
53+
54+
await handleLoginAndFetchToken(mockConfig, true);
55+
56+
expect(logger.info).toHaveBeenCalledWith('Using existing access token.\n');
57+
});
58+
59+
it('should attempt login when no access token is found', async () => {
60+
const newToken = 'new-token';
61+
mockOAuthClient.getAccessToken.mockResolvedValueOnce(null).mockResolvedValueOnce(newToken);
62+
mockOAuthClient.login.mockResolvedValue(undefined);
63+
64+
const result = await handleLoginAndFetchToken(mockConfig, false);
65+
66+
expect(result).toBe(newToken);
67+
expect(mockOAuthClient.login).toHaveBeenCalled();
68+
expect(mockOAuthClient.getAccessToken).toHaveBeenCalledTimes(2);
69+
});
70+
71+
it('should log warning when verbose is enabled and no token found', async () => {
72+
const newToken = 'new-token';
73+
mockOAuthClient.getAccessToken.mockResolvedValueOnce(null).mockResolvedValueOnce(newToken);
74+
mockOAuthClient.login.mockResolvedValue(undefined);
75+
76+
await handleLoginAndFetchToken(mockConfig, true);
77+
78+
expect(logger.warn).toHaveBeenCalledWith('No access token found. Attempting login...\n');
79+
});
80+
81+
it('should handle login failure and exit with error', async () => {
82+
const loginError = new Error('Login failed');
83+
mockOAuthClient.getAccessToken.mockResolvedValue(null);
84+
mockOAuthClient.login.mockRejectedValue(loginError);
85+
86+
await expect(handleLoginAndFetchToken(mockConfig, false)).rejects.toThrow(
87+
'exitWithError called'
88+
);
89+
90+
expect(errorUtils.exitWithError).toHaveBeenCalledWith(
91+
expect.stringContaining('Login failed. Please try again or check your connection')
92+
);
93+
});
94+
95+
it('should log error details when verbose is enabled and login fails', async () => {
96+
const loginError = new Error('Network error');
97+
mockOAuthClient.getAccessToken.mockResolvedValue(null);
98+
mockOAuthClient.login.mockRejectedValue(loginError);
99+
100+
await expect(handleLoginAndFetchToken(mockConfig, true)).rejects.toThrow();
101+
102+
expect(logger.error).toHaveBeenCalledWith('❌ Login failed.\n');
103+
expect(logger.error).toHaveBeenCalledWith('Error details: Network error\n');
104+
});
105+
});

0 commit comments

Comments
 (0)