@@ -18,6 +18,8 @@ import { faker } from '@faker-js/faker';
1818import { Test } from '@nestjs/testing' ;
1919import {
2020 AlertDefinition ,
21+ AlertState ,
22+ AlertStatus ,
2123 Counterparty ,
2224 Customer ,
2325 PaymentMethod ,
@@ -316,6 +318,145 @@ describe('AlertService', () => {
316318 const alerts = await prismaService . alert . findMany ( ) ;
317319 expect ( alerts ) . toHaveLength ( 0 ) ;
318320 } ) ;
321+
322+ test ( 'Assigning and deciding alerts should set audit timestamps' , async ( ) => {
323+ // Arrange
324+ await baseTransactionFactory
325+ . withBusinessBeneficiary ( )
326+ . withEndUserOriginator ( )
327+ . amount ( ALERT_DEFINITIONS . STRUC_CC . inlineRule . options . amountBetween . min + 1 )
328+ . direction ( TransactionDirection . inbound )
329+ . paymentMethod ( PaymentMethod . credit_card )
330+ . count ( ALERT_DEFINITIONS . STRUC_CC . inlineRule . options . amountThreshold + 1 )
331+ . create ( ) ;
332+
333+ // Act
334+ await alertService . checkAllAlerts ( ) ;
335+
336+ // Assert
337+ const alerts = await prismaService . alert . findMany ( ) ;
338+
339+ expect ( alerts ) . toHaveLength ( 1 ) ;
340+
341+ const user = await prismaService . user . create ( {
342+ data : {
343+ firstName : 'Test' ,
344+ lastName : 'User' ,
345+ password : '' ,
346+ email : faker . internet . email ( ) ,
347+ roles : [ ] ,
348+ } ,
349+ } ) ;
350+
351+ await alertService . updateAlertsAssignee (
352+ alerts . map ( alert => alert . id ) ,
353+ project . id ,
354+ user . id ,
355+ ) ;
356+
357+ const assignedAlerts = await prismaService . alert . findMany ( {
358+ where : {
359+ assignedAt : {
360+ not : null ,
361+ } ,
362+ } ,
363+ } ) ;
364+ expect ( assignedAlerts ) . toHaveLength ( 1 ) ;
365+ expect ( assignedAlerts [ 0 ] ?. assignedAt ) . toBeInstanceOf ( Date ) ;
366+ expect ( assignedAlerts [ 0 ] ?. assignedAt ) . not . toBeNull ( ) ;
367+ // whenever update Decision we set the assignee to the authicated user
368+ await alertService . updateAlertsDecision (
369+ alerts . map ( alert => alert . id ) ,
370+ project . id ,
371+ AlertState . rejected ,
372+ ) ;
373+
374+ const updatedAlerts = await prismaService . alert . findMany ( {
375+ where : {
376+ decisionAt : {
377+ not : null ,
378+ } ,
379+ } ,
380+ } ) ;
381+
382+ expect ( updatedAlerts ) . toHaveLength ( 1 ) ;
383+ expect ( updatedAlerts [ 0 ] ?. decisionAt ) . toBeInstanceOf ( Date ) ;
384+ expect ( updatedAlerts [ 0 ] ?. decisionAt ) . not . toBeNull ( ) ;
385+ expect ( updatedAlerts [ 0 ] ?. status ) . toBe ( AlertStatus . completed ) ;
386+ } ) ;
387+
388+ test ( 'Dedupe - Alert should be deduped' , async ( ) => {
389+ // Arrange
390+ await baseTransactionFactory
391+ . withBusinessBeneficiary ( )
392+ . withEndUserOriginator ( )
393+ . amount ( ALERT_DEFINITIONS . STRUC_CC . inlineRule . options . amountBetween . min + 1 )
394+ . direction ( TransactionDirection . inbound )
395+ . paymentMethod ( PaymentMethod . credit_card )
396+ . count ( ALERT_DEFINITIONS . STRUC_CC . inlineRule . options . amountThreshold + 1 )
397+ . create ( ) ;
398+
399+ await alertService . checkAllAlerts ( ) ;
400+
401+ const alerts = await prismaService . alert . findMany ( ) ;
402+
403+ expect ( alerts ) . toHaveLength ( 1 ) ;
404+
405+ // Act
406+ await alertService . checkAllAlerts ( ) ;
407+
408+ // Assert
409+ const updatedAlerts = await prismaService . alert . findMany ( {
410+ where : {
411+ dedupedAt : {
412+ not : null ,
413+ } ,
414+ } ,
415+ } ) ;
416+
417+ expect ( updatedAlerts ) . toHaveLength ( 1 ) ;
418+ expect ( updatedAlerts [ 0 ] ?. dedupedAt ) . toBeInstanceOf ( Date ) ;
419+ expect ( updatedAlerts [ 0 ] ?. dedupedAt ) . not . toBeNull ( ) ;
420+ } ) ;
421+
422+ test ( 'Dedupe - Only non completed alerts will be dedupe' , async ( ) => {
423+ // Arrange
424+ await baseTransactionFactory
425+ . withBusinessBeneficiary ( )
426+ . withEndUserOriginator ( )
427+ . amount ( ALERT_DEFINITIONS . STRUC_CC . inlineRule . options . amountBetween . min + 1 )
428+ . direction ( TransactionDirection . inbound )
429+ . paymentMethod ( PaymentMethod . credit_card )
430+ . count ( ALERT_DEFINITIONS . STRUC_CC . inlineRule . options . amountThreshold + 1 )
431+ . create ( ) ;
432+
433+ await alertService . checkAllAlerts ( ) ;
434+
435+ const alerts = await prismaService . alert . findMany ( ) ;
436+
437+ expect ( alerts ) . toHaveLength ( 1 ) ;
438+
439+ // whenever update Decision we set the assignee to the authicated user
440+ await alertService . updateAlertsDecision (
441+ alerts . map ( alert => alert . id ) ,
442+ project . id ,
443+ AlertState . rejected ,
444+ ) ;
445+
446+ // Act
447+ await alertService . checkAllAlerts ( ) ;
448+
449+ // Assert
450+ const updatedAlerts = await prismaService . alert . findMany ( {
451+ where : {
452+ dedupedAt : {
453+ not : null ,
454+ } ,
455+ } ,
456+ } ) ;
457+
458+ expect ( updatedAlerts ) . toHaveLength ( 0 ) ;
459+ } ) ;
319460 } ) ;
320461
321462 describe ( 'Rule: STRUC_APM' , ( ) => {
@@ -1013,28 +1154,6 @@ describe('AlertService', () => {
10131154 ) ;
10141155 } ) ;
10151156
1016- it ( 'When there more than 1k credit card transactions, an alert should be created' , async ( ) => {
1017- // Arrange
1018- await baseTransactionFactory
1019- . withBusinessBeneficiary ( )
1020- . direction ( TransactionDirection . inbound )
1021- . paymentMethod ( PaymentMethod . credit_card )
1022- . amount ( ALERT_DEFINITIONS . PAY_HCA_CC . inlineRule . options . amountThreshold + 1 )
1023- . count ( 1 )
1024- . create ( ) ;
1025-
1026- // Act
1027- await alertService . checkAllAlerts ( ) ;
1028-
1029- // Assert
1030- const alerts = await prismaService . alert . findMany ( ) ;
1031- expect ( alerts ) . toHaveLength ( 1 ) ;
1032- expect ( alerts [ 0 ] ?. alertDefinitionId ) . toEqual ( alertDefinition . id ) ;
1033- expect ( alerts [ 0 ] as any ) . toMatchObject ( {
1034- executionDetails : { executionRow : { transactionCount : '1' , totalAmount : 1001 } } ,
1035- } ) ;
1036- } ) ;
1037-
10381157 it ( 'When there are few transaction, no alert should be created' , async ( ) => {
10391158 // Arrange
10401159 await baseTransactionFactory
@@ -1113,28 +1232,6 @@ describe('AlertService', () => {
11131232 } ) ;
11141233 } ) ;
11151234
1116- it ( 'When there more than 1k credit card transactions, an alert should be created' , async ( ) => {
1117- // Arrange
1118- await baseTransactionFactory
1119- . withBusinessBeneficiary ( )
1120- . direction ( TransactionDirection . inbound )
1121- . paymentMethod ( PaymentMethod . debit_card )
1122- . amount ( 2 )
1123- . count ( ALERT_DEFINITIONS . PAY_HCA_APM . inlineRule . options . amountThreshold + 1 )
1124- . create ( ) ;
1125-
1126- // Act
1127- await alertService . checkAllAlerts ( ) ;
1128-
1129- // Assert
1130- const alerts = await prismaService . alert . findMany ( ) ;
1131- expect ( alerts ) . toHaveLength ( 1 ) ;
1132- expect ( alerts [ 0 ] ?. alertDefinitionId ) . toEqual ( alertDefinition . id ) ;
1133- expect ( alerts [ 0 ] as any ) . toMatchObject ( {
1134- executionDetails : { executionRow : { transactionCount : '1001' , totalAmount : 2002 } } ,
1135- } ) ;
1136- } ) ;
1137-
11381235 it ( 'When there are few transaction, no alert should be created' , async ( ) => {
11391236 // Arrange
11401237 await baseTransactionFactory
0 commit comments