158 lines
5.4 KiB
TypeScript
158 lines
5.4 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
|
|
import { useComposants } from '~/composables/useComposants'
|
|
import { mockComponentFromApi, 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 { clearComposantsCache } = useComposants()
|
|
clearComposantsCache()
|
|
})
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// createComposant
|
|
// ---------------------------------------------------------------------------
|
|
describe('createComposant', () => {
|
|
it('sends all fields in creation payload', async () => {
|
|
const created = { ...mockComponentFromApi, id: 'comp-new' }
|
|
mockPost.mockResolvedValue({ success: true, data: created })
|
|
|
|
const { createComposant } = useComposants()
|
|
const result = await createComposant({
|
|
name: 'Moteur principal',
|
|
reference: 'COMP-MOT-001',
|
|
description: 'Un moteur',
|
|
typeComposantId: 'tc-moteur',
|
|
})
|
|
|
|
expect(result.success).toBe(true)
|
|
// normalizeRelationIds converts typeComposantId to typeComposant IRI
|
|
expect(mockPost).toHaveBeenCalledWith('/composants', expect.objectContaining({
|
|
name: 'Moteur principal',
|
|
reference: 'COMP-MOT-001',
|
|
description: 'Un moteur',
|
|
typeComposant: '/api/model_types/tc-moteur',
|
|
}))
|
|
// typeComposantId should be removed by normalizeRelationIds
|
|
const payload = mockPost.mock.calls[0]![1]
|
|
expect(payload).not.toHaveProperty('typeComposantId')
|
|
})
|
|
|
|
it('adds created composant to cache', async () => {
|
|
const created = { ...mockComponentFromApi, id: 'comp-new', name: 'Nouveau composant' }
|
|
mockPost.mockResolvedValue({ success: true, data: created })
|
|
|
|
const { createComposant, composants, total } = useComposants()
|
|
|
|
expect(composants.value).toHaveLength(0)
|
|
expect(total.value).toBe(0)
|
|
|
|
await createComposant({ name: 'Nouveau composant' })
|
|
|
|
expect(composants.value).toHaveLength(1)
|
|
expect(composants.value[0]!.id).toBe('comp-new')
|
|
expect(total.value).toBe(1)
|
|
})
|
|
})
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// updateComposant
|
|
// ---------------------------------------------------------------------------
|
|
describe('updateComposant', () => {
|
|
it('patches and updates cache', async () => {
|
|
// Seed the cache with one composant
|
|
const original = { ...mockComponentFromApi, id: 'comp-001', name: 'Ancien nom' }
|
|
mockPost.mockResolvedValue({ success: true, data: original })
|
|
const { createComposant, updateComposant, composants } = useComposants()
|
|
await createComposant({ name: 'Ancien nom' })
|
|
expect(composants.value).toHaveLength(1)
|
|
|
|
// Now update
|
|
const updated = { ...original, name: 'Nouveau nom' }
|
|
mockPatch.mockResolvedValue({ success: true, data: updated })
|
|
|
|
const result = await updateComposant('comp-001', { name: 'Nouveau nom' })
|
|
|
|
expect(result.success).toBe(true)
|
|
expect(mockPatch).toHaveBeenCalledWith('/composants/comp-001', expect.objectContaining({
|
|
name: 'Nouveau nom',
|
|
}))
|
|
expect(composants.value[0]!.name).toBe('Nouveau nom')
|
|
})
|
|
})
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// deleteComposant
|
|
// ---------------------------------------------------------------------------
|
|
describe('deleteComposant', () => {
|
|
it('removes composant from cache on success', async () => {
|
|
// Seed cache
|
|
const item = { ...mockComponentFromApi, id: 'comp-del', name: 'A supprimer' }
|
|
mockPost.mockResolvedValue({ success: true, data: item })
|
|
const { createComposant, deleteComposant, composants, total } = useComposants()
|
|
await createComposant({ name: 'A supprimer' })
|
|
expect(composants.value).toHaveLength(1)
|
|
expect(total.value).toBe(1)
|
|
|
|
mockDel.mockResolvedValue({ success: true })
|
|
const result = await deleteComposant('comp-del')
|
|
|
|
expect(result.success).toBe(true)
|
|
expect(composants.value).toHaveLength(0)
|
|
expect(total.value).toBe(0)
|
|
})
|
|
|
|
it('keeps composant in cache on failure', async () => {
|
|
// Seed cache
|
|
const item = { ...mockComponentFromApi, id: 'comp-keep', name: 'Garder' }
|
|
mockPost.mockResolvedValue({ success: true, data: item })
|
|
const { createComposant, deleteComposant, composants, total } = useComposants()
|
|
await createComposant({ name: 'Garder' })
|
|
expect(composants.value).toHaveLength(1)
|
|
|
|
mockDel.mockResolvedValue({ success: false, error: 'Server error' })
|
|
const result = await deleteComposant('comp-keep')
|
|
|
|
expect(result.success).toBe(false)
|
|
expect(composants.value).toHaveLength(1)
|
|
expect(composants.value[0]!.id).toBe('comp-keep')
|
|
})
|
|
})
|