Should probably just let Claude write the commit messages too
This commit is contained in:
186
src/services/api.test.ts
Normal file
186
src/services/api.test.ts
Normal file
@@ -0,0 +1,186 @@
|
||||
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' }
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user