Files
Inventory/frontend/tests/composables/usePieces.test.ts
2026-04-06 16:52:41 +02:00

167 lines
5.4 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { usePieces } from '~/composables/usePieces'
import { mockPieceFromApi, wrapCollection } from '../fixtures/mockData'
// ---------------------------------------------------------------------------
// Mocks
// ---------------------------------------------------------------------------
const mockGet = vi.fn()
const mockPost = vi.fn()
const mockPatch = vi.fn()
const mockDel = vi.fn()
vi.mock('~/composables/useApi', () => ({
useApi: () => ({
get: mockGet,
post: mockPost,
patch: mockPatch,
put: vi.fn(),
delete: mockDel,
postFormData: vi.fn(),
}),
}))
vi.mock('~/composables/useToast', () => ({
useToast: () => ({
showSuccess: vi.fn(),
showError: vi.fn(),
showInfo: vi.fn(),
showToast: vi.fn(),
toasts: { value: [] },
clearAll: vi.fn(),
}),
}))
vi.mock('~/composables/useConstructeurs', () => ({
useConstructeurs: () => ({
ensureConstructeurs: vi.fn().mockResolvedValue([]),
}),
}))
beforeEach(() => {
vi.clearAllMocks()
const { clearPiecesCache } = usePieces()
clearPiecesCache()
})
// ---------------------------------------------------------------------------
// createPiece
// ---------------------------------------------------------------------------
describe('createPiece', () => {
it('sends all fields including prix in POST payload', async () => {
const created = { ...mockPieceFromApi, id: 'piece-new' }
mockPost.mockResolvedValue({ success: true, data: created })
const { createPiece } = usePieces()
await createPiece({
name: 'Roulement 6205',
reference: 'ROUL-6205',
prix: 25.50,
typePieceId: 'tp-bearing-001',
} as any)
expect(mockPost).toHaveBeenCalledWith('/pieces', expect.objectContaining({
name: 'Roulement 6205',
reference: 'ROUL-6205',
prix: 25.50,
typePiece: '/api/model_types/tp-bearing-001',
}))
})
it('strips constructeur fields from payload', async () => {
const created = { ...mockPieceFromApi, id: 'piece-new' }
mockPost.mockResolvedValue({ success: true, data: created })
const { createPiece } = usePieces()
await createPiece({
name: 'Test Piece',
constructeurIds: ['cstr-skf-001'],
constructeurs: [{ id: 'cstr-skf-001', name: 'SKF' }] as any,
})
const payload = mockPost.mock.calls[0]![1]
expect(payload).not.toHaveProperty('constructeurIds')
expect(payload).not.toHaveProperty('constructeurs')
expect(payload).not.toHaveProperty('constructeurId')
expect(payload).not.toHaveProperty('constructeur')
})
it('adds created piece to cache (pieces array and total)', async () => {
const created = { ...mockPieceFromApi, id: 'piece-new' }
mockPost.mockResolvedValue({ success: true, data: created })
const { createPiece, pieces, total } = usePieces()
const result = await createPiece({ name: 'New Piece' })
expect(result.success).toBe(true)
expect(pieces.value).toHaveLength(1)
expect(pieces.value[0]!.id).toBe('piece-new')
expect(total.value).toBe(1)
})
})
// ---------------------------------------------------------------------------
// updatePiece
// ---------------------------------------------------------------------------
describe('updatePiece', () => {
it('patches with supplied fields and updates cache', async () => {
// Seed cache first
const original = { ...mockPieceFromApi }
mockPost.mockResolvedValue({ success: true, data: original })
const { createPiece, updatePiece, pieces } = usePieces()
await createPiece({ name: 'Roulement 6205' })
const updated = { ...mockPieceFromApi, name: 'Updated Name', reference: 'ROUL-NEW' }
mockPatch.mockResolvedValue({ success: true, data: updated })
const result = await updatePiece(mockPieceFromApi.id, {
name: 'Updated Name',
reference: 'ROUL-NEW',
})
expect(mockPatch).toHaveBeenCalledWith(`/pieces/${mockPieceFromApi.id}`, expect.objectContaining({
name: 'Updated Name',
reference: 'ROUL-NEW',
}))
expect(result.success).toBe(true)
expect(pieces.value.find(p => p.id === mockPieceFromApi.id)?.name).toBe('Updated Name')
})
})
// ---------------------------------------------------------------------------
// deletePiece
// ---------------------------------------------------------------------------
describe('deletePiece', () => {
it('removes piece from cache on success', async () => {
// Seed cache
mockPost.mockResolvedValue({ success: true, data: { ...mockPieceFromApi } })
const { createPiece, deletePiece, pieces, total } = usePieces()
await createPiece({ name: 'To Delete' })
expect(pieces.value).toHaveLength(1)
mockDel.mockResolvedValue({ success: true })
const result = await deletePiece(mockPieceFromApi.id)
expect(result.success).toBe(true)
expect(pieces.value).toHaveLength(0)
expect(total.value).toBe(0)
})
it('does not remove on failure', async () => {
// Seed cache
mockPost.mockResolvedValue({ success: true, data: { ...mockPieceFromApi } })
const { createPiece, deletePiece, pieces, total } = usePieces()
await createPiece({ name: 'Should Stay' })
expect(pieces.value).toHaveLength(1)
mockDel.mockResolvedValue({ success: false, error: 'Server error' })
const result = await deletePiece(mockPieceFromApi.id)
expect(result.success).toBe(false)
expect(pieces.value).toHaveLength(1)
expect(total.value).toBe(1)
})
})