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

MAP-1625 enabling update of incidentDetails with incidentLocationId #725

Merged
Show file tree
Hide file tree
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
53 changes: 53 additions & 0 deletions server/routes/adhocReportActions/addhocActionController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable no-await-in-loop */
import { Request, Response } from 'express'
import type ReportService from '../../services/reportService'
import { SystemToken } from '../../types/uof'
import NomisMappingService from '../../services/nomisMappingService'
import logger from '../../../log'

export default class AddhocActionController {
constructor(
private readonly reportService: ReportService,
private readonly nomisMappingService: NomisMappingService,
private readonly systemToken: SystemToken
) {}

public updateReport = async (req: Request, res: Response): Promise<void> => {
const { fromReportId, toReportId } = req.params
const fromId = parseInt(fromReportId, 10)
const toId = parseInt(toReportId, 10)

for (let reportId = fromId; reportId <= toId; reportId += 1) {
try {
const report = await this.reportService.getReport(req.user.username, reportId)

const { locationId } = report.form.incidentDetails

if (report.form.incidentDetails.incidentLocationId) {
logger.info(
`Ad-hoc exercise: Report with id ${reportId} already has form_response.incidentDetails.incidentLocationId set`
)
} else if (locationId) {
const token = await this.systemToken(req.user.username)

const { dpsLocationId } =
Copy link
Contributor Author

@GurnankCheema GurnankCheema Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L33 get the new location id from the locations-inside-prison-api that maps to the old nomis location id

await this.nomisMappingService.getDpsLocationDetailsHavingCorrespondingNomisLocationId(token, locationId)

report.form.incidentDetails.incidentLocationId = dpsLocationId
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L36 add the new location id to the incidentDetails part of the report. No other parts of incidentDetails will change


const updatedSection = report.form.incidentDetails

await this.reportService.update(res.locals.user, reportId, 'incidentDetails', updatedSection)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L40 , the update function is existing functionality that is used for editing reports


Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have started all the logs with the word 'Ad-hoc' just to be able to target them more easily

logger.info(
`Ad-hoc exercise: Updated report with id ${reportId} by adding form_response.incidentDetails.incidentLocationId mapped to nomis locationId of ${locationId}`
)
}
} catch (error) {
logger.error(`Ad-hoc exercise: Update of report with id ${reportId} failed.`, error.message)
}
}

res.send(`Reports with id's ${fromId} to ${toId} processed`)
}
}
159 changes: 159 additions & 0 deletions server/routes/adhocReportActions/adhocActionController.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { Request, Response } from 'express'
import { ReportService, NomisMappingService } from '../../services'
import AddhocActionController from './addhocActionController'
import { LocationMapping } from '../../data/nomisMappingClientTypes'
import logger from '../../../log'

jest.mock('../../services/nomisMappingService')
jest.mock('../../services/reportService')
jest.mock('../../../log')

const reportService = new ReportService(null, null, null, null, null, null) as jest.Mocked<ReportService>
const nomisMappingService = new NomisMappingService(null) as jest.Mocked<NomisMappingService>

reportService.getReport = jest.fn()
let req = jest.fn() as unknown as jest.Mocked<Request>
let res = jest.fn() as unknown as jest.Mocked<Response>
res.send = jest.fn()

req = {
params: {
fromReportId: '1',
toReportId: '2',
},
user: {
username: 'user_name',
token: '',
refreshToken: '',
refreshTime: undefined,
},
} as any

res = {
locals: {
user: {
username: 'user_name',
token: '',
refreshToken: '',
refreshTime: undefined,
},
},
send: jest.fn(),
} as any

const systemToken = jest.fn()
systemToken.mockResolvedValue('system-token-1')

const controller = new AddhocActionController(reportService, nomisMappingService, systemToken)

