94 lines
2.7 KiB
TypeScript
94 lines
2.7 KiB
TypeScript
import type { GameDTO } from '$lib/api/schema-helpers';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { blankDraft, isDirty, nextOrder, toDraft, toDto } from './draft';
|
|
|
|
describe('toDraft / toDto', () => {
|
|
it('replaces every null with a value the inputs can bind to', () => {
|
|
const draft = toDraft({ id: 3, name: null, longName: null, order: undefined, smashId: undefined });
|
|
expect(draft).toEqual({
|
|
id: 3,
|
|
name: '',
|
|
longName: '',
|
|
order: 0,
|
|
imgUrl: '',
|
|
wordPressTag: '',
|
|
wordPressTagOs: '',
|
|
smashId: null
|
|
});
|
|
});
|
|
|
|
it('stores blank and whitespace-only text as NULL, not as an empty string', () => {
|
|
const dto = toDto({ ...blankDraft, name: 'SF6', longName: ' ', imgUrl: '' });
|
|
expect(dto.longName).toBeNull();
|
|
expect(dto.imgUrl).toBeNull();
|
|
expect(dto.name).toBe('SF6');
|
|
});
|
|
|
|
it('trims text on the way out', () => {
|
|
expect(toDto({ ...blankDraft, name: ' SF6 ' }).name).toBe('SF6');
|
|
});
|
|
|
|
it('round-trips a full game', () => {
|
|
const game: GameDTO = {
|
|
id: 4,
|
|
name: 'SF6',
|
|
longName: 'Street Fighter 6',
|
|
order: 2,
|
|
imgUrl: 'https://example.test/sf6.png',
|
|
wordPressTag: 'sf6',
|
|
wordPressTagOs: 'sf6-os',
|
|
smashId: 43868
|
|
};
|
|
expect(toDto(toDraft(game))).toEqual(game);
|
|
});
|
|
});
|
|
|
|
describe('isDirty', () => {
|
|
/*
|
|
* The editor used to compare `JSON.stringify` output, which is key-order
|
|
* dependent: an identical draft built with its keys in another order read as
|
|
* unsaved changes.
|
|
*/
|
|
it('is false for equal drafts regardless of key order', () => {
|
|
const a = { ...blankDraft, name: 'SF6', order: 2 };
|
|
const reordered = {
|
|
order: 2,
|
|
smashId: null,
|
|
wordPressTagOs: '',
|
|
wordPressTag: '',
|
|
imgUrl: '',
|
|
longName: '',
|
|
name: 'SF6',
|
|
id: 0
|
|
};
|
|
expect(JSON.stringify(a)).not.toBe(JSON.stringify(reordered));
|
|
expect(isDirty(a, reordered)).toBe(false);
|
|
});
|
|
|
|
it('detects a change in any field', () => {
|
|
const base = { ...blankDraft, name: 'SF6' };
|
|
expect(isDirty(base, { ...base, name: 'SFV' })).toBe(true);
|
|
expect(isDirty(base, { ...base, order: 9 })).toBe(true);
|
|
expect(isDirty(base, { ...base, smashId: 1 })).toBe(true);
|
|
expect(isDirty(base, { ...base })).toBe(false);
|
|
});
|
|
|
|
it('distinguishes null from 0 for the nullable numbers', () => {
|
|
expect(isDirty({ ...blankDraft, smashId: null }, { ...blankDraft, smashId: 0 })).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('nextOrder', () => {
|
|
it('sorts a new game after the current last one', () => {
|
|
expect(nextOrder([{ order: 1 }, { order: 5 }, { order: 3 }])).toBe(6);
|
|
});
|
|
|
|
it('starts at 1 for an empty catalogue', () => {
|
|
expect(nextOrder([])).toBe(1);
|
|
});
|
|
|
|
it('treats a missing order as 0', () => {
|
|
expect(nextOrder([{ order: undefined }])).toBe(1);
|
|
});
|
|
});
|