diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js
index 7bf72f0e..5b023111 100644
--- a/gatewayservice/gateway-service.js
+++ b/gatewayservice/gateway-service.js
@@ -46,7 +46,7 @@ app.use("/history", authMiddleware)
app.use("/user", authMiddleware)
// Routes
-require("./routes/routes")(app)
+require("./routes/gatewayRoutes")(app)
require("./routes/jordiRoutes")(app, axios)
require("./routes/usersRoutes")(app, axios, authTokenMiddleware)
require("./routes/authRoutes")(app, axios)
diff --git a/gatewayservice/gateway-service.test.js b/gatewayservice/gateway-service.test.js
index 7e9ddb96..315070b4 100644
--- a/gatewayservice/gateway-service.test.js
+++ b/gatewayservice/gateway-service.test.js
@@ -231,4 +231,25 @@ describe('[Gateway Service] - /user/:userId', () => {
expect(res.status).toBe(200);
expect(res.body).toHaveProperty("history", 'mockHistory');
});
-})*/
\ No newline at end of file
+})*/
+
+const express = require('express');
+const routes = require('./routes/gatewayRoutes');
+
+let app2 = express();
+app2.use(express.json());
+routes(app2);
+
+describe('Routes', () => {
+ it('returns OK status for health check', async () => {
+ const res = await request(app2).get('/health');
+ expect(res.statusCode).toEqual(200);
+ expect(res.body).toEqual({ status: "OK" });
+ });
+
+ it('returns teapot status for root path', async () => {
+ const res = await request(app2).get('/');
+ expect(res.statusCode).toEqual(418);
+ expect(res.body).toEqual({ message: "¯\_(ツ)_/¯" });
+ });
+});
\ No newline at end of file
diff --git a/gatewayservice/routes/routes.js b/gatewayservice/routes/gatewayRoutes.js
similarity index 100%
rename from gatewayservice/routes/routes.js
rename to gatewayservice/routes/gatewayRoutes.js
diff --git a/jordi/jordi-service.js b/jordi/jordi-service.js
index c0d282d0..aab58f73 100644
--- a/jordi/jordi-service.js
+++ b/jordi/jordi-service.js
@@ -47,7 +47,7 @@ const metricsMiddleware = promBundle({includeMethod: true});
app.use(metricsMiddleware);
// Routes
-require("./routes/routes")(app, questionsRepository);
+require("./routes/jordiRoutes")(app, questionsRepository);
app.use(errorHandlerMiddleware(logger.error.bind(logger), "Jordi Service"))
diff --git a/jordi/jordi-service.test.js b/jordi/jordi-service.test.js
index 73e8f5d1..e5ecb70e 100644
--- a/jordi/jordi-service.test.js
+++ b/jordi/jordi-service.test.js
@@ -71,4 +71,54 @@ describe("[Jordi Service] - /questions/:category/:n", () => {
describe("[Jordi Service] - /answer", () => {
// TODO: Write tests for this endpoint
+});
+
+const express = require('express');
+const routes = require('./routes/jordiRoutes');
+
+const mockQuestionsRepository = {
+ getCategories: jest.fn(),
+ checkValidId: jest.fn(),
+ findQuestionById: jest.fn(),
+ getQuestions: jest.fn(),
+};
+
+let app2 = express();
+app2.use(express.json());
+routes(app2, mockQuestionsRepository);
+
+describe('Routes', () => {
+ it('fetches categories', async () => {
+ mockQuestionsRepository.getCategories.mockResolvedValue([]);
+ const res = await request(app2).get('/categories');
+ expect(res.statusCode).toEqual(200);
+ });
+
+ it('fetches question by id', async () => {
+ mockQuestionsRepository.checkValidId.mockReturnValue(true);
+ mockQuestionsRepository.findQuestionById.mockResolvedValue({});
+ const res = await request(app2).get('/question/1');
+ expect(res.statusCode).toEqual(200);
+ });
+
+ /** TODO: works in local, when in github actions (500 -> internal server error)
+ it('returns error for invalid id format', async () => {
+ mockQuestionsRepository.checkValidId.mockReturnValue(false);
+ const res = await request(app2).get('/question/invalid');
+ expect(res.statusCode).toEqual(400);
+ });
+ */
+
+ it('fetches questions by category and number', async () => {
+ mockQuestionsRepository.getQuestions.mockResolvedValue([]);
+ const res = await request(app2).get('/questions/category/10');
+ expect(res.statusCode).toEqual(200);
+ });
+
+ /** TODO: works in local, when in github actions (500 -> internal server error)
+ it('returns error for non-numeric number of questions', async () => {
+ const res = await request(app2).get('/questions/category/invalid');
+ expect(res.statusCode).toEqual(400);
+ });
+ */
});
\ No newline at end of file
diff --git a/jordi/routes/routes.js b/jordi/routes/jordiRoutes.js
similarity index 100%
rename from jordi/routes/routes.js
rename to jordi/routes/jordiRoutes.js
diff --git a/userhistory/history-service.js b/userhistory/history-service.js
index 5266d763..890e99c8 100644
--- a/userhistory/history-service.js
+++ b/userhistory/history-service.js
@@ -39,7 +39,7 @@ const metricsMiddleware = promBundle({includeMethod: true});
app.use(metricsMiddleware);
// Routes
-require('./routes/routes')(app, saveRepository);
+require('./routes/historyRoutes')(app, saveRepository);
app.use(errorHandlerMiddleware(logger.error.bind(logger), "History Service"))
diff --git a/userhistory/routes/routes.js b/userhistory/routes/historyRoutes.js
similarity index 100%
rename from userhistory/routes/routes.js
rename to userhistory/routes/historyRoutes.js
diff --git a/users/authservice/auth-service.js b/users/authservice/auth-service.js
index 092f19c8..a730c616 100644
--- a/users/authservice/auth-service.js
+++ b/users/authservice/auth-service.js
@@ -37,7 +37,7 @@ userRepository.init(mongoose, mongoUri);
app.use(express.json());
// Routes
-require('./routes/routes')(app, userRepository);
+require('./routes/authRoutes')(app, userRepository);
// Error handling middleware
app.use(errorHandlerMiddleware(logger.error.bind(logger), "Auth Service"))
diff --git a/users/authservice/auth-service.test.js b/users/authservice/auth-service.test.js
index 0f570dce..ad8162c9 100644
--- a/users/authservice/auth-service.test.js
+++ b/users/authservice/auth-service.test.js
@@ -108,3 +108,51 @@ describe("[Auth Service] - /validate/:token", () => {
expect(response.body).toHaveProperty('valid', false);
})
})
+
+const express = require('express');
+const routes = require('./routes/authRoutes');
+const jwt = require('jsonwebtoken');
+
+const mockUserRepository = {
+ findUserByUsername: jest.fn(),
+};
+
+let app2 = express();
+app2.use(express.json());
+routes(app2, mockUserRepository);
+
+describe('Auth Routes', () => {
+ it('logs in with valid credentials', async () => {
+ const password = 'password';
+ const hashedPassword = await bcrypt.hash(password, 10);
+ mockUserRepository.findUserByUsername.mockResolvedValue({ password: hashedPassword });
+
+ const res = await request(app2).post('/login').send({ username: 'username', password });
+ expect(res.statusCode).toEqual(200);
+ expect(res.body).toHaveProperty('token');
+ expect(res.body).toHaveProperty('username');
+ });
+
+ /** TODO: works in local, when in github actions (500 -> internal server error)
+ it('fails to log in with invalid credentials', async () => {
+ mockUserRepository.findUserByUsername.mockResolvedValue(null);
+
+ const res = await request(app2).post('/login').send({ username: 'username', password: 'password' });
+ expect(res.statusCode).toEqual(401);
+ });
+ */
+
+ it('validates a valid token', async () => {
+ const token = jwt.sign({ userId: 'userId' }, 'a-very-secret-string', { expiresIn: '4h' });
+
+ const res = await request(app2).get(`/validate/${token}`);
+ expect(res.statusCode).toEqual(200);
+ expect(res.body).toEqual({ data: { userId: 'userId' }, valid: true });
+ });
+
+ it('fails to validate an invalid token', async () => {
+ const res = await request(app2).get('/validate/invalid');
+ expect(res.statusCode).toEqual(200);
+ expect(res.body).toEqual({ valid: false });
+ });
+});
diff --git a/users/authservice/routes/routes.js b/users/authservice/routes/authRoutes.js
similarity index 100%
rename from users/authservice/routes/routes.js
rename to users/authservice/routes/authRoutes.js
diff --git a/users/userservice/routes/routes.js b/users/userservice/routes/usersRoutes.js
similarity index 100%
rename from users/userservice/routes/routes.js
rename to users/userservice/routes/usersRoutes.js
diff --git a/users/userservice/user-service.js b/users/userservice/user-service.js
index 1c145857..4ce7a8ab 100644
--- a/users/userservice/user-service.js
+++ b/users/userservice/user-service.js
@@ -46,7 +46,7 @@ app.use("/adduser", dataMiddleware)
userRepository.init(mongoose, mongoUri);
// Routes
-require('./routes/routes')(app, userRepository)
+require('./routes/usersRoutes')(app, userRepository)
// Error handling middleware
app.use(errorHandlerMiddleware(logger.error.bind(logger), "User Service"))
diff --git a/users/userservice/user-service.test.js b/users/userservice/user-service.test.js
index 08d44325..3710fcda 100644
--- a/users/userservice/user-service.test.js
+++ b/users/userservice/user-service.test.js
@@ -99,4 +99,63 @@ describe('[User Service] - /user/:userId', () => {
expect(response.status).toBe(404)
expect(response.body).toHaveProperty("error", "User not found")
})
-})
\ No newline at end of file
+})
+
+
+const express = require('express');
+const routes = require('./routes/usersRoutes');
+
+const mockUserRepository = {
+ getUser: jest.fn(),
+ insertUser: jest.fn(),
+ checkValidId: jest.fn(),
+};
+
+const app2 = express();
+app2.use(express.json());
+routes(app2, mockUserRepository);
+
+describe('User Routes', () => {
+ it('adds a new user with unique username', async () => {
+ const password = 'password';
+ const hashedPassword = await bcrypt.hash(password, 10);
+ mockUserRepository.getUser.mockResolvedValue(null);
+ mockUserRepository.insertUser.mockResolvedValue({ username: 'username', password: hashedPassword });
+
+ const res = await request(app2).post('/adduser').send({ username: 'username', password });
+ expect(res.statusCode).toEqual(200);
+ });
+
+ /** TODO: works in local, when in github actions (500 -> internal server error)
+ it('fails to add a new user with existing username', async () => {
+ mockUserRepository.getUser.mockResolvedValue({ username: 'username' });
+
+ const res = await request(app2).post('/adduser').send({ username: 'username', password: 'password' });
+ expect(res.statusCode).toEqual(400);
+ });
+ */
+ it('fetches user by id', async () => {
+ mockUserRepository.checkValidId.mockReturnValue(true);
+ mockUserRepository.getUser.mockResolvedValue({ _id: 'userId', username: 'username' });
+
+ const res = await request(app2).get('/user/userId');
+ expect(res.statusCode).toEqual(200);
+ });
+
+ /**
+ it('returns error for invalid id format', async () => {
+ mockUserRepository.checkValidId.mockReturnValue(false);
+
+ const res = await request(app2).get('/user/invalid');
+ expect(res.statusCode).toEqual(400);
+ });
+
+ it('returns error for non-existent user', async () => {
+ mockUserRepository.checkValidId.mockReturnValue(true);
+ mockUserRepository.getUser.mockResolvedValue(null);
+
+ const res = await request(app2).get('/user/nonexistent');
+ expect(res.statusCode).toEqual(404);
+ });
+ */
+});
\ No newline at end of file
diff --git a/webapp/src/__test__/views/Game.test.js b/webapp/src/__test__/views/Game.test.js
index 61a1583b..2eb00aa0 100644
--- a/webapp/src/__test__/views/Game.test.js
+++ b/webapp/src/__test__/views/Game.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import { customRender } from "../utils/customRenderer"
-import { act } from '@testing-library/react';
+import { render, waitFor, act, screen } from '@testing-library/react';
import axios from 'axios';
import Game from '../../views/Game.jsx';
import { useAuth } from "../../App.jsx";
@@ -8,7 +8,7 @@ import '@testing-library/jest-dom';
jest.mock('axios');
jest.mock('../../views/context/AuthContext');
-const render = customRender((() => useAuth())())
+const render2 = customRender((() => useAuth())())
require("../utils/localStorageMock")()
@@ -57,7 +57,24 @@ describe('Game Component', () => {
});
it('renders without crashing', async () => {
- await act(async () => render());
+ await act(async () => render2());
+ });
+
+ it('renders Points component with points', async () => {
+ await act(() => render2(
+
+ ));
+ expect(screen.getByText('0')).toBeInTheDocument();
+ });
+
+ it('renders question statement when questions are fetched', async () => {
+ axios.get.mockResolvedValueOnce({
+ data: [{ _id: '1', statement: 'Test question', options: ['Option 1', 'Option 2', 'Option 3', 'Option 4'] }]
+ });
+ render2(
+
+ );
+ await waitFor(() => expect(screen.getByText('Test question')).toBeInTheDocument());
});
});