223 lines
6.3 KiB
TypeScript
223 lines
6.3 KiB
TypeScript
/**
|
|
* @ai-summary Tests for Community Stations API Client
|
|
*/
|
|
|
|
import axios from 'axios';
|
|
import { communityStationsApi } from '../../api/community-stations.api';
|
|
import { SubmitStationData, ReviewDecision } from '../../types/community-stations.types';
|
|
|
|
jest.mock('axios');
|
|
const mockedAxios = axios as jest.Mocked<typeof axios>;
|
|
|
|
describe('Community Stations API Client', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('submitStation', () => {
|
|
it('should submit a station successfully', async () => {
|
|
const submitData: SubmitStationData = {
|
|
name: 'Shell Downtown',
|
|
address: '123 Main St',
|
|
city: 'Denver',
|
|
state: 'CO',
|
|
zipCode: '80202',
|
|
latitude: 39.7392,
|
|
longitude: -104.9903,
|
|
brand: 'Shell',
|
|
has93Octane: true,
|
|
has93OctaneEthanolFree: false,
|
|
price93: 3.599,
|
|
notes: 'Good quality',
|
|
};
|
|
|
|
const mockResponse = {
|
|
data: {
|
|
id: '1',
|
|
...submitData,
|
|
status: 'pending',
|
|
submittedBy: 'user@example.com',
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
},
|
|
};
|
|
|
|
mockedAxios.post.mockResolvedValueOnce(mockResponse);
|
|
|
|
const result = await communityStationsApi.submitStation(submitData);
|
|
|
|
expect(result).toEqual(mockResponse.data);
|
|
expect(mockedAxios.post).toHaveBeenCalledWith(
|
|
'/stations/community/submit',
|
|
submitData
|
|
);
|
|
});
|
|
|
|
it('should handle submission errors', async () => {
|
|
const submitData: SubmitStationData = {
|
|
name: 'Shell',
|
|
address: '123 Main St',
|
|
latitude: 39.7392,
|
|
longitude: -104.9903,
|
|
has93Octane: true,
|
|
has93OctaneEthanolFree: false,
|
|
};
|
|
|
|
const mockError = new Error('Network error');
|
|
mockedAxios.post.mockRejectedValueOnce(mockError);
|
|
|
|
await expect(communityStationsApi.submitStation(submitData)).rejects.toThrow('Network error');
|
|
});
|
|
});
|
|
|
|
describe('getMySubmissions', () => {
|
|
it('should fetch user submissions', async () => {
|
|
const mockSubmissions = [
|
|
{
|
|
id: '1',
|
|
name: 'Shell Downtown',
|
|
address: '123 Main St',
|
|
latitude: 39.7392,
|
|
longitude: -104.9903,
|
|
has93Octane: true,
|
|
has93OctaneEthanolFree: false,
|
|
status: 'pending',
|
|
submittedBy: 'user@example.com',
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
},
|
|
];
|
|
|
|
mockedAxios.get.mockResolvedValueOnce({ data: mockSubmissions });
|
|
|
|
const result = await communityStationsApi.getMySubmissions();
|
|
|
|
expect(result).toEqual(mockSubmissions);
|
|
expect(mockedAxios.get).toHaveBeenCalledWith('/stations/community/mine');
|
|
});
|
|
});
|
|
|
|
describe('withdrawSubmission', () => {
|
|
it('should withdraw a submission', async () => {
|
|
mockedAxios.delete.mockResolvedValueOnce({ data: null });
|
|
|
|
await communityStationsApi.withdrawSubmission('1');
|
|
|
|
expect(mockedAxios.delete).toHaveBeenCalledWith('/stations/community/1');
|
|
});
|
|
});
|
|
|
|
describe('getApprovedStations', () => {
|
|
it('should fetch approved stations with pagination', async () => {
|
|
const mockResponse = {
|
|
data: {
|
|
stations: [
|
|
{
|
|
id: '1',
|
|
name: 'Shell Downtown',
|
|
address: '123 Main St',
|
|
latitude: 39.7392,
|
|
longitude: -104.9903,
|
|
has93Octane: true,
|
|
has93OctaneEthanolFree: false,
|
|
status: 'approved',
|
|
submittedBy: 'user@example.com',
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
},
|
|
],
|
|
total: 1,
|
|
page: 0,
|
|
limit: 50,
|
|
},
|
|
};
|
|
|
|
mockedAxios.get.mockResolvedValueOnce(mockResponse);
|
|
|
|
const result = await communityStationsApi.getApprovedStations(0, 50);
|
|
|
|
expect(result).toEqual(mockResponse.data);
|
|
expect(mockedAxios.get).toHaveBeenCalledWith('/stations/community/approved', {
|
|
params: { page: 0, limit: 50 },
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('reviewStation (admin)', () => {
|
|
it('should approve a station', async () => {
|
|
const decision: ReviewDecision = { status: 'approved' };
|
|
|
|
const mockResponse = {
|
|
data: {
|
|
id: '1',
|
|
status: 'approved',
|
|
reviewedAt: new Date().toISOString(),
|
|
reviewedBy: 'admin@example.com',
|
|
},
|
|
};
|
|
|
|
mockedAxios.patch.mockResolvedValueOnce(mockResponse);
|
|
|
|
const result = await communityStationsApi.reviewStation('1', decision);
|
|
|
|
expect(result).toEqual(mockResponse.data);
|
|
expect(mockedAxios.patch).toHaveBeenCalledWith(
|
|
'/stations/community/admin/1/review',
|
|
decision
|
|
);
|
|
});
|
|
|
|
it('should reject a station with reason', async () => {
|
|
const decision: ReviewDecision = {
|
|
status: 'rejected',
|
|
rejectionReason: 'Invalid location',
|
|
};
|
|
|
|
const mockResponse = {
|
|
data: {
|
|
id: '1',
|
|
status: 'rejected',
|
|
rejectionReason: 'Invalid location',
|
|
reviewedAt: new Date().toISOString(),
|
|
reviewedBy: 'admin@example.com',
|
|
},
|
|
};
|
|
|
|
mockedAxios.patch.mockResolvedValueOnce(mockResponse);
|
|
|
|
const result = await communityStationsApi.reviewStation('1', decision);
|
|
|
|
expect(result).toEqual(mockResponse.data);
|
|
expect(mockedAxios.patch).toHaveBeenCalledWith(
|
|
'/stations/community/admin/1/review',
|
|
decision
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('bulkReviewStations (admin)', () => {
|
|
it('should bulk approve stations', async () => {
|
|
const ids = ['1', '2', '3'];
|
|
const decision: ReviewDecision = { status: 'approved' };
|
|
|
|
const mockResponse = {
|
|
data: [
|
|
{ id: '1', status: 'approved' },
|
|
{ id: '2', status: 'approved' },
|
|
{ id: '3', status: 'approved' },
|
|
],
|
|
};
|
|
|
|
mockedAxios.post.mockResolvedValueOnce(mockResponse);
|
|
|
|
const result = await communityStationsApi.bulkReviewStations(ids, decision);
|
|
|
|
expect(result).toEqual(mockResponse.data);
|
|
expect(mockedAxios.post).toHaveBeenCalledWith('/stations/community/admin/bulk-review', {
|
|
ids,
|
|
...decision,
|
|
});
|
|
});
|
|
});
|
|
});
|