Skip to content
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

Refactors Account API Endpoints Tests #1535

Merged
merged 2 commits into from
Nov 25, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 139 additions & 61 deletions server/__tests__/account.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const {
} = require("../_jest-setup_/utils/server-setup");

let server;
let originalSendgrid = sgMail.send;

beforeAll(async () => {
server = await setupServer();
Expand All @@ -16,48 +15,76 @@ afterAll(async () => {
await teardownServer();
});

beforeEach(() => {
sgMail.send = jest.fn(async () => {
return { statusCode: 202 };
});
});

afterEach(() => {
sgMail.send = originalSendgrid;
});

describe("Account API Endpoints", () => {
describe("Account API endpoints for end user accounts", () => {
let originalSendgrid = sgMail.send;
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
let capturedToken; // confirmation token captured from the mocked sendgrid function
let userToken; // jwt for registered user - for protected endpoints

//////////////////////////////
// user endpoints //
//////////////////////////////
beforeAll(async () => {
sgMail.send = jest.fn(async () => {
return { statusCode: 202 };
});

// POST "/register" Register a new account
it("should register a new user", async () => {
const res = await request(server).post("/api/accounts/register").send({
firstName: "Jose",
const registerResponse = await request(server)
.post("/api/accounts/register")
.send({
firstName: "Jose",
lastName: "Garcia",
email: "[email protected]",
password: "Password1!!!"
});
userId = registerResponse.body.newId;

await request(server).post("/api/accounts/register").send({
firstName: "John",
lastName: "Garcia",
email: "josegarcia@test.com",
email: "JohnGarcia@test.com", // this email used in /resendConfirmationEmail test below
password: "Password1!!!"
});
userId = res.body.newId;
expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty("newId");

await request(server).post("/api/accounts/resendConfirmationEmail").send({
email: "[email protected]"
});
// captures the token from the mocked sendgird function to be used in registration confirmation
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];
}

await request(server)
.post("/api/accounts/confirmRegister")
.send({ token: capturedToken });

const loginResponse = await request(server)
.post("/api/accounts/login")
.send({
email: "[email protected]",
password: "Password1!!!"
});
userToken = loginResponse.body.token;
});

// POST "/register" attempt to register a user with invalid email format
it("should not register a new user with an invalid email format", async () => {
afterAll(async () => {
// cleanup state
sgMail.send = originalSendgrid;
userId = undefined;
capturedToken = undefined;
userToken = undefined;
});

// POST "/register" Register a new account
it("should register a new user", async () => {
const res = await request(server).post("/api/accounts/register").send({
firstName: "Jose",
lastName: "Garcia",
email: "josegarcia",
firstName: "Joseph",
lastName: "Smith",
email: "[email protected]",
password: "Password1!!!"
});
expect(res.statusCode).toEqual(400);
expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty("newId");
});

// POST "/register" attempt to register a user with an existing email
Expand All @@ -77,15 +104,8 @@ describe("Account API Endpoints", () => {
const res = await request(server)
.post("/api/accounts/resendConfirmationEmail")
.send({
email: "josegarcia@test.com"
email: "JohnGarcia@test.com"
});
// 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);
});

Expand Down Expand Up @@ -127,7 +147,6 @@ describe("Account API Endpoints", () => {
});
expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty("token");
userToken = res.body.token;
});

// GET "/" Get all accounts attempt as a regular user(Security Admin only)
Expand Down Expand Up @@ -172,17 +191,77 @@ describe("Account API Endpoints", () => {
});
expect(res.statusCode).toEqual(200);
});
});

describe("Account API endpoints for security admin", () => {
let originalSendgrid = sgMail.send;
let newUserId; // id of the registered user - to be deleted by security admin
let archUserId; // id of the archived user - to be unarchived by security admin
let adminToken; // jwt for security admin - for protected endpoints
let capturedToken; // confirmation token captured from the mocked sendgrid function

beforeAll(async () => {
sgMail.send = jest.fn(async () => {
return { statusCode: 202 };
});

// logout endpoint is not implemented properly so this test will fail. Logout is handled by frontend client
// GET "/logout" Logout as a user
// it("should logout the user", async () => {
// const logoutRes = await request(server).get("/api/accounts/logout");
// expect(logoutRes.statusCode).toEqual(200);
// });
// login as security admin
const adminTokenResponse = await request(server)
.post("/api/accounts/login")
.send({
email: process.env.SECURITY_ADMIN_EMAIL,
password: process.env.SECURITY_ADMIN_PASSWORD
});
adminToken = adminTokenResponse.body.token;

//////////////////////////////
// security admin endpoints //
//////////////////////////////
const userIdResponse = await request(server)
.post("/api/accounts/register")
.send({
firstName: "Alex",
lastName: "Johnson",
email: "[email protected]",
password: "Password1!!!"
});
newUserId = userIdResponse.body.newId;

await request(server).post("/api/accounts/resendConfirmationEmail").send({
email: "[email protected]"
});
// captures the token from the mocked sendgird function to be used in registration confirmation
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];
}

await request(server)
.post("/api/accounts/confirmRegister")
.send({ token: capturedToken });

const archiveUserResponse = await request(server)
.post("/api/accounts/register")
.send({
firstName: "Bo",
lastName: "Haase",
email: "[email protected]",
password: "Password1!!!"
});
archUserId = archiveUserResponse.body.newId;

await request(server)
.put(`/api/accounts/${archUserId}/archiveaccount`)
.set("Authorization", `Bearer ${adminToken}`);
});

afterAll(async () => {
// cleanup state
sgMail.send = originalSendgrid;
newUserId = undefined;
adminToken = undefined;
capturedToken = undefined;
archUserId = undefined;
});

// POST "/login/:email?" Login as security admin
it("should login as a security admin", async () => {
Expand All @@ -192,29 +271,28 @@ describe("Account API Endpoints", () => {
});
expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty("token");
adminToken = res.body.token;
});

// 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 () => {
// PUT "/:id/roles" Update roles for an account to give admin priviliges
it("should grant admin role to another user while logged in as security admin", async () => {
const res = await request(server)
.put(`/api/accounts/${userId}/roles`)
.put(`/api/accounts/${newUserId}/roles`)
.set("Authorization", `Bearer ${adminToken}`)
.send({
id: userId,
id: newUserId,
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 () => {
// PUT "/:id/roles" Update roles for an account to revoke admin priviliges
it("should revoke admin role to another user while logged in as security admin", async () => {
const res = await request(server)
.put(`/api/accounts/${userId}/roles`)
.put(`/api/accounts/${newUserId}/roles`)
.set("Authorization", `Bearer ${adminToken}`)
.send({
id: userId,
id: newUserId,
isAdmin: false,
isSecurityAdmin: false
});
Expand All @@ -232,15 +310,15 @@ describe("Account API Endpoints", () => {
// PUT "/:id/archiveaccount" Archive account (Security Admin only)
it("should archive a user", async () => {
const res = await request(server)
.put(`/api/accounts/${userId}/archiveaccount`)
.put(`/api/accounts/${newUserId}/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(server)
.put(`/api/accounts/${userId}/unarchiveaccount`)
.put(`/api/accounts/${archUserId}/unarchiveaccount`)
.set("Authorization", `Bearer ${adminToken}`);
expect(res.statusCode).toEqual(200);
});
Expand All @@ -256,7 +334,7 @@ describe("Account API Endpoints", () => {
// DELETE "/:id/deleteaccount" Delete a user's account (Security Admin only)
it("should delete a user", async () => {
const res = await request(server)
.delete(`/api/accounts/${userId}/deleteaccount`)
.delete(`/api/accounts/${newUserId}/deleteaccount`)
.set("Authorization", `Bearer ${adminToken}`);
expect(res.statusCode).toEqual(200);
});
Expand Down