Skip to content

Commit

Permalink
openapi doc
Browse files Browse the repository at this point in the history
  • Loading branch information
angelalvaigle committed Jan 6, 2025
1 parent 14f7e49 commit f609398
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 54 deletions.
137 changes: 137 additions & 0 deletions gatewayservice/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,17 @@ paths:
__v:
type: integer
description: The version key for the user.
'500':
description: Internal server error.
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: Error information.
example: Internal Server Error
/user:
get:
summary: Get a user by ID
Expand Down Expand Up @@ -290,6 +301,76 @@ paths:
type: string
description: Error message indicating an invalid ID.
example: Invalid ID format.
'500':
description: Internal server error.
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: Error information.
example: Internal Server Error
/questions:
get:
summary: Retrieve all questions
description: Fetches a list of all the questions stored in the system.
responses:
'200':
description: List of questions successfully retrieved
content:
application/json:
schema:
type: array
items:
type: object
properties:
_id:
type: string
description: Unique identifier for the question
type:
type: string
description: Type of the question (e.g., "multiple-choice")
name:
type: string
description: Name or title of the question (optional)
path:
type: string
description: Path or URL associated with the question
hint1:
type: string
description: First hint for the question (optional)
hint2:
type: string
description: Second hint for the question (optional)
right:
type: string
description: Correct answer for the question
wrong1:
type: string
description: First incorrect answer
wrong2:
type: string
description: Second incorrect answer
wrong3:
type: string
description: Third incorrect answer
createdAt:
type: string
format: date-time
description: Date when the question was created
'500':
description: Internal server error.
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: Error information.
example: Internal Server Error
/stats:
get:
summary: Get all game statistics
Expand Down Expand Up @@ -332,3 +413,59 @@ paths:
__v:
type: integer
description: The version key for the statistic record.
'500':
description: Internal server error.
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: Error information.
example: Internal Server Error
/ranking:
get:
summary: Get the top ranking list
description: Retrieve the top ranking list with game results, including points and time for each user.
responses:
'200':
description: A list of top-ranking users and their game results.
content:
application/json:
schema:
type: object
properties:
topRanking:
type: array
description: A list of top-ranking items.
items:
type: object
properties:
gameId:
type: string
description: The unique ID of the game.
example: a4acc100-52d6-46ab-8ce2-b0acccf93c03
userId:
type: string
description: The unique ID of the user who played the game.
example: 6767e65426af19f147062821
totalPoints:
type: integer
description: The total points scored by the user in the game.
example: 2600
totalTime:
type: integer
description: The total time (in seconds) spent by the user on the game.
example: 49
'500':
description: Internal server error.
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: Error information.
example: Internal Server Error
52 changes: 51 additions & 1 deletion statservice/stat-service.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import request from 'supertest';
import { MongoMemoryServer } from 'mongodb-memory-server';
import mongoose from 'mongoose';
import { jest } from '@jest/globals';
import Stat from './stat-model';

