@aerocorp/cli
Version:
AeroCorp CLI 5.1.0 - Future-Proofed Enterprise Infrastructure with Live Preview, Tunneling & Advanced DevOps
189 lines (143 loc) • 5.32 kB
text/typescript
import { AuthService } from '../services/auth';
import { ConfigService } from '../services/config';
// Mock axios
jest.mock('axios');
const mockAxios = require('axios');
// Mock inquirer
jest.mock('inquirer');
const mockInquirer = require('inquirer');
// Mock ora
jest.mock('ora');
const mockOra = require('ora');
describe('AuthService', () => {
let authService: AuthService;
let configService: ConfigService;
beforeEach(() => {
authService = new AuthService();
configService = new ConfigService();
// Reset mocks
jest.clearAllMocks();
// Mock ora spinner
const mockSpinner = {
start: jest.fn().mockReturnThis(),
succeed: jest.fn().mockReturnThis(),
fail: jest.fn().mockReturnThis()
};
mockOra.mockReturnValue(mockSpinner);
});
afterEach(() => {
// Clean up environment variables
delete process.env.AEROCORP_CLI_ROOT_API_TOKEN;
configService.clear();
});
describe('login', () => {
it('should authenticate with root token from environment', async () => {
// Set up environment variable
process.env.AEROCORP_CLI_ROOT_API_TOKEN = 'test-root-token';
// Mock successful API response
mockAxios.get.mockResolvedValue({
status: 200,
data: [{ id: 1, name: 'Test Project' }]
});
const result = await authService.login();
expect(result).toBe(true);
expect(mockAxios.get).toHaveBeenCalledWith(
'https://coolify.aerocorpindustries.org/api/v1/projects',
expect.objectContaining({
headers: expect.objectContaining({
'Authorization': 'Bearer test-root-token'
})
})
);
});
it('should prompt for credentials when no root token', async () => {
// Mock inquirer responses
mockInquirer.prompt
.mockResolvedValueOnce({ url: 'https://test.coolify.com' })
.mockResolvedValueOnce({ token: 'test-token' });
// Mock successful API response
mockAxios.get.mockResolvedValue({
status: 200,
data: []
});
const result = await authService.login();
expect(result).toBe(true);
expect(mockInquirer.prompt).toHaveBeenCalledTimes(2);
});
it('should handle authentication failure', async () => {
process.env.AEROCORP_CLI_ROOT_API_TOKEN = 'invalid-token';
mockAxios.get.mockRejectedValue({
response: { status: 401, data: { message: 'Unauthorized' } }
});
await expect(authService.login()).rejects.toThrow('Invalid API token');
});
it('should handle network errors', async () => {
process.env.AEROCORP_CLI_ROOT_API_TOKEN = 'test-token';
mockAxios.get.mockRejectedValue({
code: 'ECONNREFUSED'
});
await expect(authService.login()).rejects.toThrow('Connection refused');
});
});
describe('isAuthenticated', () => {
it('should return true when authenticated with token', () => {
configService.set('api_token', 'test-token');
configService.set('authenticated', true);
const result = authService.isAuthenticated();
expect(result).toBe(true);
});
it('should return true when root token is in environment', () => {
process.env.AEROCORP_CLI_ROOT_API_TOKEN = 'root-token';
const result = authService.isAuthenticated();
expect(result).toBe(true);
});
it('should return false when not authenticated', () => {
const result = authService.isAuthenticated();
expect(result).toBe(false);
});
});
describe('getAuthHeaders', () => {
it('should return headers with config token', () => {
configService.set('api_token', 'config-token');
const headers = authService.getAuthHeaders();
expect(headers).toEqual({
'Authorization': 'Bearer config-token',
'Accept': 'application/json',
'Content-Type': 'application/json'
});
});
it('should prefer environment token over config token', () => {
configService.set('api_token', 'config-token');
process.env.AEROCORP_CLI_ROOT_API_TOKEN = 'env-token';
const headers = authService.getAuthHeaders();
expect(headers).toEqual({
'Authorization': 'Bearer env-token',
'Accept': 'application/json',
'Content-Type': 'application/json'
});
});
it('should throw error when no token available', () => {
expect(() => authService.getAuthHeaders()).toThrow('Not authenticated');
});
});
describe('getCoolifyUrl', () => {
it('should return configured URL', () => {
configService.set('coolify_url', 'https://custom.coolify.com');
const url = authService.getCoolifyUrl();
expect(url).toBe('https://custom.coolify.com');
});
it('should return default URL when not configured', () => {
const url = authService.getCoolifyUrl();
expect(url).toBe('https://coolify.aerocorpindustries.org');
});
});
describe('logout', () => {
it('should clear configuration', () => {
configService.set('api_token', 'test-token');
configService.set('authenticated', true);
authService.logout();
expect(configService.get('api_token')).toBeUndefined();
expect(configService.get('authenticated')).toBeUndefined();
});
});
});