Beispiel #1
0
    def test_get_installations(self):
        app_token = GitHubToken(os.environ.get('GITHUB_APP_TEST_TOKEN', ''))
        app_user = GitHubUser(app_token)
        jwt = GitHubJsonWebToken(os.environ['GITHUB_PRIVATE_KEY'],
                                 int(os.environ['GITHUB_TEST_APP_ID']))

        self.assertEqual({i.app_id
                          for i in app_user.get_installations(jwt)}, {5408})
Beispiel #2
0
    def test_get_permission_level(self):
        sils = GitHubUser(self.token, 'sils')
        user = GitHubUser(self.token)
        nkprince007 = GitHubUser(self.token, 'nkprince007')

        self.assertEqual(self.repo.get_permission_level(sils),
                         AccessLevel.CAN_WRITE)
        self.assertEqual(self.repo.get_permission_level(user),
                         AccessLevel.ADMIN)
        self.assertEqual(self.repo.get_permission_level(nkprince007),
                         AccessLevel.CAN_READ)
Beispiel #3
0
 def owners(self) -> Set[GitHubUser]:
     """
     Returns the user handles of all admin users.
     """
     try:
         return {
             GitHubUser.from_data(user, self._token, user['login'])
             for user in get(self._token,
                             self._url + '/members',
                             params={'role': 'admin'})
         }
     except RuntimeError:
         return {GitHubUser(self._token, self.name)}
Beispiel #4
0
class GitHubUserTest(IGittTestCase):
    def setUp(self):
        self.token = GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', ''))
        self.sils = GitHubUser(self.token, 'sils')
        self.user = GitHubUser(self.token)

    def test_user_url(self):
        self.assertEqual(self.sils.url, 'https://api.github.com/users/sils')
        self.assertEqual(self.sils.web_url, 'https://github.com/sils')

    def test_user_id(self):
        self.assertEqual(self.sils.identifier, 5716520)
        self.assertEqual(self.user.identifier, 16681030)

    def test_username(self):
        self.assertEqual(self.sils.username, 'sils')
        self.assertEqual(self.user.username, 'gitmate-test-user')

    def test_installed_repositories(self):
        self.assertEqual(
            {
                repo.full_name
                for repo in self.user.installed_repositories(60731)
            }, {'gitmate-test-org/test'})

    def test_get_installations(self):
        app_token = GitHubToken(os.environ.get('GITHUB_APP_TEST_TOKEN', ''))
        app_user = GitHubUser(app_token)
        jwt = GitHubJsonWebToken(os.environ['GITHUB_PRIVATE_KEY'],
                                 int(os.environ['GITHUB_TEST_APP_ID']))

        self.assertEqual({i.app_id
                          for i in app_user.get_installations(jwt)}, {5408})
Beispiel #5
0
 def test_github_comment_after_sync_no_data_in_db(
     self, m_set_status, m_get_statuses, m_sha, m_get_perms, m_author,
     m_body, m_head, m_commits
 ):
     m_get_statuses.return_value = (
         CommitStatus(Status.FAILED, 'Terrible issues',
                      'review/gitmate/manual', 'https://gitmate.io'),
         CommitStatus(Status.SUCCESS, 'No issues',
                      'review/somewhere/else', 'https://some/url'))
     m_sha.return_value = 'f6d2b7c66372236a090a2a74df2e47f42a54456b'
     m_get_perms.return_value = AccessLevel.CAN_WRITE
     m_author.return_value = GitHubUser(self.gh_token, self.user.username)
     m_body.return_value = 'unack f6d2b7c'
     m_head.return_value = self.gh_commit
     m_commits.return_value = tuple([self.gh_commit])
     response = self.simulate_github_webhook_call('issue_comment',
                                                  self.gh_comment_data)
     self.assertEqual(response.status_code, status.HTTP_200_OK)
     args = sum([list(args) for args, _ in m_set_status.call_args_list], [])
     # 3 calls to be made as follows
     # Status.FAILED review/gitmate/manual/pr
     # Status.FAILED review/gitmate/manual
     # Status.FAILED review/gitmate/manual/pr
     self.assertEqual(m_set_status.call_count, 3)
     self.assertEqual([(arg.status, arg.context) for arg in args],
                      [(Status.FAILED, 'review/gitmate/manual/pr'),
                       (Status.FAILED, 'review/gitmate/manual'),
                       (Status.FAILED, 'review/gitmate/manual/pr')])
    def test_verify_command_access(self, m_get_perm, m_repo, m_author):
        merge_admin_only = self.plugin_config.get_settings(
            self.repo)['merge_admin_only']
        fastforward_admin_only = self.plugin_config.get_settings(
            self.repo)['fastforward_admin_only']

        m_repo.return_value = self.repo.igitt_repo
        m_author.return_value = GitHubUser(self.repo.token,
                                           self.repo.user.username)

        m_comment = GitHubComment(self.repo.token, self.repo.igitt_repo,
                                  CommentType.ISSUE, 123)

        m_get_perm.return_value = AccessLevel.CAN_WRITE
        self.assertTrue(
            verify_command_access(m_comment, merge_admin_only,
                                  fastforward_admin_only, 'merge'))

        m_get_perm.return_value = AccessLevel.CAN_WRITE
        self.assertFalse(
            verify_command_access(m_comment, merge_admin_only,
                                  fastforward_admin_only, 'fastforward'))

        m_get_perm.return_value = AccessLevel.ADMIN
        self.assertTrue(
            verify_command_access(m_comment, merge_admin_only,
                                  fastforward_admin_only, 'fastforward'))
