feat: Directus SDK client with typed helpers
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
|
||||
const mockRequest = vi.fn()
|
||||
const mockWith = vi.fn()
|
||||
|
||||
vi.mock('@directus/sdk', () => ({
|
||||
createDirectus: vi.fn(() => ({ with: mockWith })),
|
||||
rest: vi.fn(() => 'rest-plugin'),
|
||||
staticToken: vi.fn(() => 'token-plugin'),
|
||||
readItems: vi.fn((collection: string) => ({ _op: 'readItems', collection })),
|
||||
readSingleton: vi.fn((collection: string) => ({ _op: 'readSingleton', collection })),
|
||||
readItem: vi.fn((collection: string, id: string) => ({ _op: 'readItem', collection, id })),
|
||||
}))
|
||||
|
||||
mockWith.mockReturnValue({ with: mockWith, request: mockRequest })
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetModules()
|
||||
mockRequest.mockReset()
|
||||
process.env.DIRECTUS_URL = 'https://cms.achmad.dev'
|
||||
process.env.DIRECTUS_TOKEN = 'test-token'
|
||||
})
|
||||
|
||||
describe('getAllCategories', () => {
|
||||
it('returns array of categories from Directus', async () => {
|
||||
mockRequest.mockResolvedValue([
|
||||
{ id: '1', name: 'Anime', slug: 'anime', description: null },
|
||||
{ id: '2', name: 'VTubers', slug: 'vtubers', description: null },
|
||||
])
|
||||
const { getAllCategories } = await import('@/lib/directus')
|
||||
const result = await getAllCategories()
|
||||
expect(result).toHaveLength(2)
|
||||
expect(result[0].slug).toBe('anime')
|
||||
})
|
||||
})
|
||||
|
||||
describe('getArticleBySlug', () => {
|
||||
it('returns null when no article matches', async () => {
|
||||
mockRequest.mockResolvedValue([])
|
||||
const { getArticleBySlug } = await import('@/lib/directus')
|
||||
const result = await getArticleBySlug('nonexistent')
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('returns the first matching article', async () => {
|
||||
mockRequest.mockResolvedValue([
|
||||
{
|
||||
id: '1', title: 'Frieren S2', slug: 'frieren-s2', status: 'published',
|
||||
content: '<p>Body</p>', excerpt: 'Short', featured_image: null,
|
||||
published_at: '2026-05-28T00:00:00Z', is_featured: false,
|
||||
seo_title: null, seo_description: null,
|
||||
category: { id: '1', name: 'Anime', slug: 'anime', description: null },
|
||||
tags: [],
|
||||
},
|
||||
])
|
||||
const { getArticleBySlug } = await import('@/lib/directus')
|
||||
const result = await getArticleBySlug('frieren-s2')
|
||||
expect(result?.title).toBe('Frieren S2')
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAssetUrl', () => {
|
||||
it('constructs a Directus asset URL from a file UUID', async () => {
|
||||
const { getAssetUrl } = await import('@/lib/directus')
|
||||
const url = getAssetUrl('abc-123-uuid')
|
||||
expect(url).toBe('https://cms.achmad.dev/assets/abc-123-uuid')
|
||||
})
|
||||
|
||||
it('appends width and quality query params', async () => {
|
||||
const { getAssetUrl } = await import('@/lib/directus')
|
||||
const url = getAssetUrl('abc-123-uuid', { width: 800, quality: 80 })
|
||||
expect(url).toContain('width=800')
|
||||
expect(url).toContain('quality=80')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user