174 lines
5.5 KiB
JavaScript
174 lines
5.5 KiB
JavaScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
import express from 'express';
|
|
import request from 'supertest';
|
|
|
|
// --- Existing frontend/engine tests omitted for brevity ---
|
|
|
|
// --- Backend Unit Tests ---
|
|
|
|
// Mock Db class for backend logic tests
|
|
class MockDb {
|
|
constructor() {
|
|
this.data = {};
|
|
this.lastId = 0;
|
|
}
|
|
async getLastId() { return this.lastId; }
|
|
async create(collection, obj) {
|
|
this.lastId++;
|
|
obj.id = this.lastId;
|
|
this.data[obj.id] = obj;
|
|
return obj;
|
|
}
|
|
async get(collection, query) {
|
|
return Object.values(this.data).find(o => o.id === query.id);
|
|
}
|
|
async update(collection, key, value) {
|
|
if (this.data[key.id]) {
|
|
this.data[key.id] = { ...this.data[key.id], ...value };
|
|
return this.data[key.id];
|
|
}
|
|
return null;
|
|
}
|
|
async remove(collection, key) {
|
|
delete this.data[key.id];
|
|
return true;
|
|
}
|
|
async list(collection, { query }) {
|
|
return Object.values(this.data).filter(o => !query || o.id === query.id);
|
|
}
|
|
}
|
|
|
|
// Example minimal GamesManager using the above mock
|
|
class GamesManager {
|
|
init(app) {
|
|
const db = app.db;
|
|
this.create = async (ctx, data) => {
|
|
data.id = (await db.getLastId()) + 1;
|
|
await db.create('games', data);
|
|
return data;
|
|
};
|
|
this.read = async (id) => {
|
|
return await db.get('games', { id });
|
|
};
|
|
this.update = async (ctx, data) => {
|
|
await db.update('games', { id: data.id }, data);
|
|
return data;
|
|
};
|
|
this.remove = async (id) => {
|
|
await db.remove('games', { id });
|
|
};
|
|
this.list = async (query) => {
|
|
return await db.list('games', { query });
|
|
};
|
|
}
|
|
}
|
|
|
|
describe('GamesManager backend logic', () => {
|
|
let app, manager;
|
|
beforeEach(() => {
|
|
app = { db: new MockDb() };
|
|
manager = new GamesManager();
|
|
manager.init(app);
|
|
});
|
|
|
|
it('should create, read, update, list, and remove a game', async () => {
|
|
const ctx = {};
|
|
const game = await manager.create(ctx, { name: 'Test Game' });
|
|
expect(game.id).toBe(1);
|
|
expect(game.name).toBe('Test Game');
|
|
|
|
const readGame = await manager.read(1);
|
|
expect(readGame.name).toBe('Test Game');
|
|
|
|
await manager.update(ctx, { id: 1, name: 'Updated Game' });
|
|
const updatedGame = await manager.read(1);
|
|
expect(updatedGame.name).toBe('Updated Game');
|
|
|
|
const list = await manager.list({});
|
|
expect(list.length).toBe(1);
|
|
|
|
await manager.remove(1);
|
|
const afterRemove = await manager.read(1);
|
|
expect(afterRemove).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
// --- API Tests (Express) ---
|
|
|
|
// Minimal API controller for Games
|
|
function createGamesApi(manager) {
|
|
const app = express();
|
|
app.use(express.json());
|
|
app.get('/api/game/:id', async (req, res) => {
|
|
const obj = await manager.read(parseInt(req.params.id));
|
|
if (obj) res.json(obj);
|
|
else res.status(404).json({ error: 'Not found' });
|
|
});
|
|
app.post('/api/game', async (req, res) => {
|
|
const list = await manager.list(req.body || {});
|
|
res.json(list);
|
|
});
|
|
app.put('/api/game', async (req, res) => {
|
|
const obj = req.body;
|
|
if (obj.id) {
|
|
await manager.update({}, obj);
|
|
res.json({ status: 'OK', object: obj });
|
|
} else {
|
|
const created = await manager.create({}, obj);
|
|
res.json({ status: 'OK', object: created });
|
|
}
|
|
});
|
|
app.delete('/api/game/:id', async (req, res) => {
|
|
await manager.remove(parseInt(req.params.id));
|
|
res.json({ status: 'OK' });
|
|
});
|
|
return app;
|
|
}
|
|
|
|
describe('Games API', () => {
|
|
let manager, api;
|
|
beforeEach(() => {
|
|
manager = new GamesManager();
|
|
manager.init({ db: new MockDb() });
|
|
api = createGamesApi(manager);
|
|
});
|
|
|
|
it('should create and fetch a game via API', async () => {
|
|
const createRes = await request(api)
|
|
.put('/api/game')
|
|
.send({ name: 'API Game' });
|
|
expect(createRes.body.object.name).toBe('API Game');
|
|
const id = createRes.body.object.id;
|
|
|
|
const getRes = await request(api).get(`/api/game/${id}`);
|
|
expect(getRes.body.name).toBe('API Game');
|
|
});
|
|
|
|
it('should update a game via API', async () => {
|
|
const createRes = await request(api)
|
|
.put('/api/game')
|
|
.send({ name: 'ToUpdate' });
|
|
const id = createRes.body.object.id;
|
|
|
|
const updateRes = await request(api)
|
|
.put('/api/game')
|
|
.send({ id, name: 'Updated via API' });
|
|
expect(updateRes.body.object.name).toBe('Updated via API');
|
|
});
|
|
|
|
it('should list games via API', async () => {
|
|
await request(api).put('/api/game').send({ name: 'Game1' });
|
|
await request(api).put('/api/game').send({ name: 'Game2' });
|
|
const listRes = await request(api).post('/api/game').send({});
|
|
expect(listRes.body.length).toBe(2);
|
|
});
|
|
|
|
it('should delete a game via API', async () => {
|
|
const createRes = await request(api).put('/api/game').send({ name: 'ToDelete' });
|
|
const id = createRes.body.object.id;
|
|
const delRes = await request(api).delete(`/api/game/${id}`);
|
|
expect(delRes.body.status).toBe('OK');
|
|
const getRes = await request(api).get(`/api/game/${id}`);
|
|
expect(getRes.status).toBe(404);
|
|
});
|
|
}); |