Beispiel #7
0
    def _handle_webhook_installation(self, data):
        """Handles 'installation' event."""
        installation = data['installation']
        installation_obj = GitHubInstallation.from_data(
            installation, self._token, installation['id'])
        trigger_event = {
            'created': InstallationActions.CREATED,
            'deleted': InstallationActions.DELETED
        }[data['action']]

        # sender is the user who made this installation and has access to it
        sender = GitHubUser.from_data(data['sender'], self._token,
                                      data['sender']['login'])

        # When a new installation is created, it will be installed on at
        # least one repository which will be forwarded through
        # `repositories` key.
        if 'repositories' in data:
            repos = [
                GitHubRepository.from_data(repo, self._token, repo['id'])
                for repo in data['repositories']
            ]
            yield trigger_event, [installation_obj, sender, repos]
        else:
            yield trigger_event, [installation_obj, sender]
Beispiel #8
0
    def author(self) -> GitHubUser:
        """
        Retrieves the author of the merge request.

        :return: A GitHubUser object.
        """
        return GitHubUser.from_data(self.data['user'], self._token,
                                    self.data['user']['login'])
 def test_irrelevant_comment(self, m_author, m_comment, m_body):
     m_body.return_value = f'Life is full of 0s and 1s'
     m_author.return_value = GitHubUser(self.repo.token,
                                        self.repo.user.username)
     subprocess.Popen = fake_popen_success
     response = self.simulate_github_webhook_call('issue_comment',
                                                  self.github_data)
     self.assertEqual(response.status_code, status.HTTP_200_OK)
     m_comment.assert_not_called()
Beispiel #10
0
    def test_get_user_if_exists(self):
        # It is none because we never created a database entry for the user:
        # `gitmate-test-user`
        gh_user = GitHubUser(self.repo.token, 'gitmate-test-user')
        self.assertIsNone(get_user_if_exists(gh_user))

        # Mocking the exact entry from database, to get proper return value
        gl_user = GitLabUser(self.repo.token, 2)
        self.assertIsNotNone(get_user_if_exists(gl_user))
Beispiel #11
0
    def assign(self, issue: Issue, assignees: typing.List[str]) -> None:
        """Assign users (by their accounts) to the given issue."""
        if self.service_type == ServiceType.GITHUB:
            users = (GitHubUser(GitHubToken(self.token), username) for username in assignees)
        elif self.service_type == ServiceType.GITLAB:
            users = (GitLabUser(GitLabPrivateToken(self.token), username) for username in assignees)
        else:
            raise NotImplementedError

        issue.assign(*users)
Beispiel #12
0
def populate_repositories(backend: BaseOAuth2, user: User, *args, **kwargs):
    """
    Connects the user to his / her existing installations, if any were made
    prior to GitMate login.
    """
    if backend.name != Providers.GITHUB_APP.value:
        return

    raw_token = user.social_auth.get(provider=backend.name).access_token
    token = Providers(backend.name).get_token(raw_token)
    populate_github_repositories.delay(user, GitHubUser(token))
