Files
flipstone-radar/src/services/api.test.ts

186 lines
5.1 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import axios from 'axios';
import { ApiService } from './api';
// Mock axios
vi.mock('axios');
const mockedAxios = vi.mocked(axios);
describe('ApiService', () => {
let apiService: ApiService;
beforeEach(() => {
apiService = new ApiService();
vi.clearAllMocks();
});
describe('getWorkflowRuns', () => {
it('should fetch workflow runs successfully', async () => {
const mockRuns = [
{
id: 1,
name: 'Test Workflow',
display_title: 'Test Run',
status: 'completed',
conclusion: 'success',
created_at: '2024-01-01T10:00:00Z',
repository: {
id: 1,
name: 'test-repo',
full_name: 'test/test-repo',
owner: {
login: 'test-owner',
avatar_url: 'https://github.com/test-owner.png'
}
},
actor: {
login: 'test-actor',
avatar_url: 'https://github.com/test-actor.png'
}
}
];
mockedAxios.get.mockResolvedValueOnce({ data: mockRuns });
const result = await apiService.getWorkflowRuns();
expect(mockedAxios.get).toHaveBeenCalledWith('/api/workflow-runs');
expect(result).toEqual(mockRuns);
});
it('should handle API errors', async () => {
const errorMessage = 'Network Error';
mockedAxios.get.mockRejectedValueOnce(new Error(errorMessage));
await expect(apiService.getWorkflowRuns()).rejects.toThrow(errorMessage);
});
});
describe('getRepositoryWorkflowRuns', () => {
it('should fetch repository-specific workflow runs', async () => {
const mockRuns = [
{
id: 1,
name: 'Test Workflow',
display_title: 'Test Run',
status: 'completed',
conclusion: 'success',
created_at: '2024-01-01T10:00:00Z'
}
];
mockedAxios.get.mockResolvedValueOnce({ data: mockRuns });
const result = await apiService.getRepositoryWorkflowRuns('test-owner', 'test-repo');
expect(mockedAxios.get).toHaveBeenCalledWith('/api/repository/test-owner/test-repo/workflow-runs', {
params: { limit: 10 }
});
expect(result).toEqual(mockRuns);
});
it('should handle repository not found', async () => {
mockedAxios.get.mockRejectedValueOnce({
response: { status: 404 }
});
await expect(apiService.getRepositoryWorkflowRuns('invalid', 'repo')).rejects.toMatchObject({
response: { status: 404 }
});
});
});
describe('getConfig', () => {
it('should fetch configuration successfully', async () => {
const mockConfig = {
repositories: [
{
owner: 'test-owner',
name: 'test-repo',
full_name: 'test-owner/test-repo'
}
]
};
mockedAxios.get.mockResolvedValueOnce({ data: mockConfig });
const result = await apiService.getConfig();
expect(mockedAxios.get).toHaveBeenCalledWith('/api/config');
expect(result).toEqual(mockConfig);
});
});
describe('getRateLimit', () => {
it('should fetch rate limit information', async () => {
const mockRateLimit = {
limit: 5000,
remaining: 4999,
resetTime: 1640995200000,
used: 1,
resetTimeFormatted: '2022-01-01T00:00:00.000Z',
timeUntilReset: 3600000
};
mockedAxios.get.mockResolvedValueOnce({ data: mockRateLimit });
const result = await apiService.getRateLimitInfo();
expect(mockedAxios.get).toHaveBeenCalledWith('/api/rate-limit');
expect(result).toEqual(mockRateLimit);
});
});
describe('getCacheStats', () => {
it('should fetch cache statistics', async () => {
const mockStats = {
size: 10,
entries: ['key1', 'key2', 'key3']
};
mockedAxios.get.mockResolvedValueOnce({ data: mockStats });
const result = await apiService.getCacheStats();
expect(mockedAxios.get).toHaveBeenCalledWith('/api/cache/stats');
expect(result).toEqual(mockStats);
});
});
describe('clearCache', () => {
it('should clear cache successfully', async () => {
const mockResponse = { message: 'Cache cleared successfully' };
mockedAxios.delete.mockResolvedValueOnce({ data: mockResponse });
const result = await apiService.clearCache();
expect(mockedAxios.delete).toHaveBeenCalledWith('/api/cache');
expect(result).toEqual(mockResponse);
});
});
describe('error handling', () => {
it('should handle network errors', async () => {
mockedAxios.get.mockRejectedValueOnce(new Error('Network Error'));
await expect(apiService.getWorkflowRuns()).rejects.toThrow('Network Error');
});
it('should handle HTTP errors', async () => {
mockedAxios.get.mockRejectedValueOnce({
response: {
status: 500,
data: { error: 'Internal Server Error' }
}
});
await expect(apiService.getWorkflowRuns()).rejects.toMatchObject({
response: {
status: 500,
data: { error: 'Internal Server Error' }
}
});
});
});
});