예제 #1
0
    def send_logs(
        self,
        tracker_issue: TrackerIssue,
        logs: List[Log],
    ) -> SendLogsResult:
        """
        Send logs to the tracker.

        Args:
            tracker_issue: information about the tracker issue
            logs: a list of logs

        Returns:
            information about the sent logs
        """
        jira_issue = self._get_issue(issue_id=tracker_issue.issue_id, )
        tracker_comments = SendLogsResult(
            tracker_issue=tracker_issue,
            added_comments=[],
        )
        for log in logs:
            jira_comment = self._add_comment(
                issue=jira_issue,
                log=log,
            )
            tracker_comments.added_comments.append(
                TrackerIssueComment(
                    created_at=self._parse_date(date=jira_comment.created, ),
                    author=jira_comment.author.displayName,
                    comment_id=str(jira_comment.id),
                    body=jira2markdown(src=jira_comment.body, ),
                    attachments={},
                ), )
        return tracker_comments
예제 #2
0
    def send_logs(
        self,
        tracker_issue: TrackerIssue,
        logs: Iterable[Log],
    ) -> SendLogsResult:
        """
        Send logs to the tracker.

        Args:
            tracker_issue: information about the tracker issue
            logs: a list of comments

        Raises:
            GitHubTrackerClientError: if an error occurs

        Returns:
            information about the sent comments
        """
        self._ensure_auth()
        tracker_comments = SendLogsResult(
            tracker_issue=tracker_issue,
            added_comments=[],
        )
        github_issue = self._get_github_issue(
            issue_id=tracker_issue.issue_id, )
        if not github_issue:
            raise GitHubTrackerClientError(
                f'GitHub issue {tracker_issue.issue_id} not found')
        for log in logs:
            github_comment = self._add_comment(
                github_issue=github_issue,
                log=log,
            )
            self._upload_comment_attachments(
                issue=github_issue,
                comment=github_comment,
                attachments=log.attachments,
            )
            tracker_comments.added_comments.append(
                TrackerIssueComment(
                    author=github_comment.user.name
                    or github_comment.user.login,
                    created_at=self._ensure_timezone(
                        dt=github_comment.created_at,
                        tz=self._default_timezone,
                    ),
                    comment_id=str(github_comment.id),
                    body=github_comment.body,
                    attachments={},
                ), )
        return tracker_comments
예제 #3
0
    def send_logs(
        self,
        tracker_issue: TrackerIssue,
        logs: Iterable[Log],
    ) -> SendLogsResult:
        """
        Send logs to the tracker.

        Args:
            tracker_issue: information about the tracker issue
            logs: a list of comments

        Raises:
            GitLabTrackerClientError: if an error occurs

        Returns:
            information about the sent comments
        """
        self._ensure_auth()
        tracker_comments = SendLogsResult(
            tracker_issue=tracker_issue,
            added_comments=[],
        )
        gitlab_project = self._get_gitlab_project()
        gitlab_issue = self._get_gitlab_issue(
            issue_id=tracker_issue.issue_id, )
        if not gitlab_issue:
            raise GitLabTrackerClientError(
                f'GitLab issue {tracker_issue.issue_id} not found in project {self.configuration.project}',
            )
        for log in logs:
            gitlab_comment = self._add_comment(
                gitlab_project=gitlab_project,
                gitlab_issue=gitlab_issue,
                log=log,
            )
            tracker_comments.added_comments.append(
                TrackerIssueComment(
                    created_at=self._parse_date(
                        date=gitlab_comment.created_at, ),
                    author=gitlab_comment.author.get(
                        'name', self._default_author_name),
                    comment_id=str(gitlab_comment.id),
                    body=gitlab_comment.body,
                    attachments={},
                ), )
        return tracker_comments