Beispiel #13
0
 def test_assignee(self):
     self.assertEqual(self.iss.assignees, set())
     iss = GitHubIssue(self.token, 'gitmate-test-user/test', 41)
     user = GitHubUser(self.token, 'meetmangukiya')
     iss.assignees = set()
     self.assertEqual(iss.assignees, set())
     iss.assignees = {user}
     self.assertEqual(iss.assignees, {user})
     iss.assignees = set()
     self.assertEqual(iss.assignees, set())
     iss = GitHubIssue(self.token, 'gitmate-test-user/test', 107)
     self.assertEqual(iss.assignees, set())
 def test_github_successful_rebase(self, m_get_perm, m_author, m_comment,
                                   m_body):
     m_body.return_value = f'@{self.repo.user.username} rebase'
     m_author.return_value = GitHubUser(self.repo.token,
                                        self.repo.user.username)
     m_get_perm.return_value = AccessLevel.CAN_READ
     subprocess.Popen = fake_popen_success
     response = self.simulate_github_webhook_call('issue_comment',
                                                  self.github_data)
     self.assertEqual(response.status_code, status.HTTP_200_OK)
     m_comment.assert_called_with(
         'Automated rebase with [GitMate.io](https://gitmate.io) was '
         'successful! :tada:')
 def test_github_unauthorized(self, m_get_perm, m_author, m_comment,
                              m_body):
     m_body.return_value = f'@{self.repo.user.username} rebase'
     m_author.return_value = GitHubUser(self.repo.token,
                                        self.repo.user.username)
     m_get_perm.return_value = AccessLevel.NONE
     subprocess.Popen = fake_popen_success
     response = self.simulate_github_webhook_call('issue_comment',
                                                  self.github_data)
     self.assertEqual(response.status_code, status.HTTP_200_OK)
     m_comment.assert_called_with(
         f'Hey @{self.repo.user.username}, you do not have the access to '
         'perform the rebase action with [GitMate.io](https://gitmate.io). '
         'Please ask a maintainer to give you access. :warning:')
Beispiel #16
0
    def author(self) -> GitHubUser:
        """
        Retrieves the author of the comment.

        >>> from os import environ
        >>> issue = GitHubComment(GitHubToken(environ['GITHUB_TEST_TOKEN']),
        ...                      'gitmate-test-user/test', 172962077)
        >>> issue.author.username
        'sils'

        :return: A GitHubUser object.
        """
        return GitHubUser.from_data(self.data['user'], self._token,
                                    self.data['user']['login'])
 def test_github_failed_rebase(self, m_get_perm, m_author, m_comment,
                               m_body):
     m_body.return_value = '@{} rebase'.format(
         self.repo.user.username.upper())
     m_author.return_value = GitHubUser(self.repo.token,
                                        self.repo.user.username)
     m_get_perm.return_value = AccessLevel.CAN_READ
     subprocess.Popen = fake_popen_failure
     response = self.simulate_github_webhook_call('issue_comment',
                                                  self.github_data)
     self.assertEqual(response.status_code, status.HTTP_200_OK)
     m_comment.assert_called_with('Automated rebase failed! Please rebase '
                                  'your pull request manually via the '
                                  'command line.\n\nReason:\n'
                                  '```\nCommand \'[\'git\', \'rebase\', '
                                  '\'master\']\' returned non-zero exit '
                                  'status 128.\n```')
Beispiel #18
0
    def test_github_ack_unack(
        self, m_commits, m_body, m_get_perms, m_set_status, m_author
    ):
        m_commits.return_value = tuple([self.gh_commit, self.gh_commit_2])
        m_body.return_value = 'ack 3f2a3b3 unack f6d2b7c'
        m_get_perms.return_value = AccessLevel.CAN_WRITE

        self.gh_commit.set_status = Mock()
        self.gh_commit_2.set_status = Mock()

        m_author.return_value = GitHubUser(self.gh_token, self.user.username)

        self.simulate_github_webhook_call('pull_request', self.gh_pr_data)
        self.simulate_github_webhook_call(
            'issue_comment', self.gh_comment_data)

        self.assertEqual(self.gh_commit.set_status.call_args[0][0].status,
                         Status.FAILED)
        self.assertEqual(self.gh_commit_2.set_status.call_args[0][0].status,
                         Status.SUCCESS)
