190 lines
5.9 KiB
TypeScript
190 lines
5.9 KiB
TypeScript
import * as utils from '../../app/utils/index'
|
|
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
import { useTaskDefinitions } from '~/composables/useTaskDefinitions'
|
|
import type { TaskDefinitionSummary } from '~/types/task_definitions'
|
|
|
|
vi.mock('~/composables/useNotification', () => {
|
|
const success = vi.fn()
|
|
const error = vi.fn()
|
|
return {
|
|
useNotification: () => ({ success, error }),
|
|
default: () => ({ success, error })
|
|
}
|
|
})
|
|
|
|
// Sample data
|
|
const summary: TaskDefinitionSummary = {
|
|
id: 'abc',
|
|
name: 'Test',
|
|
priority: 1,
|
|
updated_at: 123456,
|
|
}
|
|
|
|
|
|
// Helper to create a mock Response object
|
|
function createMockResponse({ ok, status, jsonData }: { ok: boolean, status: number, jsonData: any }) {
|
|
return {
|
|
ok,
|
|
status,
|
|
headers: new Headers(),
|
|
redirected: false,
|
|
statusText: '',
|
|
type: 'basic',
|
|
url: '',
|
|
body: null,
|
|
bodyUsed: false,
|
|
clone() { return this },
|
|
async json() { return jsonData },
|
|
text: async () => JSON.stringify(jsonData),
|
|
arrayBuffer: async () => new ArrayBuffer(0),
|
|
blob: async () => new Blob(),
|
|
formData: async () => new FormData(),
|
|
} as Response
|
|
}
|
|
|
|
describe('useTaskDefinitions', () => {
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('sorts definitions by priority then name', async () => {
|
|
const items = [
|
|
{ id: '1', name: 'B', priority: 2, updated_at: 1 },
|
|
{ id: '2', name: 'A', priority: 2, updated_at: 2 },
|
|
{ id: '3', name: 'C', priority: 1, updated_at: 3 },
|
|
]
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce(createMockResponse({
|
|
ok: true,
|
|
status: 200,
|
|
jsonData: items,
|
|
}))
|
|
const defs = useTaskDefinitions()
|
|
await defs.loadDefinitions()
|
|
expect(defs.definitions.value.map(d => d.id)).toEqual(['3', '2', '1'])
|
|
})
|
|
|
|
it('handles empty payload', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce(createMockResponse({
|
|
ok: true,
|
|
status: 200,
|
|
jsonData: [],
|
|
}))
|
|
const defs = useTaskDefinitions()
|
|
await defs.loadDefinitions()
|
|
expect(defs.definitions.value).toEqual([])
|
|
expect(defs.lastError.value).toBeNull()
|
|
})
|
|
|
|
it('handles malformed payload', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: true,
|
|
json: async () => ({ jsonData: [{}] })
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
await expect(defs.loadDefinitions()).resolves.toBeUndefined()
|
|
})
|
|
|
|
it('handles malformed payload (throws when throwInstead is true)', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: true,
|
|
json: async () => ({ jsonData: [{}] })
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
defs.throwInstead.value = true
|
|
await expect(defs.loadDefinitions()).rejects.toThrow()
|
|
})
|
|
|
|
it('handles duplicate IDs (no deduplication, both present)', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: true,
|
|
json: async () => [
|
|
{ id: 'dup', name: 'A', priority: 1 },
|
|
{ id: 'dup', name: 'B', priority: 2 },
|
|
]
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
await defs.loadDefinitions()
|
|
expect(defs.definitions.value.length).toBe(2)
|
|
expect(defs.definitions.value[0].name).toBe('A')
|
|
expect(defs.definitions.value[1].name).toBe('B')
|
|
})
|
|
|
|
it('handles error on getDefinition', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: false,
|
|
status: 404,
|
|
statusText: 'Not Found',
|
|
json: async () => ({})
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
await expect(defs.getDefinition('notfound')).rejects.toThrow('Request failed with status 404')
|
|
})
|
|
|
|
it('handles malformed getDefinition response', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: true,
|
|
json: async () => ({})
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
await expect(defs.getDefinition('bad')).rejects.toThrow('Task definition response is missing definition payload.')
|
|
})
|
|
|
|
it('handles error on createDefinition', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: false,
|
|
status: 400,
|
|
statusText: 'Bad Request',
|
|
json: async () => ({})
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
await expect(defs.createDefinition({ id: 'fail', name: 'Fail', priority: 1 })).rejects.toThrow('Request failed with status 400')
|
|
})
|
|
|
|
it('handles error on updateDefinition', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: false,
|
|
status: 400,
|
|
statusText: 'Bad Request',
|
|
json: async () => ({})
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
await expect(defs.updateDefinition({ id: 'fail', name: 'Fail', priority: 1 })).rejects.toThrow('Request failed with status 400')
|
|
})
|
|
|
|
it('handles error on deleteDefinition', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: false,
|
|
status: 400,
|
|
statusText: 'Bad Request',
|
|
json: async () => ({})
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
await expect(defs.deleteDefinition('fail')).rejects.toThrow('Request failed with status 400')
|
|
})
|
|
|
|
it('loads definitions successfully (duplicate test)', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce(createMockResponse({
|
|
ok: true,
|
|
status: 200,
|
|
jsonData: [summary],
|
|
}))
|
|
const defs = useTaskDefinitions()
|
|
await defs.loadDefinitions()
|
|
expect(defs.definitions.value).toEqual([summary])
|
|
expect(defs.lastError.value).toBeNull()
|
|
})
|
|
|
|
|
|
it('calls success notification on createDefinition', async () => {
|
|
vi.spyOn(utils, 'request').mockResolvedValueOnce({
|
|
ok: true,
|
|
json: async () => ({})
|
|
})
|
|
const defs = useTaskDefinitions()
|
|
await defs.createDefinition({ id: 'new', name: 'New', priority: 1 })
|
|
// Access the spy directly from the mock
|
|
const notify = (await import('~/composables/useNotification')).useNotification()
|
|
expect(notify.success).toHaveBeenCalledWith('Task definition created.')
|
|
})
|
|
});
|