describe('Adhoc actions', () => {
afterEach(() => {
jest.resetAllMocks()
})

describe('updateReport', () => {
it('is successful', async () => {
await controller.updateReport(req, res)
expect(res.send).toHaveBeenCalledWith("Reports with id's 1 to 2 processed")
})

it('calls the report service to get reports correctly', async () => {
await controller.updateReport(req, res)

expect(reportService.getReport).toHaveBeenCalledTimes(2)
expect(reportService.getReport).toHaveBeenCalledWith('user_name', 1)
expect(reportService.getReport).toHaveBeenCalledWith('user_name', 2)
})

it('does not do update if incidentLocationId already exists', async () => {
const report = {
form: {
incidentDetails: {
incidentLocationId: 'some-uuid',
plannedUseOfForce: false,
},
},
}

reportService.getReport.mockResolvedValue(report as any)
await controller.updateReport(req, res)

expect(reportService.update).not.toHaveBeenCalled()

expect(logger.info).toHaveBeenCalledWith(
'Ad-hoc exercise: Report with id 1 already has form_response.incidentDetails.incidentLocationId set'
)
})

it('should call update processes but only for a reports that exist', async () => {
const report = {
form: {
incidentDetails: {
locationId: 123456,
plannedUseOfForce: false,
},
},
}

reportService.getReport.mockResolvedValueOnce(report as any)
reportService.getReport.mockRejectedValueOnce(Error(`Report does not exist: 2`))

nomisMappingService.getDpsLocationDetailsHavingCorrespondingNomisLocationId.mockResolvedValue({
dpsLocationId: 'some-uuid',
} as LocationMapping)

await controller.updateReport(req, res)

expect(reportService.update).toHaveBeenCalledWith(
{ refreshTime: undefined, refreshToken: '', token: '', username: 'user_name' },
1,
'incidentDetails',
{ incidentLocationId: 'some-uuid', locationId: 123456, plannedUseOfForce: false }
)

expect(logger.info).toHaveBeenCalledWith(
'Ad-hoc exercise: Updated report with id 1 by adding form_response.incidentDetails.incidentLocationId mapped to nomis locationId of 123456'
)
expect(logger.error).toHaveBeenLastCalledWith(
'Ad-hoc exercise: Update of report with id 2 failed.',
'Report does not exist: 2'
)
})

it('should catch errors', async () => {
req = {
params: {
fromReportId: '1',
toReportId: '1',
},
user: {
username: 'user_name',
token: '',
refreshToken: '',
refreshTime: undefined,
},
} as any

const report = {
form: {
incidentDetails: {
locationId: 123456,
plannedUseOfForce: false,
},
},
}

reportService.getReport.mockResolvedValue(report as any)

nomisMappingService.getDpsLocationDetailsHavingCorrespondingNomisLocationId.mockResolvedValue({
dpsLocationId: 'some-uuid',
} as LocationMapping)

reportService.update.mockRejectedValue(new Error())

await controller.updateReport(req, res)

expect(logger.error).toHaveBeenLastCalledWith('Ad-hoc exercise: Update of report with id 1 failed.', '')
})
})
})
17 changes: 17 additions & 0 deletions server/routes/adhocReportActions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import express, { Router } from 'express'
import asyncMiddleware from '../../middleware/asyncMiddleware'

import AddhocActionController from './addhocActionController'
import { Services } from '../../services'

export default function adhocReportActionRoutes(services: Services): Router {
const { nomisMappingService, reportService, systemToken } = services

const router = express.Router()

const controller = new AddhocActionController(reportService, nomisMappingService, systemToken)

router.get('/update-location-id/:fromReportId/:toReportId', controller.updateReport)

return router
}
3 changes: 3 additions & 0 deletions server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import flash from 'connect-flash'
import creatingReportsRoutes from './creatingReports'
import maintainingReportsRoutes from './maintainingReports'
import viewingReportsRoutes from './viewingReports'
import adhocReportActionRoutes from './adhocReportActions'

import apiRoutes from './api'
import csrf from '../middleware/csrfMiddleware'

Expand All @@ -22,6 +24,7 @@ export default function Index(authenticationMiddleware: Handler, services: Servi
router.use(creatingReportsRoutes(services))
router.use(maintainingReportsRoutes(services))
router.use(viewingReportsRoutes(services))
router.use(adhocReportActionRoutes(services))

router.use('/api/', apiRoutes(authenticationMiddleware, services))
return router
Expand Down
Loading