// Sobrescribe `authenticateUser` antes de importar el servicio
jest.unstable_mockModule('./middleware/auth-middleware', () => ({
Expand All @@ -21,6 +23,7 @@ beforeAll(async () => {
});

afterAll(async () => {
await Stat.deleteMany({});
app.close();
await mongoServer.stop();
});
Expand Down Expand Up @@ -50,8 +53,55 @@ describe('Stat Service', () => {
expect(response.status).toBe(200);
});

it('should get stats on GET /ranking', async () => {
it('should return the top ranking sorted by points and time', async () => {
const userId1 = new mongoose.Types.ObjectId();
const userId2 = new mongoose.Types.ObjectId();
const stats = [
{
gameId: 'game1',
userId: userId1,
points: 300,
time: 5,
right: true,
questionId: new mongoose.Types.ObjectId(),
},
{
gameId: 'game1',
userId: userId1,
points: 300,
time: 4,
right: true,
questionId: new mongoose.Types.ObjectId(),
},
{
gameId: 'game2',
userId: userId2,
points: 200,
time: 6,
right: false,
questionId: new mongoose.Types.ObjectId(),
},
{
gameId: 'game2',
userId: userId2,
points: 100,
time: 5,
right: false,
questionId: new mongoose.Types.ObjectId(),
},
];

await Stat.insertMany(stats);

const response = await request(app).get('/ranking');

expect(response.status).toBe(200);
expect(response.body.topRanking).toHaveLength(3); // 2 entradas (por gameId y userId)
expect(response.body.topRanking[0].totalPoints).toBeGreaterThan(
response.body.topRanking[1].totalPoints
);
expect(response.body.topRanking[0].totalTime).toBeLessThan(
response.body.topRanking[1].totalTime
);
});
});
1 change: 0 additions & 1 deletion users/userservice/user-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export const getUsersController = async (req, res) => {
};

export const getUserController = async (req, res) => {
console.log('controlador', req.query.userId);
try {
const users = await User.findOne({ _id: req.query.userId }); // Fetch user by id
res.json(users);
Expand Down
85 changes: 33 additions & 52 deletions webapp/src/tests/pages/DashboardLayout.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import DashboardLayout, {
// Mock de componentes secundarios
jest.mock('../../components/SmallSidebar', () => () => <div>SmallSidebar</div>);
jest.mock('../../components/BigSidebar', () => () => <div>BigSidebar</div>);
jest.mock('../../components/Navbar', () => () => <div>Navbar</div>);
//jest.mock('../../components/Navbar', () => () => <div>Navbar</div>);

jest.mock('axios');

Expand Down Expand Up @@ -42,61 +42,42 @@ describe('DashboardLayout Component', () => {

// Espera a que el usuario sea cargado
await waitFor(() =>
expect(screen.getByText(/Navbar/i)).toBeInTheDocument()
expect(screen.getByText(/wiq7\s*quiz\s*game/i)).toBeInTheDocument()
);

expect(screen.getByText('SmallSidebar')).toBeInTheDocument();
expect(screen.getByText('BigSidebar')).toBeInTheDocument();
expect(screen.getByText('Navbar')).toBeInTheDocument();
expect(screen.getByText(/wiq7\s*quiz\s*game/i)).toBeInTheDocument();
});

// it('handles logout and shows success snackbar', async () => {
// axios.get
// .mockResolvedValueOnce({ data: { user: mockUser } }) // Mock para cargar usuario
// .mockResolvedValueOnce({}); // Mock para logout

// const router = createMemoryRouter(routes, { initialEntries: ['/'] });
// render(<RouterProvider router={router} />);

// // Espera a que el usuario sea cargado
// await waitFor(() =>
// expect(screen.getByText(/Navbar/i)).toBeInTheDocument()
// );

// // Simula el clic en el botón de logout
// const logoutButton = screen.getByText('Navbar'); // Simula que el botón está dentro de Navbar
// fireEvent.click(logoutButton);

// // Verifica que se muestre el snackbar de éxito
// await waitFor(
// () => expect(screen.getByText('Logout successful')).toBeInTheDocument(),
// {
// timeout: 3000,
// }
// );
// });

// it('handles errors and shows error snackbar', async () => {
// axios.get.mockResolvedValueOnce({ data: { user: mockUser } });
// axios.get.mockRejectedValueOnce({
// response: { data: { error: 'Logout failed' } },
// });

// const router = createMemoryRouter(routes, { initialEntries: ['/'] });
// render(<RouterProvider router={router} />);

// // Espera a que el usuario sea cargado
// await waitFor(() =>
// expect(screen.getByText(/Navbar/i)).toBeInTheDocument()
// );

// // Simula el clic en el botón de logout
// const logoutButton = screen.getByText('Navbar'); // Simula que el botón está dentro de Navbar
// fireEvent.click(logoutButton);

// // Verifica que se muestre el snackbar de error
// await waitFor(() =>
// expect(screen.getByText(/Error: Logout failed/i)).toBeInTheDocument()
// );
// });
it('logs out and redirects to login', async () => {
axios.get.mockResolvedValueOnce({ data: { user: mockUser } });
axios.get.mockResolvedValueOnce({}); // Simula una respuesta exitosa de logout

const router = createMemoryRouter(routes, { initialEntries: ['/'] });
render(<RouterProvider router={router} />);

await waitFor(() =>
expect(screen.getByText(/wiq7\s*quiz\s*game/i)).toBeInTheDocument()
);

// Verifica que el token está en el localStorage antes del logout
expect(localStorage.getItem('token')).toBe('mockToken');

// Llama a la función de logout
fireEvent.click(screen.getByText(/logout/i));

// Espera que el Snackbar de logout exitoso se muestre
await waitFor(() =>
expect(screen.getByText(/Logout successful/i)).toBeInTheDocument()
);

// Verifica que el token se haya eliminado del localStorage
expect(localStorage.getItem('token')).toBeNull();

// Espera el retraso antes de verificar el redireccionamiento
await waitFor(() => {
expect(router.state.location.pathname).toBe('/login');
});
});
});

0 comments on commit f609398

Please sign in to comment.