diff --git a/buildtrigger/bitbuckethandler.py b/buildtrigger/bitbuckethandler.py index 33c890083..2f26626a9 100644 --- a/buildtrigger/bitbuckethandler.py +++ b/buildtrigger/bitbuckethandler.py @@ -35,7 +35,7 @@ BITBUCKET_WEBHOOK_PAYLOAD_SCHEMA = { }, }, 'required': ['full_name'], - }, + }, # /Repository 'push': { 'type': 'object', 'properties': { @@ -91,10 +91,10 @@ BITBUCKET_WEBHOOK_PAYLOAD_SCHEMA = { }, }, 'required': ['html', 'avatar'], - }, + }, # /User }, 'required': ['username'], - }, + }, # /Author }, }, 'links': { @@ -111,19 +111,19 @@ BITBUCKET_WEBHOOK_PAYLOAD_SCHEMA = { }, }, 'required': ['html'], - }, + }, # /Links }, 'required': ['hash', 'message', 'date'], - }, + }, # /Target }, - 'required': ['target'], - }, + 'required': ['name', 'target'], + }, # /New }, - }, - }, + }, # /Changes item + }, # /Changes }, 'required': ['changes'], - }, + }, # / Push }, 'actor': { 'type': 'object', @@ -157,9 +157,9 @@ BITBUCKET_WEBHOOK_PAYLOAD_SCHEMA = { }, }, 'required': ['username'], - }, + }, # /Actor 'required': ['push', 'repository'], -} +} # /Root BITBUCKET_COMMIT_INFO_SCHEMA = { 'type': 'object', @@ -242,7 +242,7 @@ def get_transformed_webhook_payload(bb_payload, default_branch=None): config['default_branch'] = default_branch config['git_url'] = 'git@bitbucket.org:%s.git' % repository_name - config['commit_info.url'] = target['links.html.href'] + config['commit_info.url'] = target['links.html.href'] or '' config['commit_info.message'] = target['message'] config['commit_info.date'] = target['date'] diff --git a/buildtrigger/test/test_bitbuckethandler.py b/buildtrigger/test/test_bitbuckethandler.py index 991d90af1..12c653db5 100644 --- a/buildtrigger/test/test_bitbuckethandler.py +++ b/buildtrigger/test/test_bitbuckethandler.py @@ -1,6 +1,11 @@ +import json import pytest from buildtrigger.test.bitbucketmock import get_bitbucket_trigger +from buildtrigger.triggerutil import (SkipRequestException, ValidationRequestException, + InvalidPayloadException) +from endpoints.building import PreparedBuild +from util.morecollections import AttrDict @pytest.fixture def bitbucket_trigger(): @@ -20,3 +25,67 @@ def test_load_dockerfile_contents(subdir, contents): trigger = get_bitbucket_trigger(subdir) assert trigger.load_dockerfile_contents() == contents + +@pytest.mark.parametrize('payload, expected_error, expected_message', [ + ('{}', InvalidPayloadException, "'push' is a required property"), + + # Valid payload: + ('''{ + "push": { + "changes": [{ + "new": { + "name": "somechange", + "target": { + "hash": "aaaaaaa", + "message": "foo", + "date": "now", + "links": { + "html": { + "href": "somelink" + } + } + } + } + }] + }, + "repository": { + "full_name": "foo/bar" + } + }''', None, None), + + # Skip message: + ('''{ + "push": { + "changes": [{ + "new": { + "name": "somechange", + "target": { + "hash": "aaaaaaa", + "message": "[skip build] foo", + "date": "now", + "links": { + "html": { + "href": "somelink" + } + } + } + } + }] + }, + "repository": { + "full_name": "foo/bar" + } + }''', SkipRequestException, ''), +]) +def test_handle_trigger_request(bitbucket_trigger, payload, expected_error, expected_message): + def get_payload(): + return json.loads(payload) + + request = AttrDict(dict(get_json=get_payload)) + + if expected_error is not None: + with pytest.raises(expected_error) as ipe: + bitbucket_trigger.handle_trigger_request(request) + assert ipe.value.message == expected_message + else: + assert isinstance(bitbucket_trigger.handle_trigger_request(request), PreparedBuild)