import axios from 'axios'; import api, { authService, colorService, filamentService } from '../src/services/api'; // Get the mock axios instance that was created const mockAxiosInstance = (axios.create as jest.Mock).mock.results[0].value; // Mock localStorage const localStorageMock = { getItem: jest.fn(), setItem: jest.fn(), removeItem: jest.fn(), clear: jest.fn(), }; (global as any).localStorage = localStorageMock; // Mock window.location const mockLocation = { pathname: '/', href: '', }; // Only define location if it doesn't exist or is configurable if (!Object.getOwnPropertyDescriptor(window, 'location') || Object.getOwnPropertyDescriptor(window, 'location')?.configurable) { Object.defineProperty(window, 'location', { value: mockLocation, configurable: true, writable: true }); } else { // If location exists and is not configurable, we'll work with the existing object Object.assign(window.location, mockLocation); } describe('API Service Tests', () => { beforeEach(() => { jest.clearAllMocks(); // Clear localStorage mocks localStorageMock.getItem.mockClear(); localStorageMock.removeItem.mockClear(); localStorageMock.setItem.mockClear(); // Reset window location mockLocation.pathname = '/'; mockLocation.href = ''; }); describe('Auth Service', () => { it('should login successfully', async () => { const mockResponse = { data: { token: 'test-token', user: 'admin' } }; mockAxiosInstance.post.mockResolvedValue(mockResponse); const result = await authService.login('admin', 'password123'); expect(mockAxiosInstance.post).toHaveBeenCalledWith('/login', { username: 'admin', password: 'password123' }); expect(result).toEqual(mockResponse.data); }); it('should handle login failure', async () => { const error = new Error('Invalid credentials'); mockAxiosInstance.post.mockRejectedValue(error); await expect(authService.login('admin', 'wrong')).rejects.toThrow('Invalid credentials'); }); }); describe('Color Service', () => { it('should get all colors', async () => { const mockColors = [ { id: '1', name: 'Red', hex: '#FF0000' }, { id: '2', name: 'Blue', hex: '#0000FF' } ]; mockAxiosInstance.get.mockResolvedValue({ data: mockColors }); const result = await colorService.getAll(); expect(mockAxiosInstance.get).toHaveBeenCalledWith('/colors'); expect(result).toEqual(mockColors); }); it('should create a color', async () => { const newColor = { name: 'Green', hex: '#00FF00', cena_refill: 100, cena_spulna: 150 }; const mockResponse = { id: '3', ...newColor }; mockAxiosInstance.post.mockResolvedValue({ data: mockResponse }); const result = await colorService.create(newColor); expect(mockAxiosInstance.post).toHaveBeenCalledWith('/colors', newColor); expect(result).toEqual(mockResponse); }); it('should update a color', async () => { const colorId = '1'; const updateData = { name: 'Dark Red', hex: '#8B0000' }; const mockResponse = { id: colorId, ...updateData }; mockAxiosInstance.put.mockResolvedValue({ data: mockResponse }); const result = await colorService.update(colorId, updateData); expect(mockAxiosInstance.put).toHaveBeenCalledWith(`/colors/${colorId}`, updateData); expect(result).toEqual(mockResponse); }); it('should delete a color', async () => { const colorId = '1'; const mockResponse = { success: true }; mockAxiosInstance.delete.mockResolvedValue({ data: mockResponse }); const result = await colorService.delete(colorId); expect(mockAxiosInstance.delete).toHaveBeenCalledWith(`/colors/${colorId}`); expect(result).toEqual(mockResponse); }); }); describe('Filament Service', () => { it('should get all filaments with cache buster', async () => { const mockFilaments = [ { id: '1', tip: 'PLA', boja: 'Red' }, { id: '2', tip: 'PETG', boja: 'Blue' } ]; mockAxiosInstance.get.mockResolvedValue({ data: mockFilaments }); // Mock Date.now() const originalDateNow = Date.now; const mockTimestamp = 1234567890; Date.now = jest.fn(() => mockTimestamp); const result = await filamentService.getAll(); expect(mockAxiosInstance.get).toHaveBeenCalledWith(`/filaments?_t=${mockTimestamp}`); expect(result).toEqual(mockFilaments); // Restore Date.now Date.now = originalDateNow; }); it('should create a filament', async () => { const newFilament = { tip: 'ABS', finish: 'Matte', boja: 'Black', boja_hex: '#000000' }; const mockResponse = { id: '3', ...newFilament }; mockAxiosInstance.post.mockResolvedValue({ data: mockResponse }); const result = await filamentService.create(newFilament); expect(mockAxiosInstance.post).toHaveBeenCalledWith('/filaments', newFilament); expect(result).toEqual(mockResponse); }); it('should update a filament', async () => { const filamentId = '1'; const updateData = { tip: 'PLA+', finish: 'Silk', cena: '4500' }; const mockResponse = { id: filamentId, ...updateData }; mockAxiosInstance.put.mockResolvedValue({ data: mockResponse }); const result = await filamentService.update(filamentId, updateData); expect(mockAxiosInstance.put).toHaveBeenCalledWith(`/filaments/${filamentId}`, updateData); expect(result).toEqual(mockResponse); }); it('should delete a filament', async () => { const filamentId = '1'; const mockResponse = { success: true }; mockAxiosInstance.delete.mockResolvedValue({ data: mockResponse }); const result = await filamentService.delete(filamentId); expect(mockAxiosInstance.delete).toHaveBeenCalledWith(`/filaments/${filamentId}`); expect(result).toEqual(mockResponse); }); it('should update bulk sale', async () => { const saleData = { filamentIds: ['1', '2', '3'], salePercentage: 20, saleStartDate: '2024-01-01', saleEndDate: '2024-01-31', enableSale: true }; const mockResponse = { updated: 3, success: true }; mockAxiosInstance.post.mockResolvedValue({ data: mockResponse }); const result = await filamentService.updateBulkSale(saleData); expect(mockAxiosInstance.post).toHaveBeenCalledWith('/filaments/sale/bulk', saleData); expect(result).toEqual(mockResponse); }); }); describe('Interceptors', () => { it('should have interceptors configured', () => { expect(mockAxiosInstance.interceptors).toBeDefined(); expect(mockAxiosInstance.interceptors.request).toBeDefined(); expect(mockAxiosInstance.interceptors.response).toBeDefined(); }); it('should have request interceptor set up', () => { const mockRequestUse = mockAxiosInstance.interceptors.request.use; expect(mockRequestUse).toBeDefined(); }); it('should have response interceptor set up', () => { const mockResponseUse = mockAxiosInstance.interceptors.response.use; expect(mockResponseUse).toBeDefined(); }); }); describe('API configuration', () => { it('should export the configured axios instance', () => { expect(api).toBe(mockAxiosInstance); }); it('should have axios instance defined', () => { expect(mockAxiosInstance).toBeDefined(); }); }); });