generated from hackforla/.github-hackforla-base-repo-template
- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Creates Test Plan for Running Integration Tests on Server API Endpoints #1493
Merged
+3,692
−1,209
Merged
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
6c8bd33
adds tests for account endpoints
agosmou 9a38856
Merge branch 'develop' of https://github.com/hackforla/tdm-calculator…
agosmou a2c8ee7
pushing WIP branch - not working yet
agosmou 66f1dc6
fixes testcontainers environment and is now functional
agosmou 5b8efa6
creates setup configuration for test database in container
agosmou 34538d8
adds mock for sendgrid and organizes .env
agosmou a9ef7b4
Merge branch 'develop' of https://github.com/hackforla/tdm-calculator…
agosmou 9f5e596
adds api endpoint blackbox tests - logout test is not passing yet
agosmou e0ff2a8
fixes logout test and adds comment
agosmou 1a3fd93
adds functionality to start and close server for each test suite
agosmou d0dc0b7
working test suite
agosmou 4435b4f
adds notes to readME and comments in jest setup
agosmou 7922153
organizes jest config in codebase
agosmou 2cbd941
removes bloat comments in code
agosmou 57d551f
renames jest setup directory and files
agosmou 60b6425
refactors jest test environment setup
agosmou 07abca5
refactors to restore original code with standard env variables
agosmou f74e5bf
edits the example env file
agosmou 0b02b6b
refactors to provide server setup and teardown to use on api endpoint…
agosmou 347f539
refactors host port on container setup to use environment variable
agosmou fb3fcc2
adds github action to include tests on CI pipeline
agosmou f751ff3
adjust test file naming conventions and minor edits to setup files
agosmou d4b9bef
organizes files into folders for maintainability
agosmou 2a82ee5
refactors for maintainability and readability
agosmou e14cf90
refactors tests
agosmou 3407be0
minor refactors and linting
agosmou 9febb94
linting
agosmou d45e2e4
resolving merge conflict
agosmou d315c4e
Merge branch 'develop' of https://github.com/hackforla/tdm-calculator…
agosmou 0b39c02
resolves merge conflict
agosmou 0425165
fixes lerna issues on branch
agosmou File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
adds api endpoint blackbox tests - logout test is not passing yet
commit 9f5e596e482493dda09c3c6c23e786ac5cc138a9
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
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 |
---|---|---|
|
@@ -7,7 +7,7 @@ require("dotenv").config(); | |
let originalSendgrid = sgMail.send; | ||
|
||
beforeEach(() => { | ||
// Mock the send function | ||
// Mock the sendgrid mail api function | ||
sgMail.send = jest.fn(async (msg) => { | ||
return {statusCode: 202}; | ||
}); | ||
|
@@ -21,58 +21,203 @@ afterEach(() => { | |
describe("Account Endpoints", () => { | ||
let userId; // id of the registered user - to be deleted by security admin | ||
let adminToken; // jwt for security admin - for protected endpoints | ||
let userToken; // jwt for registered user - for protected endpoints | ||
|
||
// GET "/" Get all accounts (Security Admin only) | ||
|
||
// PUT "/:id/roles" Update roles for an account (Security Admin only) | ||
////////////////////////////// | ||
// user endpoints // | ||
////////////////////////////// | ||
|
||
// // POST "/register" Register a new account | ||
// POST "/register" Register a new account | ||
it("should register a new user", async () => { | ||
const res = await request(app) | ||
.post("/api/accounts/register") | ||
.send({ | ||
firstName: "Jose", | ||
lastName: "Garcia", | ||
email: `'[email protected]'`, | ||
email: '[email protected]', | ||
password: "Password1!!!" | ||
}); | ||
// console.log(res.body); | ||
userId = res.body.newId; | ||
expect(res.statusCode).toEqual(200); | ||
expect(res.body).toHaveProperty("newId"); | ||
userId = res.body.newId; | ||
}); | ||
|
||
// POST "/resendConfirmationEmail" Resend confirmation email | ||
it("should resend a confirmation email", async () => { | ||
const res = await request(app) | ||
.post("/api/accounts/resendConfirmationEmail") | ||
.send({ | ||
email: '[email protected]', | ||
}); | ||
// captures the token from the mocked sendgird function to be used in confirmation test below | ||
const tokenPattern = /\/confirm\/([a-zA-Z0-9\-]+)/; | ||
const emailContent = sgMail.send.mock.calls[0][0].html; | ||
const match = emailContent.match(tokenPattern); | ||
if (match && match[1]) { | ||
capturedToken = match[1]; | ||
} | ||
expect(res.statusCode).toEqual(200); | ||
}); | ||
|
||
// POST "/confirmRegister" Confirm registration | ||
it("should confirm a user's registration", async () => { | ||
// uses the captured token from the mocked sendgrid function above | ||
const res = await request(app) | ||
.post("/api/accounts/confirmRegister") | ||
.send({ token: capturedToken }); | ||
expect(res.statusCode).toEqual(200); | ||
expect(res.body).toHaveProperty("success", true); | ||
}); | ||
|
||
// POST "/login" Login as a user | ||
it("should login as a user", async () => { | ||
const res = await request(app) | ||
.post("/api/accounts/login") | ||
.send({ | ||
email: '[email protected]', | ||
password: "Password1!!!" | ||
}); | ||
expect(res.statusCode).toEqual(200); | ||
expect(res.body).toHaveProperty("token"); | ||
userToken = res.body.token; | ||
}); | ||
|
||
// POST "/forgotPassword" Forgot password | ||
it("should send a forgot password email", async () => { | ||
const res = await request(app) | ||
.post("/api/accounts/forgotPassword") | ||
.send({ | ||
email: '[email protected]', | ||
}); | ||
expect(res.statusCode).toEqual(200); | ||
}); | ||
|
||
// POST "/resetPassword" Reset password | ||
it("should reset a password", async () => { | ||
const res = await request(app) | ||
.post("/api/accounts/resetPassword") | ||
.set("Authorization", `Bearer ${userToken}`) | ||
.send({ | ||
password: "NewPassword1!!!", | ||
token: userToken, | ||
}); | ||
expect(res.statusCode).toEqual(200); | ||
}); | ||
|
||
// PUT "/:id/updateaccount" Update account | ||
it("should update a user", async () => { | ||
const res = await request(app) | ||
.put(`/api/accounts/${userId}/updateaccount`) | ||
.set("Authorization", `Bearer ${userToken}`) | ||
.send({ | ||
firstName: "Joseph", | ||
lastName: "Garcia", | ||
email: '[email protected]', | ||
}); | ||
expect(res.statusCode).toEqual(200); | ||
}); | ||
|
||
// // GET "/logout" Logout as a user | ||
// it("should logout the user", async () => { | ||
// // Logout the user | ||
// const logoutRes = await request(app).get("/api/accounts/logout"); | ||
// // Check the response of the logout route | ||
// expect(logoutRes.statusCode).toEqual(200); | ||
// // verify that the user token is no longer valid by calling a protected endpoint | ||
// const updateAccRouteRes = await request(app) | ||
// .put(`/api/accounts/${userId}/updateaccount`) | ||
// .set("Authorization", `Bearer ${userToken}`) | ||
// .send({ | ||
// firstName: "Yusef", | ||
// lastName: "Garcia", | ||
// email: '[email protected]', | ||
// }); | ||
// expect(updateAccRouteRes.statusCode).not.toEqual(200); | ||
// }, 10000); | ||
|
||
// GET "/logout" Logout as a user | ||
it("should logout the user", async () => { | ||
const logoutRes = await request(app).get("/api/accounts/logout"); | ||
expect(logoutRes.statusCode).toEqual(200); | ||
}); | ||
|
||
// POST "/login/:email?" Login | ||
////////////////////////////// | ||
// security admin endpoints // | ||
////////////////////////////// | ||
|
||
// POST "/login/:email?" Login as security admin | ||
it("should login as a security admin", async () => { | ||
const res = await request(app).post("/api/accounts/login").send({ | ||
email: process.env.SECURITY_ADMIN_EMAIL, | ||
password: process.env.SECURITY_ADMIN_PASSWORD | ||
}); | ||
const res = await request(app) | ||
.post("/api/accounts/login") | ||
.send({ | ||
email: process.env.SECURITY_ADMIN_EMAIL, | ||
password: process.env.SECURITY_ADMIN_PASSWORD | ||
}); | ||
expect(res.statusCode).toEqual(200); | ||
expect(res.body).toHaveProperty("token"); | ||
adminToken = res.body.token; | ||
// console.log(adminToken); | ||
}); | ||
|
||
// GET "/logout" Logout | ||
// PUT "/:id/roles" Update roles for an account to give admin priviliges (Security Admin only) | ||
it("should update roles for an account while logged in as security admin", async () => { | ||
const res = await request(app) | ||
.put(`/api/accounts/${userId}/roles`) | ||
.set("Authorization", `Bearer ${adminToken}`) | ||
.send({ | ||
id: userId, | ||
isAdmin: true, | ||
isSecurityAdmin: true, | ||
}); | ||
expect(res.statusCode).toEqual(200) | ||
}); | ||
|
||
// PUT "/:id/roles" Update roles for an account to revoke admin priviliges (Security Admin only) | ||
it("should update roles for an account while logged in as security admin", async () => { | ||
const res = await request(app) | ||
.put(`/api/accounts/${userId}/roles`) | ||
.set("Authorization", `Bearer ${adminToken}`) | ||
.send({ | ||
id: userId, | ||
isAdmin: false, | ||
isSecurityAdmin: false, | ||
}); | ||
expect(res.statusCode).toEqual(200) | ||
}); | ||
|
||
// PUT "/:id/updateaccount" Update account | ||
|
||
// GET "/" Get all accounts (Security Admin only) | ||
it("should get all accounts while logged in as security admin", async () => { | ||
const res = await request(app) | ||
.get("/api/accounts") | ||
.set("Authorization", `Bearer ${adminToken}`); | ||
expect(res.statusCode).toEqual(200); | ||
}); | ||
|
||
// PUT "/:id/archiveaccount" Archive account (Security Admin only) | ||
it("should archive a user", async () => { | ||
const res = await request(app) | ||
.put(`/api/accounts/${userId}/archiveaccount`) | ||
.set("Authorization", `Bearer ${adminToken}`); | ||
expect(res.statusCode).toEqual(200); | ||
}); | ||
|
||
// PUT "/:id/unarchiveaccount" Unarchive account (Security Admin only) | ||
it("should unarchive a user", async () => { | ||
const res = await request(app) | ||
.put(`/api/accounts/${userId}/unarchiveaccount`) | ||
.set("Authorization", `Bearer ${adminToken}`); | ||
expect(res.statusCode).toEqual(200); | ||
}); | ||
|
||
// GET "/archivedaccounts" Get all archived accounts (Security Admin only) | ||
it("should get all archived accounts while logged in as security admin", async () => { | ||
const res = await request(app) | ||
.get("/api/accounts/archivedaccounts") | ||
.set("Authorization", `Bearer ${adminToken}`); | ||
expect(res.statusCode).toEqual(200); | ||
}); | ||
|
||
// DELETE "/:id/deleteaccount" Delete account (Security Admin only) | ||
// DELETE "/:id/deleteaccount" Delete a user's account (Security Admin only) | ||
it("should delete a user", async () => { | ||
const res = await request(app) | ||
.delete(`/api/accounts/${userId}/deleteaccount`) | ||
|
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 |
---|---|---|
|
@@ -9,7 +9,7 @@ | |
"main": "server.js", | ||
"scripts": { | ||
"precommit": "lint-staged", | ||
"test": "jest --passWithNoTests --forceExit", | ||
"test": "jest --runInBand --passWithNoTests --forceExit", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "--runInBand" is added to run the test files sequentially rather than in parallel because they are sharing a database instance. "--forceExit" is a measure to force jest to exit in the case there is a server that is hanging up from being improperly closed. |
||
"heroku-postbuild": "cd client && npm i && npm run build", | ||
"start": "nodemon", | ||
"release-notes": "gren release --override", | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds supertest, jest, and testcontainers. These are popular libraries that are well maintained with stable dependencies.