feat: implement complete game management with CRUD functionality
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.
This commit is contained in:
82
backend/tests/services/metadataService.spec.ts
Normal file
82
backend/tests/services/metadataService.spec.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
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();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user