Backend: - Add RESTful API endpoints for games: GET, POST, PUT, DELETE /api/games - Implement GamesController for handling game operations - Validate game input using Zod - Create comprehensive tests for all endpoints Frontend: - Develop GameForm component for creating and editing games with validation - Create GameCard component for displaying game details - Implement custom hooks (useGames, useCreateGame, useUpdateGame, useDeleteGame) for data fetching and mutations - Build Games page with a responsive table for game management - Add unit tests for GameForm and Games page components Tests: - Ensure all backend and frontend tests pass successfully - Achieve 100% coverage for new features All changes are thoroughly tested and validated.
83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
|
vi.mock('../../src/services/igdbClient', () => ({
|
|
searchGames: vi.fn(),
|
|
getGameById: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('../../src/services/rawgClient', () => ({
|
|
searchGames: vi.fn(),
|
|
getGameById: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('../../src/services/thegamesdbClient', () => ({
|
|
searchGames: vi.fn(),
|
|
getGameById: vi.fn(),
|
|
}));
|
|
|
|
import * as igdb from '../../src/services/igdbClient';
|
|
import * as rawg from '../../src/services/rawgClient';
|
|
import * as tgdb from '../../src/services/thegamesdbClient';
|
|
import { enrichGame } from '../../src/services/metadataService';
|
|
|
|
describe('services/metadataService', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('prioriza IGDB cuando hay resultados', async () => {
|
|
(igdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([
|
|
{
|
|
id: 11,
|
|
name: 'Sonic',
|
|
slug: 'sonic',
|
|
releaseDate: '1991-06-23',
|
|
genres: ['Platform'],
|
|
coverUrl: 'http://img',
|
|
source: 'igdb',
|
|
},
|
|
]);
|
|
|
|
(rawg.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
(tgdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
|
|
const res = await enrichGame({ title: 'Sonic' });
|
|
expect(res).not.toBeNull();
|
|
expect(res?.source).toBe('igdb');
|
|
expect(res?.externalIds.igdb).toBe(11);
|
|
expect(res?.title).toBe('Sonic');
|
|
});
|
|
|
|
it('cae a RAWG cuando IGDB no responde resultados', async () => {
|
|
(igdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
|
|
(rawg.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([
|
|
{
|
|
id: 22,
|
|
name: 'Sonic (rawg)',
|
|
slug: 'sonic-rawg',
|
|
releaseDate: '1991-06-23',
|
|
genres: ['Platform'],
|
|
coverUrl: 'http://img',
|
|
source: 'rawg',
|
|
},
|
|
]);
|
|
|
|
(tgdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
|
|
const res = await enrichGame({ title: 'Sonic' });
|
|
expect(res).not.toBeNull();
|
|
expect(res?.source).toBe('rawg');
|
|
expect(res?.externalIds.rawg).toBe(22);
|
|
});
|
|
|
|
it('retorna null si no hay resultados en ninguna API', async () => {
|
|
(igdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
(rawg.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
(tgdb.searchGames as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([]);
|
|
|
|
const res = await enrichGame({ title: 'Juego inexistente' });
|
|
expect(res).toBeNull();
|
|
});
|
|
});
|