From 55e115487130555f9f179b15b705df344ed50f84 Mon Sep 17 00:00:00 2001 From: Eeshan Garg Date: Fri, 21 Apr 2017 22:04:53 -0230 Subject: [PATCH] webhooks/beanstalk: Filter specific Git branches. --- zerver/webhooks/beanstalk/doc.html | 6 ++ zerver/webhooks/beanstalk/tests.py | 94 ++++++++++++++++++++++++++++++ zerver/webhooks/beanstalk/view.py | 9 ++- 3 files changed, 106 insertions(+), 3 deletions(-) diff --git a/zerver/webhooks/beanstalk/doc.html b/zerver/webhooks/beanstalk/doc.html index 920e7b9961..86df88992f 100644 --- a/zerver/webhooks/beanstalk/doc.html +++ b/zerver/webhooks/beanstalk/doc.html @@ -17,6 +17,12 @@ In the URL field, enter {{ external_uri_scheme }}bot_email:bot_api_key@{{ external_api_path_subdomain }}/v1/external/beanstalk:

+

+ You can also limit the Git notifications you receive to specific + branches by specifying them in a comma-separated list at the end + of the URL, like so: +

+

{{ external_uri_scheme }}bot_email:bot_api_key@{{ external_api_path_subdomain }}/v1/external/beanstalk?branches=master,development

