paypal_rest/tests/__init__.py
Brett Smith 2ff353bebb Initial commit.
This is enough code to start using the tool to debug itself,
so it's time to start committing individual bugfixes.
2020-11-18 15:57:38 -05:00

109 lines
2.9 KiB
Python

"""__init__.py - paypal_rest unit test common functionality"""
# Copyright © 2020 Brett Smith
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import itertools
import typing
import urllib.parse as urlparse
import requests
FLOAT_NUMBERS = [
'1200.30',
'255.75',
'99.99',
'5.00',
'0.00',
]
FLOAT_NUMBERS.extend(f'-{s}' for s in FLOAT_NUMBERS[:-1])
WHOLE_NUMBERS = [
'1250',
'255',
'99',
'5',
'0',
]
WHOLE_NUMBERS.extend(f'-{s}' for s in WHOLE_NUMBERS[:-1])
class ReceivedRequest(typing.NamedTuple):
method: str
url: urlparse.ParseResult
params: typing.Mapping[str, str]
@classmethod
def from_args(cls, method, url, params):
return cls(
method,
urlparse.urlparse(url),
dict(params or ()),
)
class MockResponse:
def __init__(self, body, status_code=requests.codes.OK):
self._body = body
self.status_code = status_code
@classmethod
def error(
cls,
name='TEST_ERROR',
message='Test error',
debug_id='0000',
status_code=requests.codes.BAD_REQUEST,
*details,
**kwargs,
):
body = {
'name': name,
'message': message,
'debug_id': debug_id,
'details': [{'issue': issue, 'location': 'test'}
for issue in details],
}
body.update(kwargs)
return cls(body, status_code)
def json(self):
return self._body.copy()
def raise_for_status(self):
if self.status_code >= 400:
raise requests.HTTPError(self.status_code)
class MockSession:
LAST_RESPONSE = MockResponse({
'name': 'NO_RESPONSE',
'message': 'MockSession got more requests than expected',
}, 509)
def __init__(self, *responses, infinite=False):
self._requests = []
if infinite:
self._responses = itertools.cycle(responses)
else:
self._responses = itertools.chain(
responses,
itertools.repeat(self.LAST_RESPONSE),
)
def request(self, method, url, params=None):
self._requests.append(ReceivedRequest.from_args(method, url, params))
return next(self._responses)
def get(self, url, params=None):
return self.request('GET', url, params)