Files
tts-workshop/packages/shared/src/schemas.test.ts
T

196 lines
4.8 KiB
TypeScript

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);
});
});