138 lines
4.5 KiB
TypeScript
138 lines
4.5 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { SessionService } from './SessionService';
|
|
import { AuthApiClient } from '../../api/auth/AuthApiClient';
|
|
import { SessionPresenter } from '../../presenters/SessionPresenter';
|
|
import { SessionViewModel } from '../../view-models';
|
|
import type { SessionDataDto } from '../../dtos';
|
|
|
|
describe('SessionService', () => {
|
|
let mockApiClient: AuthApiClient;
|
|
let mockPresenter: SessionPresenter;
|
|
let service: SessionService;
|
|
|
|
beforeEach(() => {
|
|
mockApiClient = {
|
|
getSession: vi.fn(),
|
|
signup: vi.fn(),
|
|
login: vi.fn(),
|
|
logout: vi.fn(),
|
|
getIracingAuthUrl: vi.fn(),
|
|
} as unknown as AuthApiClient;
|
|
|
|
mockPresenter = {
|
|
presentSession: vi.fn(),
|
|
} as unknown as SessionPresenter;
|
|
|
|
service = new SessionService(mockApiClient, mockPresenter);
|
|
});
|
|
|
|
describe('getSession', () => {
|
|
it('should get session via API client and present it', async () => {
|
|
// Arrange
|
|
const dto: SessionDataDto = {
|
|
userId: 'user-1',
|
|
email: 'test@example.com',
|
|
displayName: 'Test User',
|
|
driverId: 'driver-1',
|
|
isAuthenticated: true,
|
|
};
|
|
|
|
const expectedViewModel = new SessionViewModel(dto);
|
|
|
|
vi.mocked(mockApiClient.getSession).mockResolvedValue(dto);
|
|
vi.mocked(mockPresenter.presentSession).mockReturnValue(expectedViewModel);
|
|
|
|
// Act
|
|
const result = await service.getSession();
|
|
|
|
// Assert
|
|
expect(mockApiClient.getSession).toHaveBeenCalledTimes(1);
|
|
expect(mockPresenter.presentSession).toHaveBeenCalledWith(dto);
|
|
expect(mockPresenter.presentSession).toHaveBeenCalledTimes(1);
|
|
expect(result).toBe(expectedViewModel);
|
|
});
|
|
|
|
it('should return null when session is null', async () => {
|
|
// Arrange
|
|
vi.mocked(mockApiClient.getSession).mockResolvedValue(null);
|
|
vi.mocked(mockPresenter.presentSession).mockReturnValue(null);
|
|
|
|
// Act
|
|
const result = await service.getSession();
|
|
|
|
// Assert
|
|
expect(mockApiClient.getSession).toHaveBeenCalledTimes(1);
|
|
expect(mockPresenter.presentSession).toHaveBeenCalledWith(null);
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('should propagate API client errors', async () => {
|
|
// Arrange
|
|
const error = new Error('API Error: Failed to get session');
|
|
vi.mocked(mockApiClient.getSession).mockRejectedValue(error);
|
|
|
|
// Act & Assert
|
|
await expect(service.getSession()).rejects.toThrow(
|
|
'API Error: Failed to get session'
|
|
);
|
|
|
|
expect(mockApiClient.getSession).toHaveBeenCalledTimes(1);
|
|
expect(mockPresenter.presentSession).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should handle different session data', async () => {
|
|
// Arrange
|
|
const dto: SessionDataDto = {
|
|
userId: 'user-2',
|
|
email: 'another@example.com',
|
|
isAuthenticated: false,
|
|
};
|
|
|
|
const expectedViewModel = new SessionViewModel(dto);
|
|
|
|
vi.mocked(mockApiClient.getSession).mockResolvedValue(dto);
|
|
vi.mocked(mockPresenter.presentSession).mockReturnValue(expectedViewModel);
|
|
|
|
// Act
|
|
const result = await service.getSession();
|
|
|
|
// Assert
|
|
expect(mockApiClient.getSession).toHaveBeenCalledTimes(1);
|
|
expect(mockPresenter.presentSession).toHaveBeenCalledWith(dto);
|
|
expect(result).toBe(expectedViewModel);
|
|
});
|
|
});
|
|
|
|
describe('Constructor Dependency Injection', () => {
|
|
it('should require apiClient and presenter', () => {
|
|
// This test verifies the constructor signature
|
|
expect(() => {
|
|
new SessionService(mockApiClient, mockPresenter);
|
|
}).not.toThrow();
|
|
});
|
|
|
|
it('should use injected dependencies', async () => {
|
|
// Arrange
|
|
const customApiClient = {
|
|
getSession: vi.fn().mockResolvedValue({ userId: 'user-1', email: 'test@example.com', isAuthenticated: true }),
|
|
signup: vi.fn(),
|
|
login: vi.fn(),
|
|
logout: vi.fn(),
|
|
getIracingAuthUrl: vi.fn(),
|
|
} as unknown as AuthApiClient;
|
|
|
|
const customPresenter = {
|
|
presentSession: vi.fn().mockReturnValue(new SessionViewModel({ userId: 'user-1', email: 'test@example.com', isAuthenticated: true })),
|
|
} as unknown as SessionPresenter;
|
|
|
|
const customService = new SessionService(customApiClient, customPresenter);
|
|
|
|
// Act
|
|
await customService.getSession();
|
|
|
|
// Assert
|
|
expect(customApiClient.getSession).toHaveBeenCalledTimes(1);
|
|
expect(customPresenter.presentSession).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
}); |