@@ -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