Beispiel #19
0
    def assignees(self) -> Set[GitHubUser]:
        """
        Retrieves the assignee of the issue:

        >>> from os import environ
        >>> issue = GitHubIssue(GitHubToken(environ['GITHUB_TEST_TOKEN']),
        ...                     'gitmate-test-user/test', 1)
        >>> {a.username for a in issue.assignees}
        {'gitmate-test-user'}

        >>> issue = GitHubIssue(GitHubToken(environ['GITHUB_TEST_TOKEN']),
        ...                     'gitmate-test-user/test', 2)
        >>> issue.assignees  # Returns empty set, unassigned
        {}

        :return: A set containing the usernames of assignees.
        """
        return set(
            GitHubUser.from_data(user, self._token, user['login'])
            for user in self.data['assignees']
        )
Beispiel #20
0
    def test_github_ack_with_special_chars(
        self, m_set_status, m_get_statuses, m_sha, m_get_perms, m_author,
        m_body, m_head, m_commits
    ):
        self.repo.settings = [{
            'name': 'ack',
            'settings': {
                'ack_strs': r'bot\ack, bot\accept'
            }
        }]

        m_get_statuses.return_value = (
            CommitStatus(Status.SUCCESS, 'No issues',
                         'review/gitmate/manual', 'https://gitmate.io'),
            CommitStatus(Status.SUCCESS, 'No issues',
                         'review/somewhere/else', 'https://some/url'))
        m_sha.return_value = 'f6d2b7c66372236a090a2a74df2e47f42a54456b'
        m_body.return_value = r'bot\accept f6d2b7c'
        m_get_perms.return_value = AccessLevel.CAN_WRITE
        m_author.return_value = GitHubUser(self.gh_token, self.user.username)
        m_head.return_value = self.gh_commit
        m_commits.return_value = tuple([self.gh_commit])
        response = self.simulate_github_webhook_call('pull_request',
                                                     self.gh_pr_data)
        response = self.simulate_github_webhook_call('issue_comment',
                                                     self.gh_comment_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        args = sum([list(args) for args, _ in m_set_status.call_args_list], [])
        # 3 calls to be made as follows
        # Status.SUCCESS review/gitmate/manual/pr
        # Status.SUCCESS review/gitmate/manual
        # Status.SUCCESS review/gitmate/manual/pr
        self.assertEqual(m_set_status.call_count, 3)
        self.assertEqual([(arg.status, arg.context) for arg in args],
                         [(Status.SUCCESS, 'review/gitmate/manual/pr'),
                          (Status.SUCCESS, 'review/gitmate/manual'),
                          (Status.SUCCESS, 'review/gitmate/manual/pr')])
Beispiel #21
0
    def _handle_webhook_installation_repositories(self, data):
        """Handles 'installation_repositories' event."""
        installation = data['installation']
        installation_obj = GitHubInstallation.from_data(
            installation, self._token, installation['id'])

        # sender is the user who has access to this installation
        sender = GitHubUser.from_data(data['sender'], self._token,
                                      data['sender']['login'])

        if data['action'] == 'added':
            trigger_event = InstallationActions.REPOSITORIES_ADDED
            repos = [
                GitHubRepository.from_data(repo, self._token, repo['id'])
                for repo in data['repositories_added']
            ]
        elif data['action'] == 'removed':
            trigger_event = InstallationActions.REPOSITORIES_REMOVED
            repos = [
                GitHubRepository.from_data(repo, self._token, repo['id'])
                for repo in data['repositories_removed']
            ]

        yield trigger_event, [installation_obj, sender, repos]
Beispiel #22
0
 def user(self) -> GitHubUser:
     """
     Retrieves the user who reacted with this reaction.
     """
     user = self.data['user']
     return GitHubUser.from_data(user, self._token, user['login'])
Beispiel #23
0
 def setUp(self):
     self.token = GitHubToken(os.environ.get('GITHUB_TEST_TOKEN', ''))
     self.sils = GitHubUser(self.token, 'sils')
     self.user = GitHubUser(self.token)