diff --git a/apps/judicial-system/backend/src/app/formatters/formatters.spec.ts b/apps/judicial-system/backend/src/app/formatters/formatters.spec.ts
index 1e481e244591..3379703684ae 100644
--- a/apps/judicial-system/backend/src/app/formatters/formatters.spec.ts
+++ b/apps/judicial-system/backend/src/app/formatters/formatters.spec.ts
@@ -1666,7 +1666,7 @@ describe('formatDefenderRevokedEmailNotification', () => {
// Assert
expect(res).toBe(
- 'Krafa um gæsluvarðhald sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, kt. 000000-1111.
Dómstóllinn hafði skráð þig sem verjanda í málinu.',
+ 'Krafa um gæsluvarðhald sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, kt. 000000-1111.
Dómstóllinn hafði skráð þig sem verjanda/talsmann í málinu.',
)
})
@@ -1692,7 +1692,7 @@ describe('formatDefenderRevokedEmailNotification', () => {
// Assert
expect(res).toBe(
- 'Krafa um farbann sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, kt. 111100-1111.
Dómstóllinn hafði skráð þig sem verjanda í málinu.',
+ 'Krafa um farbann sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, kt. 111100-1111.
Dómstóllinn hafði skráð þig sem verjanda/talsmann í málinu.',
)
})
@@ -1718,7 +1718,7 @@ describe('formatDefenderRevokedEmailNotification', () => {
// Assert
expect(res).toBe(
- 'Krafa um vistun á viðeigandi stofnun sem taka átti fyrir hjá ótilgreindum dómstóli á ótilgreindum tíma, hefur verið afturkölluð.
Sakborningur: Nafn ekki skráð, kt. ekki skráð.
Dómstóllinn hafði skráð þig sem verjanda í málinu.',
+ 'Krafa um vistun á viðeigandi stofnun sem taka átti fyrir hjá ótilgreindum dómstóli á ótilgreindum tíma, hefur verið afturkölluð.
Sakborningur: Nafn ekki skráð, kt. ekki skráð.
Dómstóllinn hafði skráð þig sem verjanda/talsmann í málinu.',
)
})
@@ -1744,7 +1744,7 @@ describe('formatDefenderRevokedEmailNotification', () => {
// Assert
expect(res).toBe(
- 'Krafa um rannsóknarheimild (rof bankaleyndar) sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, kt. 111100-1111.
Dómstóllinn hafði skráð þig sem verjanda í málinu.',
+ 'Krafa um rannsóknarheimild (rof bankaleyndar) sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, kt. 111100-1111.
Dómstóllinn hafði skráð þig sem verjanda/talsmann í málinu.',
)
})
@@ -1770,33 +1770,7 @@ describe('formatDefenderRevokedEmailNotification', () => {
// Assert
expect(res).toBe(
- 'Krafa um rannsóknarheimild sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, fd. 01.01.2022.
Dómstóllinn hafði skráð þig sem verjanda í málinu.',
- )
- })
-
- test('should format revoked notification for indictments', () => {
- // Arrange
- const type = CaseType.INDICTMENT
- const defendantNationalId = '01.01.2022'
- const defendantName = 'Gaui Glæpon'
- const defendantNoNationalId = true
- const court = 'Héraðsdómur Þingvalla'
- const courtDate = new Date('2021-01-24T08:15')
-
- // Act
- const res = formatDefenderRevokedEmailNotification(
- formatMessage,
- type,
- defendantNationalId,
- defendantName,
- defendantNoNationalId,
- court,
- courtDate,
- )
-
- // Assert
- expect(res).toBe(
- 'Ákæra sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, fd. 01.01.2022.
Dómstóllinn hafði skráð þig sem verjanda í málinu.',
+ 'Krafa um rannsóknarheimild sem taka átti fyrir hjá Héraðsdómi Þingvalla sunnudaginn 24. janúar 2021, kl. 08:15, hefur verið afturkölluð.
Sakborningur: Gaui Glæpon, fd. 01.01.2022.
Dómstóllinn hafði skráð þig sem verjanda/talsmann í málinu.',
)
})
})
diff --git a/apps/judicial-system/backend/src/app/formatters/formatters.ts b/apps/judicial-system/backend/src/app/formatters/formatters.ts
index 7ac613007d41..e1e4d613f0e2 100644
--- a/apps/judicial-system/backend/src/app/formatters/formatters.ts
+++ b/apps/judicial-system/backend/src/app/formatters/formatters.ts
@@ -594,22 +594,17 @@ export const formatDefenderRevokedEmailNotification = (
?.replace(' kl.', ', kl.')
: 'NONE',
})
- const revokedText = isIndictmentCase(type)
- ? formatMessage(cf.revokedIndictment, {
- courtText,
- courtDateText,
- })
- : formatMessage(cf.revoked, {
- courtText,
- courtDateText,
- investigationPrefix:
- type === CaseType.OTHER
- ? 'onlyPrefix'
- : isInvestigationCase(type)
- ? 'withPrefix'
- : 'noPrefix',
- courtTypeName: formatCaseType(type),
- })
+ const revokedText = formatMessage(cf.revoked, {
+ courtText,
+ courtDateText,
+ investigationPrefix:
+ type === CaseType.OTHER
+ ? 'onlyPrefix'
+ : isInvestigationCase(type)
+ ? 'withPrefix'
+ : 'noPrefix',
+ courtTypeName: formatCaseType(type),
+ })
const defendantNationalIdText = defendantNoNationalId
? defendantNationalId || 'NONE'
: formatNationalId(defendantNationalId || 'NONE')
@@ -618,7 +613,7 @@ export const formatDefenderRevokedEmailNotification = (
defendantNationalId: defendantNationalIdText,
defendantNoNationalId: defendantNoNationalId ? 'NONE' : 'SOME',
})
- const defenderAssignedText = formatMessage(cf.defenderAssignedV2)
+ const defenderAssignedText = formatMessage(cf.defenderAssigned)
return formatMessage(cf.body, {
revokedText,
diff --git a/apps/judicial-system/backend/src/app/messages/notifications.ts b/apps/judicial-system/backend/src/app/messages/notifications.ts
index af2339b4fc38..c64652bb07d0 100644
--- a/apps/judicial-system/backend/src/app/messages/notifications.ts
+++ b/apps/judicial-system/backend/src/app/messages/notifications.ts
@@ -529,13 +529,6 @@ export const notifications = {
description:
'Texti í pósti til verjanda/talsmanns sem tilgreinir að krafa sé afturkölluð',
},
- revokedIndictment: {
- id: 'judicial.system.backend:notifications.defender_revoked_email.revoked_indictment',
- defaultMessage:
- 'Ákæra sem taka átti fyrir hjá {courtText} {courtDateText}, hefur verið afturkölluð.',
- description:
- 'Texti í pósti til verjanda/talsmanns sem tilgreinir að ákæra sé afturkölluð',
- },
defendant: {
id: 'judicial.system.backend:notifications.defender_revoked_email.defendant',
defaultMessage:
@@ -543,9 +536,10 @@ export const notifications = {
description:
'Texti í pósti til verjanda/talsmanns sem tilgreinir sakborning',
},
- defenderAssignedV2: {
- id: 'judicial.system.backend:notifications.defender_revoked_email.defender_assigned_v2',
- defaultMessage: 'Dómstóllinn hafði skráð þig sem verjanda í málinu.',
+ defenderAssigned: {
+ id: 'judicial.system.backend:notifications.defender_revoked_email.defender_assigned_v3',
+ defaultMessage:
+ 'Dómstóllinn hafði skráð þig sem verjanda/talsmann í málinu.',
description:
'Texti í pósti til verjanda/talsmanns sem tilgreinir að viðkomandi sé skráður verjandi',
},
@@ -563,11 +557,17 @@ export const notifications = {
description:
'Fyrirsögn í pósti til verjanda/talsmanns þegar krafa er afturkölluð',
},
- indictmentSubject: {
- id: 'judicial.system.backend:notifications.defender_revoked_email.indictment_subject',
- defaultMessage: 'Ákæra afturkölluð',
+ indictmentBody: {
+ id: 'judicial.system.backend:notifications.defender_revoked_email.body_indictment',
+ defaultMessage:
+ 'Dómstóllinn hafði skráð þig sem verjanda í málinu.
{defenderHasAccessToRvg, select, true {Sjá nánar á {linkStart}yfirlitssíðu málsins í Réttarvörslugátt{linkEnd}} other {Þú getur nálgast gögn málsins hjá {courtName} ef þau hafa ekki þegar verið afhent}}.',
description:
- 'Fyrirsögn í pósti til verjanda/talsmanns þegar ákæra er afturkölluð',
+ 'Notaður sem beinagrind á pósti til verjanda þegar ákæra er afturkölluð',
+ },
+ indictmentSubject: {
+ id: 'judicial.system.backend:notifications.defender_revoked_email.indictment_subject_v2',
+ defaultMessage: 'Ákæra afturkölluð í máli {courtCaseNumber}',
+ description: 'Fyrirsögn í pósti til verjanda þegar ákæra er afturkölluð',
},
}),
modified: defineMessages({
@@ -586,9 +586,9 @@ export const notifications = {
'Notaður sem texti í tölvupósti vegna breytingar á lengd gæslu/farbanns/vistunar þar sem ekki var úrskurðað í einangrun.',
},
htmlDefender: {
- id: 'judicial.system.backend:notifications.modified.html_defender',
+ id: 'judicial.system.backend:notifications.modified.html_defender_v2',
defaultMessage:
- '{actorInstitution}, {actorName} {actorTitle}, hefur uppfært lengd {caseType, select, ADMISSION_TO_FACILITY {vistunar} TRAVEL_BAN {farbanns} other {gæsluvarðhalds}} í máli {courtCaseNumber}.
{defenderHasAccessToRvg, select, true {Sjá nánar á {linkStart}yfirlitssíðu málsins í Réttarvörslugátt{linkEnd}} other {Þú getur nálgast gögn málsins hjá {courtName} ef þau hafa ekki þegar verið afhent}}.
Ný lokadagsetning: {validToDate}.',
+ '{actorInstitution}, {actorName} {actorTitle}, hefur uppfært lengd {caseType, select, ADMISSION_TO_FACILITY {vistunar} TRAVEL_BAN {farbanns} other {gæsluvarðhalds}} í máli {courtCaseNumber}.
{defenderHasAccessToRvg, select, true {Sjá nánar á {linkStart}yfirlitssíðu málsins í Réttarvörslugátt{linkEnd}} other {Þú getur nálgast gögn málsins hjá {courtName} ef þau hafa ekki þegar verið afhent}}.
Ný lokadagsetning: {validToDate}.',
description:
'Notaður sem texti í tölvupósti til verjanda vegna breytingar á lengd gæslu/farbanns/vistunar þar sem ekki var úrskurðað í einangrun.',
},
@@ -769,7 +769,6 @@ export const notifications = {
description: 'Texti í pósti til aðila máls þegar kæra er afturkölluð',
},
}),
-
emailNames: defineMessages({
prison: {
id: 'judicial.system.backend:notifications.email_names.prison',
@@ -834,4 +833,18 @@ export const notifications = {
description: 'Texti í pósti til sækjanda máls þegar ákæra er endursend',
},
}),
+ courtRevokedIndictmentEmail: defineMessages({
+ subject: {
+ id: 'judicial.system.backend:notifications.court_revoked_indictment_email.subject',
+ defaultMessage:
+ 'Ákæra afturkölluð{courtCaseNumber, select, NONE {} other { í máli {courtCaseNumber}}}',
+ description: 'Fyrirsögn í pósti til dómstóls þegar ákæra er afturkölluð',
+ },
+ body: {
+ id: 'judicial.system.backend:notifications.court_revoked_indictment_email.body',
+ defaultMessage:
+ '{prosecutorsOffice} hefur afturkallað ákæru {courtCaseNumber, select, NONE {í máli sem ekki hefur enn fengið málsnúmer} other {í máli {courtCaseNumber}}}.',
+ description: 'Texti í pósti til dómstóls þegar ákæra er afturkölluð',
+ },
+ }),
}
diff --git a/apps/judicial-system/backend/src/app/modules/case/case.service.ts b/apps/judicial-system/backend/src/app/modules/case/case.service.ts
index a6b0f5b397b5..90531b9eae0d 100644
--- a/apps/judicial-system/backend/src/app/modules/case/case.service.ts
+++ b/apps/judicial-system/backend/src/app/modules/case/case.service.ts
@@ -835,11 +835,8 @@ export class CaseService {
return this.messageService.sendMessagesToQueue(messages)
}
- private addMessagesForDeletedCaseToQueue(
- theCase: Case,
- user: TUser,
- ): Promise {
- const messages: CaseMessage[] = [
+ private getRevokeMessages(user: TUser, theCase: Case): CaseMessage[] {
+ return [
{
type: MessageType.NOTIFICATION,
user,
@@ -847,8 +844,24 @@ export class CaseService {
body: { type: NotificationType.REVOKED },
},
]
+ }
- return this.messageService.sendMessagesToQueue(messages)
+ private addMessagesForDeletedCaseToQueue(
+ theCase: Case,
+ user: TUser,
+ ): Promise {
+ return this.messageService.sendMessagesToQueue(
+ this.getRevokeMessages(user, theCase),
+ )
+ }
+
+ private addMessagesForRevokedIndictmentCaseToQueue(
+ theCase: Case,
+ user: TUser,
+ ): Promise {
+ return this.messageService.sendMessagesToQueue(
+ this.getRevokeMessages(user, theCase),
+ )
}
private async addMessagesForAppealedCaseToQueue(
@@ -1077,6 +1090,7 @@ export class CaseService {
user: TUser,
): Promise {
const isIndictment = isIndictmentCase(updatedCase.type)
+
if (updatedCase.state !== theCase.state) {
// New case state
if (
@@ -1086,13 +1100,17 @@ export class CaseService {
// Only send messages if the case was in a SUBMITTED state - not when reopening a case
await this.addMessagesForReceivedCaseToQueue(updatedCase, user)
} else if (updatedCase.state === CaseState.DELETED) {
- await this.addMessagesForDeletedCaseToQueue(updatedCase, user)
+ if (!isIndictment) {
+ await this.addMessagesForDeletedCaseToQueue(updatedCase, user)
+ }
} else if (isCompletedCase(updatedCase.state)) {
if (isIndictment) {
- await this.addMessagesForCompletedIndictmentCaseToQueue(
- updatedCase,
- user,
- )
+ if (theCase.state !== CaseState.WAITING_FOR_CANCELLATION) {
+ await this.addMessagesForCompletedIndictmentCaseToQueue(
+ updatedCase,
+ user,
+ )
+ }
} else {
await this.addMessagesForCompletedCaseToQueue(updatedCase, user)
}
@@ -1116,6 +1134,8 @@ export class CaseService {
updatedCase,
user,
)
+ } else if (updatedCase.state === CaseState.WAITING_FOR_CANCELLATION) {
+ await this.addMessagesForRevokedIndictmentCaseToQueue(updatedCase, user)
}
}
diff --git a/apps/judicial-system/backend/src/app/modules/case/test/caseController/transition.spec.ts b/apps/judicial-system/backend/src/app/modules/case/test/caseController/transition.spec.ts
index 2a81eeddc219..a1098a85ef53 100644
--- a/apps/judicial-system/backend/src/app/modules/case/test/caseController/transition.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/case/test/caseController/transition.spec.ts
@@ -401,7 +401,10 @@ describe('CaseController - Transition', () => {
},
],
)
- } else if (newState === CaseState.DELETED) {
+ } else if (
+ newState === CaseState.DELETED &&
+ !isIndictmentCase(theCase.type)
+ ) {
expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledWith(
[
{
@@ -505,6 +508,23 @@ describe('CaseController - Transition', () => {
},
],
)
+ } else if (
+ newState === CaseState.WAITING_FOR_CANCELLATION &&
+ isIndictmentCase(theCase.type)
+ ) {
+ expect(mockMessageService.sendMessagesToQueue).toHaveBeenCalledWith(
+ [
+ {
+ type: MessageType.NOTIFICATION,
+ user: {
+ ...defaultUser,
+ canConfirmIndictment: isIndictmentCase(theCase.type),
+ },
+ caseId,
+ body: { type: NotificationType.REVOKED },
+ },
+ ],
+ )
} else {
expect(
mockMessageService.sendMessagesToQueue,
diff --git a/apps/judicial-system/backend/src/app/modules/notification/notification.service.ts b/apps/judicial-system/backend/src/app/modules/notification/notification.service.ts
index 13e3ee13cc38..4764814ed4cd 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/notification.service.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/notification.service.ts
@@ -46,6 +46,7 @@ import {
isIndictmentCase,
isInvestigationCase,
isProsecutionUser,
+ isRequestCase,
isRestrictionCase,
NotificationType,
RequestSharedWithDefender,
@@ -130,25 +131,26 @@ export class NotificationService {
})
}
- private async hasSentNotification(caseId: string, type: NotificationType) {
- const previousNotifications = await this.notificationModel.findAll({
- where: { caseId, type },
- })
- return previousNotifications.length > 0
+ private hasSentNotification(
+ type: NotificationType,
+ notifications?: Notification[],
+ ) {
+ return notifications?.some((notification) => notification.type === type)
}
- private async hasReceivedNotification(
- caseId: string,
- type: NotificationType | NotificationType[],
+ private hasReceivedNotification(
+ type?: NotificationType | NotificationType[],
address?: string,
+ notifications?: Notification[],
) {
- const previousNotifications = await this.notificationModel.findAll({
- where: { caseId, type },
- })
+ const types = type ? [type].flat() : Object.values(NotificationType)
- return previousNotifications.some((notification) => {
- return notification.recipients.some(
- (recipient) => recipient.address === address && recipient.success,
+ return notifications?.some((notification) => {
+ return (
+ types.includes(notification.type) &&
+ notification.recipients.some(
+ (recipient) => recipient.address === address && recipient.success,
+ )
)
})
}
@@ -425,7 +427,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
)
}
@@ -486,7 +488,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
)
}
@@ -509,10 +511,10 @@ export class NotificationService {
this.sendReadyForCourtEmailNotificationToProsecutor(theCase),
]
- const courtHasBeenNotified = await this.hasReceivedNotification(
- theCase.id,
+ const courtHasBeenNotified = this.hasReceivedNotification(
NotificationType.READY_FOR_COURT,
this.getCourtMobileNumbers(theCase.courtId),
+ theCase.notifications,
)
if (!courtHasBeenNotified) {
@@ -528,10 +530,10 @@ export class NotificationService {
RequestSharedWithDefender.READY_FOR_COURT ||
theCase.requestSharedWithDefender === RequestSharedWithDefender.COURT_DATE
) {
- const hasDefenderBeenNotified = await this.hasReceivedNotification(
- theCase.id,
+ const hasDefenderBeenNotified = this.hasReceivedNotification(
[NotificationType.READY_FOR_COURT, NotificationType.COURT_DATE],
theCase.defenderEmail,
+ theCase.notifications,
)
if (hasDefenderBeenNotified) {
@@ -727,7 +729,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
calendarInvite ? [calendarInvite] : undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
).then((recipient) => {
if (recipient.success) {
// No need to wait
@@ -773,7 +775,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
)
}
@@ -910,10 +912,10 @@ export class NotificationService {
),
)
- const hasDefenderBeenNotified = await this.hasReceivedNotification(
- theCase.id,
+ const hasDefenderBeenNotified = this.hasReceivedNotification(
[NotificationType.READY_FOR_COURT],
theCase.defenderEmail,
+ theCase.notifications,
)
if (!hasDefenderBeenNotified) {
@@ -1181,10 +1183,10 @@ export class NotificationService {
(theCase.decision === CaseDecision.REJECTING ||
theCase.decision === CaseDecision.ACCEPTING_ALTERNATIVE_TRAVEL_BAN)
) {
- const prisonHasBeenNotified = await this.hasReceivedNotification(
- theCase.id,
+ const prisonHasBeenNotified = this.hasReceivedNotification(
NotificationType.COURT_DATE,
this.config.email.prisonEmail,
+ theCase.notifications,
)
if (prisonHasBeenNotified) {
@@ -1245,7 +1247,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
)
}
@@ -1354,24 +1356,6 @@ export class NotificationService {
//#endregion
//#region REVOKED notifications */
- private async existsRevokableNotification(
- caseId: string,
- address?: string,
- isIndictment?: boolean,
- ): Promise {
- return this.hasReceivedNotification(
- caseId,
- isIndictment
- ? [NotificationType.DEFENDER_ASSIGNED]
- : [
- NotificationType.HEADS_UP,
- NotificationType.READY_FOR_COURT,
- NotificationType.COURT_DATE,
- ],
- address,
- )
- }
-
private sendRevokedSmsNotificationToCourt(theCase: Case): Promise {
const smsText = formatCourtRevokedSmsNotification(
this.formatMessage,
@@ -1409,10 +1393,12 @@ export class NotificationService {
html,
this.formatMessage(notifications.emailNames.prison),
this.config.email.prisonEmail,
+ undefined,
+ true,
)
}
- private sendRevokedEmailNotificationToDefender(
+ private sendRevokedEmailNotificationToDefenderForRequestCase(
caseType: CaseType,
defendant: Defendant,
defenderName?: string,
@@ -1420,11 +1406,10 @@ export class NotificationService {
arraignmentDate?: Date,
courtName?: string,
): Promise {
- const subject = isIndictmentCase(caseType)
- ? this.formatMessage(notifications.defenderRevokedEmail.indictmentSubject)
- : this.formatMessage(notifications.defenderRevokedEmail.subject, {
- caseType,
- })
+ const subject = this.formatMessage(
+ notifications.defenderRevokedEmail.subject,
+ { caseType },
+ )
const html = formatDefenderRevokedEmailNotification(
this.formatMessage,
@@ -1436,74 +1421,190 @@ export class NotificationService {
arraignmentDate,
)
- return this.sendEmail(subject, html, defenderName, defenderEmail)
+ return this.sendEmail(
+ subject,
+ html,
+ defenderName,
+ defenderEmail,
+ undefined,
+ true,
+ )
}
- private async sendRevokedNotifications(
+ private sendRevokedEmailNotificationToDefenderForIndictmentCase(
+ caseId: string,
+ defenderNationalId?: string,
+ defenderName?: string,
+ defenderEmail?: string,
+ courtName?: string,
+ courtCaseNumber?: string,
+ ): Promise {
+ const subject = this.formatMessage(
+ notifications.defenderRevokedEmail.indictmentSubject,
+ { courtCaseNumber },
+ )
+
+ const html = this.formatMessage(
+ notifications.defenderRevokedEmail.indictmentBody,
+ {
+ courtName: courtName?.replace('dómur', 'dómi'),
+ defenderHasAccessToRvg: Boolean(defenderNationalId),
+ linkStart: ``,
+ linkEnd: '',
+ },
+ )
+
+ return this.sendEmail(
+ subject,
+ html,
+ defenderName,
+ defenderEmail,
+ undefined,
+ !defenderNationalId,
+ )
+ }
+
+ private async sendRevokedNotificationsForRequestCase(
theCase: Case,
): Promise {
const promises: Promise[] = []
- const arraignmentDate = DateLog.arraignmentDate(theCase.dateLogs)?.date
- const courtWasNotified =
- !isIndictmentCase(theCase.type) &&
- (await this.existsRevokableNotification(
- theCase.id,
- this.getCourtMobileNumbers(theCase.courtId),
- ))
+ const courtWasNotified = this.hasReceivedNotification(
+ undefined,
+ this.getCourtMobileNumbers(theCase.courtId),
+ theCase.notifications,
+ )
if (courtWasNotified) {
promises.push(this.sendRevokedSmsNotificationToCourt(theCase))
}
- const prisonWasNotified =
- (theCase.type === CaseType.CUSTODY ||
- theCase.type === CaseType.ADMISSION_TO_FACILITY) &&
- (await this.existsRevokableNotification(
- theCase.id,
- this.config.email.prisonEmail,
- ))
+ const prisonWasNotified = this.hasReceivedNotification(
+ undefined,
+ this.config.email.prisonEmail,
+ theCase.notifications,
+ )
if (prisonWasNotified) {
promises.push(this.sendRevokedEmailNotificationToPrison(theCase))
}
- if (isIndictmentCase(theCase.type)) {
- for (const defendant of theCase.defendants ?? []) {
- const defenderWasNotified = await this.existsRevokableNotification(
- theCase.id,
- defendant.defenderEmail,
- isIndictmentCase(theCase.type),
+ const defenderWasNotified = this.hasReceivedNotification(
+ undefined,
+ theCase.defenderEmail,
+ theCase.notifications,
+ )
+
+ if (defenderWasNotified && theCase.defendants) {
+ const arraignmentDate = DateLog.arraignmentDate(theCase.dateLogs)?.date
+
+ promises.push(
+ this.sendRevokedEmailNotificationToDefenderForRequestCase(
+ theCase.type,
+ theCase.defendants[0],
+ theCase.defenderName,
+ theCase.defenderEmail,
+ arraignmentDate,
+ theCase.court?.name,
+ ),
+ )
+ }
+
+ const recipients = await Promise.all(promises)
+
+ if (recipients.length === 0) {
+ // Nothing to send
+ return { notificationSent: true }
+ }
+
+ return this.recordNotification(
+ theCase.id,
+ NotificationType.REVOKED,
+ recipients,
+ )
+ }
+
+ private sendRevokedNotificationToCourt(
+ theCase: Case,
+ recipientName?: string,
+ recipientEmail?: string,
+ ): Promise {
+ const subject = this.formatMessage(
+ notifications.courtRevokedIndictmentEmail.subject,
+ {
+ courtCaseNumber: theCase.courtCaseNumber ?? 'NONE',
+ },
+ )
+ const body = this.formatMessage(
+ notifications.courtRevokedIndictmentEmail.body,
+ {
+ prosecutorsOffice: theCase.creatingProsecutor?.institution?.name,
+ courtCaseNumber: theCase.courtCaseNumber ?? 'NONE',
+ },
+ )
+
+ return this.sendEmail(subject, body, recipientName, recipientEmail)
+ }
+
+ private async sendRevodeNotificationsForIndictmentCase(
+ theCase: Case,
+ ): Promise {
+ const promises: Promise[] = []
+
+ if (!theCase.judge && !theCase.registrar) {
+ promises.push(
+ this.sendRevokedNotificationToCourt(
+ theCase,
+ theCase.court?.name,
+ this.getCourtEmail(theCase.courtId),
+ ),
+ )
+ } else {
+ if (theCase.judge) {
+ promises.push(
+ this.sendRevokedNotificationToCourt(
+ theCase,
+ theCase.judge.name,
+ theCase.judge.email,
+ ),
)
+ }
- if (defenderWasNotified) {
- promises.push(
- this.sendRevokedEmailNotificationToDefender(
- theCase.type,
- defendant,
- defendant.defenderName,
- defendant.defenderEmail,
- arraignmentDate,
- theCase.court?.name,
- ),
- )
- }
+ if (theCase.registrar) {
+ promises.push(
+ this.sendRevokedNotificationToCourt(
+ theCase,
+ theCase.registrar.name,
+ theCase.registrar.email,
+ ),
+ )
}
- } else {
- const defenderWasNotified = await this.existsRevokableNotification(
- theCase.id,
- theCase.defenderEmail,
- isIndictmentCase(theCase.type),
+ }
+
+ const uniqDefendants = _uniqBy(
+ theCase.defendants ?? [],
+ (d: Defendant) => d.defenderEmail,
+ )
+ for (const defendant of uniqDefendants) {
+ const defenderWasNotified = this.hasReceivedNotification(
+ undefined,
+ defendant.defenderEmail,
+ theCase.notifications,
)
- if (defenderWasNotified && theCase.defendants) {
+
+ if (defenderWasNotified) {
promises.push(
- this.sendRevokedEmailNotificationToDefender(
- theCase.type,
- theCase.defendants[0],
- theCase.defenderName,
- theCase.defenderEmail,
- arraignmentDate,
+ this.sendRevokedEmailNotificationToDefenderForIndictmentCase(
+ theCase.id,
+ defendant.defenderNationalId,
+ defendant.defenderName,
+ defendant.defenderEmail,
theCase.court?.name,
+ theCase.courtCaseNumber,
),
)
}
@@ -1522,21 +1623,31 @@ export class NotificationService {
recipients,
)
}
+
+ private sendRevokedNotifications(
+ theCase: Case,
+ ): Promise {
+ if (isRequestCase(theCase.type)) {
+ return this.sendRevokedNotificationsForRequestCase(theCase)
+ } else {
+ return this.sendRevodeNotificationsForIndictmentCase(theCase)
+ }
+ }
//#endregion
//#region DEFENDER_ASSIGNED notifications */
- private async shouldSendDefenderAssignedNotification(
+ private shouldSendDefenderAssignedNotification(
theCase: Case,
defenderEmail?: string,
- ): Promise {
+ ): boolean {
if (!defenderEmail) {
return false
}
if (isIndictmentCase(theCase.type)) {
- const hasSentNotificationBefore = await this.hasReceivedNotification(
- theCase.id,
+ const hasSentNotificationBefore = this.hasReceivedNotification(
NotificationType.DEFENDER_ASSIGNED,
defenderEmail,
+ theCase.notifications,
)
if (hasSentNotificationBefore) {
@@ -1552,15 +1663,16 @@ export class NotificationService {
if (!isDefenderIncludedInSessionArrangements) return false
} else {
- const hasDefenderBeenNotified = await this.hasReceivedNotification(
- theCase.id,
+ const hasDefenderBeenNotified = this.hasReceivedNotification(
[
NotificationType.READY_FOR_COURT,
NotificationType.COURT_DATE,
NotificationType.DEFENDER_ASSIGNED,
],
theCase.defenderEmail,
+ theCase.notifications,
)
+
if (hasDefenderBeenNotified) {
return false
}
@@ -1605,7 +1717,7 @@ export class NotificationService {
for (const defendant of uniqDefendants) {
const { defenderEmail, defenderNationalId, defenderName } = defendant
- const shouldSend = await this.shouldSendDefenderAssignedNotification(
+ const shouldSend = this.shouldSendDefenderAssignedNotification(
theCase,
defenderEmail,
)
@@ -1622,21 +1734,13 @@ export class NotificationService {
}
}
} else if (DateLog.arraignmentDate(theCase.dateLogs)?.date) {
- const shouldSend = await this.shouldSendDefenderAssignedNotification(
+ const shouldSend = this.shouldSendDefenderAssignedNotification(
theCase,
theCase.defenderEmail,
)
if (shouldSend) {
- const recipient = await this.sendCourtDateEmailNotificationToDefender(
- theCase,
- )
-
- return this.recordNotification(
- theCase.id,
- NotificationType.DEFENDER_ASSIGNED,
- [recipient],
- )
+ promises.push(this.sendCourtDateEmailNotificationToDefender(theCase))
}
}
@@ -1661,11 +1765,11 @@ export class NotificationService {
): Promise {
if (
!theCase.registrar ||
- (await this.hasReceivedNotification(
- theCase.id,
+ this.hasReceivedNotification(
NotificationType.DEFENDANTS_NOT_UPDATED_AT_COURT,
theCase.registrar?.email,
- ))
+ theCase.notifications,
+ )
) {
// Nothing to send
return { notificationSent: true }
@@ -1715,8 +1819,6 @@ export class NotificationService {
html,
theCase.prosecutor?.name,
theCase.prosecutor?.email,
- undefined,
- true,
)
return this.recordNotification(
@@ -1749,8 +1851,6 @@ export class NotificationService {
html,
theCase.prosecutor?.name,
theCase.prosecutor?.email,
- undefined,
- true,
)
return this.recordNotification(
@@ -1889,7 +1989,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
),
)
}
@@ -1996,7 +2096,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
),
)
}
@@ -2130,7 +2230,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
),
)
}
@@ -2185,14 +2285,7 @@ export class NotificationService {
courtOfAppealUsers.forEach((user) => {
if (user) {
promises.push(
- this.sendEmail(
- subject,
- courtOfAppealHtml,
- user.name,
- user.email,
- undefined,
- true,
- ),
+ this.sendEmail(subject, courtOfAppealHtml, user.name, user.email),
)
}
})
@@ -2237,9 +2330,9 @@ export class NotificationService {
private async sendAppealCompletedResultNotifications(
theCase: Case,
): Promise {
- const isReopened = await this.hasSentNotification(
- theCase.id,
+ const isReopened = this.hasSentNotification(
NotificationType.APPEAL_COMPLETED,
+ theCase.notifications,
)
const promises = []
@@ -2338,7 +2431,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
),
)
}
@@ -2376,7 +2469,7 @@ export class NotificationService {
theCase.defenderName,
theCase.defenderEmail,
undefined,
- Boolean(theCase.defenderNationalId) === false,
+ !theCase.defenderNationalId,
),
)
@@ -2427,7 +2520,9 @@ export class NotificationService {
courtCaseNumber: theCase.courtCaseNumber,
})
- const sendTo = await this.getWithdrawnNotificationRecipients(
+ // This may result in a defender with no national id getting a link to RVG
+ // TODO: Separate defenders from other recipients and handle no national id
+ const sendTo = this.getWithdrawnNotificationRecipients(
theCase,
user,
wasWithdrawnByProsecution,
@@ -2440,6 +2535,7 @@ export class NotificationService {
})
const recipients = await Promise.all(promises)
+
return this.recordNotification(
theCase.id,
NotificationType.APPEAL_WITHDRAWN,
@@ -2447,14 +2543,14 @@ export class NotificationService {
)
}
- private async getWithdrawnNotificationRecipients(
+ private getWithdrawnNotificationRecipients(
theCase: Case,
user: User,
wasWithdrawnByProsecution: boolean,
- ): Promise {
- const hasBeenAssigned = await this.hasSentNotification(
- theCase.id,
+ ): RecipientInfo[] {
+ const hasBeenAssigned = this.hasSentNotification(
NotificationType.APPEAL_JUDGES_ASSIGNED,
+ theCase.notifications,
)
const recipients = [
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/createTestingNotificationModule.ts b/apps/judicial-system/backend/src/app/modules/notification/test/createTestingNotificationModule.ts
index 0909a33faa6f..11983dbe9cc7 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/createTestingNotificationModule.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/createTestingNotificationModule.ts
@@ -81,9 +81,6 @@ export const createTestingNotificationModule = async () => {
provide: getModelToken(Notification),
useValue: {
create: jest.fn(),
- findOne: jest.fn(),
- findAll: jest.fn(),
- update: jest.fn(),
},
},
NotificationService,
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendAppealCompletedNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendAppealCompletedNotifications.spec.ts
index 4012c218e6d0..88b1e6ab7f73 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendAppealCompletedNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendAppealCompletedNotifications.spec.ts
@@ -49,19 +49,12 @@ describe('InternalNotificationController - Send appeal completed notifications',
beforeEach(async () => {
process.env.COURTS_EMAILS = `{"4676f08b-aab4-4b4f-a366-697540788088":"${courtOfAppealsEmail}"}`
- const {
- emailService,
- notificationConfig,
- notificationModel,
- internalNotificationController,
- } = await createTestingNotificationModule()
+ const { emailService, notificationConfig, internalNotificationController } =
+ await createTestingNotificationModule()
mockEmailService = emailService
mockConfig = notificationConfig
- const mockFindAll = notificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
-
givenWhenThen = async (
defenderNationalId?: string,
appealRulingDecision?: CaseAppealRulingDecision,
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendAppealWithdrawnNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendAppealWithdrawnNotifications.spec.ts
index 141d4cc38a4a..1d83fc0d0db8 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendAppealWithdrawnNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendAppealWithdrawnNotifications.spec.ts
@@ -23,6 +23,7 @@ interface Then {
type GivenWhenThen = (
userRole: UserRole,
appealReceivedByCourtDate?: Date,
+ notifications?: Notification[],
) => Promise
describe('InternalNotificationController - Send appeal withdrawn notifications', () => {
@@ -60,10 +61,11 @@ describe('InternalNotificationController - Send appeal withdrawn notifications',
mockEmailService = emailService
mockNotificationModel = notificationModel
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
-
- givenWhenThen = async (userRole, appealReceivedByCourtDate) => {
+ givenWhenThen = async (
+ userRole,
+ appealReceivedByCourtDate,
+ notifications,
+ ) => {
const then = {} as Then
await internalNotificationController
@@ -88,6 +90,7 @@ describe('InternalNotificationController - Send appeal withdrawn notifications',
judge: { name: judgeName, email: judgeEmail },
appealJudge1: { name: appealJudge1Name, email: appealJudge1Email },
registrar: { name: registrarName, email: registrarEmail },
+ notifications,
} as Case,
{
user: {
@@ -151,15 +154,13 @@ describe('InternalNotificationController - Send appeal withdrawn notifications',
beforeEach(async () => {
const mockCreate = mockNotificationModel.create as jest.Mock
mockCreate.mockResolvedValueOnce({} as Notification)
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([
+
+ then = await givenWhenThen(UserRole.PROSECUTOR, receivedDate, [
{
caseId,
type: NotificationType.APPEAL_JUDGES_ASSIGNED,
} as Notification,
])
-
- then = await givenWhenThen(UserRole.PROSECUTOR, receivedDate)
})
it('should send notification to defender', () => {
expect(mockEmailService.sendEmail).toHaveBeenCalledWith(
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendCourtDateNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendCourtDateNotifications.spec.ts
index e1e092ff174e..fc497ddc5de5 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendCourtDateNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendCourtDateNotifications.spec.ts
@@ -49,9 +49,6 @@ describe('InternalNotificationController - Send court date notifications', () =>
mockEmailService = emailService
mockNotificationModel = notificationModel
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
-
givenWhenThen = async (
theCase: Case,
notificationDto: SendInternalNotificationDto,
@@ -86,9 +83,6 @@ describe('InternalNotificationController - Send court date notifications', () =>
} as Case
beforeEach(async () => {
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([])
-
then = await givenWhenThen(theCase, notificationDto)
})
@@ -141,16 +135,20 @@ describe('InternalNotificationController - Send court date notifications', () =>
beforeEach(async () => {
const mockCreate = mockNotificationModel.create as jest.Mock
mockCreate.mockResolvedValueOnce({} as Notification)
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([
- {
- caseId,
- type: NotificationType.READY_FOR_COURT,
- recipients: [{ address: defenderEmail, success: true }],
- } as Notification,
- ])
- then = await givenWhenThen(theCase, notificationDto)
+ then = await givenWhenThen(
+ {
+ ...theCase,
+ notifications: [
+ {
+ caseId,
+ type: NotificationType.READY_FOR_COURT,
+ recipients: [{ address: defenderEmail, success: true }],
+ },
+ ],
+ } as Case,
+ notificationDto,
+ )
})
it('should not send link to case to defender', () => {
@@ -190,9 +188,6 @@ describe('InternalNotificationController - Send court date notifications', () =>
} as Case
beforeEach(async () => {
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([])
-
then = await givenWhenThen(theCase, notificationDto)
})
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendDefendantsNotUpdatedAtCourtNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendDefendantsNotUpdatedAtCourtNotifications.spec.ts
index ad2941570d7d..6e98046a7a9b 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendDefendantsNotUpdatedAtCourtNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendDefendantsNotUpdatedAtCourtNotifications.spec.ts
@@ -9,7 +9,6 @@ import { createTestingNotificationModule } from '../createTestingNotificationMod
import { Case } from '../../../case'
import { SendInternalNotificationDto } from '../../dto/sendInternalNotification.dto'
import { DeliverResponse } from '../../models/deliver.response'
-import { Notification } from '../../models/notification.model'
interface Then {
result: DeliverResponse
@@ -39,18 +38,13 @@ describe('InternalNotificationController - Send defendants not updated at court
} as Case
let mockEmailService: EmailService
- let mockNotificationModel: typeof Notification
let givenWhenThen: GivenWhenThen
beforeEach(async () => {
- const { emailService, notificationModel, internalNotificationController } =
+ const { emailService, internalNotificationController } =
await createTestingNotificationModule()
mockEmailService = emailService
- mockNotificationModel = notificationModel
-
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
givenWhenThen = async (
caseId: string,
@@ -91,11 +85,19 @@ describe('InternalNotificationController - Send defendants not updated at court
let then: Then
beforeEach(async () => {
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([
- { recipients: [{ address: registrarEmail, success: true }] },
- ])
- then = await givenWhenThen(caseId, theCase, notificationDto)
+ then = await givenWhenThen(
+ caseId,
+ {
+ ...theCase,
+ notifications: [
+ {
+ type: NotificationType.DEFENDANTS_NOT_UPDATED_AT_COURT,
+ recipients: [{ address: registrarEmail, success: true }],
+ },
+ ],
+ } as Case,
+ notificationDto,
+ )
})
it('should not send email', () => {
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendDefenderAssignedNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendDefenderAssignedNotifications.spec.ts
index 81dcac2bfade..cdefc359ef4c 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendDefenderAssignedNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendDefenderAssignedNotifications.spec.ts
@@ -56,9 +56,6 @@ describe('InternalNotificationController - Send defender assigned notifications'
mockConfig = notificationConfig
mockNotificationModel = notificationModel
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
-
givenWhenThen = async (
caseId: string,
theCase: Case,
@@ -241,16 +238,21 @@ describe('InternalNotificationController - Send defender assigned notifications'
beforeEach(async () => {
const mockCreate = mockNotificationModel.create as jest.Mock
mockCreate.mockResolvedValueOnce({} as Notification)
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([
- {
- caseId,
- type: notificationDto.type,
- recipients: [{ address: defendant.defenderEmail, success: true }],
- } as Notification,
- ])
- then = await givenWhenThen(caseId, theCase, notificationDto)
+ then = await givenWhenThen(
+ caseId,
+ {
+ ...theCase,
+ notifications: [
+ {
+ caseId,
+ type: notificationDto.type,
+ recipients: [{ address: defendant.defenderEmail, success: true }],
+ },
+ ],
+ } as Case,
+ notificationDto,
+ )
})
it('should return notification was not sent', () => {
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendIndictmentDeniedNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendIndictmentDeniedNotifications.spec.ts
index b75d942d4755..6e6463038ad4 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendIndictmentDeniedNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendIndictmentDeniedNotifications.spec.ts
@@ -13,7 +13,6 @@ import { createTestingNotificationModule } from '../createTestingNotificationMod
import { Case } from '../../../case'
import { SendInternalNotificationDto } from '../../dto/sendInternalNotification.dto'
import { DeliverResponse } from '../../models/deliver.response'
-import { Notification } from '../../models/notification.model'
jest.mock('../../../../factories')
@@ -35,18 +34,13 @@ describe('InternalNotificationController - Send indictment denied notification',
const policeCaseNumbers = [uuid(), uuid()]
let mockEmailService: EmailService
- let mockNotificationModel: typeof Notification
let givenWhenThen: GivenWhenThen
beforeEach(async () => {
- const { emailService, internalNotificationController, notificationModel } =
+ const { emailService, internalNotificationController } =
await createTestingNotificationModule()
mockEmailService = emailService
- mockNotificationModel = notificationModel
-
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
givenWhenThen = async (
theCase: Case,
@@ -79,9 +73,6 @@ describe('InternalNotificationController - Send indictment denied notification',
} as Case
beforeEach(async () => {
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([])
-
then = await givenWhenThen(theCase, notificationDto)
})
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendIndictmentReturnedNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendIndictmentReturnedNotifications.spec.ts
index 86ba67ab84f4..4c5737885fb1 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendIndictmentReturnedNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendIndictmentReturnedNotifications.spec.ts
@@ -13,7 +13,6 @@ import { createTestingNotificationModule } from '../createTestingNotificationMod
import { Case } from '../../../case'
import { SendInternalNotificationDto } from '../../dto/sendInternalNotification.dto'
import { DeliverResponse } from '../../models/deliver.response'
-import { Notification } from '../../models/notification.model'
jest.mock('../../../../factories')
@@ -36,18 +35,13 @@ describe('InternalNotificationController - Send indictment returned notification
const courtName = uuid()
let mockEmailService: EmailService
- let mockNotificationModel: typeof Notification
let givenWhenThen: GivenWhenThen
beforeEach(async () => {
- const { emailService, internalNotificationController, notificationModel } =
+ const { emailService, internalNotificationController } =
await createTestingNotificationModule()
mockEmailService = emailService
- mockNotificationModel = notificationModel
-
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
givenWhenThen = async (
theCase: Case,
@@ -81,9 +75,6 @@ describe('InternalNotificationController - Send indictment returned notification
} as Case
beforeEach(async () => {
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([])
-
then = await givenWhenThen(theCase, notificationDto)
})
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendReadyForCourtNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendReadyForCourtNotifications.spec.ts
index 34d47928b101..df061d7eb038 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendReadyForCourtNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendReadyForCourtNotifications.spec.ts
@@ -74,7 +74,6 @@ describe('InternalNotificationController - Send ready for court notifications fo
let mockEmailService: EmailService
let mockSmsService: SmsService
let mockNotificationConfig: ConfigType
- let mockNotificationModel: typeof Notification
let givenWhenThen: GivenWhenThen
beforeEach(async () => {
@@ -84,17 +83,12 @@ describe('InternalNotificationController - Send ready for court notifications fo
emailService,
smsService,
notificationConfig,
- notificationModel,
internalNotificationController,
} = await createTestingNotificationModule()
mockEmailService = emailService
mockSmsService = smsService
mockNotificationConfig = notificationConfig
- mockNotificationModel = notificationModel
-
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
givenWhenThen = async (caseId, theCase, notificationDto) => {
const then = {} as Then
@@ -115,12 +109,6 @@ describe('InternalNotificationController - Send ready for court notifications fo
then = await givenWhenThen(caseId, theCase, notificationDto)
})
- it('should lookup previous ready for court notifications', () => {
- expect(mockNotificationModel.findAll).toHaveBeenCalledWith({
- where: { caseId, type: NotificationType.READY_FOR_COURT },
- })
- })
-
it('should send ready for court email notification to prosecutor', () => {
expect(mockEmailService.sendEmail).toHaveBeenCalledWith({
from: {
@@ -153,21 +141,26 @@ describe('InternalNotificationController - Send ready for court notifications fo
describe('subsequent notifications', () => {
beforeEach(async () => {
- const mockFindOne = mockNotificationModel.findAll as jest.Mock
- mockFindOne.mockResolvedValueOnce([
+ await givenWhenThen(
+ caseId,
{
- caseId,
- type: NotificationType.READY_FOR_COURT,
- recipients: [
+ ...theCase,
+ notifications: [
{
- address: mockNotificationConfig.sms.courtsMobileNumbers[courtId],
- success: true,
+ caseId,
+ type: NotificationType.READY_FOR_COURT,
+ recipients: [
+ {
+ address:
+ mockNotificationConfig.sms.courtsMobileNumbers[courtId],
+ success: true,
+ },
+ ],
},
],
- },
- ])
-
- await givenWhenThen(caseId, theCase, notificationDto)
+ } as Case,
+ notificationDto,
+ )
})
it('should send ready for court email notification to prosecutor', () => {
@@ -195,15 +188,6 @@ describe('InternalNotificationController - Send ready for court notifications fo
)
})
- it('should lookup previous court date notifications', () => {
- expect(mockNotificationModel.findAll).toHaveBeenCalledWith({
- where: {
- caseId,
- type: [NotificationType.READY_FOR_COURT, NotificationType.COURT_DATE],
- },
- })
- })
-
it('should not send ready for court email notification to defender', () => {
expect(mockEmailService.sendEmail).not.toHaveBeenCalledWith(
expect.objectContaining({
@@ -234,16 +218,19 @@ describe('InternalNotificationController - Send ready for court notifications fo
describe('defender notification', () => {
beforeEach(async () => {
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValueOnce([]).mockResolvedValueOnce([
+ await givenWhenThen(
+ caseId,
{
- recipients: [
- { name: 'Saul Goodman', address: 'saul@dummy.is', success: true },
+ ...theCase,
+ notifications: [
+ {
+ type: NotificationType.READY_FOR_COURT,
+ recipients: [{ address: 'saul@dummy.is', success: true }],
+ },
],
- },
- ])
-
- await givenWhenThen(caseId, theCase, notificationDto)
+ } as Case,
+ notificationDto,
+ )
})
it('should send ready for court email updated notification to defender', () => {
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendRevokedNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendRevokedNotifications.spec.ts
new file mode 100644
index 000000000000..2f5d518e82f9
--- /dev/null
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendRevokedNotifications.spec.ts
@@ -0,0 +1,116 @@
+import { uuid } from 'uuidv4'
+
+import { EmailService } from '@island.is/email-service'
+
+import { NotificationType } from '@island.is/judicial-system/types'
+
+import { createTestingNotificationModule } from '../createTestingNotificationModule'
+
+import { Case } from '../../../case'
+import { SendInternalNotificationDto } from '../../dto/sendInternalNotification.dto'
+import { DeliverResponse } from '../../models/deliver.response'
+import { Notification } from '../../models/notification.model'
+
+interface Then {
+ result: DeliverResponse
+ error: Error
+}
+
+type GivenWhenThen = (notifications?: Notification[]) => Promise
+
+describe('InternalNotificationController - Send revoked notifications for indictment cases', () => {
+ const caseId = uuid()
+ const judgeName = uuid()
+ const judgeEmail = uuid()
+ const registrarName = uuid()
+ const registrarEmail = uuid()
+ const defenderNationalId = uuid()
+ const defenderName = uuid()
+ const defenderEmail = uuid()
+ const prosecutorsOfficeName = uuid()
+ const courtName = uuid()
+ const courtCaseNumber = uuid()
+ const theCase = {
+ id: caseId,
+ judge: { name: judgeName, email: judgeEmail },
+ registrar: { name: registrarName, email: registrarEmail },
+ defendants: [{ defenderNationalId, defenderName, defenderEmail }],
+ creatingProsecutor: { institution: { name: prosecutorsOfficeName } },
+ court: { name: courtName },
+ courtCaseNumber,
+ }
+
+ let mockEmailService: EmailService
+ let mockNotificationModel: typeof Notification
+ let givenWhenThen: GivenWhenThen
+
+ beforeEach(async () => {
+ const { emailService, notificationModel, internalNotificationController } =
+ await createTestingNotificationModule()
+
+ mockEmailService = emailService
+ mockNotificationModel = notificationModel
+
+ givenWhenThen = async (notifications?: Notification[]) => {
+ const then = {} as Then
+
+ await internalNotificationController
+ .sendCaseNotification(
+ theCase.id,
+ { ...theCase, notifications } as Case,
+ { type: NotificationType.REVOKED } as SendInternalNotificationDto,
+ )
+ .then((result) => (then.result = result))
+ .catch((error) => (then.error = error))
+
+ return then
+ }
+ })
+
+ describe('notifications sent', () => {
+ let then: Then
+
+ beforeEach(async () => {
+ then = await givenWhenThen([
+ {
+ type: NotificationType.COURT_DATE,
+ recipients: [{ address: defenderEmail, success: true }],
+ } as Notification,
+ ])
+ })
+
+ it('should send a notifications', () => {
+ expect(mockEmailService.sendEmail).toHaveBeenCalledWith(
+ expect.objectContaining({
+ to: [{ address: judgeEmail, name: judgeName }],
+ subject: `Ákæra afturkölluð í máli ${courtCaseNumber}`,
+ html: `${prosecutorsOfficeName} hefur afturkallað ákæru í máli ${courtCaseNumber}. Hægt er að nálgast yfirlitssíðu málsins á rettarvorslugatt.island.is.`,
+ }),
+ )
+ expect(mockEmailService.sendEmail).toHaveBeenCalledWith(
+ expect.objectContaining({
+ to: [{ address: registrarEmail, name: registrarName }],
+ subject: `Ákæra afturkölluð í máli ${courtCaseNumber}`,
+ html: `${prosecutorsOfficeName} hefur afturkallað ákæru í máli ${courtCaseNumber}. Hægt er að nálgast yfirlitssíðu málsins á rettarvorslugatt.island.is.`,
+ }),
+ )
+ expect(mockEmailService.sendEmail).toHaveBeenCalledWith(
+ expect.objectContaining({
+ to: [{ address: defenderEmail, name: defenderName }],
+ subject: `Ákæra afturkölluð í máli ${courtCaseNumber}`,
+ html: `Dómstóllinn hafði skráð þig sem verjanda í málinu.
Sjá nánar á yfirlitssíðu málsins í Réttarvörslugátt.`,
+ }),
+ )
+ expect(mockNotificationModel.create).toHaveBeenCalledWith({
+ caseId: caseId,
+ type: NotificationType.REVOKED,
+ recipients: [
+ { address: judgeEmail, success: true },
+ { address: registrarEmail, success: true },
+ { address: defenderEmail, success: true },
+ ],
+ })
+ expect(then.result).toEqual({ delivered: true })
+ })
+ })
+})
diff --git a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendRulingNotifications.spec.ts b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendRulingNotifications.spec.ts
index d8fa2a8618b1..73d76c2e2489 100644
--- a/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendRulingNotifications.spec.ts
+++ b/apps/judicial-system/backend/src/app/modules/notification/test/internalNotificationController/sendRulingNotifications.spec.ts
@@ -21,7 +21,6 @@ import { Case } from '../../../case'
import { Defendant, DefendantService } from '../../../defendant'
import { SendInternalNotificationDto } from '../../dto/sendInternalNotification.dto'
import { DeliverResponse } from '../../models/deliver.response'
-import { Notification } from '../../models/notification.model'
import { notificationModuleConfig } from '../../notification.config'
jest.mock('../../../../factories')
@@ -46,7 +45,6 @@ describe('InternalNotificationController - Send ruling notifications', () => {
let mockEmailService: EmailService
let mockConfig: ConfigType
- let mockNotificationModel: typeof Notification
let mockDefendantService: DefendantService
let givenWhenThen: GivenWhenThen
@@ -56,19 +54,14 @@ describe('InternalNotificationController - Send ruling notifications', () => {
const {
emailService,
notificationConfig,
- notificationModel,
defendantService,
internalNotificationController,
} = await createTestingNotificationModule()
mockEmailService = emailService
mockConfig = notificationConfig
- mockNotificationModel = notificationModel
mockDefendantService = defendantService
- const mockFindAll = mockNotificationModel.findAll as jest.Mock
- mockFindAll.mockResolvedValue([])
-
givenWhenThen = async (caseId: string, theCase: Case) => {
const then = {} as Then