예제 #4
0
 def _send_synchronizable_logs(
     self,
     tracker_issue: TrackerIssue,
     logs: List[Log],
 ) -> SendLogsResult:
     synchronizable_logs = []
     for log in logs:
         synchronize = self._is_synchronizable_log(log=log, )
         if synchronize:
             synchronizable_logs.append(log)
     if not synchronizable_logs:
         return SendLogsResult(
             tracker_issue=tracker_issue,
             added_comments=[],
         )
     return self._send_logs(
         tracker_issue=tracker_issue,
         logs=synchronizable_logs,
     )
예제 #5
0
 def test_partially_synced(self, ) -> None:
     comment_log1 = CommentLog(
         created_at='2021-01-01T00:00:00+00:00',
         log_id=1,
         log_type='comment',
         private=True,
         author=Author(username='******', ),
         message_html='This is a comment',
         attachments=[],
     )
     tracking_status = TrackingStatusLog(
         created_at='2021-01-01T00:30:00+00:00',
         log_id=1,
         log_type='tracking-status',
         private=True,
         author=Author(username='******', ),
         message_html='Tracked',
         attachments=[],
         tracker_name='my-tracker',
         tracker_url='http://tracker/issue/1',
         tracker_id='1',
     )
     tracker_update_log1 = TrackerUpdateLog(
         created_at='2021-01-01T01:00:00+00:00',
         log_id=2,
         log_type='tracker-update',
         private=True,
         author=Author(username='******', ),
         message_html='This is a a tracker update',
         attachments=[],
         tracker_name='my-tracker',
         tracker_id='1',
         tracker_url='http://tracker/issue/1',
         tracker_token=StateEncryptor.encrypt(
             key='123',
             state=TrackerIssueState(
                 closed=False,
                 bugtracker_name='my-tracker',
             ),
         ),
     )
     comment_log2 = CommentLog(
         created_at='2021-01-01T02:00:00+00:00',
         log_id=3,
         log_type='comment',
         private=True,
         author=Author(username='******', ),
         message_html='This is another comment',
         attachments=[],
     )
     report = self._build_report(
         report_id=123,
         tracking_status='T',
         logs=[
             comment_log1,
             tracking_status,
             tracker_update_log1,
             comment_log2,
         ],
     )
     ywh_api_client_mock = create_autospec(YesWeHackApiClient,
                                           spec_set=True)
     tracker_client_mock = create_autospec(TrackerClient, spec_set=True)
     tracker_client_mock.tracker_type = 'MyTracker'
     issue = TrackerIssue(
         tracker_url='http://tracker/issue/1',
         project='my-project',
         issue_id='1',
         issue_url='http://tracker/issue/1',
         closed=False,
     )
     tracker_client_mock.get_tracker_issue.return_value = issue
     tracker_client_mock.send_logs.return_value = SendLogsResult(
         tracker_issue=issue,
         added_comments=[
             TrackerIssueComment(
                 created_at=datetime.datetime(
                     year=2020,
                     month=1,
                     day=1,
                     hour=15,
                     minute=17,
                     second=23,
                     microsecond=420000,
                     tzinfo=datetime.timezone.utc,
                 ),
                 author='tracker-user',
                 comment_id='456',
                 body='',
                 attachments={},
             ),
         ],
     )
     Given(
         case=self,
         report=report,
         yeswehack_client=ywh_api_client_mock,
         tracker_name='my-tracker',
         tracker_client=tracker_client_mock,
         synchronize_options=SynchronizeOptions(
             upload_private_comments=True,
             upload_public_comments=True,
             upload_details_updates=True,
             upload_rewards=True,
             upload_status_updates=True,
         ),
         feedback_options=FeedbackOptions(),
         message_formatter=SimpleMessageFormatter(
             tracking_status_update_format=
             'issue url: {tracker_issue.issue_url}',
             synchronization_done_format=
             'issue url: {send_logs_result.tracker_issue.issue_url}',
             download_comment_format='comment: {comment}',
             status_update_comment_format='comment: {comment}',
         ),
     ).when_synchronize_report().then_assert_no_error(
     ).then_assert_has_result().then_assert_is_existing_issue(
     ).then_assert_tracker_client_send_report_not_called(
     ).then_assert_tracker_client_send_logs_called_once_with(
         tracker_issue=issue,
         logs=[
             comment_log2,
         ],
     ).then_assert_yeswehack_client_post_report_tracker_update_called_once_with(
         report=report,
         tracker_name='my-tracker',
         issue_id='1',
         issue_url='http://tracker/issue/1',
         comment='issue url: http://tracker/issue/1',
         token=StateEncryptor.encrypt(
             key='123',
             state=TrackerIssueState(closed=False,
                                     bugtracker_name='my-tracker',
                                     downloaded_comments=['456']),
         ),
     )
