import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { buildApp } from '../../src/app'; import { FastifyInstance } from 'fastify'; import { prisma } from '../../src/plugins/prisma'; describe('ROMs API', () => { let app: FastifyInstance; beforeEach(async () => { app = buildApp(); await app.ready(); // Limpiar base de datos antes de cada test (eliminar ROMs primero por foreign key) await prisma.romFile.deleteMany(); await prisma.gamePlatform.deleteMany(); await prisma.purchase.deleteMany(); await prisma.artwork.deleteMany(); await prisma.priceHistory.deleteMany(); await prisma.game.deleteMany(); }); afterEach(async () => { await app.close(); }); describe('GET /api/roms', () => { it('debería devolver una lista vacía cuando no hay ROMs', async () => { const res = await app.inject({ method: 'GET', url: '/api/roms', }); expect(res.statusCode).toBe(200); expect(res.json()).toEqual([]); }); it('debería devolver una lista de ROMs con sus propiedades', async () => { // Crear un ROM de prueba const rom = await prisma.romFile.create({ data: { path: '/roms/games/', filename: 'game.zip', checksum: 'abc123def456', size: 1024, format: 'zip', }, }); const res = await app.inject({ method: 'GET', url: '/api/roms', }); expect(res.statusCode).toBe(200); const body = res.json(); expect(Array.isArray(body)).toBe(true); expect(body.length).toBe(1); expect(body[0].id).toBe(rom.id); expect(body[0].filename).toBe('game.zip'); }); it('debería incluir información del juego asociado', async () => { const game = await prisma.game.create({ data: { title: 'Test Game', slug: 'test-game', }, }); const rom = await prisma.romFile.create({ data: { path: '/roms/', filename: 'test-with-game.zip', checksum: 'checksum-game-123', size: 2048, format: 'zip', gameId: game.id, }, }); const res = await app.inject({ method: 'GET', url: '/api/roms', }); expect(res.statusCode).toBe(200); const body = res.json(); // Buscar el ROM que creamos por checksum const createdRom = body.find((r: any) => r.checksum === 'checksum-game-123'); expect(createdRom).toBeDefined(); expect(createdRom.game).toBeDefined(); expect(createdRom.game.title).toBe('Test Game'); }); }); describe('GET /api/roms/:id', () => { it('debería retornar un ROM existente', async () => { const rom = await prisma.romFile.create({ data: { path: '/roms/', filename: 'game1.zip', checksum: 'checksum1', size: 1024, format: 'zip', }, }); const res = await app.inject({ method: 'GET', url: `/api/roms/${rom.id}`, }); expect(res.statusCode).toBe(200); const body = res.json(); expect(body.id).toBe(rom.id); expect(body.filename).toBe('game1.zip'); }); it('debería retornar 404 si el ROM no existe', async () => { const res = await app.inject({ method: 'GET', url: '/api/roms/non-existing-id', }); expect(res.statusCode).toBe(404); expect(res.json()).toHaveProperty('error'); }); it('debería incluir el juego asociado al ROM', async () => { const game = await prisma.game.create({ data: { title: 'Zelda', slug: 'zelda', }, }); const rom = await prisma.romFile.create({ data: { path: '/roms/', filename: 'zelda.zip', checksum: 'checksum2', size: 2048, format: 'zip', gameId: game.id, }, }); const res = await app.inject({ method: 'GET', url: `/api/roms/${rom.id}`, }); expect(res.statusCode).toBe(200); const body = res.json(); expect(body.game).toBeDefined(); expect(body.game.title).toBe('Zelda'); }); }); describe('PUT /api/roms/:id/game', () => { it('debería vincular un juego a un ROM existente', async () => { const game = await prisma.game.create({ data: { title: 'Mario', slug: 'mario', }, }); const rom = await prisma.romFile.create({ data: { path: '/roms/', filename: 'mario.zip', checksum: 'checksum3', size: 512, format: 'zip', }, }); const res = await app.inject({ method: 'PUT', url: `/api/roms/${rom.id}/game`, payload: { gameId: game.id, }, }); expect(res.statusCode).toBe(200); const body = res.json(); expect(body.gameId).toBe(game.id); expect(body.game.title).toBe('Mario'); }); it('debería devolver 400 si el gameId es inválido', async () => { const rom = await prisma.romFile.create({ data: { path: '/roms/', filename: 'game.zip', checksum: 'checksum4', size: 1024, format: 'zip', }, }); const res = await app.inject({ method: 'PUT', url: `/api/roms/${rom.id}/game`, payload: { gameId: 'invalid-game-id', }, }); expect(res.statusCode).toBe(400); }); it('debería devolver 404 si el ROM no existe', async () => { const game = await prisma.game.create({ data: { title: 'Test', slug: 'test', }, }); const res = await app.inject({ method: 'PUT', url: '/api/roms/non-existing-id/game', payload: { gameId: game.id, }, }); expect(res.statusCode).toBe(404); }); it('debería devolver 400 si falta gameId', async () => { const rom = await prisma.romFile.create({ data: { path: '/roms/', filename: 'game.zip', checksum: 'checksum5', size: 1024, format: 'zip', }, }); const res = await app.inject({ method: 'PUT', url: `/api/roms/${rom.id}/game`, payload: {}, }); expect(res.statusCode).toBe(400); }); }); describe('DELETE /api/roms/:id', () => { it('debería eliminar un ROM existente', async () => { const rom = await prisma.romFile.create({ data: { path: '/roms/', filename: 'delete-me.zip', checksum: 'checksum6', size: 1024, format: 'zip', }, }); const res = await app.inject({ method: 'DELETE', url: `/api/roms/${rom.id}`, }); expect(res.statusCode).toBe(204); // Verificar que el ROM fue eliminado const deletedRom = await prisma.romFile.findUnique({ where: { id: rom.id }, }); expect(deletedRom).toBeNull(); }); it('debería devolver 404 si el ROM no existe', async () => { const res = await app.inject({ method: 'DELETE', url: '/api/roms/non-existing-id', }); expect(res.statusCode).toBe(404); }); }); }); /** * Metadatos: * Autor: GitHub Copilot * Última actualización: 2026-02-11 */