deckhearth/test/api/public-games.test.js

105 lines
2.6 KiB
JavaScript
Raw Normal View History

import { beforeEach, describe, expect, it, vi } from 'vitest';
vi.mock('../../lib/sql.js', () => ({ sql: vi.fn() }));
import { sql } from '../../lib/sql.js';
import listHandler from '../../pages/api/public/games/index.js';
import itemHandler from '../../pages/api/public/games/[id].js';
function createRes() {
const res = {
statusCode: 200,
body: null,
status(code) {
res.statusCode = code;
return res;
},
json(data) {
res.body = data;
return res;
},
};
return res;
}
describe('/api/public/games', () => {
beforeEach(() => {
vi.clearAllMocks();
sql.mockResolvedValue({ rows: [] });
});
it('rejects non-GET methods', async () => {
const res = createRes();
await listHandler({ method: 'POST' }, res);
expect(res.statusCode).toBe(405);
expect(sql).not.toHaveBeenCalled();
});
it('lists public games with author and card counts', async () => {
sql.mockResolvedValueOnce({
rows: [{ id: 9, name: 'Aetherfall', author: 'rstillw', card_count: 4 }],
});
const res = createRes();
await listHandler({ method: 'GET' }, res);
expect(res.statusCode).toBe(200);
expect(res.body.games).toHaveLength(1);
const listed = sql.mock.calls[0][0].join('');
expect(listed).toContain('is_public = true');
});
});
describe('/api/public/games/[id]', () => {
beforeEach(() => {
vi.clearAllMocks();
sql.mockResolvedValue({ rows: [] });
});
it('rejects invalid ids', async () => {
const res = createRes();
await itemHandler({ method: 'GET', query: { id: 'abc' } }, res);
expect(res.statusCode).toBe(400);
});
it('404s private or missing games', async () => {
sql.mockResolvedValueOnce({ rows: [] }); // public filter misses
const res = createRes();
await itemHandler({ method: 'GET', query: { id: '9' } }, res);
expect(res.statusCode).toBe(404);
});
it('returns the game and its designs with resolved frames', async () => {
sql
.mockResolvedValueOnce({
rows: [{ id: 9, name: 'Aetherfall', author: 'rstillw' }],
})
.mockResolvedValueOnce({
rows: [
{
id: 3,
name: 'Stormsage',
frame_pk: 2,
frame_name: 'Molten',
frame_palette: { outer: '#111111' },
frame_texture: null,
},
],
});
const res = createRes();
await itemHandler({ method: 'GET', query: { id: '9' } }, res);
expect(res.statusCode).toBe(200);
expect(res.body.game.name).toBe('Aetherfall');
expect(res.body.designs[0].custom_frame.name).toBe('Molten');
expect(res.body.designs[0].frame_pk).toBeUndefined();
});
});