def test_get_issuetracker_info(self, api_value, tmpl_value, audit_value, expected, mock_tmpl, mock_audit): """Test _get_issuetracker_info(api_val={0}, tmpl_val={1}, audit_val={2})""" # pylint: disable=protected-access,too-many-arguments asmt = mock.Mock() asmt.title = 'T' api_dict = dict() if api_value is not None: api_dict['issue_tracker'] = api_value if tmpl_value is not None: api_dict['template'] = {'type': 'A', 'id': 'B'} mock_tmpl.return_value = tmpl_value else: mock_tmpl.return_value = {} if audit_value is not None: api_dict['audit'] = {'type': 'A', 'id': 'B'} mock_audit.return_value = audit_value else: mock_audit.return_value = {} # test result tracker_handler = assessment_integration.AssessmentTrackerHandler() ret = tracker_handler._get_issuetracker_info(asmt, api_dict) self.assertEqual(ret, expected)
def handle_assessment_post(sender, objects=None, sources=None, service=None): """Applies custom attribute definitions and maps people roles. Applicable when generating Assessment with template. Args: sender: A class of Resource handling the POST request. objects: A list of model instances created from the POSTed JSON. sources: A list of original POSTed JSON dictionaries. """ del sender, service # Unused db.session.flush() for assessment, src in itertools.izip(objects, sources): _handle_assessment(assessment, src) # Flush roles objects for generated assessments. db.session.flush() tracker_handler = assessment_integration.AssessmentTrackerHandler() for assessment, src in itertools.izip(objects, sources): # Handling IssueTracker info here rather than in hooks/issue_tracker # would avoid querying same data (such as snapshots, audits and # templates) twice. tracker_handler.handle_assessment_create(assessment, src)
def test_is_issue_on_create_enabled(self, is_tracker_enabled, api_issue_dict, tmpl_issue_dict, expected, mock_tracker_enabled, mock_template): """Test _is_issue_on_create_enabled(in_audit={0}, api={1}, tmpl={2})""" # pylint: disable=protected-access,too-many-arguments # prepare Assessment instance asmt = mock.Mock() asmt.audit = mock.Mock() mock_tracker_enabled.return_value = is_tracker_enabled # prepare API dictionary api_dict = {} if api_issue_dict is not None: api_dict['issue_tracker'] = api_issue_dict if tmpl_issue_dict is not None: api_dict['template'] = {} mock_template.return_value = tmpl_issue_dict else: mock_template.return_value = {} # test result tracker_handler = assessment_integration.AssessmentTrackerHandler() ret = tracker_handler._is_issue_on_create_enabled(asmt, api_dict) self.assertEqual(ret, expected)
def handle_assessment_post(sender, objects=None, sources=None, service=None): """Applies custom attribute definitions and maps people roles. Applicable when generating Assessment with template. Args: sender: A class of Resource handling the POST request. objects: A list of model instances created from the POSTed JSON. sources: A list of original POSTed JSON dictionaries. """ del sender, service # Unused db.session.flush() audit, template = None, None for assessment, src in itertools.izip(objects, sources): audit = _get_object_from_src(src, _get_audit_id, all_models.Audit, current=audit) template = _get_object_from_src(src, _get_template_id, all_models.AssessmentTemplate, current=template) snapshot_rev_content = None snapshot = _get_object_from_src(src, _get_snapshot_id, all_models.Snapshot) if snapshot is not None: # Since every content call on revision leads to it calculation (and # one is quite expensive) it is better for performance to compute it # one time and pass it everywhere though it may seem redundant. snapshot_rev_content = snapshot.revision.content _handle_assessment( assessment, audit, tmpl=template, snapshot=snapshot, snapshot_rev_content=snapshot_rev_content, is_autogenerated=_is_autogenerated(src), ) _batch_insert_cads(attributables=objects) _batch_insert_acps(assessments=objects) # Flush roles objects for generated assessments. db.session.flush() tracker_handler = assessment_integration.AssessmentTrackerHandler() for assessment, src in itertools.izip(objects, sources): # Handling IssueTracker info here rather than in hooks/issue_tracker # would avoid querying same data (such as snapshots, audits and # templates) twice. integration_utils.update_issue_tracker_for_import(assessment) tracker_handler.handle_assessment_create(assessment, src)
def test_merge_ccs_method(self, object_ccs, additional_ccs, expected_ccs): """Test merge_ccs method""" # pylint: disable=protected-access tracker_handler = assessment_integration.AssessmentTrackerHandler() grouped_ccs = tracker_handler._merge_ccs( object_ccs, additional_ccs, ) self.assertEqual(set(grouped_ccs), set(expected_ccs))
def test_validate_info(self, info, expected_error): """Test _validate_issue_tracker_info function.""" initial_info = dict(info) tracker_handler = assessment_integration.AssessmentTrackerHandler() # pylint: disable=protected-access if expected_error: with self.assertRaises(expected_error): tracker_handler._validate_generic_fields(info) else: tracker_handler._validate_generic_fields(info) self.assertEqual(info, initial_info)
def test_assignee_sync_not_exists(self): """Test for get assignee on sync if not assignee exists.""" # pylint: disable=protected-access assmt_object = mock.MagicMock(id=1) with mock.patch.object(assessment_integration.AssessmentTrackerHandler, '_is_assignee_exists', return_value=False): tracker_handler = assessment_integration.AssessmentTrackerHandler() reporter = "*****@*****.**" reporter_tracker = tracker_handler._get_assignee_on_sync( assmt_object, reporter) self.assertEqual("*****@*****.**", reporter_tracker)
def test_reporter_sync_exists(self): """Test for get reporter on sync if reporter exists.""" # pylint: disable=protected-access mock_object = mock.MagicMock(id=1) with mock.patch.object(assessment_integration.AssessmentTrackerHandler, '_is_reporter_exists', return_value=True): tracker_handler = assessment_integration.AssessmentTrackerHandler() reporter = "*****@*****.**" reporter_tracker = tracker_handler._get_reporter_on_sync( mock_object, reporter) self.assertEqual(reporter, reporter_tracker)
def sync_assessment_attributes(): # noqa """Synchronizes issue tracker ticket statuses with the Assessment statuses. Checks for Assessments which are in sync with Issue Tracker issues and updates their statuses in accordance to the corresponding Assessments if differ. """ logger.info( "Assessment synchronization start: %s", datetime.datetime.utcnow() ) assessment_issues = sync_utils.collect_issue_tracker_info( "Assessment" ) if not assessment_issues: return logger.info("Syncing state of %d issues.", len(assessment_issues)) processed_ids = set() tracker_handler = assessment_integration.AssessmentTrackerHandler() for batch in sync_utils.iter_issue_batches(assessment_issues.keys()): for issue_id, issuetracker_state in batch.iteritems(): issue_id, issue_info = _get_issue_info_by_issue_id( issue_id, assessment_issues ) if not issue_info: logger.warning( "Got an unexpected issue from Issue Tracker: %s", issue_id ) continue processed_ids.add(issue_id) try: tracker_handler.handle_assessment_sync( issue_info, issue_id, issuetracker_state ) except Exception as ex: # pylint: disable=broad-except logger.error( "Unhandled synchronization error: %s %s %s", issue_id, issue_info, ex ) continue logger.info("Sync is done, %d issue(s) were processed.", len(processed_ids)) _check_missing_ids(assessment_issues, processed_ids)
def test_is_issue_create_disabled(self): """Test 'is issue tracker disabled' on create.""" # pylint: disable=protected-access assessment_src = { "issue_tracker": { "enabled": False, }, } tracker_handler = assessment_integration.AssessmentTrackerHandler() is_issue_enabled = tracker_handler._is_issue_on_create_enabled( assessment_src) self.assertFalse(is_issue_enabled)
def test_is_issue_disabled_template(self, return_value, get_issue_mock): """Test 'is issue tracker disabled' from assessment template.""" # pylint: disable=protected-access get_issue_mock.return_value = return_value assessment_src = { "template": { "type": 1, "id": 1, }, } tracker_handler = assessment_integration.AssessmentTrackerHandler() is_issue_enabled = tracker_handler._is_issue_on_create_enabled( assessment_src) self.assertFalse(is_issue_enabled)
def test_change_assessment_status(self, status, additional_kwargs, mocked_update_issue): """Issue status should be changed for assessment with {status} status.""" iti_issue_id = [] iti = factories.IssueTrackerIssueFactory( enabled=True, component_id="123123", issue_type="PROCESS", issue_priority="P2", issue_severity="S2" ) iti_issue_id.append(iti.issue_id) asmt = iti.issue_tracked_obj tracker_handler = assessment_integration.AssessmentTrackerHandler() with mock.patch.object( assessment_integration.AssessmentTrackerHandler, '_is_tracker_enabled', return_value=True ): self.api.put( asmt, { "status": status, }, ) kwargs = {'component_id': 123123, 'severity': "S2", 'title': iti.title, 'hotlist_ids': [], 'priority': "P2"} asmt_link = tracker_handler._get_assessment_page_url(asmt) if 'comment' in additional_kwargs: try: additional_kwargs['comment'] = \ additional_kwargs['comment'] % (status, asmt_link) except TypeError: pass kwargs.update(additional_kwargs) mocked_update_issue.assert_called_once_with(iti_issue_id[0], kwargs) issue = db.session.query(models.IssuetrackerIssue).get(iti.id) self.assertEqual(issue.cc_list, "")
def test_is_need_sync(self, custom_same, common_same, ccs_same, custom_mock, common_mock, ccs_mock): """Test _is_need_sync works correctly. Test that assessment needs to be synced with Issue Tracker when either ccs, common or custom fields differ. """ asmt_handler = assessment_integration.AssessmentTrackerHandler() custom_mock.return_value = (custom_same, True) common_mock.return_value = common_same ccs_mock.return_value = ccs_same assessment_id = 0 self.assertEqual( not all([custom_same, common_same, ccs_same]), asmt_handler._is_need_sync( assessment_id=assessment_id, issue_payload={"status": "Not Started"}, issue_tracker_info={"status": "ASSIGNED"}), )
def test_adding_comment_to_assessment(self, desc, mocked_update_issue): """Test adding comment with blank lines in the end.""" with mock.patch.object( assessment_integration.AssessmentTrackerHandler, '_is_tracker_enabled', return_value=True ): iti = factories.IssueTrackerIssueFactory( enabled=True, component_id="11111", hotlist_id="222222", issue_type="PROCESS", issue_priority="P2", issue_severity="S2" ) iti_title = iti.title iti_issue_id = iti.issue_id asmt = iti.issue_tracked_obj comment = factories.CommentFactory(description=desc) self.api.put(asmt, { "actions": {"add_related": [{"id": comment.id, "type": "Comment"}]}, }) tracker_handler = assessment_integration.AssessmentTrackerHandler() asmt = db.session.query(models.Assessment).get(asmt.id) builder_class = params_builder.BaseIssueTrackerParamsBuilder expected_comment = builder_class.COMMENT_TMPL.format( author=None, comment="test comment", model="Assessment", link=tracker_handler._get_assessment_page_url(asmt), ) kwargs = {'status': 'ACCEPTED', 'component_id': 11111, 'severity': "S2", 'title': iti_title, 'hotlist_ids': [222222], 'priority': "P2", 'comment': expected_comment} mocked_update_issue.assert_called_once_with(iti_issue_id, kwargs)
def test_prepare_update_json(self): """Test prepare_update_json method for Assessment.""" with factories.single_commit(): audit = factories.AuditFactory() factories.IssueTrackerIssueFactory( enabled=True, issue_tracked_obj=audit, component_id=213, hotlist_id=333, issue_type=constants.DEFAULT_ISSUETRACKER_VALUES['issue_type'], issue_priority="P0", issue_severity="S0", ) assmt = factories.AssessmentFactory( audit=audit, title="title", ) factories.IssueTrackerIssueFactory( enabled=True, issue_tracked_obj=assmt, title='', ) tracker_handler = assessment_integration.AssessmentTrackerHandler() without_info = tracker_handler.prepare_issue_update_json(assmt) issue_info = assmt.issue_tracker with_info = tracker_handler.prepare_issue_update_json( assmt, issue_info ) expected_info = { 'component_id': 213, 'severity': u'S0', 'title': assmt.title, 'hotlist_ids': [333, ], 'priority': u'P0', 'type': constants.DEFAULT_ISSUETRACKER_VALUES['issue_type'], } self.assertEqual(expected_info, with_info) self.assertEqual(without_info, with_info)