From bf578873695109868bfb77dbe8ae718dda7ca24b Mon Sep 17 00:00:00 2001 From: Danny Prikazsky Date: Mon, 24 Mar 2025 17:40:22 -0700 Subject: [PATCH 1/4] Create unit tests for users.router.js and move integration tests --- backend/routers/users.router.test.js | 316 ++++++++++--------------- backend/test/users.integration.test.js | 199 ++++++++++++++++ 2 files changed, 321 insertions(+), 194 deletions(-) create mode 100644 backend/test/users.integration.test.js diff --git a/backend/routers/users.router.test.js b/backend/routers/users.router.test.js index 61d91791d..798993043 100644 --- a/backend/routers/users.router.test.js +++ b/backend/routers/users.router.test.js @@ -1,199 +1,127 @@ -const supertest = require('supertest'); -const app = require('../app'); -const request = supertest(app); - -const { setupDB } = require('../setup-test'); -setupDB('api-users'); - -const backendHeaders = process.env.CUSTOM_REQUEST_HEADER; -describe('CREATE', () => { - test('Create a User with POST to /api/users/', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - done(); - }); -}); - -describe('READ', () => { - test('Get a list of Users with with GET to /api/users/', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - // Get all Users - const res2 = await request.get('/api/users/').set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body[0]; - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); - test('Get a specific User by param with GET to /api/users?email=', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - // Get all Users - const res2 = await request - .get('/api/users?email=newtest@test.com') - .set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body[0]; - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); +// Setup mocks for UserController +jest.mock('../controllers/user.controller'); +const { UserController } = require('../controllers'); - test('Get a specific User by UserId with GET to /api/users/:UserId', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - // Get User by UserId - const res2 = await request - .get(`/api/users/${res.body._id}`) - .set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body; - expect(APIData.email).toBe(submittedData.email); - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); -}); +// Must import usersRouter after setting up mocks for UserController +const usersRouter = require('./users.router'); +const express = require('express'); +const supertest = require('supertest'); -describe('UPDATE', () => { - test('Update a User with PATCH to /api/users/:UserId', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', +// Setup testapp with just usersRouter which calls mocked UserController +const testapp = express(); +testapp.use('/api/users', usersRouter); +const request = supertest(testapp); + +describe('Unit Tests for userRouter', () => { + // Mocked user data + const mockUser = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - const updatedEmail = { - email: 'newtest@test.com', + const mockId = '12345'; + const mockUpdatedEmail = { + email: 'newtest@test.com', }; - // Update User - const resUpdate = await request - .patch(`/api/users/${res.body._id}`) - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(updatedEmail); - expect(resUpdate.status).toBe(200); - // TODO: The updated User call is not returning a repsonse. Uncomment below line and - // run to see. - // expect(resUpdate.name).toMatchObject(submittedData.name); - - const res2 = await request - .get(`/api/users/${res.body._id}`) - .set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body; - expect(APIData.email).toBe(updatedEmail.email); - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); -}); - -describe('DELETE', () => { - test('Delete a specific user by Id with DELETE /api/users/:UserId', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - // Delete User - const res2 = await request - .delete(`/api/users/${res.body._id}`) - .set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body; - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); -}); + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('CREATE', () => { + it('should create a User through the UserController', async (done) => { + UserController.create.mockImplementationOnce( + (req, res) => { return res.status(201).send(mockUser) } + ); + + const response = await request + .post('/api/users/') + .send(mockUser); + expect(UserController.create).toHaveBeenCalled(); + expect(response.status).toBe(201); + expect(response.body).toEqual(mockUser); + + done(); + }); + }); + + describe('READ', () => { + it('should get a list of Users with with GET to /api/users/ through UserController', async (done) => { + UserController.user_list.mockImplementationOnce( + (req, res) => { return res.status(200).send([mockUser]) } + ); + + const response = await request + .get('/api/users/'); + expect(UserController.user_list).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body[0]).toEqual(mockUser); + + done(); + }); + + it('should get a specific User by param with GET to /api/users?email= through UserController', async (done) => { + UserController.user_list.mockImplementationOnce( + (req, res) => { return res.status(200).send([mockUser]) } + ); + + const response = await request + .get('/api/users?email=newtest@test.com'); + expect(UserController.user_list).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body[0]).toEqual(mockUser); + + done(); + }); + + it('should get a specific User by UserId with GET to /api/users/:UserId through UserController', async (done) => { + UserController.user_by_id.mockImplementationOnce( + (req, res) => { return res.status(200).send(mockUser) } + ); + + const response = await request + .get(`/api/users/${mockId}`); + expect(UserController.user_by_id).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body).toEqual(mockUser); + + done(); + }); + }); + + describe('UPDATE', () => { + it('should update a User with PATCH to /api/users/:UserId through UserController', async (done) => { + UserController.update.mockImplementationOnce( + (req, res) => { return res.status(200).send(mockUser) } + ); + + const response = await request + .patch(`/api/users/${mockId}`) + .send(mockUpdatedEmail); + expect(UserController.update).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body).toEqual(mockUser); + + done(); + }); + }); + + describe('DELETE', () => { + it('should delete a specific user by Id with DELETE /api/users/:UserId through UserController', async (done) => { + UserController.delete.mockImplementationOnce( + (req, res) => { return res.status(200).send(mockUser) } + ); + + const response = await request + .delete(`/api/users/${mockId}`) + .send(mockUpdatedEmail); + expect(UserController.delete).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body).toEqual(mockUser); + + done(); + }); + }); +}); \ No newline at end of file diff --git a/backend/test/users.integration.test.js b/backend/test/users.integration.test.js new file mode 100644 index 000000000..61d91791d --- /dev/null +++ b/backend/test/users.integration.test.js @@ -0,0 +1,199 @@ +const supertest = require('supertest'); +const app = require('../app'); +const request = supertest(app); + +const { setupDB } = require('../setup-test'); +setupDB('api-users'); + +const backendHeaders = process.env.CUSTOM_REQUEST_HEADER; +describe('CREATE', () => { + test('Create a User with POST to /api/users/', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + done(); + }); +}); + +describe('READ', () => { + test('Get a list of Users with with GET to /api/users/', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + // Get all Users + const res2 = await request.get('/api/users/').set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body[0]; + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); + test('Get a specific User by param with GET to /api/users?email=', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + // Get all Users + const res2 = await request + .get('/api/users?email=newtest@test.com') + .set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body[0]; + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); + + test('Get a specific User by UserId with GET to /api/users/:UserId', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + // Get User by UserId + const res2 = await request + .get(`/api/users/${res.body._id}`) + .set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body; + expect(APIData.email).toBe(submittedData.email); + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); +}); + +describe('UPDATE', () => { + test('Update a User with PATCH to /api/users/:UserId', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + const updatedEmail = { + email: 'newtest@test.com', + }; + + // Update User + const resUpdate = await request + .patch(`/api/users/${res.body._id}`) + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(updatedEmail); + expect(resUpdate.status).toBe(200); + // TODO: The updated User call is not returning a repsonse. Uncomment below line and + // run to see. + // expect(resUpdate.name).toMatchObject(submittedData.name); + + const res2 = await request + .get(`/api/users/${res.body._id}`) + .set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body; + expect(APIData.email).toBe(updatedEmail.email); + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); +}); + +describe('DELETE', () => { + test('Delete a specific user by Id with DELETE /api/users/:UserId', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + // Delete User + const res2 = await request + .delete(`/api/users/${res.body._id}`) + .set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body; + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); +}); From 50de32269d212423e2cee18930e154909866289f Mon Sep 17 00:00:00 2001 From: Danny Prikazsky Date: Thu, 10 Apr 2025 08:31:51 -0700 Subject: [PATCH 2/4] Fix location of tests after all old tests were moved --- backend/routers/users.router.test.js | 127 ++++++++ backend/test/old-tests/users.router.test.js | 316 ++++++++++++-------- backend/test/users.integration.test.js | 199 ------------ 3 files changed, 321 insertions(+), 321 deletions(-) create mode 100644 backend/routers/users.router.test.js delete mode 100644 backend/test/users.integration.test.js diff --git a/backend/routers/users.router.test.js b/backend/routers/users.router.test.js new file mode 100644 index 000000000..798993043 --- /dev/null +++ b/backend/routers/users.router.test.js @@ -0,0 +1,127 @@ +// Setup mocks for UserController +jest.mock('../controllers/user.controller'); +const { UserController } = require('../controllers'); + +// Must import usersRouter after setting up mocks for UserController +const usersRouter = require('./users.router'); +const express = require('express'); +const supertest = require('supertest'); + +// Setup testapp with just usersRouter which calls mocked UserController +const testapp = express(); +testapp.use('/api/users', usersRouter); +const request = supertest(testapp); + +describe('Unit Tests for userRouter', () => { + // Mocked user data + const mockUser = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + const mockId = '12345'; + const mockUpdatedEmail = { + email: 'newtest@test.com', + }; + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('CREATE', () => { + it('should create a User through the UserController', async (done) => { + UserController.create.mockImplementationOnce( + (req, res) => { return res.status(201).send(mockUser) } + ); + + const response = await request + .post('/api/users/') + .send(mockUser); + expect(UserController.create).toHaveBeenCalled(); + expect(response.status).toBe(201); + expect(response.body).toEqual(mockUser); + + done(); + }); + }); + + describe('READ', () => { + it('should get a list of Users with with GET to /api/users/ through UserController', async (done) => { + UserController.user_list.mockImplementationOnce( + (req, res) => { return res.status(200).send([mockUser]) } + ); + + const response = await request + .get('/api/users/'); + expect(UserController.user_list).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body[0]).toEqual(mockUser); + + done(); + }); + + it('should get a specific User by param with GET to /api/users?email= through UserController', async (done) => { + UserController.user_list.mockImplementationOnce( + (req, res) => { return res.status(200).send([mockUser]) } + ); + + const response = await request + .get('/api/users?email=newtest@test.com'); + expect(UserController.user_list).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body[0]).toEqual(mockUser); + + done(); + }); + + it('should get a specific User by UserId with GET to /api/users/:UserId through UserController', async (done) => { + UserController.user_by_id.mockImplementationOnce( + (req, res) => { return res.status(200).send(mockUser) } + ); + + const response = await request + .get(`/api/users/${mockId}`); + expect(UserController.user_by_id).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body).toEqual(mockUser); + + done(); + }); + }); + + describe('UPDATE', () => { + it('should update a User with PATCH to /api/users/:UserId through UserController', async (done) => { + UserController.update.mockImplementationOnce( + (req, res) => { return res.status(200).send(mockUser) } + ); + + const response = await request + .patch(`/api/users/${mockId}`) + .send(mockUpdatedEmail); + expect(UserController.update).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body).toEqual(mockUser); + + done(); + }); + }); + + describe('DELETE', () => { + it('should delete a specific user by Id with DELETE /api/users/:UserId through UserController', async (done) => { + UserController.delete.mockImplementationOnce( + (req, res) => { return res.status(200).send(mockUser) } + ); + + const response = await request + .delete(`/api/users/${mockId}`) + .send(mockUpdatedEmail); + expect(UserController.delete).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body).toEqual(mockUser); + + done(); + }); + }); +}); \ No newline at end of file diff --git a/backend/test/old-tests/users.router.test.js b/backend/test/old-tests/users.router.test.js index 798993043..61d91791d 100644 --- a/backend/test/old-tests/users.router.test.js +++ b/backend/test/old-tests/users.router.test.js @@ -1,127 +1,199 @@ -// Setup mocks for UserController -jest.mock('../controllers/user.controller'); -const { UserController } = require('../controllers'); - -// Must import usersRouter after setting up mocks for UserController -const usersRouter = require('./users.router'); -const express = require('express'); const supertest = require('supertest'); +const app = require('../app'); +const request = supertest(app); + +const { setupDB } = require('../setup-test'); +setupDB('api-users'); + +const backendHeaders = process.env.CUSTOM_REQUEST_HEADER; +describe('CREATE', () => { + test('Create a User with POST to /api/users/', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + done(); + }); +}); + +describe('READ', () => { + test('Get a list of Users with with GET to /api/users/', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + // Get all Users + const res2 = await request.get('/api/users/').set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body[0]; + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); + test('Get a specific User by param with GET to /api/users?email=', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + // Get all Users + const res2 = await request + .get('/api/users?email=newtest@test.com') + .set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body[0]; + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); -// Setup testapp with just usersRouter which calls mocked UserController -const testapp = express(); -testapp.use('/api/users', usersRouter); -const request = supertest(testapp); - -describe('Unit Tests for userRouter', () => { - // Mocked user data - const mockUser = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', + test('Get a specific User by UserId with GET to /api/users/:UserId', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', }; - const mockId = '12345'; - const mockUpdatedEmail = { - email: 'newtest@test.com', + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + // Get User by UserId + const res2 = await request + .get(`/api/users/${res.body._id}`) + .set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body; + expect(APIData.email).toBe(submittedData.email); + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); +}); + +describe('UPDATE', () => { + test('Update a User with PATCH to /api/users/:UserId', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', }; - afterEach(() => { - jest.clearAllMocks(); - }); - - describe('CREATE', () => { - it('should create a User through the UserController', async (done) => { - UserController.create.mockImplementationOnce( - (req, res) => { return res.status(201).send(mockUser) } - ); - - const response = await request - .post('/api/users/') - .send(mockUser); - expect(UserController.create).toHaveBeenCalled(); - expect(response.status).toBe(201); - expect(response.body).toEqual(mockUser); - - done(); - }); - }); - - describe('READ', () => { - it('should get a list of Users with with GET to /api/users/ through UserController', async (done) => { - UserController.user_list.mockImplementationOnce( - (req, res) => { return res.status(200).send([mockUser]) } - ); - - const response = await request - .get('/api/users/'); - expect(UserController.user_list).toHaveBeenCalled(); - expect(response.status).toBe(200); - expect(response.body[0]).toEqual(mockUser); - - done(); - }); - - it('should get a specific User by param with GET to /api/users?email= through UserController', async (done) => { - UserController.user_list.mockImplementationOnce( - (req, res) => { return res.status(200).send([mockUser]) } - ); - - const response = await request - .get('/api/users?email=newtest@test.com'); - expect(UserController.user_list).toHaveBeenCalled(); - expect(response.status).toBe(200); - expect(response.body[0]).toEqual(mockUser); - - done(); - }); - - it('should get a specific User by UserId with GET to /api/users/:UserId through UserController', async (done) => { - UserController.user_by_id.mockImplementationOnce( - (req, res) => { return res.status(200).send(mockUser) } - ); - - const response = await request - .get(`/api/users/${mockId}`); - expect(UserController.user_by_id).toHaveBeenCalled(); - expect(response.status).toBe(200); - expect(response.body).toEqual(mockUser); - - done(); - }); - }); - - describe('UPDATE', () => { - it('should update a User with PATCH to /api/users/:UserId through UserController', async (done) => { - UserController.update.mockImplementationOnce( - (req, res) => { return res.status(200).send(mockUser) } - ); - - const response = await request - .patch(`/api/users/${mockId}`) - .send(mockUpdatedEmail); - expect(UserController.update).toHaveBeenCalled(); - expect(response.status).toBe(200); - expect(response.body).toEqual(mockUser); - - done(); - }); - }); - - describe('DELETE', () => { - it('should delete a specific user by Id with DELETE /api/users/:UserId through UserController', async (done) => { - UserController.delete.mockImplementationOnce( - (req, res) => { return res.status(200).send(mockUser) } - ); - - const response = await request - .delete(`/api/users/${mockId}`) - .send(mockUpdatedEmail); - expect(UserController.delete).toHaveBeenCalled(); - expect(response.status).toBe(200); - expect(response.body).toEqual(mockUser); - - done(); - }); - }); -}); \ No newline at end of file + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + const updatedEmail = { + email: 'newtest@test.com', + }; + + // Update User + const resUpdate = await request + .patch(`/api/users/${res.body._id}`) + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(updatedEmail); + expect(resUpdate.status).toBe(200); + // TODO: The updated User call is not returning a repsonse. Uncomment below line and + // run to see. + // expect(resUpdate.name).toMatchObject(submittedData.name); + + const res2 = await request + .get(`/api/users/${res.body._id}`) + .set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body; + expect(APIData.email).toBe(updatedEmail.email); + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); +}); + +describe('DELETE', () => { + test('Delete a specific user by Id with DELETE /api/users/:UserId', async (done) => { + // Test Data + const submittedData = { + name: { + firstName: 'test', + lastName: 'user', + }, + email: 'newtest@test.com', + }; + + // Submit a User + const res = await request + .post('/api/users/') + .set('Accept', 'application/json') + .set('x-customrequired-header', backendHeaders) + .send(submittedData); + expect(res.status).toBe(201); + + // Delete User + const res2 = await request + .delete(`/api/users/${res.body._id}`) + .set('x-customrequired-header', backendHeaders); + expect(res2.status).toBe(200); + + const APIData = res2.body; + expect(APIData.name).toMatchObject(submittedData.name); + + done(); + }); +}); diff --git a/backend/test/users.integration.test.js b/backend/test/users.integration.test.js deleted file mode 100644 index 61d91791d..000000000 --- a/backend/test/users.integration.test.js +++ /dev/null @@ -1,199 +0,0 @@ -const supertest = require('supertest'); -const app = require('../app'); -const request = supertest(app); - -const { setupDB } = require('../setup-test'); -setupDB('api-users'); - -const backendHeaders = process.env.CUSTOM_REQUEST_HEADER; -describe('CREATE', () => { - test('Create a User with POST to /api/users/', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - done(); - }); -}); - -describe('READ', () => { - test('Get a list of Users with with GET to /api/users/', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - // Get all Users - const res2 = await request.get('/api/users/').set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body[0]; - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); - test('Get a specific User by param with GET to /api/users?email=', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - // Get all Users - const res2 = await request - .get('/api/users?email=newtest@test.com') - .set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body[0]; - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); - - test('Get a specific User by UserId with GET to /api/users/:UserId', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - // Get User by UserId - const res2 = await request - .get(`/api/users/${res.body._id}`) - .set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body; - expect(APIData.email).toBe(submittedData.email); - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); -}); - -describe('UPDATE', () => { - test('Update a User with PATCH to /api/users/:UserId', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - const updatedEmail = { - email: 'newtest@test.com', - }; - - // Update User - const resUpdate = await request - .patch(`/api/users/${res.body._id}`) - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(updatedEmail); - expect(resUpdate.status).toBe(200); - // TODO: The updated User call is not returning a repsonse. Uncomment below line and - // run to see. - // expect(resUpdate.name).toMatchObject(submittedData.name); - - const res2 = await request - .get(`/api/users/${res.body._id}`) - .set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body; - expect(APIData.email).toBe(updatedEmail.email); - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); -}); - -describe('DELETE', () => { - test('Delete a specific user by Id with DELETE /api/users/:UserId', async (done) => { - // Test Data - const submittedData = { - name: { - firstName: 'test', - lastName: 'user', - }, - email: 'newtest@test.com', - }; - - // Submit a User - const res = await request - .post('/api/users/') - .set('Accept', 'application/json') - .set('x-customrequired-header', backendHeaders) - .send(submittedData); - expect(res.status).toBe(201); - - // Delete User - const res2 = await request - .delete(`/api/users/${res.body._id}`) - .set('x-customrequired-header', backendHeaders); - expect(res2.status).toBe(200); - - const APIData = res2.body; - expect(APIData.name).toMatchObject(submittedData.name); - - done(); - }); -}); From 0c3a14755232e3de36c8912653b86e2eeb21ab61 Mon Sep 17 00:00:00 2001 From: Danny Prikazsky Date: Thu, 10 Apr 2025 09:26:19 -0700 Subject: [PATCH 3/4] Add tests for /admins and /projectManagers + add comments --- backend/routers/users.router.test.js | 75 ++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/backend/routers/users.router.test.js b/backend/routers/users.router.test.js index 798993043..4d017ddd1 100644 --- a/backend/routers/users.router.test.js +++ b/backend/routers/users.router.test.js @@ -32,13 +32,19 @@ describe('Unit Tests for userRouter', () => { describe('CREATE', () => { it('should create a User through the UserController', async (done) => { + //Setup + //Mock the UserController function that this route calls with expected results UserController.create.mockImplementationOnce( (req, res) => { return res.status(201).send(mockUser) } ); + //Functionality + //Post mockUser to CREATE API Endpoint const response = await request .post('/api/users/') .send(mockUser); + + //Test expect(UserController.create).toHaveBeenCalled(); expect(response.status).toBe(201); expect(response.body).toEqual(mockUser); @@ -49,12 +55,18 @@ describe('Unit Tests for userRouter', () => { describe('READ', () => { it('should get a list of Users with with GET to /api/users/ through UserController', async (done) => { + //Setup + //Mock the UserController function that this route calls with expected results UserController.user_list.mockImplementationOnce( (req, res) => { return res.status(200).send([mockUser]) } ); + //Functionality + //Get list of all users from READ API Endpoint const response = await request .get('/api/users/'); + + //Test expect(UserController.user_list).toHaveBeenCalled(); expect(response.status).toBe(200); expect(response.body[0]).toEqual(mockUser); @@ -63,12 +75,18 @@ describe('Unit Tests for userRouter', () => { }); it('should get a specific User by param with GET to /api/users?email= through UserController', async (done) => { + //Setup + //Mock the UserController function that this route calls with expected results UserController.user_list.mockImplementationOnce( (req, res) => { return res.status(200).send([mockUser]) } ); + //Functionality + //Get a user with a specific email using a query param to READ API Endpoint const response = await request .get('/api/users?email=newtest@test.com'); + + //Test expect(UserController.user_list).toHaveBeenCalled(); expect(response.status).toBe(200); expect(response.body[0]).toEqual(mockUser); @@ -76,13 +94,59 @@ describe('Unit Tests for userRouter', () => { done(); }); + it('should get a list of Users with accessLevel of admin or superadmin with GET to /api/users/admins through UserController', async (done) => { + //Setup + //Mock the UserController function that this route calls with expected results + UserController.admin_list.mockImplementationOnce( + (req, res) => { return res.status(200).send([mockUser]) } + ); + + //Functionality + //Get a list of admins and superadmins from READ API Endpoint for admins + const response = await request + .get('/api/users/admins'); + + //Test + expect(UserController.admin_list).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body[0]).toEqual(mockUser); + + done(); + }); + + it('should get a list of Users with the ability to manage projects with GET to /api/users/projectManagers through UserController', async (done) => { + //Setup + //Mock the UserController function that this route calls with expected results + UserController.projectLead_list.mockImplementationOnce( + (req, res) => { return res.status(200).send([mockUser]) } + ); + + //Functionality + //Get a list of project leads and admins from READ API Endpoint for project leads + const response = await request + .get('/api/users/projectManagers'); + + //Test + expect(UserController.projectLead_list).toHaveBeenCalled(); + expect(response.status).toBe(200); + expect(response.body[0]).toEqual(mockUser); + + done(); + }); + it('should get a specific User by UserId with GET to /api/users/:UserId through UserController', async (done) => { + //Setup + //Mock the UserController function that this route calls with expected results UserController.user_by_id.mockImplementationOnce( (req, res) => { return res.status(200).send(mockUser) } ); + //Functionality + //Get a specific user from READ API Endpoint for specific UUIDs const response = await request .get(`/api/users/${mockId}`); + + //Test expect(UserController.user_by_id).toHaveBeenCalled(); expect(response.status).toBe(200); expect(response.body).toEqual(mockUser); @@ -93,13 +157,19 @@ describe('Unit Tests for userRouter', () => { describe('UPDATE', () => { it('should update a User with PATCH to /api/users/:UserId through UserController', async (done) => { + //Setup + //Mock the UserController function that this route calls with expected results UserController.update.mockImplementationOnce( (req, res) => { return res.status(200).send(mockUser) } ); + //Functionality + //Patch a user with a specific id by sending new user data to UPDATE API Endpoint const response = await request .patch(`/api/users/${mockId}`) .send(mockUpdatedEmail); + + //Test expect(UserController.update).toHaveBeenCalled(); expect(response.status).toBe(200); expect(response.body).toEqual(mockUser); @@ -110,13 +180,18 @@ describe('Unit Tests for userRouter', () => { describe('DELETE', () => { it('should delete a specific user by Id with DELETE /api/users/:UserId through UserController', async (done) => { + //Setup + //Mock the UserController function that this route calls with expected results UserController.delete.mockImplementationOnce( (req, res) => { return res.status(200).send(mockUser) } ); + //Delete user with a specific id via a request to DELETE API Endpoint const response = await request .delete(`/api/users/${mockId}`) .send(mockUpdatedEmail); + + //Test expect(UserController.delete).toHaveBeenCalled(); expect(response.status).toBe(200); expect(response.body).toEqual(mockUser); From 00406d090162d2f4e96d2ad6621baa4fcf78fe3f Mon Sep 17 00:00:00 2001 From: Daniel Prikazsky Date: Sun, 25 May 2025 20:48:54 -0700 Subject: [PATCH 4/4] Expect create to be called with mockUser --- backend/routers/users.router.test.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/routers/users.router.test.js b/backend/routers/users.router.test.js index 4d017ddd1..1a09948aa 100644 --- a/backend/routers/users.router.test.js +++ b/backend/routers/users.router.test.js @@ -9,6 +9,8 @@ const supertest = require('supertest'); // Setup testapp with just usersRouter which calls mocked UserController const testapp = express(); +testapp.use(express.json()); +testapp.use(express.urlencoded({ extended: false })); testapp.use('/api/users', usersRouter); const request = supertest(testapp); @@ -45,7 +47,11 @@ describe('Unit Tests for userRouter', () => { .send(mockUser); //Test - expect(UserController.create).toHaveBeenCalled(); + expect(UserController.create).toHaveBeenCalledWith( + expect.objectContaining({body: mockUser}), + expect.anything(), // Mock the response object + expect.anything() // Mock the next function + ); expect(response.status).toBe(201); expect(response.body).toEqual(mockUser);