import { describe, expect, it } from 'vitest'; import { assetRefSchema, extractedObjectSchema, itemIdSchema, searchQuerySchema, searchResultSchema, traceRequestSchema, workshopItemSchema, } from './schemas.js'; describe('itemIdSchema', () => { it('accepts a run of digits', () => { expect(itemIdSchema.parse('123456')).toBe('123456'); }); it('rejects empty strings', () => { expect(itemIdSchema.safeParse('').success).toBe(false); }); it('rejects non-numeric input', () => { expect(itemIdSchema.safeParse('abc').success).toBe(false); expect(itemIdSchema.safeParse('12a34').success).toBe(false); }); }); describe('searchQuerySchema', () => { it('coerces page to a number and defaults it', () => { expect(searchQuerySchema.parse({ q: 'cards' })).toEqual({ q: 'cards', page: 1, }); expect(searchQuerySchema.parse({ q: 'cards', page: '3' })).toEqual({ q: 'cards', page: 3, }); }); it('rejects a missing or blank query', () => { expect(searchQuerySchema.safeParse({}).success).toBe(false); expect(searchQuerySchema.safeParse({ q: ' ' }).success).toBe(false); }); it('rejects a non-positive page', () => { expect(searchQuerySchema.safeParse({ q: 'cards', page: 0 }).success).toBe( false, ); }); }); describe('assetRefSchema', () => { it('accepts a valid ref', () => { const ref = { kind: 'pdf', url: 'https://example.com/doc.pdf', ownerGuid: 'abc', }; expect(assetRefSchema.parse(ref)).toEqual(ref); }); it('rejects an invalid URL', () => { expect( assetRefSchema.safeParse({ kind: 'pdf', url: 'not-a-url', ownerGuid: 'abc', }).success, ).toBe(false); }); it('rejects an unknown kind', () => { expect( assetRefSchema.safeParse({ kind: 'video', url: 'https://example.com/a.mp4', ownerGuid: 'abc', }).success, ).toBe(false); }); }); describe('extractedObjectSchema', () => { it('accepts a minimal object', () => { const obj = { guid: 'g1', name: 'Card', type: 'Card', childrenGuids: [], refs: [], }; expect(extractedObjectSchema.parse(obj)).toEqual(obj); }); it('accepts optional parentGuid', () => { const obj = { guid: 'g1', name: 'Card', type: 'Card', parentGuid: 'g0', childrenGuids: ['g2'], refs: [], }; expect(extractedObjectSchema.parse(obj).parentGuid).toBe('g0'); }); }); describe('workshopItemSchema', () => { it('accepts a full item', () => { const item = { id: '1', title: 'Deck', author: 'someone', previewImageUrl: 'https://example.com/p.png', tags: ['card'], timeCreated: 123, }; expect(workshopItemSchema.parse(item)).toEqual(item); }); it('accepts a minimal item', () => { const item = { id: '1', title: 'Deck', author: 'someone', previewImageUrl: 'https://example.com/p.png', }; expect(workshopItemSchema.parse(item)).toEqual(item); }); }); describe('searchResultSchema', () => { it('accepts an empty result set', () => { const result = { items: [], page: 1, hasMore: false }; expect(searchResultSchema.parse(result)).toEqual(result); }); }); describe('traceRequestSchema', () => { it('defaults mode, threshold, and format', () => { expect(traceRequestSchema.parse({ url: 'https://example.com/a.png' })).toEqual({ url: 'https://example.com/a.png', mode: 'alpha', threshold: 128, format: 'shape', }); }); it('coerces threshold and accepts optional params', () => { expect( traceRequestSchema.parse({ url: 'https://example.com/a.png', mode: 'bw', threshold: '200', format: 'svg', simplify: 1.5, maxColors: '8', }), ).toEqual({ url: 'https://example.com/a.png', mode: 'bw', threshold: 200, format: 'svg', simplify: 1.5, maxColors: 8, }); }); it('accepts a local game asset path (not just http(s))', () => { // The proxy resolves relative paths against the games root, so a bare // path is a valid trace source. expect( traceRequestSchema.safeParse({ url: 'poker/parts/assets/cards.png' }) .success, ).toBe(true); }); it('rejects a missing or blank url', () => { expect(traceRequestSchema.safeParse({}).success).toBe(false); expect(traceRequestSchema.safeParse({ url: '' }).success).toBe(false); }); it('rejects an unknown mode or format', () => { expect( traceRequestSchema.safeParse({ url: 'https://example.com/a.png', mode: 'nope', }).success, ).toBe(false); expect( traceRequestSchema.safeParse({ url: 'https://example.com/a.png', format: 'nope', }).success, ).toBe(false); }); });