From a9d99def19266d2982661e2fbafa2dee3bcc9152 Mon Sep 17 00:00:00 2001 From: Nitanshu Date: Fri, 13 Jul 2018 02:34:44 +0530 Subject: [PATCH] tests: Implement CoroboTestCase Shift from `tests.helper.plugin_testbot` to `CoroboTestCase` for loading plugins in the TestBot. Closes https://github.com/coala/corobo/issues/584 --- tests/ban_test.py | 25 +++--- tests/corobo_test_case.py | 44 ++++++++++ tests/git_stats_test.py | 14 ++- tests/helper.py | 21 ----- tests/labhub_test.py | 174 ++++++++++++++++++-------------------- 5 files changed, 143 insertions(+), 135 deletions(-) create mode 100644 tests/corobo_test_case.py delete mode 100644 tests/helper.py diff --git a/tests/ban_test.py b/tests/ban_test.py index 678bde64..4920a79c 100644 --- a/tests/ban_test.py +++ b/tests/ban_test.py @@ -1,22 +1,22 @@ -import logging -import unittest from unittest.mock import MagicMock, patch, PropertyMock import plugins.ban -from tests.helper import plugin_testbot +from tests.corobo_test_case import CoroboTestCase -class TestBan(unittest.TestCase): +class TestBan(CoroboTestCase): + + def setUp(self): + super().setUp((plugins.ban.Ban,)) + self.ban = self.load_plugin('Ban') + self.ban.bot_config.ROOMS_TO_JOIN = ( + 'coala/coala', 'coala/coala-bears') + self.ban.bot_config.BOT_IDENTITY['token'] = 'mocked?' @patch('plugins.ban.requests') @patch('plugins.ban.json') def test_ban_cmd(self, mockjson, mockreq): - ban, testbot = plugin_testbot(plugins.ban.Ban, logging.ERROR) - ban.activate() - - ban.bot_config.ROOMS_TO_JOIN = ('coala/coala', 'coala/coala-bears') - ban.bot_config.BOT_IDENTITY['token'] = 'mocked?' status_mock = MagicMock() type(status_mock).status_code = PropertyMock(return_value=200) mockreq.post.return_value = status_mock @@ -27,6 +27,7 @@ def test_ban_cmd(self, mockjson, mockreq): {'id': '897', 'uri': 'coala/coala-bears'} ] mockjson.loads.return_value = fake_room_data + testbot = self testbot.assertCommand('!ban @nvzard', 'nvzard has been banned from: coala/coala, ' 'coala/coala-bears') @@ -34,11 +35,6 @@ def test_ban_cmd(self, mockjson, mockreq): @patch('plugins.ban.requests') @patch('plugins.ban.json') def test_unban_cmd(self, mockjson, mockreq): - ban, testbot = plugin_testbot(plugins.ban.Ban, logging.ERROR) - ban.activate() - - ban.bot_config.ROOMS_TO_JOIN = ('coala/coala', 'coala/coala-bears') - ban.bot_config.BOT_IDENTITY['token'] = 'mocked?' status_mock = MagicMock() type(status_mock).status_code = PropertyMock(return_value=200) mockreq.delete.return_value = status_mock @@ -49,6 +45,7 @@ def test_unban_cmd(self, mockjson, mockreq): {'id': '897', 'uri': 'coala/coala-bears'} ] mockjson.loads.return_value = fake_room_data + testbot = self testbot.assertCommand('!unban @nvzard', 'nvzard has been unbanned from: coala/coala, ' 'coala/coala-bears') diff --git a/tests/corobo_test_case.py b/tests/corobo_test_case.py new file mode 100644 index 00000000..e741d55e --- /dev/null +++ b/tests/corobo_test_case.py @@ -0,0 +1,44 @@ +from errbot.backends.test import FullStackTest +from errbot.plugin_info import PluginInfo +from errbot.templating import add_plugin_templates_path +from pathlib import Path + +import logging + + +class CoroboTestCase(FullStackTest): + + def setUp(self, klasses: tuple): + super().setUp(loglevel=logging.ERROR, + extra_config={'BACKEND': 'text'}) + self.klasses = {} + self.plug_files = {} + self.plugins = {} + + for klass in klasses: + self.klasses[klass.__name__] = klass + self.load_plugin_templates(klass) + + def load_plugin_templates(self, klass): + plug_filename = klass.__module__.split('.')[-1] + '.plug' + plug_file_path = (Path(__file__) + .parent / '..' / 'plugins' / plug_filename) + with plug_file_path.open() as plugfile: + plug_info = PluginInfo.load_file(plugfile, plug_file_path) + self.plug_files[klass.__name__] = plug_info + add_plugin_templates_path(plug_info) + + def load_plugin(self, plugin_name: str, mock_dict=False): + """Load plugin manually""" + klass = self.klasses[plugin_name] + plugin = klass(self.bot, plugin_name) + plugin.activate() + self.plugins[plugin_name] = plugin + self.bot.plugin_manager.plugins[plugin_name] = plugin + plug_file = self.plug_files[plugin_name] + self.bot.plugin_manager.plugin_infos[plug_file.name] = plug_file + + if mock_dict: + self.inject_mocks(plugin_name=plugin_name, mock_dict=mock_dict) + + return plugin diff --git a/tests/git_stats_test.py b/tests/git_stats_test.py index 4f16d0e7..0d3df963 100644 --- a/tests/git_stats_test.py +++ b/tests/git_stats_test.py @@ -1,7 +1,5 @@ -import logging from tempfile import mkdtemp from errbot import BotPlugin -import unittest from unittest.mock import create_autospec from IGitt.GitHub.GitHubMergeRequest import GitHubMergeRequest @@ -14,12 +12,13 @@ import IGitt import plugins.git_stats import plugins.labhub -from tests.helper import plugin_testbot +from tests.corobo_test_case import CoroboTestCase -class TestGitStats(unittest.TestCase): +class TestGitStats(CoroboTestCase): def setUp(self): + super().setUp((plugins.git_stats.GitStats,)) plugins.git_stats.github3 = create_autospec(github3) self.mock_org = create_autospec(github3.orgs.Organization) self.mock_gh = create_autospec(github3.GitHub) @@ -30,12 +29,10 @@ def setUp(self): self.plugin = plugins.git_stats.GitStats self.plugin.__bases__ = (BotPlugin, ) + self.git_stats = self.load_plugin('GitStats') + self.git_stats.REPOS = {'test': self.mock_repo} def test_pr_list(self): - git_stats, testbot = plugin_testbot(self.plugin, logging.ERROR) - git_stats.activate() - - git_stats.REPOS = {'test': self.mock_repo} mock_github_mr = create_autospec(GitHubMergeRequest) mock_gitlab_mr = create_autospec(GitLabMergeRequest) mock_github_issue = create_autospec(GitHubIssue) @@ -49,6 +46,7 @@ def test_pr_list(self): mock_repo_obj = create_autospec(Repo) cmd_github = '!mergable {}' cmd_gitlab = '!mergable {}' + testbot = self self.mock_repo.merge_requests = [mock_github_mr] diff --git a/tests/helper.py b/tests/helper.py deleted file mode 100644 index b00db3b0..00000000 --- a/tests/helper.py +++ /dev/null @@ -1,21 +0,0 @@ -from errbot.backends.test import TestBot -from errbot.plugin_info import PluginInfo -from errbot.templating import add_plugin_templates_path -from pathlib import Path - - -def plugin_testbot(klass, loglevel, config=None): - config = config if config else dict() - testbot = TestBot(loglevel=loglevel, extra_config=config) - testbot.start() - plugin_name = klass.__name__ - plug = klass(testbot.bot, plugin_name) - return plug, testbot - - -def load_templates(plug_file_name): - plugin_info_path = (Path(__file__) - .parent / '..' / 'plugins' / plug_file_name) - with plugin_info_path.open() as plugfile: - plugin_info = PluginInfo.load_file(plugfile, plugin_info_path) - add_plugin_templates_path(plugin_info) diff --git a/tests/labhub_test.py b/tests/labhub_test.py index 446f5ffd..7d8d0f90 100644 --- a/tests/labhub_test.py +++ b/tests/labhub_test.py @@ -1,7 +1,5 @@ -import logging import queue import textwrap -import unittest from unittest.mock import Mock, MagicMock, create_autospec, PropertyMock, patch import github3 @@ -16,13 +14,13 @@ import plugins.labhub from plugins.labhub import LabHub -from tests.helper import load_templates, plugin_testbot +from tests.corobo_test_case import CoroboTestCase -class TestLabHub(unittest.TestCase): +class TestLabHub(CoroboTestCase): def setUp(self): - load_templates('labhub.plug') + super().setUp((plugins.labhub.LabHub,)) plugins.labhub.github3 = create_autospec(github3) self.mock_org = create_autospec(github3.orgs.Organization) @@ -42,6 +40,22 @@ def setUp(self): self.mock_org.teams.return_value = [self.mock_team] plugins.labhub.github3.organization.return_value = self.mock_org + # patching + plugins.labhub.GitHub = create_autospec(IGitt.GitHub.GitHub.GitHub) + plugins.labhub.GitLab = create_autospec(IGitt.GitLab.GitLab.GitLab) + plugins.labhub.GitHubToken = create_autospec(IGitt.GitHub.GitHubToken) + plugins.labhub.GitLabPrivateToken = create_autospec( + IGitt.GitLab.GitLabPrivateToken) + + self.global_mocks = { + 'REPOS': { + 'repository': self.mock_repo, + 'repository.github.io': self.mock_repo, + }, + '_teams': self.teams, + } + self.labhub = self.load_plugin('LabHub', self.global_mocks) + def test_invite_cmd(self): mock_team_newcomers = create_autospec(github3.orgs.Team) mock_team_developers = create_autospec(github3.orgs.Team) @@ -51,19 +65,22 @@ def test_invite_cmd(self): self.teams['coala developers'] = mock_team_developers self.teams['coala maintainers'] = mock_team_maintainers - labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR) - labhub.activate() - labhub._teams = self.teams + mock_dict = { + 'TEAMS': self.teams, + 'is_room_member': MagicMock(), + } + self.inject_mocks('LabHub', mock_dict) + testbot = self plugins.labhub.os.environ['GH_TOKEN'] = 'patched?' - self.assertEqual(labhub.TEAMS, self.teams) + self.assertEqual(self.labhub.TEAMS, self.teams) - labhub.is_room_member = MagicMock(return_value=False) + mock_dict['is_room_member'].return_value = False testbot.assertCommand('!invite meet to newcomers', '@meet is not a member of this room.') - labhub.is_room_member = MagicMock(return_value=True) + mock_dict['is_room_member'].return_value = True # invite by maintainer mock_team_newcomers.is_member.return_value = True @@ -80,7 +97,7 @@ def test_invite_cmd(self): # invite by developer mock_team_maintainers.is_member.return_value = False - labhub.is_room_member = MagicMock(return_value=True) + mock_dict['is_room_member'].return_value = True testbot.assertCommand( '!invite meet to newcomers', @@ -124,11 +141,8 @@ def test_is_room_member(self): self.assertTrue(LabHub.is_room_member('batman', msg)) def test_hello_world_callback(self): - testbot = TestBot(extra_plugin_dir='plugins', loglevel=logging.ERROR) - testbot.start() - labhub = testbot.bot.plugin_manager.get_plugin_obj_by_name('LabHub') - labhub.TEAMS = self.teams self.mock_team.is_member.return_value = False + testbot = self testbot.assertCommand('hello, world', 'newcomer') # Since the user won't be invited again, it'll timeout waiting for a # response. @@ -136,20 +150,6 @@ def test_hello_world_callback(self): testbot.assertCommand('helloworld', 'newcomer') def test_create_issue_cmd(self): - plugins.labhub.GitHub = create_autospec(IGitt.GitHub.GitHub.GitHub) - plugins.labhub.GitLab = create_autospec(IGitt.GitLab.GitLab.GitLab) - plugins.labhub.GitHubToken = create_autospec(IGitt.GitHub.GitHubToken) - plugins.labhub.GitLabPrivateToken = create_autospec( - IGitt.GitLab.GitLabPrivateToken) - - labhub, testbot_private = plugin_testbot( - plugins.labhub.LabHub, logging.ERROR, - {'BACKEND': 'text', - 'ACCESS_CONTROLS': {'create_issue_cmd': {'allowprivate': False}}, - } - ) - labhub.activate() - labhub.REPOS = {'repository': self.mock_repo} plugins.labhub.GitHubToken.assert_called_with(None) plugins.labhub.GitLabPrivateToken.assert_called_with(None) @@ -162,14 +162,8 @@ def test_create_issue_cmd(self): # Stop ignoring # Creating issue in public chat - labhub, testbot_public = plugin_testbot( - plugins.labhub.LabHub, logging.ERROR, {'BACKEND': 'text'} - ) - labhub.activate() - labhub._teams = self.teams self.mock_team.is_member.return_value = True - labhub.REPOS = {'repository': self.mock_repo, - 'repository.github.io': self.mock_repo} + testbot_public = self testbot_public.assertCommand( textwrap.dedent('''\ @@ -179,12 +173,13 @@ def test_create_issue_cmd(self): '''), 'Here you go') - labhub.REPOS['repository'].create_issue.assert_called_once_with( - 'this is the title', - textwrap.dedent('''\ - first line of body - second line of body - Opened by @None at [text]()''') + self.global_mocks['REPOS']['repository'].create_issue \ + .assert_called_once_with( + 'this is the title', + textwrap.dedent('''\ + first line of body + second line of body + Opened by @None at [text]()''') ) testbot_public.assertCommand( @@ -194,11 +189,12 @@ def test_create_issue_cmd(self): '''), 'Here you go') - labhub.REPOS['repository.github.io'].create_issue.assert_called_with( - 'another title', - textwrap.dedent('''\ - body - Opened by @None at [text]()''') + self.global_mocks['REPOS']['repository.github.io'].create_issue \ + .assert_called_with( + 'another title', + textwrap.dedent('''\ + body + Opened by @None at [text]()''') ) testbot_public.assertCommand( @@ -207,10 +203,6 @@ def test_create_issue_cmd(self): # not a member of org self.mock_team.is_member.return_value = False - labhub.REPOS = { - 'repository': self.mock_repo, - 'repository.github.io': self.mock_repo, - } testbot_public.assertCommand( textwrap.dedent('''\ !new issue repository this is the title @@ -228,20 +220,14 @@ def test_is_newcomer_issue(self): self.assertFalse(LabHub.is_newcomer_issue(mock_iss)) def test_unassign_cmd(self): - plugins.labhub.GitHub = create_autospec(IGitt.GitHub.GitHub.GitHub) - plugins.labhub.GitLab = create_autospec(IGitt.GitLab.GitLab.GitLab) - labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR) - - labhub.activate() - labhub.REPOS = {'example': self.mock_repo} - labhub._teams = self.teams - + self.inject_mocks('LabHub', {'REPOS': {'example': self.mock_repo}}) mock_iss = create_autospec(IGitt.GitHub.GitHubIssue) self.mock_repo.get_issue.return_value = mock_iss mock_iss.assignees = PropertyMock() mock_iss.assignees = (None, ) mock_iss.unassign = MagicMock() self.mock_team.is_member.return_value = True + testbot = self testbot.assertCommand( '!unassign https://github.com/coala/example/issues/999', @@ -271,16 +257,9 @@ def test_unassign_cmd(self): 'to use this command.') def test_assign_cmd(self): - plugins.labhub.GitHub = create_autospec(IGitt.GitHub.GitHub.GitHub) - plugins.labhub.GitLab = create_autospec(IGitt.GitLab.GitLab.GitLab) - labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR) - labhub.activate() - mock_issue = create_autospec(GitHubIssue) self.mock_repo.get_issue.return_value = mock_issue - labhub.REPOS = {'a': self.mock_repo} - mock_dev_team = create_autospec(github3.orgs.Team) mock_maint_team = create_autospec(github3.orgs.Team) mock_dev_team.is_member.return_value = False @@ -288,7 +267,13 @@ def test_assign_cmd(self): self.teams['coala developers'] = mock_dev_team self.teams['coala maintainers'] = mock_maint_team - labhub._teams = self.teams + + mock_dict = { + 'REPOS': {'a': self.mock_repo}, + 'TEAMS': self.teams, + } + self.inject_mocks('LabHub', mock_dict) + testbot = self cmd = '!assign https://github.com/{}/{}/issues/{}' # no assignee, not newcomer @@ -345,17 +330,21 @@ def test_assign_cmd(self): testbot.pop_message() # no assignee, newcomer, difficulty medium - labhub.GH_ORG_NAME = 'not-coala' - labhub.TEAMS = { - 'not-coala newcomers': self.mock_team, - 'not-coala developers': mock_dev_team, - 'not-coala maintainers': mock_maint_team + mock_dict = { + 'GH_ORG_NAME': 'not-coala', + 'TEAMS': { + 'not-coala newcomers': self.mock_team, + 'not-coala developers': mock_dev_team, + 'not-coala maintainers': mock_maint_team, + }, } + self.inject_mocks('LabHub', mock_dict) testbot.assertCommand(cmd.format('coala', 'a', '23'), 'assigned') - labhub.GH_ORG_NAME = 'coala' - labhub.TEAMS = self.teams + mock_dict['GH_ORG_NAME'] = 'coala' + mock_dict['TEAMS'] = self.teams + self.inject_mocks('LabHub', mock_dict) # newcomer, developer, difficulty/medium mock_dev_team.is_member.return_value = True @@ -393,11 +382,9 @@ def test_assign_cmd(self): 'not eligible to be assigned to this issue') def test_mark_cmd(self): - labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR) - labhub.activate() + self.inject_mocks('LabHub', {'REPOS': {'test': self.mock_repo}}) + testbot = self - labhub.REPOS = {'test': self.mock_repo} - labhub._teams = self.teams mock_github_mr = create_autospec(GitHubMergeRequest) mock_gitlab_mr = create_autospec(GitLabMergeRequest) mock_github_mr.labels = PropertyMock() @@ -461,9 +448,8 @@ def test_mark_cmd(self): 'You need to be a member of this organization to use this command') def test_alive(self): - labhub, testbot = plugin_testbot(plugins.labhub.LabHub, logging.ERROR) with patch('plugins.labhub.time.sleep') as mock_sleep: - labhub.gh_repos = { + gh_repos_mock = { 'coala': create_autospec(IGitt.GitHub.GitHub.GitHubRepository), 'coala-bears': @@ -472,30 +458,34 @@ def test_alive(self): create_autospec(IGitt.GitHub.GitHub.GitHubRepository), } # for the branch where program sleeps - labhub.gh_repos.update({str(i): - create_autospec( + gh_repos_mock.update({str(i): + create_autospec( IGitt.GitHub.GitHub.GitHubRepository) - for i in range(30)}) - labhub.gl_repos = { + for i in range(30)}) + gl_repos_mock = { 'test': create_autospec(IGitt.GitLab.GitLab.GitLabRepository), } - labhub.activate() - labhub._teams = self.teams self.mock_team.is_member.return_value = True + mock_dict = { + 'gh_repos': gh_repos_mock, + 'gl_repos': gl_repos_mock, + } + self.inject_mocks('LabHub', mock_dict) + testbot = self - labhub.gh_repos['coala'].search_mrs.return_value = [1, 2] - labhub.gh_repos['coala-bears'].search_mrs.return_value = [] - labhub.gh_repos['coala-utils'].search_mrs.return_value = [] + mock_dict['gh_repos']['coala'].search_mrs.return_value = [1, 2] + mock_dict['gh_repos']['coala-bears'].search_mrs.return_value = [] + mock_dict['gh_repos']['coala-utils'].search_mrs.return_value = [] testbot.assertCommand('!pr stats 10hours', '2 PRs opened in last 10 hours\n' 'The community is alive', timeout=100) - labhub.gh_repos['coala'].search_mrs.return_value = [] + mock_dict['gh_repos']['coala'].search_mrs.return_value = [] testbot.assertCommand('!pr stats 5hours', '0 PRs opened in last 5 hours\n' 'The community is dead', timeout=100) - labhub.gh_repos['coala'].search_mrs.return_value = [ + mock_dict['gh_repos']['coala'].search_mrs.return_value = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]