예제 #6
0
    def synchronize_report(self, ) -> SynchronizeReportResult:
        """
        Synchronize a YesWeHack report and a tracker issue.

        Raises:
            SynchronizerError: if a synchronization error occur

        Returns:
            the result of the synchronization
        """
        log = self._report.get_last_tracking_status_update_log(
            tracker_name=self._tracker_name, )
        is_created_issue = False
        tracker_issue = None
        if log and isinstance(log, TrackingStatusLog):
            is_created_issue = True
            tracker_issue = self._get_tracker_issue_from_logs(log=log, )
        if tracker_issue is None:
            if not self._synchronize_options.recreate_missing_issues:
                return SynchronizeReportResult(
                    is_created_issue=is_created_issue,
                    is_existing_issue=False,
                    new_report_status=None,
                    send_logs_result=SendLogsResult(
                        tracker_issue=None,
                        added_comments=[],
                    ),
                    download_comments_result=DownloadCommentsResult(
                        downloaded_comments=[], ),
                )
            is_created_issue = False
            tracker_issue = self._create_tracker_issue()
        if not isinstance(tracker_issue, TrackerIssue):
            raise SynchronizerError(
                f'Unable to create new or get existing issue for #{self._report.report_id} in {self._tracker_name}',
            )
        if self._report.tracking_status != 'T' or not is_created_issue:
            self._update_tracking_status(tracker_issue=tracker_issue, )
        tracker_issue_state = TrackerIssueState(
            closed=False,
            bugtracker_name=self._tracker_name,
        )
        logs = self._report.logs
        if is_created_issue:
            log_state = self._get_last_tracker_update_log()
            if log_state:
                last_tracker_update_log, tracker_issue_state = log_state
                if last_tracker_update_log:
                    logs = self._report.get_logs_after(
                        log=last_tracker_update_log, )
        send_logs_result = self._send_synchronizable_logs(
            tracker_issue=tracker_issue,
            logs=logs,
        )
        for added_comment in send_logs_result.added_comments:
            tracker_issue_state.add_downloaded_comment(
                added_comment.comment_id)
        download_comments_result = self._download_comments(
            tracker_issue=tracker_issue,
            exclude_comments=tracker_issue_state.downloaded_comments,
        )
        for downloaded_comment in download_comments_result.downloaded_comments:
            tracker_issue_state.add_downloaded_comment(downloaded_comment)
        new_report_status = self._update_report_status(
            tracker_issue=tracker_issue,
            tracker_issue_state=tracker_issue_state,
        )
        issue_status = self._get_issue_status_change(
            tracker_issue=tracker_issue,
            tracker_issue_state=tracker_issue_state,
        )
        tracker_issue_state.closed = tracker_issue.closed
        self._post_report_tracker_update(
            tracker_issue=tracker_issue,
            tracker_issue_state=tracker_issue_state,
            send_logs_result=send_logs_result,
            download_comments_result=download_comments_result,
            new_report_status=new_report_status,
            issue_status=issue_status,
        )
        return SynchronizeReportResult(
            is_created_issue=is_created_issue,
            is_existing_issue=True,
            new_report_status=new_report_status,
            send_logs_result=send_logs_result,
            download_comments_result=download_comments_result,
        )