@@ -370,6 +370,81 @@ func TestMarkFindingsByDDFindings(t *testing.T) {
370370 assert .Equal (t , models .FindingStatusDuplicate , result [0 ].Status )
371371 })
372372
373+ t .Run ("Should mark finding as INACTIVE when DD finding has out_of_scope=true" , func (t * testing.T ) {
374+ local := []models.Finding {
375+ localFinding ("LOW" , "Info leak" , "src/leak.go" , 3 , "Redact output" ),
376+ }
377+ ddFindings := []defectdojo.Finding {
378+ {Title : "Info leak" , Severity : "Low" , FilePath : "src/leak.go" , Line : 3 ,
379+ Mitigation : "Redact output" , Active : false , Duplicate : false , OutOfScope : true },
380+ }
381+
382+ result := MarkFindingsByDDFindings (local , ddFindings )
383+
384+ assert .Len (t , result , 1 )
385+ assert .Equal (t , models .FindingStatusInactive , result [0 ].Status )
386+ })
387+
388+ t .Run ("Should mark finding as INACTIVE when DD finding has risk_accepted=true" , func (t * testing.T ) {
389+ local := []models.Finding {
390+ localFinding ("HIGH" , "Weak Cipher" , "src/crypto.go" , 8 , "Use AES-256" ),
391+ }
392+ ddFindings := []defectdojo.Finding {
393+ {Title : "Weak Cipher" , Severity : "High" , FilePath : "src/crypto.go" , Line : 8 ,
394+ Mitigation : "Use AES-256" , Active : false , Duplicate : false , RiskAccepted : true },
395+ }
396+
397+ result := MarkFindingsByDDFindings (local , ddFindings )
398+
399+ assert .Len (t , result , 1 )
400+ assert .Equal (t , models .FindingStatusInactive , result [0 ].Status )
401+ })
402+
403+ t .Run ("Should mark finding as INACTIVE when DD finding has false_p=true" , func (t * testing.T ) {
404+ local := []models.Finding {
405+ localFinding ("MEDIUM" , "Path Traversal" , "src/files.go" , 21 , "Validate path" ),
406+ }
407+ ddFindings := []defectdojo.Finding {
408+ {Title : "Path Traversal" , Severity : "Medium" , FilePath : "src/files.go" , Line : 21 ,
409+ Mitigation : "Validate path" , Active : false , Duplicate : false , FalseP : true },
410+ }
411+
412+ result := MarkFindingsByDDFindings (local , ddFindings )
413+
414+ assert .Len (t , result , 1 )
415+ assert .Equal (t , models .FindingStatusInactive , result [0 ].Status )
416+ })
417+
418+ t .Run ("Should mark finding as INACTIVE when risk_accepted=true even if active=true" , func (t * testing.T ) {
419+ local := []models.Finding {
420+ localFinding ("CRITICAL" , "Insecure Deserialization" , "src/serde.go" , 55 , "Use safe parser" ),
421+ }
422+ ddFindings := []defectdojo.Finding {
423+ {Title : "Insecure Deserialization" , Severity : "Critical" , FilePath : "src/serde.go" , Line : 55 ,
424+ Mitigation : "Use safe parser" , Active : true , Duplicate : false , RiskAccepted : true },
425+ }
426+
427+ result := MarkFindingsByDDFindings (local , ddFindings )
428+
429+ assert .Len (t , result , 1 )
430+ assert .Equal (t , models .FindingStatusInactive , result [0 ].Status )
431+ })
432+
433+ t .Run ("Should prioritise duplicate=true over risk_accepted=true" , func (t * testing.T ) {
434+ local := []models.Finding {
435+ localFinding ("HIGH" , "Vuln2" , "src/main2.go" , 6 , "Fix it" ),
436+ }
437+ ddFindings := []defectdojo.Finding {
438+ {Title : "Vuln2" , Severity : "High" , FilePath : "src/main2.go" , Line : 6 ,
439+ Mitigation : "Fix it" , Active : false , Duplicate : true , RiskAccepted : true },
440+ }
441+
442+ result := MarkFindingsByDDFindings (local , ddFindings )
443+
444+ assert .Len (t , result , 1 )
445+ assert .Equal (t , models .FindingStatusDuplicate , result [0 ].Status )
446+ })
447+
373448 t .Run ("Should default to ACTIVE when local finding has no DD counterpart" , func (t * testing.T ) {
374449 local := []models.Finding {
375450 localFinding ("HIGH" , "New Finding" , "src/new.go" , 1 , "Fix it" ),
0 commit comments