Skip to content

Commit

Permalink
feat(j-s): Deliver Subpoena to Court (#17239)
Browse files Browse the repository at this point in the history
* Delivers subpoena to court

* Updates tests

* Update apps/judicial-system/backend/src/app/modules/subpoena/test/internalSubpoenaController/deliverSubpoenaToPolice.spec.ts

---------

Co-authored-by: unakb <[email protected]>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 19, 2024
1 parent 68f32f0 commit f31b613
Show file tree
Hide file tree
Showing 15 changed files with 334 additions and 52 deletions.
36 changes: 25 additions & 11 deletions apps/judicial-system/backend/src/app/modules/case/case.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1312,18 +1312,29 @@ export class CaseService {
(defendant) => defendant.id === updatedDefendant.id,
)?.subpoenas?.[0]?.id !== updatedDefendant.subpoenas?.[0]?.id,
)
.map((updatedDefendant) => ({
type: MessageType.DELIVERY_TO_POLICE_SUBPOENA,
user,
caseId: theCase.id,
elementId: [
updatedDefendant.id,
updatedDefendant.subpoenas?.[0].id ?? '',
],
}))
.map((updatedDefendant) => [
{
type: MessageType.DELIVERY_TO_POLICE_SUBPOENA,
user,
caseId: theCase.id,
elementId: [
updatedDefendant.id,
updatedDefendant.subpoenas?.[0].id ?? '',
],
},
{
type: MessageType.DELIVERY_TO_COURT_SUBPOENA,
user,
caseId: theCase.id,
elementId: [
updatedDefendant.id,
updatedDefendant.subpoenas?.[0].id ?? '',
],
},
])

if (messages && messages.length > 0) {
return this.messageService.sendMessagesToQueue(messages)
return this.messageService.sendMessagesToQueue(messages.flat())
}
}

