generated from CS3219-AY2324S1/course-assessment-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #157 from CS3219-AY2324S1/add-jest-testing
Add integration testing module
- Loading branch information
Showing
15 changed files
with
2,773 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
name: Run tests on PeerPrepTest | ||
|
||
on: | ||
workflow_dispatch: {} | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
defaults: | ||
run: | ||
working-directory: tests | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
with: | ||
ref: master | ||
|
||
- name: Install dependencies | ||
run: yarn install --frozen-lockfile --production=false | ||
|
||
- name: Run all tests | ||
run: yarn test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const { v4: uuid } = require("uuid"); | ||
|
||
const getUser = (isMaintainer) => { | ||
if (isMaintainer) return MAINTAINER_USER; | ||
const userId = uuid(); | ||
return { | ||
name: userId, | ||
email: `${userId}@example.com`, | ||
password: userId | ||
} | ||
} | ||
|
||
const MAINTAINER_USER = { | ||
name: "Maintainer", | ||
email: "[email protected]", | ||
password: "maintainer", | ||
} | ||
|
||
module.exports = { | ||
getUser | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
UNEXPECTED_SUCCESS_MSG: "Expected an error but the request succeeded." | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/** @type { import('jest').Config} */ | ||
const config = { | ||
setupFiles: ["<rootDir>/setEnvVars.js"], | ||
transform: {} | ||
} | ||
|
||
export default config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"type": "module", | ||
"dependencies": { | ||
"axios": "^1.6.0", | ||
"jest": "^29.7.0", | ||
"socket.io-client": "^4.7.2", | ||
"uuid": "^9.0.1" | ||
}, | ||
"scripts": { | ||
"test": "jest", | ||
"test:watch": "yarn test --watch", | ||
"test:dev": "NODE_ENV=dev yarn test" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
const axios = require('axios'); | ||
const { UNEXPECTED_SUCCESS_MSG } = require("../errors.js"); | ||
const { signUpAndLogin, loginAsMaintainer, deleteUserWithToken } = require("../utils.js") | ||
const questionsUrl = `${process.env.REACT_APP_QUESTIONS_SERVICE_HOST}/questions` | ||
|
||
let normalToken; | ||
let maintainerToken; | ||
beforeAll(async () => { | ||
await signUpAndLogin().then((x) => normalToken = x.token); | ||
await loginAsMaintainer().then((x) => maintainerToken = x.token) | ||
}); | ||
afterAll(async () => { | ||
deleteUserWithToken(normalToken); | ||
}); | ||
|
||
describe('Non-maintainer actions', () => { | ||
test('Get one questions', async () => { | ||
const response = await axios.get(`${questionsUrl}/1`, { headers: { Authorization: normalToken }}); | ||
expect(response.status).toBe(200); | ||
expect(response.data).not.toBeNull(); | ||
}); | ||
|
||
test('Add a new question without maintainer permission', async () => { | ||
try { | ||
const header = { | ||
headers: { Authorization: normalToken }, | ||
}; | ||
const params = { | ||
title: "New Question", | ||
complexity: "easy", | ||
categories: [], | ||
description: "testing question", | ||
}; | ||
await axios.post(questionsUrl, params, header); | ||
throw new Error(UNEXPECTED_SUCCESS_MSG); | ||
} catch (error) { | ||
expect(error.response.status).toBe(401); | ||
expect(error.response.data).toBe("not a maintainer!") | ||
} | ||
}); | ||
|
||
test('Edit existing question without maintainer permission', async () => { | ||
try { | ||
const header = { | ||
headers: { Authorization: normalToken }, | ||
}; | ||
const params = { | ||
title: "Edited Question", | ||
complexity: "easy", | ||
categories: [], | ||
description: "Editing question description", | ||
}; | ||
await axios.put(`${questionsUrl}/1`, params, header); | ||
throw new Error(UNEXPECTED_SUCCESS_MSG); | ||
} catch (error) { | ||
expect(error.response.status).toBe(401); | ||
expect(error.response.data).toBe("not a maintainer!") | ||
} | ||
}); | ||
|
||
test('Delete existing question without maintainer permission', async () => { | ||
try { | ||
const header = { | ||
headers: { Authorization: normalToken }, | ||
}; | ||
await axios.delete(`${questionsUrl}/1`, header); | ||
throw new Error(UNEXPECTED_SUCCESS_MSG); | ||
} catch (error) { | ||
expect(error.response.status).toBe(401); | ||
expect(error.response.data).toBe("not a maintainer!") | ||
} | ||
}); | ||
}); | ||
|
||
describe('Maintainer actions', () => { | ||
let questionId; | ||
let questionTitle; | ||
let questionComplexity; | ||
let questionCategories; | ||
let questionDescription; | ||
test('Get one questions', async () => { | ||
const response = await axios.get(`${questionsUrl}/1`, { headers: { Authorization: maintainerToken }}); | ||
expect(response.status).toBe(200); | ||
expect(response.data).not.toBeNull(); | ||
}); | ||
|
||
test('Add a new question', async () => { | ||
const header = { | ||
headers: { Authorization: maintainerToken }, | ||
}; | ||
questionTitle = "Question Added"; | ||
questionComplexity = "easy"; | ||
questionCategories = []; | ||
questionDescription = "Test description" | ||
const params = { | ||
title: questionTitle, | ||
complexity: questionComplexity, | ||
categories: questionCategories, | ||
description: questionDescription, | ||
}; | ||
const response = await axios.post(questionsUrl, params, header); | ||
expect(response.status).toBe(200); | ||
expect(response.data.title).toBe(questionTitle); | ||
expect(response.data.complexity).toBe(questionComplexity); | ||
expect(response.data.categories).toStrictEqual(questionCategories); | ||
expect(response.data.description).toBe(questionDescription); | ||
expect(response.data.question_id).not.toBeNull(); | ||
questionId = response.data.question_id; | ||
}); | ||
|
||
test('Edit existing question', async () => { | ||
const header = { | ||
headers: { Authorization: maintainerToken }, | ||
}; | ||
questionTitle = "Question Edited"; | ||
questionComplexity = "hard"; | ||
questionDescription = "Test description edited" | ||
const params = { | ||
title: questionTitle, | ||
complexity: questionComplexity, | ||
categories: questionCategories, | ||
description: questionDescription, | ||
}; | ||
response = await axios.put(`${questionsUrl}/${questionId}`, params, header); | ||
expect(response.status).toBe(200); | ||
expect(response.data.title).toBe(questionTitle); | ||
expect(response.data.complexity).toBe(questionComplexity); | ||
expect(response.data.categories).toStrictEqual(questionCategories); | ||
expect(response.data.description).toBe(questionDescription); | ||
expect(response.data.question_id).not.toBeNull(); | ||
}); | ||
|
||
test('Delete existing question', async () => { | ||
const header = { | ||
headers: { Authorization: maintainerToken }, | ||
}; | ||
const response = await axios.delete(`${questionsUrl}/${questionId}`, header); | ||
expect(response.status).toBe(200); | ||
expect(response.data.title).toBe(questionTitle); | ||
expect(response.data.complexity).toBe(questionComplexity); | ||
expect(response.data.categories).toStrictEqual(questionCategories); | ||
expect(response.data.description).toBe(questionDescription); | ||
expect(response.data.question_id).not.toBeNull(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const axios = require("axios"); | ||
const { signUpAndLogin, deleteUserWithToken } = require("../utils.js"); | ||
const questionsUrl = `${process.env.REACT_APP_QUESTIONS_SERVICE_HOST}/questions`; | ||
|
||
let token; | ||
beforeAll(() => signUpAndLogin().then((x) => { token = x.token })); | ||
afterAll(() => deleteUserWithToken(token)); | ||
|
||
test('Get all questions', async () => { | ||
const response = await axios.get( questionsUrl, { headers: { Authorization: token }}); | ||
expect(response.status).toBe(200); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
if (process.env.NODE_ENV === 'dev') { | ||
process.env.REACT_APP_QUESTIONS_SERVICE_HOST = "http://localhost:3001"; | ||
process.env.REACT_APP_USERS_SERVICE_HOST = "http://localhost:3002"; | ||
process.env.REACT_APP_MATCHMAKING_SERVICE_HOST = "http://localhost:3003"; | ||
process.env.REACT_APP_COLLABORATION_SERVICE_HOST = "http://localhost:3004"; | ||
} else { | ||
process.env.REACT_APP_QUESTIONS_SERVICE_HOST = "https://peerpreptest.bryanlohxz.com/api/questions-service"; | ||
process.env.REACT_APP_USERS_SERVICE_HOST = "https://peerpreptest.bryanlohxz.com/api/users-service"; | ||
process.env.REACT_APP_MATCHMAKING_SERVICE_HOST = "https://peerpreptest.bryanlohxz.com/api/matchmaking-service"; | ||
process.env.REACT_APP_COLLABORATION_SERVICE_HOST = "https://peerpreptest.bryanlohxz.com/api/collaboration-service"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
const axios = require('axios'); | ||
|
||
const { INVALID_JWT_ERROR_MSG } = require("./errors.js"); | ||
const { signUpAndLogin } = require("../utils.js"); | ||
const profileUrl = `${process.env.REACT_APP_USERS_SERVICE_HOST}/profile`; | ||
|
||
let token; | ||
beforeAll(() => signUpAndLogin().then((x) => token = x.token)); | ||
|
||
test('Delete user profile with unauthorized token', async () => { | ||
try { | ||
const unauthorizedToken = 'invalid-token'; | ||
await axios.delete(profileUrl, { headers: { Authorization: unauthorizedToken }}); | ||
throw new Error(UNEXPECTED_SUCCESS_MSG); | ||
} catch (error) { | ||
expect(error.response.status).toBe(401); | ||
expect(error.response.data).toBe(INVALID_JWT_ERROR_MSG); | ||
} | ||
}); | ||
|
||
test('Delete user profile with a valid token', async () => { | ||
const response = await axios.delete(profileUrl, { headers: { Authorization: token }}); | ||
expect(response.status).toBe(200); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module.exports = { | ||
INCORRECT_PASSWORD_MSG: "The password entered is incorrect.", | ||
INVALID_JWT_ERROR_MSG: "JWT is either missing, invalid or has expired.", | ||
INVALID_REQUEST_BODY_ERROR_MESSAGE: "Please check your request body.", | ||
SERVER_ERROR_MSG: "Sorry, something went wrong with the server.", | ||
USER_NOT_FOUND_MSG: "Sorry, the user cannot be found.", | ||
USER_WITH_SAME_EMAIL_FOUND_MSG: "Another user with this email already exists.", | ||
}; |
Oops, something went wrong.