mirror of https://github.com/zulip/zulip.git
webhooks/bitbucket2: Include title in message body if not in topic.
This is a follow-up in response to Tim's comments on #9951. In instances where all messages from a BitBucket integration are grouped under one user specified topic (specified in the URL), we should include the title of the PR in the message body, since the availability of a user-specified topic precludes us from including it in the topic itself (which was the default behaviour).
This commit is contained in:
parent
85b555b1a8
commit
4a54e8ac17
|
@ -91,6 +91,12 @@ class Bitbucket2HookTests(WebhookTestCase):
|
|||
expected_message = u"kolaszek created [Issue #1](https://bitbucket.org/kolaszek/repository-name/issues/2/bug)(assigned to kolaszek)\n\n~~~ quote\nSuch a bug\n~~~"
|
||||
self.send_and_test_stream_message('issue_created', self.EXPECTED_SUBJECT_ISSUE_EVENTS, expected_message)
|
||||
|
||||
def test_bitbucket2_on_issue_created_with_custom_topic_in_url(self) -> None:
|
||||
self.url = self.build_webhook_url(topic="notifications")
|
||||
expected_subject = u"notifications"
|
||||
expected_message = u"kolaszek created [Issue #1 Bug](https://bitbucket.org/kolaszek/repository-name/issues/2/bug)(assigned to kolaszek)\n\n~~~ quote\nSuch a bug\n~~~"
|
||||
self.send_and_test_stream_message('issue_created', expected_subject, expected_message)
|
||||
|
||||
def test_bitbucket2_on_issue_updated_event(self) -> None:
|
||||
expected_message = u"kolaszek updated [Issue #1](https://bitbucket.org/kolaszek/repository-name/issues/2/bug)"
|
||||
self.send_and_test_stream_message('issue_updated', self.EXPECTED_SUBJECT_ISSUE_EVENTS, expected_message)
|
||||
|
@ -99,6 +105,12 @@ class Bitbucket2HookTests(WebhookTestCase):
|
|||
expected_message = u"kolaszek [commented](https://bitbucket.org/kolaszek/repository-name/issues/2#comment-28973596) on [Issue #1](https://bitbucket.org/kolaszek/repository-name/issues/2/bug)"
|
||||
self.send_and_test_stream_message('issue_commented', self.EXPECTED_SUBJECT_ISSUE_EVENTS, expected_message)
|
||||
|
||||
def test_bitbucket2_on_issue_commented_with_custom_topic_in_url(self) -> None:
|
||||
self.url = self.build_webhook_url(topic="notifications")
|
||||
expected_subject = u"notifications"
|
||||
expected_message = u"kolaszek [commented](https://bitbucket.org/kolaszek/repository-name/issues/2#comment-28973596) on [Issue #1 Bug](https://bitbucket.org/kolaszek/repository-name/issues/2/bug)"
|
||||
self.send_and_test_stream_message('issue_commented', expected_subject, expected_message)
|
||||
|
||||
def test_bitbucket2_on_pull_request_created_event(self) -> None:
|
||||
expected_message = u"kolaszek created [PR #1](https://bitbucket.org/kolaszek/repository-name/pull-requests/1)(assigned to tkolek)\nfrom `new-branch` to `master`\n\n~~~ quote\ndescription\n~~~"
|
||||
kwargs = {
|
||||
|
@ -106,6 +118,15 @@ class Bitbucket2HookTests(WebhookTestCase):
|
|||
}
|
||||
self.send_and_test_stream_message('pull_request_created_or_updated', self.EXPECTED_SUBJECT_PR_EVENTS, expected_message, **kwargs)
|
||||
|
||||
def test_bitbucket2_on_pull_request_created_with_custom_topic_in_url(self) -> None:
|
||||
self.url = self.build_webhook_url(topic="notifications")
|
||||
expected_subject = u"notifications"
|
||||
expected_message = u"kolaszek created [PR #1 new commit](https://bitbucket.org/kolaszek/repository-name/pull-requests/1)(assigned to tkolek)\nfrom `new-branch` to `master`\n\n~~~ quote\ndescription\n~~~"
|
||||
kwargs = {
|
||||
"HTTP_X_EVENT_KEY": 'pullrequest:created'
|
||||
}
|
||||
self.send_and_test_stream_message('pull_request_created_or_updated', expected_subject, expected_message, **kwargs)
|
||||
|
||||
def test_bitbucket2_on_pull_request_updated_event(self) -> None:
|
||||
expected_message = u"kolaszek updated [PR #1](https://bitbucket.org/kolaszek/repository-name/pull-requests/1)(assigned to tkolek)\nfrom `new-branch` to `master`\n\n~~~ quote\ndescription\n~~~"
|
||||
kwargs = {
|
||||
|
@ -120,6 +141,15 @@ class Bitbucket2HookTests(WebhookTestCase):
|
|||
}
|
||||
self.send_and_test_stream_message('pull_request_approved_or_unapproved', self.EXPECTED_SUBJECT_PR_EVENTS, expected_message, **kwargs)
|
||||
|
||||
def test_bitbucket2_on_pull_request_approved_with_custom_topic_in_url(self) -> None:
|
||||
self.url = self.build_webhook_url(topic="notifications")
|
||||
expected_subject = u"notifications"
|
||||
expected_message = u"kolaszek approved [PR #1 new commit](https://bitbucket.org/kolaszek/repository-name/pull-requests/1)"
|
||||
kwargs = {
|
||||
"HTTP_X_EVENT_KEY": 'pullrequest:approved'
|
||||
}
|
||||
self.send_and_test_stream_message('pull_request_approved_or_unapproved', expected_subject, expected_message, **kwargs)
|
||||
|
||||
def test_bitbucket2_on_pull_request_unapproved_event(self) -> None:
|
||||
expected_message = u"kolaszek unapproved [PR #1](https://bitbucket.org/kolaszek/repository-name/pull-requests/1)"
|
||||
kwargs = {
|
||||
|
@ -148,6 +178,15 @@ class Bitbucket2HookTests(WebhookTestCase):
|
|||
}
|
||||
self.send_and_test_stream_message('pull_request_comment_action', self.EXPECTED_SUBJECT_PR_EVENTS, expected_message, **kwargs)
|
||||
|
||||
def test_bitbucket2_on_pull_request_comment_created_with_custom_topic_in_url(self) -> None:
|
||||
self.url = self.build_webhook_url(topic="notifications")
|
||||
expected_subject = u"notifications"
|
||||
expected_message = u"kolaszek [commented](https://bitbucket.org/kolaszek/repository-name/pull-requests/3/_/diff#comment-20576503) on [PR #1 new commit](https://bitbucket.org/kolaszek/repository-name/pull-requests/3)\n\n~~~ quote\nComment1\n~~~"
|
||||
kwargs = {
|
||||
"HTTP_X_EVENT_KEY": 'pullrequest:comment_created'
|
||||
}
|
||||
self.send_and_test_stream_message('pull_request_comment_action', expected_subject, expected_message, **kwargs)
|
||||
|
||||
def test_bitbucket2_on_pull_request_comment_updated_event(self) -> None:
|
||||
expected_message = u"kolaszek updated a [comment](https://bitbucket.org/kolaszek/repository-name/pull-requests/3/_/diff#comment-20576503) on [PR #1](https://bitbucket.org/kolaszek/repository-name/pull-requests/3)\n\n~~~ quote\nComment1\n~~~"
|
||||
kwargs = {
|
||||
|
@ -155,6 +194,15 @@ class Bitbucket2HookTests(WebhookTestCase):
|
|||
}
|
||||
self.send_and_test_stream_message('pull_request_comment_action', self.EXPECTED_SUBJECT_PR_EVENTS, expected_message, **kwargs)
|
||||
|
||||
def test_bitbucket2_on_pull_request_comment_updated_with_custom_topic_in_url(self) -> None:
|
||||
self.url = self.build_webhook_url(topic="notifications")
|
||||
expected_subject = u"notifications"
|
||||
expected_message = u"kolaszek updated a [comment](https://bitbucket.org/kolaszek/repository-name/pull-requests/3/_/diff#comment-20576503) on [PR #1 new commit](https://bitbucket.org/kolaszek/repository-name/pull-requests/3)\n\n~~~ quote\nComment1\n~~~"
|
||||
kwargs = {
|
||||
"HTTP_X_EVENT_KEY": 'pullrequest:comment_updated'
|
||||
}
|
||||
self.send_and_test_stream_message('pull_request_comment_action', expected_subject, expected_message, **kwargs)
|
||||
|
||||
def test_bitbucket2_on_pull_request_comment_deleted_event(self) -> None:
|
||||
expected_message = u"kolaszek deleted a [comment](https://bitbucket.org/kolaszek/repository-name/pull-requests/3/_/diff#comment-20576503) on [PR #1](https://bitbucket.org/kolaszek/repository-name/pull-requests/3)\n\n~~~ quote\nComment1\n~~~"
|
||||
kwargs = {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import re
|
||||
from functools import partial
|
||||
from typing import Any, Callable, Dict, List, Optional
|
||||
from inspect import signature
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils.translation import ugettext as _
|
||||
|
@ -45,13 +46,10 @@ PULL_REQUEST_SUPPORTED_ACTIONS = [
|
|||
@has_request_variables
|
||||
def api_bitbucket2_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||
payload: Dict[str, Any]=REQ(argument_type='body'),
|
||||
branches: Optional[str]=REQ(default=None)) -> HttpResponse:
|
||||
branches: Optional[str]=REQ(default=None),
|
||||
user_specified_topic: Optional[str]=REQ("topic", default=None)) -> HttpResponse:
|
||||
type = get_type(request, payload)
|
||||
if type != 'push':
|
||||
subject = get_subject_based_on_type(payload, type)
|
||||
body = get_body_based_on_type(type)(payload)
|
||||
check_send_webhook_message(request, user_profile, subject, body)
|
||||
else:
|
||||
if type == 'push':
|
||||
# ignore push events with no changes
|
||||
if not payload['push']['changes']:
|
||||
return json_success()
|
||||
|
@ -59,10 +57,22 @@ def api_bitbucket2_webhook(request: HttpRequest, user_profile: UserProfile,
|
|||
if branch and branches:
|
||||
if branches.find(branch) == -1:
|
||||
return json_success()
|
||||
subjects = get_push_subjects(payload)
|
||||
bodies_list = get_push_bodies(payload)
|
||||
for body, subject in zip(bodies_list, subjects):
|
||||
|
||||
subject = get_subject_based_on_type(payload, type)
|
||||
body_function = get_body_based_on_type(type)
|
||||
if 'include_title' in signature(body_function).parameters:
|
||||
body = body_function(
|
||||
payload,
|
||||
include_title=user_specified_topic is not None
|
||||
)
|
||||
else:
|
||||
body = body_function(payload)
|
||||
|
||||
if type != 'push':
|
||||
check_send_webhook_message(request, user_profile, subject, body)
|
||||
else:
|
||||
for b, s in zip(body, subject):
|
||||
check_send_webhook_message(request, user_profile, s, b)
|
||||
|
||||
return json_success()
|
||||
|
||||
|
@ -91,7 +101,7 @@ def get_subject(payload: Dict[str, Any]) -> str:
|
|||
assert(payload['repository'] is not None)
|
||||
return BITBUCKET_SUBJECT_TEMPLATE.format(repository_name=get_repository_name(payload['repository']))
|
||||
|
||||
def get_subject_based_on_type(payload: Dict[str, Any], type: str) -> str:
|
||||
def get_subject_based_on_type(payload: Dict[str, Any], type: str) -> Any:
|
||||
if type.startswith('pull_request'):
|
||||
return SUBJECT_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format(
|
||||
repo=get_repository_name(payload['repository']),
|
||||
|
@ -106,6 +116,8 @@ def get_subject_based_on_type(payload: Dict[str, Any], type: str) -> str:
|
|||
id=payload['issue']['id'],
|
||||
title=payload['issue']['title']
|
||||
)
|
||||
if type == 'push':
|
||||
return get_push_subjects(payload)
|
||||
return get_subject(payload)
|
||||
|
||||
def get_type(request: HttpRequest, payload: Dict[str, Any]) -> str:
|
||||
|
@ -140,9 +152,8 @@ def get_type(request: HttpRequest, payload: Dict[str, Any]) -> str:
|
|||
|
||||
raise UnexpectedWebhookEventType('BitBucket2', event_key)
|
||||
|
||||
def get_body_based_on_type(type: str) -> Callable[[Dict[str, Any]], str]:
|
||||
def get_body_based_on_type(type: str) -> Any:
|
||||
fn = GET_SINGLE_MESSAGE_BODY_DEPENDING_ON_TYPE_MAPPER.get(type)
|
||||
assert callable(fn) # type parameter should be pre-checked, so not None
|
||||
return fn
|
||||
|
||||
def get_push_bodies(payload: Dict[str, Any]) -> List[str]:
|
||||
|
@ -230,11 +241,13 @@ def get_commit_status_changed_body(payload: Dict[str, Any]) -> str:
|
|||
status=payload['commit_status']['state']
|
||||
)
|
||||
|
||||
def get_issue_commented_body(payload: Dict[str, Any]) -> str:
|
||||
def get_issue_commented_body(payload: Dict[str, Any],
|
||||
include_title: Optional[bool]=False) -> str:
|
||||
action = '[commented]({}) on'.format(payload['comment']['links']['html']['href'])
|
||||
return get_issue_action_body(payload, action)
|
||||
return get_issue_action_body(payload, action, include_title)
|
||||
|
||||
def get_issue_action_body(payload: Dict[str, Any], action: str) -> str:
|
||||
def get_issue_action_body(payload: Dict[str, Any], action: str,
|
||||
include_title: Optional[bool]=False) -> str:
|
||||
issue = payload['issue']
|
||||
assignee = None
|
||||
message = None
|
||||
|
@ -249,19 +262,23 @@ def get_issue_action_body(payload: Dict[str, Any], action: str) -> str:
|
|||
issue['links']['html']['href'],
|
||||
issue['id'],
|
||||
message,
|
||||
assignee
|
||||
assignee,
|
||||
title=issue['title'] if include_title else None
|
||||
)
|
||||
|
||||
def get_pull_request_action_body(payload: Dict[str, Any], action: str) -> str:
|
||||
def get_pull_request_action_body(payload: Dict[str, Any], action: str,
|
||||
include_title: Optional[bool]=False) -> str:
|
||||
pull_request = payload['pullrequest']
|
||||
return get_pull_request_event_message(
|
||||
get_user_username(payload),
|
||||
action,
|
||||
get_pull_request_url(pull_request),
|
||||
pull_request.get('id')
|
||||
pull_request.get('id'),
|
||||
title=pull_request['title'] if include_title else None
|
||||
)
|
||||
|
||||
def get_pull_request_created_or_updated_body(payload: Dict[str, Any], action: str) -> str:
|
||||
def get_pull_request_created_or_updated_body(payload: Dict[str, Any], action: str,
|
||||
include_title: Optional[bool]=False) -> str:
|
||||
pull_request = payload['pullrequest']
|
||||
assignee = None
|
||||
if pull_request.get('reviewers'):
|
||||
|
@ -275,25 +292,36 @@ def get_pull_request_created_or_updated_body(payload: Dict[str, Any], action: st
|
|||
target_branch=pull_request['source']['branch']['name'],
|
||||
base_branch=pull_request['destination']['branch']['name'],
|
||||
message=pull_request['description'],
|
||||
assignee=assignee
|
||||
assignee=assignee,
|
||||
title=pull_request['title'] if include_title else None
|
||||
)
|
||||
|
||||
def get_pull_request_comment_created_action_body(payload: Dict[str, Any]) -> str:
|
||||
def get_pull_request_comment_created_action_body(
|
||||
payload: Dict[str, Any],
|
||||
include_title: Optional[bool]=False
|
||||
) -> str:
|
||||
action = '[commented]({})'.format(payload['comment']['links']['html']['href'])
|
||||
return get_pull_request_comment_action_body(payload, action)
|
||||
return get_pull_request_comment_action_body(payload, action, include_title)
|
||||
|
||||
def get_pull_request_deleted_or_updated_comment_action_body(payload: Dict[str, Any], action: str) -> str:
|
||||
def get_pull_request_deleted_or_updated_comment_action_body(
|
||||
payload: Dict[str, Any], action: str,
|
||||
include_title: Optional[bool]=False
|
||||
) -> str:
|
||||
action = "{} a [comment]({})".format(action, payload['comment']['links']['html']['href'])
|
||||
return get_pull_request_comment_action_body(payload, action)
|
||||
return get_pull_request_comment_action_body(payload, action, include_title)
|
||||
|
||||
def get_pull_request_comment_action_body(payload: Dict[str, Any], action: str) -> str:
|
||||
def get_pull_request_comment_action_body(
|
||||
payload: Dict[str, Any], action: str,
|
||||
include_title: Optional[bool]=False
|
||||
) -> str:
|
||||
action += ' on'
|
||||
return get_pull_request_event_message(
|
||||
get_user_username(payload),
|
||||
action,
|
||||
payload['pullrequest']['links']['html']['href'],
|
||||
payload['pullrequest']['id'],
|
||||
message=payload['comment']['content']['raw']
|
||||
message=payload['comment']['content']['raw'],
|
||||
title=payload['pullrequest']['title'] if include_title else None
|
||||
)
|
||||
|
||||
def get_push_tag_body(payload: Dict[str, Any], change: Dict[str, Any]) -> str:
|
||||
|
@ -385,5 +413,6 @@ GET_SINGLE_MESSAGE_BODY_DEPENDING_ON_TYPE_MAPPER = {
|
|||
action='updated'),
|
||||
'pull_request_comment_deleted': partial(get_pull_request_deleted_or_updated_comment_action_body,
|
||||
action='deleted'),
|
||||
'push': get_push_bodies,
|
||||
'repo:updated': get_repo_updated_body,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue