def test_notify_creates_new_issue_no_match(self, get_config_mock): """Test notifier creates a new issue when no match exists.""" config_mock = create_autospec(ComplianceConfig) config_mock.get.side_effect = [ { 'foo': { 'repo': ['foo/bar'], 'status': ['pass'] } }, 'https://github.com/foo/bar' ] get_config_mock.return_value = config_mock controls = create_autospec(ControlDescriptor) controls.get_accreditations.return_value = ['foo'] self.search_issues_mock.return_value = [] notifier = GHIssuesNotifier(self.results, controls) notifier.notify() self.search_issues_mock.assert_called_once_with( 'pass_example type:issue in:title is:open repo:foo/bar' ) self.assertEqual(self.add_issue_mock.call_count, 1) args, kwargs = self.add_issue_mock.call_args self.assertEqual(len(args), 4) self.assertEqual(args[0], 'foo') self.assertEqual(args[1], 'bar') self.assertEqual(args[2], 'pass_example') self.assertTrue(args[3].startswith('## Compliance check alert')) self.assertEqual( kwargs, { 'assignees': [], 'labels': ['accreditation: foo', 'run status: pass'] } ) self.patch_issue_mock.assert_not_called() self.add_issue_comment_mock.assert_not_called()
def test_notify_plain_summary_issue(self, get_config_mock): """Test notifier creates a new plain summary issue.""" config_mock = create_autospec(ComplianceConfig) config_mock.get.side_effect = [ { 'accred_foo': { 'repo': ['foo/bar'], 'summary_issue': { 'title': 'foo-title' } } }, 'https://github.com/foo/bar' ] get_config_mock.return_value = config_mock controls = create_autospec(ControlDescriptor) controls.get_accreditations.return_value = ['accred_foo'] self.search_issues_mock.return_value = [] notifier = GHIssuesNotifier(self.results, controls) notifier.notify() self.search_issues_mock.assert_called_once_with( 'foo-title type:issue in:title is:open repo:foo/bar' ) self.assertEqual(self.add_issue_mock.call_count, 1) args, kwargs = self.add_issue_mock.call_args self.assertEqual(len(args), 4) self.assertEqual(args[0], 'foo') self.assertEqual(args[1], 'bar') self.assertEqual(args[2], 'foo-title') self.assertTrue(args[3].startswith('# CHECK RESULTS:')) self.assertTrue('### Passed Checks' in args[3]) self.assertTrue('### Errored Checks' in args[3]) self.assertTrue('### Failures/Warnings' in args[3]) self.assertEqual(kwargs, {'assignees': [], 'labels': []}) self.patch_issue_mock.assert_not_called() self.add_issue_comment_mock.assert_not_called()
def test_add_issue_to_project_invalid_project(self, get_config_mock): """Test issue is not added to project without valid project config.""" config_mock = create_autospec(ComplianceConfig) config_mock.get.side_effect = [ { 'accred_foo': { 'repo': ['foo/bar'], 'project': { 'invalid-project': 'a-column' }, 'summary_issue': { 'title': 'foo-title' } } }, 'https://github.com/foo/bar' ] get_config_mock.return_value = config_mock controls = create_autospec(ControlDescriptor) controls.get_accreditations.return_value = ['accred_foo'] self.search_issues_mock.return_value = [] self.get_all_projects_mock.return_value = [ { 'id': 1, 'name': 'valid-project' } ] notifier = GHIssuesNotifier(self.results, controls) notifier.logger.warning = MagicMock() notifier.notify() self.get_all_projects_mock.assert_called_once_with('foo/bar') self.get_columns_mock.assert_not_called() self.get_all_cards_mock.assert_not_called() self.add_card_mock.assert_not_called() notifier.logger.warning.assert_called_once_with( 'Project invalid-project not found in foo/bar' )
def test_notify_alerts_in_multiple_repos(self, get_config_mock): """Test notifier notifies in multiple repositories.""" config_mock = create_autospec(ComplianceConfig) config_mock.get.side_effect = [ { 'foo': { 'repo': ['foo/bar', 'bing/bong'], 'status': ['pass'] } }, 'https://github.com/foo/bar' ] get_config_mock.return_value = config_mock controls = create_autospec(ControlDescriptor) controls.get_accreditations.return_value = ['foo'] self.search_issues_mock.return_value = [] notifier = GHIssuesNotifier(self.results, controls) notifier.notify() self.assertEqual(self.search_issues_mock.call_count, 2) self.search_issues_mock.assert_any_call( 'pass_example type:issue in:title is:open repo:foo/bar' ) self.search_issues_mock.assert_any_call( 'pass_example type:issue in:title is:open repo:bing/bong' ) self.assertEqual(self.add_issue_mock.call_count, 2) foo_bar_call_args, _ = self.add_issue_mock.call_args_list[0] bing_bong_call_args, _ = self.add_issue_mock.call_args_list[1] self.assertEqual(foo_bar_call_args[0], 'foo') self.assertEqual(foo_bar_call_args[1], 'bar') self.assertEqual(bing_bong_call_args[0], 'bing') self.assertEqual(bing_bong_call_args[1], 'bong') self.patch_issue_mock.assert_not_called() self.add_issue_comment_mock.assert_not_called()
def test_notify_for_new_and_old_alerts(self, get_config_mock): """Test notifier updates an open GH issue for a passed check.""" config_mock = create_autospec(ComplianceConfig) config_mock.get.side_effect = [ { 'foo': { 'repo': ['foo/bar'], 'status': ['fail'] } }, 'https://github.com/foo/bar' ] get_config_mock.return_value = config_mock controls = create_autospec(ControlDescriptor) controls.get_accreditations.return_value = ['foo'] self.search_issues_mock.side_effect = [ [], [ { 'id': 1, 'number': 123, 'labels': [ { 'name': 'accreditation: foo', 'other': 'junk' }, { 'name': 'run status: warn', 'other': 'junk' } ], 'title': 'pass_example', 'url': '123.url' } ] ] notifier = GHIssuesNotifier(self.results, controls) notifier.notify() self.assertEqual(self.search_issues_mock.call_count, 2) self.search_issues_mock.assert_any_call( 'fail_example type:issue in:title is:open repo:foo/bar' ) self.search_issues_mock.assert_any_call( 'pass_example type:issue in:title is:open repo:foo/bar' ) self.assertEqual(self.add_issue_mock.call_count, 1) args, kwargs = self.add_issue_mock.call_args self.assertEqual(len(args), 4) self.assertEqual(args[0], 'foo') self.assertEqual(args[1], 'bar') self.assertEqual(args[2], 'fail_example') self.assertTrue(args[3].startswith('## Compliance check alert')) self.assertEqual( kwargs, { 'assignees': [], 'labels': ['accreditation: foo', 'run status: fail'] } ) self.patch_issue_mock.assert_called_once_with( 'foo', 'bar', 123, labels=['accreditation: foo', 'run status: pass'] ) self.assertEqual(self.add_issue_comment_mock.call_count, 1) args, kwargs = self.add_issue_comment_mock.call_args self.assertEqual(len(args), 4) self.assertEqual(args[0], 'foo') self.assertEqual(args[1], 'bar') self.assertEqual(args[2], 123) self.assertTrue(args[3].startswith('## Compliance check alert')) self.assertTrue('Run Status: **PASS' in args[3]) self.assertEqual(kwargs, {})