aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--docs/pull_requests.rst35
-rw-r--r--docs/services.rst1
-rw-r--r--pygithub3/core/errors.py6
-rw-r--r--pygithub3/core/utils.py5
-rw-r--r--pygithub3/exceptions.py4
-rw-r--r--pygithub3/github.py9
-rw-r--r--pygithub3/requests/base.py91
-rw-r--r--pygithub3/requests/pull_requests/__init__.py68
-rw-r--r--pygithub3/requests/pull_requests/comments.py46
-rw-r--r--pygithub3/resources/base.py5
-rw-r--r--pygithub3/resources/pull_requests.py22
-rw-r--r--pygithub3/services/pull_requests/__init__.py140
-rw-r--r--pygithub3/services/pull_requests/comments.py84
-rw-r--r--pygithub3/tests/requests/test_core.py8
-rw-r--r--pygithub3/tests/services/test_pull_requests.py190
-rw-r--r--pygithub3/tests/utils/base.py2
16 files changed, 649 insertions, 67 deletions
diff --git a/docs/pull_requests.rst b/docs/pull_requests.rst
new file mode 100644
index 0000000..09313eb
--- /dev/null
+++ b/docs/pull_requests.rst
@@ -0,0 +1,35 @@
+.. _Pull Requests service:
+
+Pull Requests service
+=====================
+
+**Example**::
+
+ from pygithub3 import Github
+
+ gh = Github(user='octocat', repo='sample')
+
+ pull_requests = gh.pull_requests.list().all()
+ pull_request_commits = gh.pull_requests.list_commits(2512).all()
+
+Pull Requests
+-------------
+
+.. autoclass:: pygithub3.services.pull_requests.PullRequests
+ :members:
+
+ .. attribute:: comments
+
+ :ref:`Pull Request Comments service`
+
+
+.. _Pull Request Comments service:
+
+Pull Request Comments
+---------------------
+
+.. autoclass:: pygithub3.services.pull_requests.Comments
+ :members:
+
+.. _github pullrequests doc: http://developer.github.com/v3/pulls
+.. _github pullrequests comments doc: http://developer.github.com/v3/pulls/comments
diff --git a/docs/services.rst b/docs/services.rst
index 2fbd2ee..190ae99 100644
--- a/docs/services.rst
+++ b/docs/services.rst
@@ -73,5 +73,6 @@ List of services
repos
gists
git_data
+ pull_requests
.. _mimetypes: http://developer.github.com/v3/mime
diff --git a/pygithub3/core/errors.py b/pygithub3/core/errors.py
index 4a95df0..9b84479 100644
--- a/pygithub3/core/errors.py
+++ b/pygithub3/core/errors.py
@@ -1,11 +1,7 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
-try:
- import simplejson as json
-except ImportError:
- import json
-
+from pygithub3.core.utils import json
from pygithub3.exceptions import NotFound, BadRequest, UnprocessableEntity
diff --git a/pygithub3/core/utils.py b/pygithub3/core/utils.py
index c6dbf0a..24a3bbf 100644
--- a/pygithub3/core/utils.py
+++ b/pygithub3/core/utils.py
@@ -2,6 +2,11 @@
# -*- encoding: utf-8 -*-
""" Utils to support python 2.6 compatibility """
+try:
+ import simplejson as json
+except ImportError:
+ import json
+
from collections import MutableMapping
diff --git a/pygithub3/exceptions.py b/pygithub3/exceptions.py
index a467256..9ee2597 100644
--- a/pygithub3/exceptions.py
+++ b/pygithub3/exceptions.py
@@ -8,7 +8,7 @@ class InvalidBodySchema(Exception):
pass
-class DoesNotExists(Exception):
+class RequestDoesNotExist(Exception):
""" Raised when `Request` factory can't find the subclass """
pass
@@ -37,6 +37,6 @@ class UnprocessableEntity(Exception):
class NotFound(Exception):
""" Raised when server response is 404
- Catched with a pygithub3-exception to `services.base.Service._bool` method
+ Caught with a pygithub3-exception to `services.base.Service._bool` method
"""
pass
diff --git a/pygithub3/github.py b/pygithub3/github.py
index 13829a0..87c4a6d 100644
--- a/pygithub3/github.py
+++ b/pygithub3/github.py
@@ -18,10 +18,12 @@ class Github(object):
from pygithub3.services.repos import Repo
from pygithub3.services.gists import Gist
from pygithub3.services.git_data import GitData
+ from pygithub3.services.pull_requests import PullRequests
self._users = User(**config)
self._repos = Repo(**config)
self._gists = Gist(**config)
self._git_data = GitData(**config)
+ self._pull_requests = PullRequests(**config)
@property
def remaining_requests(self):
@@ -56,3 +58,10 @@ class Github(object):
:ref:`Git Data service <Git Data service>`
"""
return self._git_data
+
+ @property
+ def pull_requests(self):
+ """
+ :ref:`Pull Requests service <Pull Requests service>`
+ """
+ return self._pull_requests
diff --git a/pygithub3/requests/base.py b/pygithub3/requests/base.py
index 03b0f8a..c4fe5cc 100644
--- a/pygithub3/requests/base.py
+++ b/pygithub3/requests/base.py
@@ -2,20 +2,17 @@
# -*- encoding: utf-8 -*-
import re
-try:
- import simplejson as json
-except ImportError:
- import json
-from pygithub3.exceptions import (DoesNotExists, UriInvalid, ValidationError,
- InvalidBodySchema)
+from pygithub3.core.utils import import_module, json
+from pygithub3.exceptions import (RequestDoesNotExist, UriInvalid,
+ ValidationError, InvalidBodySchema)
from pygithub3.resources.base import Raw
-from pygithub3.core.utils import import_module
ABS_IMPORT_PREFIX = 'pygithub3.requests'
class Body(object):
+ """ Input's request handler """
def __init__(self, content, schema, required):
self.content = content
@@ -28,6 +25,7 @@ class Body(object):
return json.dumps(self.parse())
def parse(self):
+ """ Parse body with schema-required rules """
if not hasattr(self.content, 'items'):
raise ValidationError("'%s' needs a content dictionary"
% self.__class__.__name__)
@@ -44,21 +42,34 @@ class Body(object):
class Request(object):
- """ """
uri = ''
resource = Raw
body_schema = {}
def __init__(self, **kwargs):
- """ """
- self.body = kwargs.pop('body', None)
+ self.body = kwargs.pop('body', {})
self.args = kwargs
self.clean()
+ def __getattr__(self, name):
+ return self.args.get(name)
+
+ def __str__(self):
+ return self.populate_uri()
+
+ def populate_uri(self):
+ try:
+ populated_uri = self.uri.format(**self.args)
+ except KeyError:
+ raise ValidationError(
+ "'%s' request wasn't be able to populate the uri '%s' with "
+ "'%s' args" % (self.__class__.__name__, self.uri, self.args))
+ return str(populated_uri).strip('/')
+
def clean(self):
self.uri = self.clean_uri() or self.uri
- self.body = Body(self.clean_body(), **self.clean_valid_body())
+ self.body = Body(self.clean_body(), **self._clean_valid_body())
def clean_body(self):
return self.body
@@ -66,7 +77,7 @@ class Request(object):
def clean_uri(self):
return None
- def clean_valid_body(self):
+ def _clean_valid_body(self):
schema = set(self.body_schema.get('schema', ()))
required = set(self.body_schema.get('required', ()))
if not required.issubset(schema):
@@ -76,21 +87,6 @@ class Request(object):
self.__class__.__name__, required, schema))
return dict(schema=schema, required=required)
- def __getattr__(self, name):
- return self.args.get(name)
-
- def __str__(self):
- return self.populate_uri()
-
- def populate_uri(self):
- try:
- populated_uri = self.uri.format(**self.args)
- except KeyError:
- raise ValidationError(
- "'%s' request wasn't be able to populate the uri '%s' with "
- "'%s' args" % (self.__class__.__name__, self.uri, self.args))
- return str(populated_uri).strip('/')
-
def get_body(self):
return self.body.dumps()
@@ -110,28 +106,21 @@ class Factory(object):
return func(self, request_uri.lower(), **kwargs)
return wrapper
- def dispatch(func):
- def wrapper(self, request_uri, **kwargs):
- module_chunk, s, request_chunk = request_uri.rpartition('.')
- request_chunk = request_chunk.capitalize()
- try:
- # TODO: CamelCase and under_score support, now only Class Name
- module = import_module('%s.%s'
- % (ABS_IMPORT_PREFIX, module_chunk))
- request = getattr(module, request_chunk)
- except ImportError:
- raise DoesNotExists("'%s' module does not exists"
- % module_chunk)
- except AttributeError:
- raise DoesNotExists(
- "'%s' request doesn't exists into '%s' module"
- % (request_chunk, module_chunk))
- return func(self, request, **kwargs)
- return wrapper
-
@validate
- @dispatch
- def __call__(self, request='', **kwargs):
- request = request(**kwargs)
- assert isinstance(request, Request)
- return request
+ def __call__(self, request_uri, **kwargs):
+ module_chunk, s, request_chunk = request_uri.rpartition('.')
+ request_chunk = request_chunk.capitalize()
+ try:
+ # TODO: CamelCase and under_score support, now only Class Name
+ module = import_module('%s.%s' % (ABS_IMPORT_PREFIX, module_chunk))
+ request_class = getattr(module, request_chunk)
+ request = request_class(**kwargs)
+ assert isinstance(request, Request)
+ return request
+ except ImportError:
+ raise RequestDoesNotExist("'%s' module does not exist"
+ % module_chunk)
+ except AttributeError:
+ raise RequestDoesNotExist("'%s' request does not exist in "
+ "'%s' module" % (request_chunk,
+ module_chunk))
diff --git a/pygithub3/requests/pull_requests/__init__.py b/pygithub3/requests/pull_requests/__init__.py
new file mode 100644
index 0000000..f25572d
--- /dev/null
+++ b/pygithub3/requests/pull_requests/__init__.py
@@ -0,0 +1,68 @@
+# -*- encoding: utf-8 -*-
+
+from pygithub3.requests.base import Request, ValidationError
+from pygithub3.resources.pull_requests import PullRequest, File
+from pygithub3.resources.repos import Commit
+
+
+class List(Request):
+ uri = 'repos/{user}/{repo}/pulls'
+ resource = PullRequest
+
+
+class Get(Request):
+ uri = 'repos/{user}/{repo}/pulls/{number}'
+ resource = PullRequest
+
+
+class Create(Request):
+ uri = 'repos/{user}/{repo}/pulls'
+ resource = PullRequest
+ body_schema = {
+ 'schema': ('title', 'body', 'base', 'head', 'issue'),
+ 'required': ('base', 'head'),
+ }
+
+ def clean_body(self):
+ if (not ('title' in self.body and 'body' in self.body) and
+ not 'issue' in self.body):
+ raise ValidationError('pull request creation requires either an '
+ 'issue number or a title and body')
+ return self.body
+
+class Update(Request):
+ uri = 'repos/{user}/{repo}/pulls/{number}'
+ resource = PullRequest
+ body_schema = {
+ 'schema': ('title', 'body', 'state'),
+ 'required': (),
+ }
+
+ def clean_body(self):
+ if ('state' in self.body and
+ self.body['state'] not in ['open', 'closed']):
+ raise ValidationError('If a state is specified, it must be one '
+ 'of "open" or "closed"')
+ return self.body
+
+
+class List_commits(Request):
+ uri = 'repos/{user}/{repo}/pulls/{number}/commits'
+ resource = Commit
+
+
+class List_files(Request):
+ uri = 'repos/{user}/{repo}/pulls/{number}/files'
+ resource = File
+
+
+class Is_merged(Request):
+ uri = 'repos/{user}/{repo}/pulls/{number}/merge'
+
+
+class Merge(Request):
+ uri = 'repos/{user}/{repo}/pulls/{number}/merge'
+ body_schema = {
+ 'schema': ('commit_message',),
+ 'required': (),
+ }
diff --git a/pygithub3/requests/pull_requests/comments.py b/pygithub3/requests/pull_requests/comments.py
new file mode 100644
index 0000000..dd69894
--- /dev/null
+++ b/pygithub3/requests/pull_requests/comments.py
@@ -0,0 +1,46 @@
+# -*- encoding: utf-8 -*-
+
+from pygithub3.requests.base import Request, ValidationError
+from pygithub3.resources.pull_requests import Comment
+
+
+class List(Request):
+ uri = 'repos/{user}/{repo}/pulls/{number}/comments'
+ resource = Comment
+
+
+class Get(Request):
+ uri = 'repos/{user}/{repo}/pulls/comments/{number}'
+ resource = Comment
+
+
+class Create(Request):
+ uri = 'repos/{user}/{repo}/pulls/{number}/comments'
+ resource = Comment
+ body_schema = {
+ 'schema': ('body', 'commit_id', 'path', 'position', 'in_reply_to'),
+ 'required': ('body',),
+ }
+
+ def clean_body(self):
+ if (not ('commit_id' in self.body and
+ 'path' in self.body and
+ 'position' in self.body) and
+ not 'in_reply_to' in self.body):
+ raise ValidationError('supply either in_reply_to or commit_id, '
+ 'path, and position')
+ return self.body
+
+
+class Edit(Request):
+ uri = 'repos/{user}/{repo}/pulls/comments/{number}'
+ resource = Comment
+ body_schema = {
+ 'schema': ('body',),
+ 'required': ('body',),
+ }
+
+
+class Delete(Request):
+ uri = 'repos/{user}/{repo}/pulls/comments/{number}'
+ resource = Comment
diff --git a/pygithub3/resources/base.py b/pygithub3/resources/base.py
index 4ca2aa3..7045529 100644
--- a/pygithub3/resources/base.py
+++ b/pygithub3/resources/base.py
@@ -1,10 +1,7 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
-try:
- import simplejson as json
-except ImportError:
- import json
+from pygithub3.core.utils import json
class Resource(object):
diff --git a/pygithub3/resources/pull_requests.py b/pygithub3/resources/pull_requests.py
new file mode 100644
index 0000000..a28e0fe
--- /dev/null
+++ b/pygithub3/resources/pull_requests.py
@@ -0,0 +1,22 @@
+# -*- encoding: utf-8 -*-
+
+from .base import Resource
+
+
+class PullRequest(Resource):
+ _dates = ('created_at', 'updated_at', 'closed_at', 'merged_at')
+
+ def __str__(self):
+ return '<PullRequest (%s)>' % getattr(self, 'title', '')
+
+
+class File(Resource):
+ def __str__(self):
+ return '<File (%s)>' % getattr(self, 'filename', '')
+
+
+class Comment(Resource):
+ _dates = ('created_at', 'updated_at')
+
+ def __str__(self):
+ return '<Comment (#%s)>' % getattr(self, 'id', '')
diff --git a/pygithub3/services/pull_requests/__init__.py b/pygithub3/services/pull_requests/__init__.py
new file mode 100644
index 0000000..545f862
--- /dev/null
+++ b/pygithub3/services/pull_requests/__init__.py
@@ -0,0 +1,140 @@
+# -*- encoding: utf-8 -*-
+
+from pygithub3.services.base import Service, MimeTypeMixin
+from .comments import Comments
+
+
+class PullRequests(Service, MimeTypeMixin):
+ """Consume `Pull Request API <http://developer.github.com/v3/pulls/>`_"""
+
+ def __init__(self, **config):
+ self.comments = Comments(**config)
+ super(PullRequests, self).__init__(**config)
+
+ def list(self, user=None, repo=None):
+ """List all of the pull requests for a repo
+
+ :param str user: Username
+ :param str repo: Repository
+ :returns: A :doc:`result`
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._get_result(
+ self.make_request('pull_requests.list', user=user, repo=repo)
+ )
+
+ def get(self, number, user=None, repo=None):
+ """Get a single pull request
+
+ :param str number: The number of the pull request to get
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._get(
+ self.make_request('pull_requests.get', number=number, user=user,
+ repo=repo)
+ )
+
+ def create(self, data, user=None, repo=None):
+ """Create a pull request
+
+ :param dict data: Input. See `github pullrequests doc`_
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._post(
+ self.make_request('pull_requests.create', body=data, user=user,
+ repo=repo)
+ )
+
+ def update(self, number, data, user=None, repo=None):
+ """Update a pull request
+
+ :param str number: The number of the the pull request to update
+ :param dict data: Input. See `github pullrequests doc`_
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._patch(
+ self.make_request('pull_requests.update', number=number,
+ body=data, user=user, repo=repo)
+ )
+
+ def list_commits(self, number, user=None, repo=None):
+ """List the commits for a pull request
+
+ :param str number: The number of the pull request to list commits for
+ :param str user: Username
+ :param str repo: Repository
+ :returns: A :doc:`result`
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._get_result(
+ self.make_request('pull_requests.list_commits', number=number,
+ user=user, repo=repo)
+ )
+
+ def list_files(self, number, user=None, repo=None):
+ """List the files for a pull request
+
+ :param str number: The number of the pull request to list files for
+ :param str user: Username
+ :param str repo: Repository
+ :returns: A :doc:`result`
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._get_result(
+ self.make_request('pull_requests.list_files', number=number,
+ user=user, repo=repo)
+ )
+
+ def is_merged(self, number, user=None, repo=None):
+ """Gets whether a pull request has been merged or not.
+
+ :param str number: The pull request to check
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._bool(
+ self.make_request('pull_requests.is_merged', number=number,
+ user=user, repo=repo)
+ )
+
+ def merge(self, number, message='', user=None, repo=None):
+ """Merge a pull request.
+
+ :param str number: The pull request to merge
+ :param str message: Message of pull request
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+
+ This currently raises an HTTP 405 error if the request is not
+ mergable.
+
+ """
+ body = {'commit_message': message}
+ return self._put(
+ self.make_request('pull_requests.merge', number=number,
+ body=body, user=user, repo=repo)
+ )
diff --git a/pygithub3/services/pull_requests/comments.py b/pygithub3/services/pull_requests/comments.py
new file mode 100644
index 0000000..2edbfdf
--- /dev/null
+++ b/pygithub3/services/pull_requests/comments.py
@@ -0,0 +1,84 @@
+# -*- encoding: utf-8 -*-
+from pygithub3.services.base import Service, MimeTypeMixin
+
+
+class Comments(Service, MimeTypeMixin):
+ """Consume `Review Comments API
+ <http://developer.github.com/v3/pulls/comments/>`_ """
+
+ def list(self, number, user=None, repo=None):
+ """List all the comments for a pull request
+
+ :param str number: The number of the pull request
+ :param str user: Username
+ :param str repo: Repository
+ :returns: A :doc:`result`
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._get_result(
+ self.make_request('pull_requests.comments.list', number=number,
+ user=user, repo=repo)
+ )
+
+ def get(self, number, user=None, repo=None):
+ """Get a single comment
+
+ :param str number: The comment to get
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._get(
+ self.make_request('pull_requests.comments.get', number=number,
+ user=user, repo=repo)
+ )
+
+ def create(self, number, data, user=None, repo=None):
+ """Create a comment
+
+ :param str number: the pull request to comment on
+ :param dict data: Input. See `github pullrequests comments doc`_
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._post(
+ self.make_request('pull_requests.comments.create', number=number,
+ body=data, user=user, repo=repo)
+ )
+
+ def update(self, number, message, user=None, repo=None):
+ """Edit a comment
+
+ :param str number: The id of the comment to edit
+ :param str message: Comment message
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ request = self.make_request('pull_requests.comments.edit',
+ number=number, body={'body': message}, user=user, repo=repo)
+ return self._patch(request)
+
+ def delete(self, number, user=None, repo=None):
+ """Delete a comment
+
+ :param str number: The comment to delete
+ :param str user: Username
+ :param str repo: Repository
+
+ .. note::
+ Remember :ref:`config precedence`
+ """
+ return self._delete(
+ self.make_request('pull_requests.comments.delete', number=number,
+ user=user, repo=repo)
+ )
diff --git a/pygithub3/tests/requests/test_core.py b/pygithub3/tests/requests/test_core.py
index cd162b3..110f00e 100644
--- a/pygithub3/tests/requests/test_core.py
+++ b/pygithub3/tests/requests/test_core.py
@@ -5,8 +5,8 @@ from mock import Mock
from pygithub3.tests.utils.core import TestCase
from pygithub3.requests.base import Factory, Body, json, Request
-from pygithub3.exceptions import (UriInvalid, DoesNotExists, ValidationError,
- InvalidBodySchema)
+from pygithub3.exceptions import (UriInvalid, RequestDoesNotExist,
+ ValidationError, InvalidBodySchema)
from pygithub3.tests.utils.base import mock_json, DummyRequest
from pygithub3.tests.utils.requests import (
RequestWithArgs, RequestCleanedUri, RequestBodyInvalidSchema,
@@ -27,8 +27,8 @@ class TestFactory(TestCase):
self.assertRaises(UriInvalid, self.f, '.invalid')
def test_BUILDER_with_fake_action(self):
- self.assertRaises(DoesNotExists, self.f, 'users.fake')
- self.assertRaises(DoesNotExists, self.f, 'fake.users')
+ self.assertRaises(RequestDoesNotExist, self.f, 'users.fake')
+ self.assertRaises(RequestDoesNotExist, self.f, 'fake.users')
def test_BUILDER_builds_users(self):
""" Users.get as real test because it wouldn't be useful mock
diff --git a/pygithub3/tests/services/test_pull_requests.py b/pygithub3/tests/services/test_pull_requests.py
new file mode 100644
index 0000000..93646df
--- /dev/null
+++ b/pygithub3/tests/services/test_pull_requests.py
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+import requests
+from mock import patch, Mock
+from nose.tools import raises
+
+from pygithub3.tests.utils.core import TestCase
+from pygithub3.services.pull_requests import PullRequests, Comments
+from pygithub3.requests.base import ValidationError, json
+from pygithub3.tests.utils.base import (mock_response, mock_response_result,
+ mock_json)
+from pygithub3.tests.utils.services import _
+
+
+json.dumps = Mock(side_effect=mock_json)
+json.loads = Mock(side_effect=mock_json)
+
+
+@patch.object(requests.sessions.Session, 'request')
+class TestPullRequestsService(TestCase):
+ def setUp(self):
+ self.service = PullRequests(user='user', repo='repo')
+
+ def test_LIST(self, reqm):
+ reqm.return_value = mock_response_result()
+ self.service.list().all()
+ self.assertEqual(
+ reqm.call_args[0],
+ ('get', _('repos/user/repo/pulls'))
+ )
+
+ def test_GET(self, reqm):
+ reqm.return_value = mock_response()
+ self.service.get(123)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('get', _('repos/user/repo/pulls/123'))
+ )
+
+ def test_CREATE_with_title_and_body(self, reqm):
+ reqm.return_value = mock_response('post')
+ data = {
+ 'title': 'this is a pull request',
+ 'body': 'merge me!',
+ 'head': 'octocat:some-feature',
+ 'base': 'master',
+ }
+ self.service.create(data)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('post', _('repos/user/repo/pulls'))
+ )
+
+ def test_CREATE_with_issue(self, reqm):
+ reqm.return_value = mock_response('post')
+ data = {
+ 'issue': 1,
+ 'head': 'octocat:some-feature',
+ 'base': 'master',
+ }
+ self.service.create(data)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('post', _('repos/user/repo/pulls'))
+ )
+
+ @raises(ValidationError)
+ def test_CREATE_with_no_title(self, reqm):
+ reqm.return_value = mock_response('post')
+ data = {
+ 'body': 'merge me!',
+ 'head': 'octocat:some-feature',
+ 'base': 'master',
+ }
+ self.service.create(data)
+
+ def test_UPDATE(self, reqm):
+ reqm.return_value = mock_response('patch')
+ data = {}
+ self.service.update(123, data)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('patch', _('repos/user/repo/pulls/123'))
+ )
+
+ @raises(ValidationError)
+ def test_UPDATE_with_invalid_state(self, reqm):
+ reqm.return_value = mock_response('patch')
+ data = {'state': 'Illinois'}
+ self.service.update(123, data)
+
+ def test_LIST_COMMITS(self, reqm):
+ reqm.return_value = mock_response_result('get')
+ self.service.list_commits(123).all()
+ self.assertEqual(
+ reqm.call_args[0],
+ ('get', _('repos/user/repo/pulls/123/commits'))
+ )
+
+ def test_LIST_FILES(self, reqm):
+ reqm.return_value = mock_response_result('get')
+ self.service.list_files(123).all()
+ self.assertEqual(
+ reqm.call_args[0],
+ ('get', _('repos/user/repo/pulls/123/files'))
+ )
+
+ def test_IS_MERGED(self, reqm):
+ resp = self.service.is_merged(123)
+ self.assertTrue(resp)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('head', _('repos/user/repo/pulls/123/merge'))
+ )
+
+ def test_MERGE(self, reqm):
+ reqm.return_value = mock_response(200)
+ self.service.merge(123, 'merging this')
+ self.assertEqual(
+ reqm.call_args[0],
+ ('put', _('repos/user/repo/pulls/123/merge'))
+ )
+
+
+@patch.object(requests.sessions.Session, 'request')
+class TestPullRequestCommentsService(TestCase):
+ def setUp(self):
+ self.service = Comments(user='user', repo='repo')
+
+ def test_LIST(self, reqm):
+ reqm.return_value = mock_response_result(200)
+ self.service.list(123).all()
+ self.assertEqual(
+ reqm.call_args[0],
+ ('get', _('repos/user/repo/pulls/123/comments'))
+ )
+
+ def test_GET(self, reqm):
+ reqm.return_value = mock_response(200)
+ self.service.get(1)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('get', _('repos/user/repo/pulls/comments/1'))
+ )
+
+ def test_CREATE(self, reqm):
+ reqm.return_value = mock_response(201)
+ data = {
+ 'body': ':sparkles:',
+ 'commit_id': 'abc123',
+ 'path': 'foo.txt',
+ 'position': '2',
+ }
+ self.service.create(1, data)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('post', _('repos/user/repo/pulls/1/comments'))
+ )
+
+ def test_CREATE_in_reply_to(self, reqm):
+ reqm.return_value = mock_response(201)
+ data = {
+ 'body': ':sparkles:',
+ 'in_reply_to': '5',
+ }
+ self.service.create(1, data)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('post', _('repos/user/repo/pulls/1/comments'))
+ )
+
+ def test_EDIT(self, reqm):
+ reqm.return_value = mock_response(200)
+ data = {
+ 'body': 'something completely different',
+ }
+ self.service.edit(1, data)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('patch', _('repos/user/repo/pulls/comments/1'))
+ )
+
+ def test_DELETE(self, reqm):
+ reqm.return_value = mock_response(204)
+ self.service.delete(1)
+ self.assertEqual(
+ reqm.call_args[0],
+ ('delete', _('repos/user/repo/pulls/comments/1'))
+ )
diff --git a/pygithub3/tests/utils/base.py b/pygithub3/tests/utils/base.py
index 49ea2b4..f90b5d3 100644
--- a/pygithub3/tests/utils/base.py
+++ b/pygithub3/tests/utils/base.py
@@ -14,7 +14,7 @@ def mock_json(content):
def mock_response(status_code='get', content={}):
CODES = dict(get=200, patch=200, post=201, delete=204)
response = Mock(name='response')
- response.status_code = CODES[str(status_code).lower()] or status_code
+ response.status_code = CODES.get(str(status_code).lower(), status_code)
response.content = content
return response