// Mock axios before importing services jest.mock('axios', () => ({ create: jest.fn(() => ({ interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } }, get: jest.fn(), post: jest.fn(), put: jest.fn(), delete: jest.fn() })) })); import { filamentService, authService } from '../src/services/api'; describe('Filament CRUD Operations', () => { let authToken: string; beforeAll(async () => { // Mock successful login jest.spyOn(authService, 'login').mockResolvedValue({ token: 'test-token' }); const loginResponse = await authService.login('admin', 'admin123'); authToken = loginResponse.token; }); afterEach(() => { jest.clearAllMocks(); }); describe('Create Filament', () => { it('should create a new filament without brand field', async () => { const newFilament = { tip: 'PLA', finish: 'Basic', boja: 'Black', boja_hex: '#000000', refill: '2', spulna: '1 spulna', kolicina: '3', cena: '3999' }; const mockResponse = { id: '123', ...newFilament, boja_hex: '#000000', created_at: new Date().toISOString(), updated_at: new Date().toISOString() }; jest.spyOn(filamentService, 'create').mockResolvedValue(mockResponse); const result = await filamentService.create(newFilament); expect(result).toEqual(mockResponse); expect(filamentService.create).toHaveBeenCalledWith(newFilament); // Verify no brand field was sent const callArg = (filamentService.create as jest.Mock).mock.calls[0][0]; expect(callArg).not.toHaveProperty('brand'); }); it('should use boja_hex field directly', async () => { const filamentWithHex = { tip: 'PETG', finish: 'Silk', boja: 'Red', boja_hex: '#FF0000', refill: 'Ne', spulna: 'Ne', kolicina: '1', cena: '4500' }; // Spy on the actual implementation const createSpy = jest.spyOn(filamentService, 'create'); // We can't test the actual transformation without a real axios call, // but we can verify the method is called correctly await expect(async () => { await filamentService.create(filamentWithHex); }).not.toThrow(); expect(createSpy).toHaveBeenCalledWith(filamentWithHex); }); }); describe('Update Filament', () => { it('should update a filament without brand field', async () => { const filamentId = '123'; const updateData = { tip: 'ABS', finish: 'Matte', boja: 'Blue', boja_hex: '#0000FF', refill: '1', spulna: '2 spulna', kolicina: '4', cena: '5000' }; const mockResponse = { id: filamentId, ...updateData, boja_hex: '#0000FF', updated_at: new Date().toISOString() }; jest.spyOn(filamentService, 'update').mockResolvedValue(mockResponse); const result = await filamentService.update(filamentId, updateData); expect(result).toEqual(mockResponse); expect(filamentService.update).toHaveBeenCalledWith(filamentId, updateData); // Verify no brand field was sent const callArgs = (filamentService.update as jest.Mock).mock.calls[0]; expect(callArgs[1]).not.toHaveProperty('brand'); }); }); describe('Delete Filament', () => { it('should delete a filament by ID', async () => { const filamentId = '123'; const mockResponse = { success: true }; jest.spyOn(filamentService, 'delete').mockResolvedValue(mockResponse); const result = await filamentService.delete(filamentId); expect(result).toEqual(mockResponse); expect(filamentService.delete).toHaveBeenCalledWith(filamentId); }); }); describe('Get All Filaments', () => { it('should retrieve all filaments with boja_hex field', async () => { const mockFilaments = [ { id: '1', tip: 'PLA', finish: 'Basic', boja: 'Black', boja_hex: '#000000', refill: '2', spulna: '1 spulna', kolicina: '3', cena: '3999' }, { id: '2', tip: 'PETG', finish: 'Silk', boja: 'Red', boja_hex: '#FF0000', refill: 'Ne', spulna: 'Ne', kolicina: '1', cena: '4500' } ]; // No transformation needed anymore - we use boja_hex directly const expectedFilaments = mockFilaments; jest.spyOn(filamentService, 'getAll').mockResolvedValue(expectedFilaments); const result = await filamentService.getAll(); expect(result).toEqual(expectedFilaments); expect(result[0]).toHaveProperty('boja_hex', '#000000'); expect(result[1]).toHaveProperty('boja_hex', '#FF0000'); }); }); describe('Quantity Calculations', () => { it('should correctly calculate total quantity from refill and spulna', () => { const testCases = [ { refill: '2', spulna: '1 spulna', expected: 3 }, { refill: 'Ne', spulna: '3 spulna', expected: 3 }, { refill: '1', spulna: 'Ne', expected: 1 }, { refill: 'Da', spulna: 'spulna', expected: 2 } ]; testCases.forEach(({ refill, spulna, expected }) => { // Parse refill const refillCount = parseInt(refill) || (refill?.toLowerCase() === 'da' ? 1 : 0); // Parse spulna const vakuumMatch = spulna?.match(/^(\d+)\s*spulna/); const vakuumCount = vakuumMatch ? parseInt(vakuumMatch[1]) : (spulna?.toLowerCase().includes('spulna') ? 1 : 0); const total = refillCount + vakuumCount; expect(total).toBe(expected); }); }); }); });