From 3a92ab606d46b18eaeef837caf3a8456c5342b2b Mon Sep 17 00:00:00 2001 From: Daniel Murray Date: Tue, 3 Sep 2024 15:12:10 +0100 Subject: [PATCH 1/5] update additional-requests controller and route naming and endpoint structure --- src/config/index.ts | 4 +-- .../additional-request.controller.ts} | 34 +++++++++---------- src/routes/additional-requests.ts | 18 ---------- src/routes/github/additional-request.ts | 20 +++++++++++ src/routes/index.ts | 4 +-- 5 files changed, 41 insertions(+), 39 deletions(-) rename src/controller/{additional-requests.controller.ts => github/additional-request.controller.ts} (54%) delete mode 100644 src/routes/additional-requests.ts create mode 100644 src/routes/github/additional-request.ts diff --git a/src/config/index.ts b/src/config/index.ts index 3073d58..065f651 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -51,7 +51,7 @@ export const TEAM_MEMBER = 'team-member'; export const REPO = 'repo'; export const COLLABORATOR = 'collaborator'; export const CHECK_YOUR_REQUESTS = 'check-your-requests'; -export const ADDITIONAL_REQUESTS = 'additional-requests'; +export const ADDITIONAL_REQUEST = 'additional-request'; export const ACCESSIBILITY_STATEMENT = 'accessibility-statement'; export const COOKIES = 'cookies'; export const CONTACT_US = 'contact-us'; @@ -68,7 +68,7 @@ export const TEAM_MEMBER_URL = '/team-member'; export const REPO_URL = '/repo'; export const COLLABORATOR_URL = '/collaborator'; export const CHECK_YOUR_REQUESTS_URL = '/check-your-requests'; -export const ADDITIONAL_REQUESTS_URL = '/additional-requests'; +export const ADDITIONAL_REQUEST_URL = '/additional-request'; export const ACCESSIBILITY_STATEMENT_URL = '/accessibility-statement'; export const COOKIES_URL = '/cookies'; export const CONTACT_US_URL = '/contact-us'; diff --git a/src/controller/additional-requests.controller.ts b/src/controller/github/additional-request.controller.ts similarity index 54% rename from src/controller/additional-requests.controller.ts rename to src/controller/github/additional-request.controller.ts index 98d9980..525f752 100644 --- a/src/controller/additional-requests.controller.ts +++ b/src/controller/github/additional-request.controller.ts @@ -7,24 +7,24 @@ import { } from '@co-digital/login'; import { v4 as uuidv4 } from 'uuid'; -import * as config from '../config'; -import { log } from '../utils/logger'; +import * as config from '../../config'; +import { log } from '../../utils/logger'; -import { AdditionalRequests, AdditionalRequestsKey } from '../model/additional-requests.model'; -import { getPreviousPageUrl } from '../utils/getPreviousPageUrl'; +import { AdditionalRequest, AdditionalRequestKey } from '../../model/github/additional-request.model'; +import { getPreviousPageUrl } from '../../utils/getPreviousPageUrl'; export const get = (_req: Request, res: Response) => { - return res.render(config.ADDITIONAL_REQUESTS); + return res.render(config.ADDITIONAL_REQUEST); }; export const post = (req: Request, res: Response, next: NextFunction) => { try { - const additionalRequestsID = uuidv4(); + const additionalRequestID = uuidv4(); const context = req.body.context; - log.info(`Context: ${context}, Additional Requests ID: ${additionalRequestsID}`); + log.info(`Context: ${context}, Additional Request ID: ${additionalRequestID}`); - setApplicationDataKey(req.session, { ...req.body, [config.ID]: additionalRequestsID }, AdditionalRequestsKey); + setApplicationDataKey(req.session, { ...req.body, [config.ID]: additionalRequestID }, AdditionalRequestKey); return res.redirect(config.GITHUB_HOME_URL); } catch (err: any) { @@ -35,12 +35,12 @@ export const post = (req: Request, res: Response, next: NextFunction) => { export const getById = (req: Request, res: Response, next: NextFunction) => { try { - const additionalRequestsID = req.params[config.ID]; - const additionalRequestsData: AdditionalRequests = getApplicationDataByID(req.session, AdditionalRequestsKey, additionalRequestsID); + const additionalRequestID = req.params[config.ID]; + const additionalRequestData: AdditionalRequest = getApplicationDataByID(req.session, AdditionalRequestKey, additionalRequestID); - log.info(`Context: ${additionalRequestsData.context}, Additional Requests ID: ${additionalRequestsID}`); + log.info(`Context: ${additionalRequestData.context}, Additional Request ID: ${additionalRequestID}`); - return res.render(config.ADDITIONAL_REQUESTS, { ...additionalRequestsData, [config.ID]: additionalRequestsID }); + return res.render(config.ADDITIONAL_REQUEST, { ...additionalRequestData, [config.ID]: additionalRequestID }); } catch (err: any) { log.errorRequest(req, err.message); next(err); @@ -50,11 +50,11 @@ export const getById = (req: Request, res: Response, next: NextFunction) => { export const postById = (req: Request, res: Response, next: NextFunction) => { try { const context = req.body.context; - const additionalRequestsID = req.params[config.ID]; + const additionalRequestID = req.params[config.ID]; - log.info(`Context: ${context}, Additional Requests ID: ${additionalRequestsID}`); + log.info(`Context: ${context}, Additional Request ID: ${additionalRequestID}`); - setApplicationDataByID(req.session, { ...req.body, [config.ID]: additionalRequestsID }, AdditionalRequestsKey, additionalRequestsID); + setApplicationDataByID(req.session, { ...req.body, [config.ID]: additionalRequestID }, AdditionalRequestKey, additionalRequestID); return res.redirect(getPreviousPageUrl(req)); } catch (err: any) { @@ -65,9 +65,9 @@ export const postById = (req: Request, res: Response, next: NextFunction) => { export const removeById = (req: Request, res: Response, next: NextFunction) => { try { - log.info(`Additional Requests ID: ${req.params.id}`); + log.info(`Additional Request ID: ${req.params.id}`); - removeApplicationDataByID(req.session, AdditionalRequestsKey, req.params[config.ID]); + removeApplicationDataByID(req.session, AdditionalRequestKey, req.params[config.ID]); return res.redirect(config.GITHUB_HOME_URL); } catch (err: any) { diff --git a/src/routes/additional-requests.ts b/src/routes/additional-requests.ts deleted file mode 100644 index 0df2513..0000000 --- a/src/routes/additional-requests.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Router } from 'express'; - -import { checkValidations } from '../middleware/validation.middleware'; -import { authentication } from '../middleware/authentication.middleware'; -import { additionalRequests as additionalRequestsValidation } from '../validation/additional-requests.validation'; - -import { get, post, getById, removeById, postById } from '../controller/additional-requests.controller'; -import * as config from '../config'; - -const additionalRequestsRouter = Router(); - -additionalRequestsRouter.get(config.ADDITIONAL_REQUESTS_URL, authentication, get); -additionalRequestsRouter.post(config.ADDITIONAL_REQUESTS_URL, authentication, ...additionalRequestsValidation, checkValidations, post); -additionalRequestsRouter.get(config.ADDITIONAL_REQUESTS_URL + config.PARAM_ID, authentication, getById); -additionalRequestsRouter.get(config.ADDITIONAL_REQUESTS_URL + config.REMOVE + config.PARAM_ID, authentication, removeById); -additionalRequestsRouter.post(config.ADDITIONAL_REQUESTS_URL + config.PARAM_ID, authentication, ...additionalRequestsValidation, checkValidations, postById); - -export default additionalRequestsRouter; diff --git a/src/routes/github/additional-request.ts b/src/routes/github/additional-request.ts new file mode 100644 index 0000000..4725e39 --- /dev/null +++ b/src/routes/github/additional-request.ts @@ -0,0 +1,20 @@ +import { Router } from 'express'; + +import { checkValidations } from '../../middleware/validation.middleware'; +import { authentication } from '../../middleware/authentication.middleware'; +import { additionalRequest as additionalRequestValidation } from '../../validation/github/additional-request.validation'; + +import { get, post, getById, removeById, postById } from '../../controller/github/additional-request.controller'; +import * as config from '../../config'; + +const additionalRequestRouter = Router(); + +additionalRequestRouter.get(config.GITHUB_URL + config.CREATE + config.ADDITIONAL_REQUEST_URL, authentication, get); +additionalRequestRouter.post(config.GITHUB_URL + config.CREATE + config.ADDITIONAL_REQUEST_URL, authentication, ...additionalRequestValidation, checkValidations, post); + +additionalRequestRouter.get(config.GITHUB_URL + config.REMOVE + config.ADDITIONAL_REQUEST_URL + config.PARAM_ID, authentication, removeById); + +additionalRequestRouter.get(config.GITHUB_URL + config.UPDATE + config.ADDITIONAL_REQUEST_URL + config.PARAM_ID, authentication, getById); +additionalRequestRouter.post(config.GITHUB_URL + config.UPDATE + config.ADDITIONAL_REQUEST_URL + config.PARAM_ID, authentication, ...additionalRequestValidation, checkValidations, postById); + +export default additionalRequestRouter; diff --git a/src/routes/index.ts b/src/routes/index.ts index 8aa228a..4709f85 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -12,7 +12,7 @@ import teamRouter from './github/team'; import teamMemberRouter from './github/team-member'; import collaboratorRouter from './github/collaborator'; import checkYourRequestsRouter from './check-your-requests'; -import additionalRequestsRouter from './additional-requests'; +import additionalRequestRouter from './github/additional-request'; import accessibilityStatementRouter from './accessibility-statement'; import cookiesRouter from './cookies'; import contactUsRouter from './contact-us'; @@ -33,7 +33,7 @@ router.use(teamRouter); router.use(teamMemberRouter); router.use(collaboratorRouter); router.use(checkYourRequestsRouter); -router.use(additionalRequestsRouter); +router.use(additionalRequestRouter); router.use(accessibilityStatementRouter); router.use(cookiesRouter); router.use(contactUsRouter); From dbc2cbbe745bcab81b27e47354bf6ee9505d267d Mon Sep 17 00:00:00 2001 From: Daniel Murray Date: Tue, 3 Sep 2024 15:12:48 +0100 Subject: [PATCH 2/5] update additional-requests validation and model naming and endpoint structure --- src/model/additional-requests.model.ts | 13 ------------- src/model/application.model.ts | 4 ++-- src/model/github/additional-request.model.ts | 13 +++++++++++++ src/validation/additional-requests.validation.ts | 7 ------- .../github/additional-request.validation.ts | 7 +++++++ 5 files changed, 22 insertions(+), 22 deletions(-) delete mode 100644 src/model/additional-requests.model.ts create mode 100644 src/model/github/additional-request.model.ts delete mode 100644 src/validation/additional-requests.validation.ts create mode 100644 src/validation/github/additional-request.validation.ts diff --git a/src/model/additional-requests.model.ts b/src/model/additional-requests.model.ts deleted file mode 100644 index c5fff6a..0000000 --- a/src/model/additional-requests.model.ts +++ /dev/null @@ -1,13 +0,0 @@ -export const AdditionalRequestsKey = 'additional_requests'; - -export const AdditionalRequestsMappingKeys: (keyof AdditionalRequests)[] = [ - 'id', - 'context', - 'description' -]; - -export interface AdditionalRequests { - id?: string; - context?: string; - description?: string; -} diff --git a/src/model/application.model.ts b/src/model/application.model.ts index b633574..27132a1 100644 --- a/src/model/application.model.ts +++ b/src/model/application.model.ts @@ -2,7 +2,7 @@ import { Member } from './github/member.model'; import { Team } from './github/team.model'; import { Repo } from './github/repo.model'; import { TeamMember } from './github/team-member.model'; -import { AdditionalRequests } from './additional-requests.model'; +import { AdditionalRequest } from './github/additional-request.model'; import { Collaborator } from './github/collaborator.model'; /* @@ -15,6 +15,6 @@ export interface ApplicationData { repos?: Repo[] team_members?: TeamMember[] collaborators?: Collaborator[] - additional_requests?: AdditionalRequests[] + additional_requests?: AdditionalRequest[] } diff --git a/src/model/github/additional-request.model.ts b/src/model/github/additional-request.model.ts new file mode 100644 index 0000000..ea30754 --- /dev/null +++ b/src/model/github/additional-request.model.ts @@ -0,0 +1,13 @@ +export const AdditionalRequestKey = 'additional_requests'; + +export const AdditionalRequestMappingKeys: (keyof AdditionalRequest)[] = [ + 'id', + 'context', + 'description' +]; + +export interface AdditionalRequest { + id?: string; + context?: string; + description?: string; +} diff --git a/src/validation/additional-requests.validation.ts b/src/validation/additional-requests.validation.ts deleted file mode 100644 index 3074229..0000000 --- a/src/validation/additional-requests.validation.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { body } from 'express-validator'; -import { descriptionRequiredValidation } from './fields/description-required.validation'; -import { ErrorMessages } from './error.messages'; - -export const additionalRequests = [ - body('context').notEmpty({ ignore_whitespace: true }).withMessage(ErrorMessages.CONTEXT), ...descriptionRequiredValidation -]; diff --git a/src/validation/github/additional-request.validation.ts b/src/validation/github/additional-request.validation.ts new file mode 100644 index 0000000..74f47e3 --- /dev/null +++ b/src/validation/github/additional-request.validation.ts @@ -0,0 +1,7 @@ +import { body } from 'express-validator'; +import { descriptionRequiredValidation } from '../fields/description-required.validation'; +import { ErrorMessages } from '../error.messages'; + +export const additionalRequest = [ + body('context').notEmpty({ ignore_whitespace: true }).withMessage(ErrorMessages.CONTEXT), ...descriptionRequiredValidation +]; From 843c8143f1ef93299bf428f53e02d8f75cdb84b9 Mon Sep 17 00:00:00 2001 From: Daniel Murray Date: Tue, 3 Sep 2024 15:13:24 +0100 Subject: [PATCH 3/5] update additional-requests view naming and endpoint structure --- ...-requests.html => additional-request.html} | 2 +- src/views/check-your-requests.html | 2 +- src/views/github-home.html | 2 +- ...-requests.html => additional-request.html} | 4 +- src/views/include/list/added.html | 2 +- .../include/list/additional-request.html | 35 +++++++++++++++ .../include/list/additional-requests.html | 35 --------------- .../additional-request.spec.ts} | 43 ++++++++++--------- 8 files changed, 64 insertions(+), 61 deletions(-) rename src/views/{additional-requests.html => additional-request.html} (96%) rename src/views/include/check-your-requests/{additional-requests.html => additional-request.html} (78%) create mode 100644 src/views/include/list/additional-request.html delete mode 100644 src/views/include/list/additional-requests.html rename test/integration/routes/{additional-requests.spec.ts => github/additional-request.spec.ts} (63%) diff --git a/src/views/additional-requests.html b/src/views/additional-request.html similarity index 96% rename from src/views/additional-requests.html rename to src/views/additional-request.html index df223c5..0612dce 100644 --- a/src/views/additional-requests.html +++ b/src/views/additional-request.html @@ -5,7 +5,7 @@ {% endblock %} {% block pageContent %} -

Additional requests

+

Additional request

Make an additional request that is not covered by the other options. For example, removal requests or permission changes. diff --git a/src/views/check-your-requests.html b/src/views/check-your-requests.html index b358b81..4c13696 100644 --- a/src/views/check-your-requests.html +++ b/src/views/check-your-requests.html @@ -34,7 +34,7 @@

Collaborators details

{% endif %} {% if (additional_requests and additional_requests.length > 0) %}

Additional Requests details

- {% include "include/check-your-requests/additional-requests.html" %} + {% include "include/check-your-requests/additional-request.html" %}
{% endif %} diff --git a/src/views/github-home.html b/src/views/github-home.html index b5c0c54..d65bfea 100644 --- a/src/views/github-home.html +++ b/src/views/github-home.html @@ -28,7 +28,7 @@

Additional requests

diff --git a/src/views/include/check-your-requests/additional-requests.html b/src/views/include/check-your-requests/additional-request.html similarity index 78% rename from src/views/include/check-your-requests/additional-requests.html rename to src/views/include/check-your-requests/additional-request.html index 42dc8ba..fc3cc6e 100644 --- a/src/views/include/check-your-requests/additional-requests.html +++ b/src/views/include/check-your-requests/additional-request.html @@ -2,8 +2,8 @@ {% for additional_request in additional_requests %} - {% set contextHref = "/additional-requests/" + additional_request.id + previousPageQueryParam + "#context" %} - {% set descriptionHref = "/additional-requests/" + additional_request.id + previousPageQueryParam + "#description" %} + {% set contextHref = "/github/update/additional-request/" + additional_request.id + previousPageQueryParam + "#context" %} + {% set descriptionHref = "/github/update/additional-request/" + additional_request.id + previousPageQueryParam + "#description" %}
{{ govukSummaryList({ diff --git a/src/views/include/list/added.html b/src/views/include/list/added.html index 85bfbf7..805b166 100644 --- a/src/views/include/list/added.html +++ b/src/views/include/list/added.html @@ -30,5 +30,5 @@

New collaborator requests

{% endif %} {% if (additional_requests and additional_requests.length > 0) %}

Additional requests

- {% include "include/list/additional-requests.html" %} + {% include "include/list/additional-request.html" %} {% endif %} \ No newline at end of file diff --git a/src/views/include/list/additional-request.html b/src/views/include/list/additional-request.html new file mode 100644 index 0000000..45ae706 --- /dev/null +++ b/src/views/include/list/additional-request.html @@ -0,0 +1,35 @@ +{% set additionalRequestSummaryData = [] %} + +{% for additional_request in additional_requests %} + + {% set additionalRequestEditHref = "/github/update/additional-request/" + additional_request.id %} + {% set additionalRequestDeleteHref = "/github/remove/additional-request/" + additional_request.id %} + + {% set additionalRequestSummaryData = (additionalRequestSummaryData.push({ + key: { + text: "Additional request context" + }, + value: { + text: additional_request.context + }, + actions: { + items: [ + { + href: additionalRequestEditHref, + text: "Edit", + visuallyHiddenText: "Additional request context" + }, + { + href: additionalRequestDeleteHref, + text: "Delete", + visuallyHiddenText: "Additional request context" + } + ] + } + }), additionalRequestSummaryData) %} + +{% endfor %} + +{{ govukSummaryList({ + rows: additionalRequestSummaryData +}) }} \ No newline at end of file diff --git a/src/views/include/list/additional-requests.html b/src/views/include/list/additional-requests.html deleted file mode 100644 index 920374b..0000000 --- a/src/views/include/list/additional-requests.html +++ /dev/null @@ -1,35 +0,0 @@ -{% set additionalRequestsSummaryData = [] %} - -{% for additional_request in additional_requests %} - - {% set additionalRequestsEditHref = "/additional-requests/" + additional_request.id %} - {% set additionalRequestsDeleteHref = "/additional-requests/remove/" + additional_request.id %} - - {% set additionalRequestsSummaryData = (additionalRequestsSummaryData.push({ - key: { - text: "Additional request context" - }, - value: { - text: additional_request.context - }, - actions: { - items: [ - { - href: additionalRequestsEditHref, - text: "Edit", - visuallyHiddenText: "Additional requests context" - }, - { - href: additionalRequestsDeleteHref, - text: "Delete", - visuallyHiddenText: "Additional requests context" - } - ] - } - }), additionalRequestsSummaryData) %} - -{% endfor %} - -{{ govukSummaryList({ - rows: additionalRequestsSummaryData -}) }} \ No newline at end of file diff --git a/test/integration/routes/additional-requests.spec.ts b/test/integration/routes/github/additional-request.spec.ts similarity index 63% rename from test/integration/routes/additional-requests.spec.ts rename to test/integration/routes/github/additional-request.spec.ts index 4585fd1..c127964 100644 --- a/test/integration/routes/additional-requests.spec.ts +++ b/test/integration/routes/github/additional-request.spec.ts @@ -1,46 +1,49 @@ -jest.mock('../../../src/utils/logger'); -jest.mock('../../../src/middleware/logger.middleware'); -jest.mock('../../../src/middleware/authentication.middleware'); +jest.mock('../../../../src/utils/logger'); +jest.mock('../../../../src/middleware/logger.middleware'); +jest.mock('../../../../src/middleware/authentication.middleware'); jest.mock('uuid'); import { jest, beforeEach, describe, expect, test } from '@jest/globals'; import { Request, Response, NextFunction } from 'express'; import request from 'supertest'; -import app from '../../../src/app'; -import * as config from '../../../src/config'; -import { logger } from '../../../src/middleware/logger.middleware'; -import { log } from '../../../src/utils/logger'; -import { authentication } from '../../../src/middleware/authentication.middleware'; +import app from '../../../../src/app'; +import * as config from '../../../../src/config'; +import { logger } from '../../../../src/middleware/logger.middleware'; +import { log } from '../../../../src/utils/logger'; +import { authentication } from '../../../../src/middleware/authentication.middleware'; -import { MOCK_GITHUB_HOME_REDIRECT_MESSAGE, MOCK_POST_ADDITIONAL_REQUESTS_RESPONSE, MOCK_GET_ADDITIONAL_REQUESTS_RESPONSE } from '../../mock/text.mock'; -import { MOCK_POST_ADDITIONAL_REQUESTS } from '../../mock/data'; -import { ErrorMessages } from '../../../src/validation/error.messages'; -import { mockID, mockUuidv4 } from '../../mock/session.mock'; +import { MOCK_GITHUB_HOME_REDIRECT_MESSAGE, MOCK_POST_ADDITIONAL_REQUEST_RESPONSE, MOCK_GET_ADDITIONAL_REQUEST_RESPONSE } from '../../../mock/text.mock'; +import { MOCK_POST_ADDITIONAL_REQUEST } from '../../../mock/data'; +import { ErrorMessages } from '../../../../src/validation/error.messages'; +import { mockID, mockUuidv4 } from '../../../mock/session.mock'; const mockedLogger = logger as jest.Mock; mockedLogger.mockImplementation((_req: Request, _res: Response, next: NextFunction) => next()); const mockedAuth = authentication as jest.Mock; mockedAuth.mockImplementation((_req: Request, _res: Response, next: NextFunction) => next()); -describe('additional-requests endpoint integration tests', () => { +describe('additional-request endpoint integration tests', () => { + + const additionalReqeuestEndpoint = config.GITHUB_URL + config.CREATE + config.ADDITIONAL_REQUEST_URL; + beforeEach(() => { jest.clearAllMocks(); }); describe('GET tests', () => { test('renders the additional-requests page', async () => { - const res = await request(app).get(config.ADDITIONAL_REQUESTS_URL); + const res = await request(app).get(additionalReqeuestEndpoint); expect(res.status).toEqual(200); - expect(res.text).toContain(MOCK_GET_ADDITIONAL_REQUESTS_RESPONSE); + expect(res.text).toContain(MOCK_GET_ADDITIONAL_REQUEST_RESPONSE); expect(mockedLogger).toHaveBeenCalledTimes(1); expect(mockedAuth).toHaveBeenCalledTimes(1); }); }); describe('POST tests', () => { test('Should redirect to github-home page after POST request', async () => { - const res = await request(app).post(config.ADDITIONAL_REQUESTS_URL).send(MOCK_POST_ADDITIONAL_REQUESTS); + const res = await request(app).post(additionalReqeuestEndpoint).send(MOCK_POST_ADDITIONAL_REQUEST); expect(res.status).toEqual(302); expect(res.text).toContain(MOCK_GITHUB_HOME_REDIRECT_MESSAGE); @@ -49,7 +52,7 @@ describe('additional-requests endpoint integration tests', () => { }); test('Should render the same page with error messages after POST request', async () => { - const res = await request(app).post(config.ADDITIONAL_REQUESTS_URL).send({ + const res = await request(app).post(additionalReqeuestEndpoint).send({ context: '', description: '' }); @@ -57,19 +60,19 @@ describe('additional-requests endpoint integration tests', () => { expect(res.status).toEqual(200); expect(res.text).toContain(ErrorMessages.CONTEXT); expect(res.text).toContain(ErrorMessages.DESCRIPTION_REQUIRED); - expect(res.text).toContain(MOCK_GET_ADDITIONAL_REQUESTS_RESPONSE); + expect(res.text).toContain(MOCK_GET_ADDITIONAL_REQUEST_RESPONSE); expect(mockedLogger).toHaveBeenCalledTimes(1); expect(mockedAuth).toHaveBeenCalledTimes(1); }); test('Should log the Context on POST request.', async () => { mockUuidv4.mockImplementation(_ => mockID); - const res = await request(app).post(config.ADDITIONAL_REQUESTS_URL).send(MOCK_POST_ADDITIONAL_REQUESTS); + const res = await request(app).post(additionalReqeuestEndpoint).send(MOCK_POST_ADDITIONAL_REQUEST); const mockLog = log.info as jest.Mock; expect(res.text).toContain(MOCK_GITHUB_HOME_REDIRECT_MESSAGE); - expect(mockLog).toBeCalledWith(`${MOCK_POST_ADDITIONAL_REQUESTS_RESPONSE}${mockID}`); + expect(mockLog).toBeCalledWith(`${MOCK_POST_ADDITIONAL_REQUEST_RESPONSE}${mockID}`); expect(mockedLogger).toHaveBeenCalledTimes(1); expect(mockedAuth).toHaveBeenCalledTimes(1); }); From 158f3822a4714b866bf29b106ed498fe994d43a0 Mon Sep 17 00:00:00 2001 From: Daniel Murray Date: Tue, 3 Sep 2024 15:13:56 +0100 Subject: [PATCH 4/5] update additional-requests integration and unit test naming and endpoint structure --- test/mock/data.ts | 2 +- test/mock/text.mock.ts | 6 +- .../additional-requests.controller.spec.ts | 74 +++++++++---------- 3 files changed, 41 insertions(+), 41 deletions(-) rename test/unit/controller/{ => github}/additional-requests.controller.spec.ts (76%) diff --git a/test/mock/data.ts b/test/mock/data.ts index 521a372..e3b654b 100644 --- a/test/mock/data.ts +++ b/test/mock/data.ts @@ -81,7 +81,7 @@ export const MOCK_DYNAMODB_RECORD = { }; export const MOCK_POST_TEAM = { team_name: 'team1', github_handle: 'bob' }; -export const MOCK_POST_ADDITIONAL_REQUESTS = { context: 'member', description: 'description' }; +export const MOCK_POST_ADDITIONAL_REQUEST = { context: 'member', description: 'description' }; export const MOCK_POST_REMOVE_MEMBER = { github_handle: 'example' }; export const MOCK_POST_TEAM_REQUEST = { team_name: 'team1' }; export const MOCK_POST_MEMBER_REQUEST = { github_handle: 'example' }; diff --git a/test/mock/text.mock.ts b/test/mock/text.mock.ts index 51c90b6..377ca6f 100644 --- a/test/mock/text.mock.ts +++ b/test/mock/text.mock.ts @@ -39,9 +39,9 @@ export const MOCK_BY_ID_COLLABORATOR_RESPONSE = 'GitHub handle: example, Collabo // additional-requests mocks -export const MOCK_GET_ADDITIONAL_REQUESTS_RESPONSE = 'Make an additional request that is not covered by the other options. For example, removal requests or permission changes'; -export const MOCK_POST_ADDITIONAL_REQUESTS_RESPONSE = 'Context: member, Additional Requests ID: '; -export const MOCK_BY_ID_ADDITIONAL_REQUESTS_RESPONSE = 'Context: member, Additional Requests ID: '; +export const MOCK_GET_ADDITIONAL_REQUEST_RESPONSE = 'Make an additional request that is not covered by the other options. For example, removal requests or permission changes'; +export const MOCK_POST_ADDITIONAL_REQUEST_RESPONSE = 'Context: member, Additional Request ID: '; +export const MOCK_BY_ID_ADDITIONAL_REQUEST_RESPONSE = 'Context: member, Additional Request ID: '; export const MOCK_CHECK_YOUR_REQUESTS_TITLE = 'Check your requests before sending your application'; diff --git a/test/unit/controller/additional-requests.controller.spec.ts b/test/unit/controller/github/additional-requests.controller.spec.ts similarity index 76% rename from test/unit/controller/additional-requests.controller.spec.ts rename to test/unit/controller/github/additional-requests.controller.spec.ts index cdbb20c..927f533 100644 --- a/test/unit/controller/additional-requests.controller.spec.ts +++ b/test/unit/controller/github/additional-requests.controller.spec.ts @@ -1,19 +1,19 @@ -jest.mock('../../../src/utils/logger'); -jest.mock('../../../src/utils/getPreviousPageUrl'); +jest.mock('../../../../src/utils/logger'); +jest.mock('../../../../src/utils/getPreviousPageUrl'); jest.mock('@co-digital/login'); jest.mock('uuid'); import { describe, expect, afterEach, test, jest } from '@jest/globals'; -import { get, getById, post, postById, removeById } from '../../../src/controller/additional-requests.controller'; -import { AdditionalRequestsKey } from '../../../src/model/additional-requests.model'; -import * as config from '../../../src/config'; +import { get, getById, post, postById, removeById } from '../../../../src/controller/github/additional-request.controller'; +import { AdditionalRequestKey } from '../../../../src/model/github/additional-request.model'; +import * as config from '../../../../src/config'; -import { getPreviousPageUrl } from '../../../src/utils/getPreviousPageUrl'; +import { getPreviousPageUrl } from '../../../../src/utils/getPreviousPageUrl'; -import { MOCK_POST_ADDITIONAL_REQUESTS } from '../../mock/data'; -import { MOCK_POST_ADDITIONAL_REQUESTS_RESPONSE, MOCK_LOG_ERROR_REQUEST, MOCK_BY_ID_ADDITIONAL_REQUESTS_RESPONSE } from '../../mock/text.mock'; -import { mockRequest, mockResponse, mockNext, mockBadRequest } from '../../mock/express.mock'; +import { MOCK_POST_ADDITIONAL_REQUEST } from '../../../mock/data'; +import { MOCK_POST_ADDITIONAL_REQUEST_RESPONSE, MOCK_LOG_ERROR_REQUEST, MOCK_BY_ID_ADDITIONAL_REQUEST_RESPONSE } from '../../../mock/text.mock'; +import { mockRequest, mockResponse, mockNext, mockBadRequest } from '../../../mock/express.mock'; import { mockGetApplicationDataByID, @@ -22,22 +22,22 @@ import { mockSetApplicationDataByID, mockSetApplicationDataKey, mockUuidv4 -} from '../../mock/session.mock'; +} from '../../../mock/session.mock'; import { mockLogInfo, mockLogErrorRequest -} from '../../mock/log.mock'; +} from '../../../mock/log.mock'; const mockGetPreviousPageUrl = getPreviousPageUrl as jest.Mock; -describe('additional-requests controller test suites', () => { +describe('additional-request controller test suites', () => { afterEach(() => { jest.resetAllMocks(); }); - describe('additional-requests GET tests', () => { + describe('additional-request GET tests', () => { test('should render additional-requests page', () => { const res = mockResponse(); @@ -45,36 +45,36 @@ describe('additional-requests controller test suites', () => { get(req, res); - expect(res.render).toHaveBeenCalledWith(config.ADDITIONAL_REQUESTS); + expect(res.render).toHaveBeenCalledWith(config.ADDITIONAL_REQUEST); }); }); - describe('additional-requests POST tests', () => { + describe('additional-request POST tests', () => { test('should redirect to github-home page on POST request', () => { mockUuidv4.mockImplementation(_ => mockID); const res = mockResponse(); - const req = { ...mockRequest(MOCK_POST_ADDITIONAL_REQUESTS), session: {} } as any; + const req = { ...mockRequest(MOCK_POST_ADDITIONAL_REQUEST), session: {} } as any; post(req, res, mockNext); expect(mockSetApplicationDataKey).toHaveBeenCalledWith(req.session, { id: mockID, - ...MOCK_POST_ADDITIONAL_REQUESTS - }, AdditionalRequestsKey); + ...MOCK_POST_ADDITIONAL_REQUEST + }, AdditionalRequestKey); expect(res.redirect).toBeCalledWith(config.GITHUB_HOME_URL); expect(mockNext).not.toHaveBeenCalled(); }); test('should log Context on POST request', () => { const res = mockResponse(); - const req = mockRequest(MOCK_POST_ADDITIONAL_REQUESTS); + const req = mockRequest(MOCK_POST_ADDITIONAL_REQUEST); mockUuidv4.mockImplementationOnce(_ => mockID); post(req, res, mockNext); expect(mockSetApplicationDataKey).toHaveBeenCalledTimes(1); - expect(mockLogInfo).toHaveBeenCalledWith(`${MOCK_POST_ADDITIONAL_REQUESTS_RESPONSE}${mockID}`); + expect(mockLogInfo).toHaveBeenCalledWith(`${MOCK_POST_ADDITIONAL_REQUEST_RESPONSE}${mockID}`); expect(mockNext).not.toHaveBeenCalled(); }); test('should log error request and call next', () => { @@ -97,7 +97,7 @@ describe('additional-requests controller test suites', () => { const res = mockResponse(); const req = { - ...mockRequest(MOCK_POST_ADDITIONAL_REQUESTS), + ...mockRequest(MOCK_POST_ADDITIONAL_REQUEST), session: {}, params: { id: mockID } } as any; @@ -106,25 +106,25 @@ describe('additional-requests controller test suites', () => { expect(mockSetApplicationDataByID).toHaveBeenCalledWith(req.session, { id: mockID, - ...MOCK_POST_ADDITIONAL_REQUESTS - }, AdditionalRequestsKey, mockID); + ...MOCK_POST_ADDITIONAL_REQUEST + }, AdditionalRequestKey, mockID); expect(mockGetPreviousPageUrl).toHaveBeenCalledWith(req); expect(res.redirect).toBeCalledWith(config.CHECK_YOUR_REQUESTS_URL); expect(mockNext).not.toHaveBeenCalled(); }); - test('should log additional-requests details on POST ById request', () => { + test('should log additional-request details on POST ById request', () => { const res = mockResponse(); const req = { - ...mockRequest(MOCK_POST_ADDITIONAL_REQUESTS), + ...mockRequest(MOCK_POST_ADDITIONAL_REQUEST), params: { id: mockID } } as any; postById(req, res, mockNext); expect(mockSetApplicationDataByID).toHaveBeenCalledTimes(1); - expect(mockLogInfo).toHaveBeenCalledWith(`${MOCK_BY_ID_ADDITIONAL_REQUESTS_RESPONSE}${mockID}`); + expect(mockLogInfo).toHaveBeenCalledWith(`${MOCK_BY_ID_ADDITIONAL_REQUEST_RESPONSE}${mockID}`); expect(mockNext).not.toHaveBeenCalled(); }); @@ -140,20 +140,20 @@ describe('additional-requests controller test suites', () => { }); }); - describe('additional-requests GET ById tests', () => { + describe('additional-request GET ById tests', () => { test('should render additional-requests template', () => { const res = mockResponse(); const req = { params: { id: mockID } } as any; - mockGetApplicationDataByID.mockImplementationOnce( _ => MOCK_POST_ADDITIONAL_REQUESTS); + mockGetApplicationDataByID.mockImplementationOnce( _ => MOCK_POST_ADDITIONAL_REQUEST); getById(req, res, mockNext); - expect(mockGetApplicationDataByID).toHaveBeenCalledWith(req.session, AdditionalRequestsKey, mockID); + expect(mockGetApplicationDataByID).toHaveBeenCalledWith(req.session, AdditionalRequestKey, mockID); expect(res.render).toBeCalledWith( - config.ADDITIONAL_REQUESTS, - { ...MOCK_POST_ADDITIONAL_REQUESTS, [config.ID]: mockID } + config.ADDITIONAL_REQUEST, + { ...MOCK_POST_ADDITIONAL_REQUEST, [config.ID]: mockID } ); expect(mockNext).not.toHaveBeenCalled(); }); @@ -163,11 +163,11 @@ describe('additional-requests controller test suites', () => { const req = { params: { id: mockID } } as any; - mockGetApplicationDataByID.mockImplementationOnce( _ => MOCK_POST_ADDITIONAL_REQUESTS); + mockGetApplicationDataByID.mockImplementationOnce( _ => MOCK_POST_ADDITIONAL_REQUEST); getById(req, res, mockNext); expect(mockGetApplicationDataByID).toHaveBeenCalledTimes(1); - expect(mockLogInfo).toHaveBeenCalledWith(`${MOCK_BY_ID_ADDITIONAL_REQUESTS_RESPONSE}${mockID}`); + expect(mockLogInfo).toHaveBeenCalledWith(`${MOCK_BY_ID_ADDITIONAL_REQUEST_RESPONSE}${mockID}`); expect(mockNext).not.toHaveBeenCalled(); }); @@ -183,7 +183,7 @@ describe('additional-requests controller test suites', () => { }); }); - describe('additional-requests REMOVE ById tests', () => { + describe('additional-request REMOVE ById tests', () => { test('should redirect to github-home page', () => { const res = mockResponse(); @@ -191,20 +191,20 @@ describe('additional-requests controller test suites', () => { removeById(req, res, mockNext); - expect(mockRemoveApplicationDataByID).toHaveBeenCalledWith(req.session, AdditionalRequestsKey, mockID); + expect(mockRemoveApplicationDataByID).toHaveBeenCalledWith(req.session, AdditionalRequestKey, mockID); expect(res.redirect).toBeCalledWith(config.GITHUB_HOME_URL); expect(mockNext).not.toHaveBeenCalled(); }); - test('should log additional-requests details on Remove ById request', () => { + test('should log additional-request details on Remove ById request', () => { const res = mockResponse(); const req = { params: { id: mockID } } as any; removeById(req, res, mockNext); expect(mockRemoveApplicationDataByID).toHaveBeenCalledTimes(1); - expect(mockLogInfo).toHaveBeenCalledWith(`Additional Requests ID: ${mockID}`); + expect(mockLogInfo).toHaveBeenCalledWith(`Additional Request ID: ${mockID}`); expect(mockNext).not.toHaveBeenCalled(); }); From 54490f7c73c76645169cf2007f49be2fdc2547dd Mon Sep 17 00:00:00 2001 From: Daniel Murray Date: Tue, 3 Sep 2024 15:14:27 +0100 Subject: [PATCH 5/5] fix vulnerability --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 13f8cec..41c37c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6169,12 +6169,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": {