Skip to content

Commit 426c179

Browse files
bulk edit: push groups to JIRA when sync is enabled (#14265)
1 parent 66bc7a9 commit 426c179

2 files changed

Lines changed: 104 additions & 1 deletion

File tree

dojo/finding/views.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2963,7 +2963,11 @@ def _bulk_push_to_jira(finds, form, note):
29632963
)
29642964
logger.debug("finding_groups: %s", finding_groups)
29652965
for group in finding_groups:
2966-
if form.cleaned_data.get("push_to_jira"):
2966+
if (
2967+
form.cleaned_data.get("push_to_jira")
2968+
or jira_helper.is_push_all_issues(group)
2969+
or jira_helper.is_keep_in_sync_with_jira(group)
2970+
):
29672971
(
29682972
can_be_pushed_to_jira,
29692973
error_message,

unittests/test_jira_import_and_pushing_api.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,105 @@ def test_bulk_edit_mixed_findings_and_groups_jira_push_bug(self, mock_webhooks,
10731073
self.assertEqual(len(group_calls), 2, "Expected 2 finding groups to be pushed")
10741074
self.assertEqual(len(individual_calls), 2, "Expected 2 individual findings to be pushed")
10751075

1076+
def _bulk_edit_finding_groups_without_checkbox(self):
1077+
"""
1078+
Helper: sets up a mixed grouped/ungrouped scenario and performs a bulk edit
1079+
WITHOUT the push_to_jira checkbox. Returns the test_id and finding IDs used.
1080+
"""
1081+
# Import scan with groups but don't push to JIRA initially
1082+
import0 = self.import_scan_with_params(
1083+
self.npm_groups_sample_filename,
1084+
scan_type="NPM Audit Scan",
1085+
group_by="component_name+component_version",
1086+
push_to_jira=False,
1087+
verified=True,
1088+
)
1089+
test_id = import0["test"]
1090+
1091+
# Verify no JIRA issues were created during import
1092+
self.assert_jira_issue_count_in_test(test_id, 0)
1093+
self.assert_jira_group_issue_count_in_test(test_id, 0)
1094+
1095+
# Get the finding groups created
1096+
finding_groups = Finding_Group.objects.filter(test__id=test_id)
1097+
1098+
# Create mixed scenario: some findings in groups, some ungrouped
1099+
if finding_groups.exists():
1100+
group_to_remove = finding_groups.first()
1101+
group_to_remove.findings.clear()
1102+
group_to_remove.delete()
1103+
1104+
# Verify we now have both grouped and ungrouped findings
1105+
all_findings = Finding.objects.filter(test__id=test_id)
1106+
grouped_findings = [f for f in all_findings if f.finding_group is not None]
1107+
ungrouped_findings = [f for f in all_findings if f.finding_group is None]
1108+
1109+
self.assertGreater(len(grouped_findings), 0, "Should have some grouped findings")
1110+
self.assertGreater(len(ungrouped_findings), 0, "Should have some ungrouped findings")
1111+
1112+
current_findings = Finding.objects.filter(test__id=test_id)
1113+
all_finding_ids = [str(f.id) for f in current_findings]
1114+
1115+
admin_user = get_user_model().objects.get(username="admin")
1116+
self.client.force_login(admin_user)
1117+
1118+
# NOTE: push_to_jira is NOT in the post data -- the checkbox is unchecked
1119+
post_data = {
1120+
"finding_to_update": all_finding_ids,
1121+
"severity": "",
1122+
"active": "",
1123+
"verified": "",
1124+
"false_p": "",
1125+
"duplicate": "",
1126+
"out_of_scope": "",
1127+
"is_mitigated": "",
1128+
"status": "",
1129+
}
1130+
1131+
self.client.post("/finding/bulk", post_data)
1132+
1133+
@patch("dojo.jira_link.helper.can_be_pushed_to_jira", return_value=(True, None, None))
1134+
@patch("dojo.jira_link.helper.is_push_all_issues", return_value=True)
1135+
@patch("dojo.jira_link.helper.push_to_jira", return_value=None)
1136+
@patch("dojo.notifications.helper.WebhookNotificationManger.send_webhooks_notification")
1137+
def test_bulk_edit_push_all_issues_pushes_finding_groups(self, mock_webhooks, mock_push_to_jira, mock_is_push_all_issues, mock_can_be_pushed):
1138+
"""
1139+
When push_all_issues is enabled on the JIRA project, bulk editing findings
1140+
should push finding groups to JIRA even without the push_to_jira checkbox.
1141+
"""
1142+
self._bulk_edit_finding_groups_without_checkbox()
1143+
1144+
group_calls = [call for call in mock_push_to_jira.call_args_list if isinstance(call[0][0], Finding_Group)]
1145+
individual_calls = [call for call in mock_push_to_jira.call_args_list if isinstance(call[0][0], Finding)]
1146+
1147+
self.assertGreater(len(group_calls), 0, "Finding groups should be pushed when push_all_issues is enabled")
1148+
self.assertGreater(len(individual_calls), 0, "Individual ungrouped findings should be pushed when push_all_issues is enabled")
1149+
1150+
self.assertEqual(len(group_calls), 2, "Expected 2 finding groups to be pushed")
1151+
self.assertEqual(len(individual_calls), 2, "Expected 2 individual findings to be pushed")
1152+
1153+
@patch("dojo.jira_link.helper.can_be_pushed_to_jira", return_value=(True, None, None))
1154+
@patch("dojo.jira_link.helper.is_keep_in_sync_with_jira", return_value=True)
1155+
@patch("dojo.jira_link.helper.is_push_all_issues", return_value=False)
1156+
@patch("dojo.jira_link.helper.push_to_jira", return_value=None)
1157+
@patch("dojo.notifications.helper.WebhookNotificationManger.send_webhooks_notification")
1158+
def test_bulk_edit_keep_in_sync_pushes_finding_groups(self, mock_webhooks, mock_push_to_jira, mock_is_push_all_issues, mock_is_keep_in_sync, mock_can_be_pushed):
1159+
"""
1160+
When keep_in_sync_with_jira (finding_jira_sync) is enabled on the JIRA instance,
1161+
bulk editing findings should push finding groups to JIRA even without the
1162+
push_to_jira checkbox.
1163+
"""
1164+
self._bulk_edit_finding_groups_without_checkbox()
1165+
1166+
group_calls = [call for call in mock_push_to_jira.call_args_list if isinstance(call[0][0], Finding_Group)]
1167+
individual_calls = [call for call in mock_push_to_jira.call_args_list if isinstance(call[0][0], Finding)]
1168+
1169+
self.assertGreater(len(group_calls), 0, "Finding groups should be pushed when keep_in_sync is enabled")
1170+
self.assertGreater(len(individual_calls), 0, "Individual ungrouped findings should be pushed when keep_in_sync is enabled")
1171+
1172+
self.assertEqual(len(group_calls), 2, "Expected 2 finding groups to be pushed")
1173+
self.assertEqual(len(individual_calls), 2, "Expected 2 individual findings to be pushed")
1174+
10761175
def test_keep_sync_push_finding_then_update_individual_finding_with_no_push(self):
10771176
"""
10781177
With keep_sync enabled, import a scan with push_to_jira=True, then update one of the

0 commit comments

Comments
 (0)