ytptube/ui/tests/composables/useTaskDefinitions.test.ts
2026-05-04 22:23:19 +03:00

175 lines
4.9 KiB
TypeScript

import { beforeEach, describe, expect, it, mock, spyOn } from 'bun:test'
const successMock = mock(() => {})
const errorMock = mock(() => {})
globalThis.useNotificationStore = () => ({
add: () => 'test-id',
markRead: () => {},
}) as any
mock.module('~/composables/useNotification', () => ({
useNotification: () => ({ success: successMock, error: errorMock }),
default: () => ({ success: successMock, error: errorMock }),
}))
mock.module('~/stores/notification', () => ({
useNotificationStore: () => ({
add: () => 'test-id',
markRead: () => {},
}),
}))
// eslint-disable-next-line import/first
import * as utils from '~/utils/index'
// eslint-disable-next-line import/first
import { useTaskDefinitions } from '~/composables/useTaskDefinitions'
// eslint-disable-next-line import/first
import type { TaskDefinitionDetailed, TaskDefinitionSummary } from '~/types/task_definitions'
const summary: TaskDefinitionSummary = {
id: 1,
name: 'Test',
priority: 1,
updated_at: 123456,
}
const listPayload = (items: TaskDefinitionSummary[]) => ({
items,
pagination: {
page: 1,
per_page: 50,
total: items.length,
total_pages: 1,
has_next: false,
has_prev: false,
},
})
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(() => {
successMock.mockClear()
errorMock.mockClear()
})
it('sort_priority', 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 },
]
const requestSpy = spyOn(utils, 'request')
requestSpy.mockResolvedValueOnce(createMockResponse({
ok: true,
status: 200,
jsonData: listPayload(items),
}))
const defs = useTaskDefinitions()
await defs.loadDefinitions()
expect(defs.definitions.value.map(d => d.id)).toEqual([3, 2, 1])
requestSpy.mockRestore()
})
it('handle_empty_payload', async () => {
const requestSpy = spyOn(utils, 'request')
requestSpy.mockResolvedValueOnce(createMockResponse({
ok: true,
status: 200,
jsonData: listPayload([]),
}))
const defs = useTaskDefinitions()
await defs.loadDefinitions()
expect(defs.definitions.value).toEqual([])
expect(defs.lastError.value).toBeNull()
requestSpy.mockRestore()
})
it('throw_load_error', async () => {
const requestSpy = spyOn(utils, 'request')
requestSpy.mockResolvedValueOnce(createMockResponse({
ok: false,
status: 500,
jsonData: { error: 'Server error' },
}))
const defs = useTaskDefinitions()
defs.throwInstead.value = true
await expect(defs.loadDefinitions()).rejects.toThrow('Server error')
requestSpy.mockRestore()
})
it('store_get_error', async () => {
const requestSpy = spyOn(utils, 'request')
requestSpy.mockResolvedValueOnce(createMockResponse({
ok: false,
status: 404,
jsonData: { error: 'Not Found' },
}))
const defs = useTaskDefinitions()
defs.throwInstead.value = false
const result = await defs.getDefinition(123)
expect(result).toBeNull()
expect(defs.lastError.value).toBe('Not Found')
requestSpy.mockRestore()
})
it('create_definition', async () => {
const payload: TaskDefinitionDetailed = {
id: 2,
name: 'New',
priority: 0,
updated_at: 999,
definition: { name: 'New', match: ['https://example.com'], parse: { link: { type: 'css', expression: 'a' } } },
}
const requestSpy = spyOn(utils, 'request')
requestSpy.mockResolvedValueOnce(createMockResponse({
ok: true,
status: 200,
jsonData: payload,
}))
const defs = useTaskDefinitions()
await defs.createDefinition(payload.definition)
expect(defs.definitions.value.some(item => item.id === payload.id)).toBe(true)
requestSpy.mockRestore()
})
it('remove_deleted_definition', async () => {
const requestSpy = spyOn(utils, 'request')
requestSpy.mockResolvedValueOnce(createMockResponse({
ok: true,
status: 200,
jsonData: listPayload([summary]),
}))
const defs = useTaskDefinitions()
await defs.loadDefinitions()
requestSpy.mockResolvedValueOnce(createMockResponse({
ok: true,
status: 200,
jsonData: { status: 'deleted' },
}))
const result = await defs.deleteDefinition(summary.id)
expect(result).toBe(true)
expect(defs.definitions.value).toEqual([])
requestSpy.mockRestore()
})
})