Expand Down Expand Up @@ -1426,7 +1437,10 @@ export class CaseService {
await this.addMessagesForCourtCaseConnectionToQueue(updatedCase, user)
}
} else {
if (updatedCase.prosecutorId !== theCase.prosecutorId) {
if (
!isIndictment &&
updatedCase.prosecutorId !== theCase.prosecutorId
) {
// New prosecutor
await this.addMessagesForProsecutorChangeToQueue(updatedCase, user)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ export class InternalCaseController {
)
}

@UseGuards(CaseExistsGuard)
@UseGuards(
CaseExistsGuard,
new CaseTypeGuard([...restrictionCases, ...investigationCases]),
)
@Post(
`case/:caseId/${messageEndpoint[MessageType.DELIVERY_TO_COURT_PROSECUTOR]}`,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -897,12 +897,24 @@ describe('CaseController - Update', () => {
caseId: theCase.id,
elementId: [defendantId1, subpoenaId1],
},
{
type: MessageType.DELIVERY_TO_COURT_SUBPOENA,
user,
caseId: theCase.id,
elementId: [defendantId1, subpoenaId1],
},
{
type: MessageType.DELIVERY_TO_POLICE_SUBPOENA,
user,
caseId: theCase.id,
elementId: [defendantId2, subpoenaId2],
},
{
type: MessageType.DELIVERY_TO_COURT_SUBPOENA,
user,
caseId: theCase.id,
elementId: [defendantId2, subpoenaId2],
},
])
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { CanActivate } from '@nestjs/common'
import {
investigationCases,
restrictionCases,
} from '@island.is/judicial-system/types'

import { CaseExistsGuard } from '../../guards/caseExists.guard'
import { CaseTypeGuard } from '../../guards/caseType.guard'
import { InternalCaseController } from '../../internalCase.controller'

describe('InternalCaseController - Deliver prosecutor to court guards', () => {
Expand All @@ -14,19 +18,12 @@ describe('InternalCaseController - Deliver prosecutor to court guards', () => {
)
})

it('should have one guards', () => {
expect(guards).toHaveLength(1)
})

describe('CaseExistsGuard', () => {
let guard: CanActivate

beforeEach(() => {
guard = new guards[0]()
})

it('should have CaseExistsGuard as guard 1', () => {
expect(guard).toBeInstanceOf(CaseExistsGuard)
it('should have the right guard configuration', () => {
expect(guards).toHaveLength(2)
expect(new guards[0]()).toBeInstanceOf(CaseExistsGuard)
expect(guards[1]).toBeInstanceOf(CaseTypeGuard)
expect(guards[1]).toEqual({
allowedCaseTypes: [...restrictionCases, ...investigationCases],
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export enum CourtDocumentFolder {
CASE_DOCUMENTS = 'Gögn málsins',
COURT_DOCUMENTS = 'Dómar, úrskurðir og Þingbók',
APPEAL_DOCUMENTS = 'Kæra til Landsréttar',
SUBPOENA_DOCUMENTS = 'Boðanir',
}

export type Subtype = Exclude<CaseType, CaseType.INDICTMENT> | IndictmentSubtype
Expand Down Expand Up @@ -342,6 +343,7 @@ export class CourtService {

return await this.courtClientService.createCase(courtId, {
caseType: isIndictment ? 'S - Ákærumál' : 'R - Rannsóknarmál',
// TODO: send a list of subtypes when CourtService supports it
subtype: courtSubtype as string,
status: 'Skráð',
receivalDate: formatISO(receivalDate, { representation: 'date' }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class InternalSubpoenaController {
)
@ApiOkResponse({
type: DeliverResponse,
description: 'Delivers a subpoena to police',
description: 'Delivers a subpoena to the police',
})
deliverSubpoenaToPolice(
@Param('caseId') caseId: string,
Expand All @@ -79,7 +79,7 @@ export class InternalSubpoenaController {
@Body() deliverDto: DeliverDto,
): Promise<DeliverResponse> {
this.logger.debug(
`Delivering subpoena ${subpoenaId} to police for defendant ${defendantId} of case ${caseId}`,
`Delivering subpoena ${subpoenaId} pdf to police for defendant ${defendantId} of case ${caseId}`,
)

return this.subpoenaService.deliverSubpoenaToPolice(
Expand All @@ -89,4 +89,40 @@ export class InternalSubpoenaController {
deliverDto.user,
)
}

@UseGuards(
CaseExistsGuard,
new CaseTypeGuard(indictmentCases),
DefendantExistsGuard,
SubpoenaExistsGuard,
)
@Post(
`case/:caseId/${
messageEndpoint[MessageType.DELIVERY_TO_COURT_SUBPOENA]
}/:defendantId/:subpoenaId`,
)
@ApiOkResponse({
type: DeliverResponse,
description: 'Delivers a subpoena to the court',
})
deliverSubpoenaToCourt(
@Param('caseId') caseId: string,
@Param('defendantId') defendantId: string,
@Param('subpoenaId') subpoenaId: string,
@CurrentCase() theCase: Case,
@CurrentDefendant() defendant: Defendant,
@CurrentSubpoena() subpoena: Subpoena,
@Body() deliverDto: DeliverDto,
): Promise<DeliverResponse> {
this.logger.debug(
`Delivering subpoena ${subpoenaId} pdf to court for defendant ${defendantId} of case ${caseId}`,
)

return this.subpoenaService.deliverSubpoenaToCourt(
theCase,
defendant,
subpoena,
deliverDto.user,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SequelizeModule } from '@nestjs/sequelize'
import { MessageModule } from '@island.is/judicial-system/message'

import { CaseModule } from '../case/case.module'
import { CourtModule } from '../court/court.module'
import { DefendantModule } from '../defendant/defendant.module'
import { Defendant } from '../defendant/models/defendant.model'
import { EventModule } from '../event/event.module'
Expand All @@ -23,6 +24,7 @@ import { SubpoenaService } from './subpoena.service'
forwardRef(() => MessageModule),
forwardRef(() => EventModule),
forwardRef(() => DefendantModule),
CourtModule,
SequelizeModule.forFeature([Subpoena, Defendant]),
],
controllers: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {

import { Case } from '../case/models/case.model'
import { PdfService } from '../case/pdf.service'
import { CourtDocumentFolder, CourtService } from '../court'
import { DefendantService } from '../defendant/defendant.service'
import { Defendant } from '../defendant/models/defendant.model'
import { EventService } from '../event'
Expand Down Expand Up @@ -93,6 +94,7 @@ export class SubpoenaService {
private readonly fileService: FileService,
private readonly eventService: EventService,
private readonly defendantService: DefendantService,
private readonly courtService: CourtService,
@Inject(LOGGER_PROVIDER) private readonly logger: Logger,
) {}

Expand Down Expand Up @@ -356,6 +358,41 @@ export class SubpoenaService {
}
}

async deliverSubpoenaToCourt(
theCase: Case,
defendant: Defendant,
subpoena: Subpoena,
user: TUser,
): Promise<DeliverResponse> {
return this.pdfService
.getSubpoenaPdf(theCase, defendant, subpoena)
.then(async (pdf) => {
const fileName = `Fyrirkall - ${defendant.name}`

return this.courtService.createDocument(
user,
theCase.id,
theCase.courtId,
theCase.courtCaseNumber,
CourtDocumentFolder.SUBPOENA_DOCUMENTS,
fileName,
`${fileName}.pdf`,
'application/pdf',
pdf,
)
})
.then(() => ({ delivered: true }))
.catch((reason) => {
// Tolerate failure, but log error
this.logger.warn(
`Failed to upload subpoena ${subpoena.id} pdf to court for defendant ${defendant.id} of case ${theCase.id}`,
{ reason },
)

return { delivered: false }
})
}

async getSubpoena(subpoena: Subpoena, user?: TUser): Promise<Subpoena> {
if (!subpoena.subpoenaId) {
// The subpoena has not been delivered to the police
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { MessageService } from '@island.is/judicial-system/message'

import { CaseService, PdfService } from '../../case'
import { CourtService } from '../../court'
import { Defendant, DefendantService } from '../../defendant'
import { EventService } from '../../event'
import { FileService } from '../../file'
Expand All @@ -24,14 +25,15 @@ import { Subpoena } from '../models/subpoena.model'
import { SubpoenaController } from '../subpoena.controller'
import { SubpoenaService } from '../subpoena.service'

jest.mock('@island.is/judicial-system/message')
jest.mock('../../user/user.service')
jest.mock('../../case/case.service')
jest.mock('../../case/pdf.service')
jest.mock('../../police/police.service')
jest.mock('../../file/file.service')
jest.mock('../../event/event.service')
jest.mock('../../defendant/defendant.service')
jest.mock('@island.is/judicial-system/message')
jest.mock('../../court/court.service')

export const createTestingSubpoenaModule = async () => {
const subpoenaModule = await Test.createTestingModule({
Expand All @@ -51,6 +53,7 @@ export const createTestingSubpoenaModule = async () => {
FileService,
EventService,
DefendantService,
CourtService,
{
provide: LOGGER_PROVIDER,
useValue: {
Expand Down Expand Up @@ -94,6 +97,8 @@ export const createTestingSubpoenaModule = async () => {

const fileService = subpoenaModule.get<FileService>(FileService)

const courtService = subpoenaModule.get<CourtService>(CourtService)

const subpoenaModel = await subpoenaModule.resolve<typeof Subpoena>(
getModelToken(Subpoena),
)
Expand All @@ -118,6 +123,7 @@ export const createTestingSubpoenaModule = async () => {
pdfService,
policeService,
fileService,
courtService,
subpoenaModel,
subpoenaService,
subpoenaController,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { indictmentCases } from '@island.is/judicial-system/types'

import { CaseExistsGuard, CaseTypeGuard } from '../../../case'
import { DefendantExistsGuard } from '../../../defendant'
import { SubpoenaExistsGuard } from '../../guards/subpoenaExists.guard'
import { InternalSubpoenaController } from '../../internalSubpoena.controller'

describe('InternalSubpoenaController - Deliver subpoena to court guards', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let guards: any[]

beforeEach(() => {
guards = Reflect.getMetadata(
'__guards__',
InternalSubpoenaController.prototype.deliverSubpoenaToCourt,
)
})

it('should have the right guard configuration', () => {
expect(guards).toHaveLength(4)
expect(new guards[0]()).toBeInstanceOf(CaseExistsGuard)
expect(guards[1]).toBeInstanceOf(CaseTypeGuard)
expect(guards[1]).toEqual({
allowedCaseTypes: indictmentCases,
})
expect(new guards[2]()).toBeInstanceOf(DefendantExistsGuard)
expect(new guards[3]()).toBeInstanceOf(SubpoenaExistsGuard)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { indictmentCases } from '@island.is/judicial-system/types'

import { CaseExistsGuard, CaseTypeGuard } from '../../../case'
import { DefendantExistsGuard } from '../../../defendant'
import { SubpoenaExistsGuard } from '../../guards/subpoenaExists.guard'
import { InternalSubpoenaController } from '../../internalSubpoena.controller'

describe('InternalSubpoenaController - Deliver subpoena to police guards', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let guards: any[]

beforeEach(() => {
guards = Reflect.getMetadata(
'__guards__',
InternalSubpoenaController.prototype.deliverSubpoenaToPolice,
)
})

it('should have the right guard configuration', () => {
expect(guards).toHaveLength(4)
expect(new guards[0]()).toBeInstanceOf(CaseExistsGuard)
expect(guards[1]).toBeInstanceOf(CaseTypeGuard)
expect(guards[1]).toEqual({
allowedCaseTypes: indictmentCases,
})
expect(new guards[2]()).toBeInstanceOf(DefendantExistsGuard)
expect(new guards[3]()).toBeInstanceOf(SubpoenaExistsGuard)
})
})
Loading

0 comments on commit f31b613

Please sign in to comment.