-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4289 from GSA-TTS/main
- Loading branch information
Showing
14 changed files
with
180 additions
and
1 deletion.
There are no files selected for viewing
Binary file added
BIN
+487 KB
...d_fail/audit-findings/has_duplicate_finding_reference_with_different_finding_details.xlsx
Binary file not shown.
67 changes: 67 additions & 0 deletions
67
backend/audit/intakelib/checks/check_finding_uniqueness.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from ..common.util import build_cell_error_tuple, get_message, get_range_start_row | ||
from ..intermediate_representation import get_range_by_name, get_range_values_by_name | ||
|
||
|
||
def check_finding_uniqueness(ir, is_gsa_migration=False): | ||
""" | ||
Check the uniqueness of finding associated with the same finding reference number. | ||
""" | ||
|
||
errors = [] | ||
findings_by_reference = {} | ||
|
||
if is_gsa_migration: | ||
return errors | ||
|
||
modified_opinion = get_range_values_by_name(ir, "modified_opinion") | ||
other_matters = get_range_values_by_name(ir, "other_matters") | ||
material_weakness = get_range_values_by_name(ir, "material_weakness") | ||
significant_deficiency = get_range_values_by_name(ir, "significant_deficiency") | ||
other_findings = get_range_values_by_name(ir, "other_findings") | ||
finding_references = get_range_values_by_name(ir, "reference_number") | ||
compliance_requirements = get_range_values_by_name(ir, "compliance_requirement") | ||
questioned_costs = get_range_values_by_name(ir, "questioned_costs") | ||
repeat_prior_reference = get_range_values_by_name(ir, "repeat_prior_reference") | ||
prior_references = get_range_values_by_name(ir, "prior_references") | ||
|
||
reference_number_range = get_range_by_name(ir, "reference_number") | ||
range_start = int(get_range_start_row(reference_number_range)) | ||
# Iterate through the data rows | ||
for ndx, (fr, cr, mo, om, mw, sd, of, qc, rr, pr) in enumerate( | ||
zip( | ||
finding_references, | ||
compliance_requirements, | ||
modified_opinion, | ||
other_matters, | ||
material_weakness, | ||
significant_deficiency, | ||
other_findings, | ||
questioned_costs, | ||
repeat_prior_reference, | ||
prior_references, | ||
) | ||
): | ||
|
||
finding_set = (fr, cr, mo, om, mw, sd, of, qc, rr, pr) | ||
|
||
if fr in findings_by_reference: | ||
if findings_by_reference[fr]["values"] != finding_set: | ||
previous_row = findings_by_reference[fr]["row"] | ||
current_row = ndx | ||
errors.append( | ||
build_cell_error_tuple( | ||
ir, | ||
reference_number_range, | ||
ndx, | ||
get_message("check_finding_uniqueness").format( | ||
range_start + previous_row, | ||
f'|{" | ".join(findings_by_reference[fr]["values"])}|', | ||
range_start + current_row, | ||
f'|{" | ".join(finding_set)}|', | ||
), | ||
) | ||
) | ||
else: | ||
findings_by_reference[fr] = {"values": finding_set, "row": ndx} | ||
|
||
return errors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
from django.test import SimpleTestCase | ||
|
||
from audit.intakelib.checks.check_finding_uniqueness import check_finding_uniqueness | ||
|
||
|
||
class TestCheckFindingUniqueness(SimpleTestCase): | ||
def setUp(self): | ||
self.ir = [ | ||
{ | ||
"name": "Form", | ||
"ranges": [ | ||
{ | ||
"name": "reference_number", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "20001"}, | ||
"values": ["FR1", "FR1", "FR2"], | ||
}, | ||
{ | ||
"name": "compliance_requirement", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "2"}, | ||
"values": ["CR1", "CR1", "CR2"], | ||
}, | ||
{ | ||
"name": "modified_opinion", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "2"}, | ||
"values": ["MO1", "MO1", "MO2"], | ||
}, | ||
{ | ||
"name": "other_matters", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "20001"}, | ||
"values": ["OM1", "OM1", "OM2"], | ||
}, | ||
{ | ||
"name": "material_weakness", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "2"}, | ||
"values": ["MW1", "MW1", "MW2"], | ||
}, | ||
{ | ||
"name": "significant_deficiency", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "20001"}, | ||
"values": ["SD1", "SD1", "SD2"], | ||
}, | ||
{ | ||
"name": "other_findings", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "2"}, | ||
"values": ["OF1", "OF1", "OF2"], | ||
}, | ||
{ | ||
"name": "questioned_costs", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "20001"}, | ||
"values": ["QC1", "QC1", "QC2"], | ||
}, | ||
{ | ||
"name": "repeat_prior_reference", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "2"}, | ||
"values": ["RR1", "RR1", "RR2"], | ||
}, | ||
{ | ||
"name": "prior_references", | ||
"start_cell": {"column": "A", "row": "2"}, | ||
"end_cell": {"column": "A", "row": "20001"}, | ||
"values": ["PR1", "PR1", "PR2"], | ||
}, | ||
], | ||
} | ||
] | ||
|
||
def test_unique_finding_success(self): | ||
""" | ||
Test case where all findings are unique for each reference. | ||
""" | ||
errors = check_finding_uniqueness(self.ir) | ||
self.assertEqual(errors, []) | ||
|
||
def test_duplicate_finding_reference(self): | ||
""" | ||
Test case where a finding reference has multiple different findings associated with it. | ||
""" | ||
# Modify the finding sets to simulate a mismatch for FR1 | ||
self.ir[0]["ranges"][6]["values"] = [ | ||
"OF1", | ||
"OF2", | ||
"OF2", | ||
] # Change in `other_findings` | ||
|
||
errors = check_finding_uniqueness(self.ir) | ||
|
||
# Expect an error for FR1 due to different findings in rows 0 and 1 | ||
self.assertEqual(len(errors), 1) | ||
self.assertIn("On row", errors[0][3]["text"]) | ||
|
||
def test_gsa_migration(self): | ||
""" | ||
Test case where is_gsa_migration is True and no errors should be returned. | ||
""" | ||
errors = check_finding_uniqueness(self.ir, is_gsa_migration=True) | ||
self.assertEqual(errors, []) |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.