diff --git a/zerver/webhooks/beanstalk/tests.py b/zerver/webhooks/beanstalk/tests.py index 89f5899aa2..44eb98b5b3 100644 --- a/zerver/webhooks/beanstalk/tests.py +++ b/zerver/webhooks/beanstalk/tests.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +from mock import patch, MagicMock from typing import Dict, Text + from zerver.lib.webhooks.git import COMMITS_LIMIT from zerver.lib.test_classes import WebhookTestCase @@ -12,6 +14,17 @@ class BeanstalkHookTests(WebhookTestCase): expected_subject = "work-test / master" expected_message = """Leo Franchi [pushed](http://lfranchi-svn.beanstalkapp.com/work-test) 1 commit to branch master. Commits by Leo Franchi(1) +* add some stuff ([e50508d](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/e50508df))""" + self.send_and_test_stream_message('git_singlecommit', expected_subject, expected_message, + content_type=None, + **self.api_auth(self.TEST_USER_EMAIL)) + + def test_git_single_filtered_by_branches(self): + # type: () -> None + self.url = self.build_webhook_url(branches='master,development') + expected_subject = "work-test / master" + expected_message = """Leo Franchi [pushed](http://lfranchi-svn.beanstalkapp.com/work-test) 1 commit to branch master. Commits by Leo Franchi(1) + * add some stuff ([e50508d](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/e50508df))""" self.send_and_test_stream_message('git_singlecommit', expected_subject, expected_message, content_type=None, @@ -22,6 +35,19 @@ class BeanstalkHookTests(WebhookTestCase): expected_subject = "work-test / master" expected_message = """Leo Franchi [pushed](http://lfranchi-svn.beanstalkapp.com/work-test) 3 commits to branch master. Commits by Leo Franchi(2) and Tomasz Kolek(1) +* Added new file ([edf529c](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/edf529c7)) +* Filled in new file with some stuff ([c2a191b](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/c2a191b9)) +* More work to fix some bugs ([2009815](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/20098158))""" + self.send_and_test_stream_message('git_multiple_committers', expected_subject, expected_message, + content_type=None, + **self.api_auth(self.TEST_USER_EMAIL)) + + def test_git_multiple_committers_filtered_by_branches(self): + # type: () -> None + self.url = self.build_webhook_url(branches='master,development') + expected_subject = "work-test / master" + expected_message = """Leo Franchi [pushed](http://lfranchi-svn.beanstalkapp.com/work-test) 3 commits to branch master. Commits by Leo Franchi(2) and Tomasz Kolek(1) + * Added new file ([edf529c](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/edf529c7)) * Filled in new file with some stuff ([c2a191b](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/c2a191b9)) * More work to fix some bugs ([2009815](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/20098158))""" @@ -34,6 +60,19 @@ class BeanstalkHookTests(WebhookTestCase): expected_subject = "work-test / master" expected_message = """Leo Franchi [pushed](http://lfranchi-svn.beanstalkapp.com/work-test) 3 commits to branch master. Commits by Leo Franchi(3) +* Added new file ([edf529c](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/edf529c7)) +* Filled in new file with some stuff ([c2a191b](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/c2a191b9)) +* More work to fix some bugs ([2009815](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/20098158))""" + self.send_and_test_stream_message('git_multiple', expected_subject, expected_message, + content_type=None, + **self.api_auth(self.TEST_USER_EMAIL)) + + def test_git_multiple_filtered_by_branches(self): + # type: () -> None + self.url = self.build_webhook_url(branches='master,development') + expected_subject = "work-test / master" + expected_message = """Leo Franchi [pushed](http://lfranchi-svn.beanstalkapp.com/work-test) 3 commits to branch master. Commits by Leo Franchi(3) + * Added new file ([edf529c](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/edf529c7)) * Filled in new file with some stuff ([c2a191b](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/c2a191b9)) * More work to fix some bugs ([2009815](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/20098158))""" @@ -52,6 +91,61 @@ class BeanstalkHookTests(WebhookTestCase): content_type=None, **self.api_auth(self.TEST_USER_EMAIL)) + def test_git_more_than_limit_filtered_by_branches(self): + # type: () -> None + self.url = self.build_webhook_url(branches='master,development') + commits_info = "* add some stuff ([e50508d](http://lfranchi-svn.beanstalkapp.com/work-test/changesets/e50508df))\n" + expected_subject = "work-test / master" + expected_message = """Leo Franchi [pushed](http://lfranchi-svn.beanstalkapp.com/work-test) 50 commits to branch master. Commits by Leo Franchi(50) + +{}[and {} more commit(s)]""".format((commits_info * COMMITS_LIMIT), 50 - COMMITS_LIMIT) + self.send_and_test_stream_message('git_morethanlimitcommits', expected_subject, expected_message, + content_type=None, + **self.api_auth(self.TEST_USER_EMAIL)) + + @patch('zerver.webhooks.beanstalk.view.check_send_message') + def test_git_single_filtered_by_branches_ignore(self, check_send_message_mock): + # type: (MagicMock) -> None + self.url = self.build_webhook_url(branches='changes,development') + payload = self.get_body('git_singlecommit') + result = self.client_post(self.url, payload, + **self.api_auth(self.TEST_USER_EMAIL)) + self.assertFalse(check_send_message_mock.called) + self.assert_json_success(result) + + @patch('zerver.webhooks.beanstalk.view.check_send_message') + def test_git_multiple_committers_filtered_by_branches_ignore( + self, check_send_message_mock): + # type: (MagicMock) -> None + self.url = self.build_webhook_url(branches='changes,development') + payload = self.get_body('git_multiple_committers') + result = self.client_post(self.url, payload, + **self.api_auth(self.TEST_USER_EMAIL)) + self.assertFalse(check_send_message_mock.called) + self.assert_json_success(result) + + @patch('zerver.webhooks.beanstalk.view.check_send_message') + def test_git_multiple_filtered_by_branches_ignore( + self, check_send_message_mock): + # type: (MagicMock) -> None + self.url = self.build_webhook_url(branches='changes,development') + payload = self.get_body('git_multiple') + result = self.client_post(self.url, payload, + **self.api_auth(self.TEST_USER_EMAIL)) + self.assertFalse(check_send_message_mock.called) + self.assert_json_success(result) + + @patch('zerver.webhooks.beanstalk.view.check_send_message') + def test_git_more_than_limit_filtered_by_branches_ignore( + self, check_send_message_mock): + # type: (MagicMock) -> None + self.url = self.build_webhook_url(branches='changes,development') + payload = self.get_body('git_morethanlimitcommits') + result = self.client_post(self.url, payload, + **self.api_auth(self.TEST_USER_EMAIL)) + self.assertFalse(check_send_message_mock.called) + self.assert_json_success(result) + def test_svn_addremove(self): # type: () -> None expected_subject = "svn r3" diff --git a/zerver/webhooks/beanstalk/view.py b/zerver/webhooks/beanstalk/view.py index a822da1387..5b39ca7e5f 100644 --- a/zerver/webhooks/beanstalk/view.py +++ b/zerver/webhooks/beanstalk/view.py @@ -13,7 +13,7 @@ from functools import wraps from zerver.webhooks.github.view import build_message_from_gitlog -from typing import Any, Callable, Dict, TypeVar +from typing import Any, Callable, Dict, TypeVar, Optional, Text from zerver.lib.str_utils import force_str, force_bytes ViewFuncT = TypeVar('ViewFuncT', bound=Callable[..., HttpResponse]) @@ -45,13 +45,16 @@ def beanstalk_decoder(view_func): @authenticated_rest_api_view(is_webhook=True) @has_request_variables def api_beanstalk_webhook(request, user_profile, - payload=REQ(validator=check_dict([]))): - # type: (HttpRequest, UserProfile, Dict[str, Any]) -> HttpResponse + payload=REQ(validator=check_dict([])), + branches=REQ(default=None)): + # type: (HttpRequest, UserProfile, Dict[str, Any], Optional[Text]) -> HttpResponse # Beanstalk supports both SVN and git repositories # We distinguish between the two by checking for a # 'uri' key that is only present for git repos git_repo = 'uri' in payload if git_repo: + if branches is not None and branches.find(payload['branch']) == -1: + return json_success() # To get a linkable url, for commit in payload['commits']: commit['committer'] = {'username': commit['author']['name']}