Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add request to response #8

Merged
merged 11 commits into from
Feb 29, 2024
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers =
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Topic :: Software Development :: Libraries
project_urls =
Bug Reports = https://github.com/funnel-io/requtests/issues
Expand Down
4 changes: 3 additions & 1 deletion src/requtests/fake_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ def close(self):
def send(self, request, **kwargs):
if self.assertions:
next(self.assertions)(request, **kwargs)
return next(self.responses)
response = next(self.responses)
response.request = request
return response


def _to_generator(element_or_collection):
Expand Down
46 changes: 23 additions & 23 deletions src/requtests/fake_request.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
from functools import partial
from requests import Session
from requtests.fake_adapter import FakeAdapter
from requtests.fake_response import fake_response


def fake_delete(*responses):
return partial(fake_request(*responses), "delete")
def fake_delete(*responses, assertions=None):
return partial(fake_request(*responses, assertions=assertions), "delete")


def fake_get(*responses):
return partial(fake_request(*responses), "get")
def fake_get(*responses, assertions=None):
return partial(fake_request(*responses, assertions=assertions), "get")


def fake_head(*responses):
return partial(fake_request(*responses), "head")
def fake_head(*responses, assertions=None):
return partial(fake_request(*responses, assertions=assertions), "head")


def fake_options(*responses):
return partial(fake_request(*responses), "options")
def fake_options(*responses, assertions=None):
return partial(fake_request(*responses, assertions=assertions), "options")


def fake_patch(*responses):
return partial(fake_request(*responses), "patch")
def fake_patch(*responses, assertions=None):
return partial(fake_request(*responses, assertions=assertions), "patch")


def fake_post(*responses):
return partial(fake_request(*responses), "post")
def fake_post(*responses, assertions=None):
return partial(fake_request(*responses, assertions=assertions), "post")


def fake_put(*responses):
return partial(fake_request(*responses), "put")
def fake_put(*responses, assertions=None):
return partial(fake_request(*responses, assertions=assertions), "put")


def fake_request_with_response(**response_config):
def fake_request_with_response(assertions=None, **response_config):
"""
Creates a request function that returns a response given the response_config.
"""
return fake_request(fake_response(**response_config))
return fake_request(fake_response(**response_config), assertions=assertions)


def fake_request(*responses):
def fake_request(*responses, assertions=None):
"""
Creates a request function that returns the supplied responses, one at a time.
Making a new request after the last response has been returned results in a StopIteration error.
"""
iterator = (response for response in responses)

def request(method, url, **kwargs):
return next(iterator)

return request
adapter = FakeAdapter(*responses, assertions=assertions)
session = Session()
session.get_adapter = lambda url: adapter
return session.request
13 changes: 8 additions & 5 deletions tests/fake_adapter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
def test_fake_adapter():
response = fake_response()
adapter = FakeAdapter(response)
request = PreparedRequest()
assert response.request is None
assert isinstance(adapter, BaseAdapter)
assert not adapter.closed
assert adapter.send(PreparedRequest()) == response
assert adapter.send(request) is response
assert adapter.close() is None
assert adapter.closed
assert response.request is request


def test_fake_adapter_with_assert_step():
Expand Down Expand Up @@ -47,8 +50,8 @@ def test_fake_adapter_with_multiple_responses():
assertions=assert_prepared_request(url=TEST_URL, body=TEST_DATA),
)
request = build_request(url=TEST_URL, body=TEST_DATA)
assert adapter.send(request) == response_1
assert adapter.send(request) == response_2
assert adapter.send(request) is response_1
assert adapter.send(request) is response_2


def test_fake_adapter_with_multiple_responses_and_assertions():
Expand All @@ -66,8 +69,8 @@ def test_fake_adapter_with_multiple_responses_and_assertions():
)
request_1 = build_request(url=TEST_URL, body=data_1)
request_2 = build_request(url=TEST_URL, body=data_2)
assert adapter.send(request_1) == response_1
assert adapter.send(request_2) == response_2
assert adapter.send(request_1) is response_1
assert adapter.send(request_2) is response_2


def test_fake_adapter_mounted_on_session():
Expand Down
12 changes: 11 additions & 1 deletion tests/fake_http_verbs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,19 @@
}.items(),
)
def test_fake_http_method(func_name, method):
assertions_called = False

def assertions(prepared_request, **_):
nonlocal assertions_called
assertions_called = True
assert prepared_request.method == method.upper()

responses = [
fake_response(json={"tea": "brewing"}, status_code=418),
fake_response(json={"status": "I'm afraid I can't do that, Dave."}, status_code=405),
]

fake_http_method = getattr(requtests, func_name)(*responses)
fake_http_method = getattr(requtests, func_name)(*responses, assertions=assertions)
assert isinstance(fake_http_method, partial)
assert fake_http_method.args == (method,)

Expand All @@ -32,9 +39,12 @@ def test_fake_http_method(func_name, method):
json={"tea": "brewing"},
status_code=418,
)
assert assertions_called

assertions_called = False
assert_response(
fake_http_method("https://api.example.com/endpoint", params={"page": 2}),
json={"status": "I'm afraid I can't do that, Dave."},
status_code=405,
)
assert assertions_called
44 changes: 43 additions & 1 deletion tests/fake_request_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from requtests import fake_request_with_response, fake_response, fake_request
import pytest
from requests.models import PreparedRequest

from requtests import fake_request, fake_request_with_response, fake_response
from tests.test_utils import assert_response


Expand All @@ -21,6 +24,19 @@ def test_fake_request():
)


def test_fake_request_with_assertions():
assertions_called = False

def assertions(prepared_request, **_):
nonlocal assertions_called
assertions_called = True
assert isinstance(prepared_request, PreparedRequest)

response = fake_response(json={"some": "data"}, status_code=418)
fake_request(response, assertions=assertions)("get", "https://example.com")
assert assertions_called


def test_fake_request_with_response():
response_config = {
"json": {"some": "data"},
Expand All @@ -37,3 +53,29 @@ def test_fake_request_with_response():
headers={"some": "header"},
)
assert_response(response, **response_config)


def test_fake_request_with_response_with_assertions():
response_config = {
"json": {"some": "data"},
"reason": "some reason",
"status_code": 418,
"url": "some url",
}

assertions_called = False

def assertions(prepared_request, **_):
nonlocal assertions_called
assertions_called = True
assert isinstance(prepared_request, PreparedRequest)

request = fake_request_with_response(**response_config, assertions=assertions)
request(
"GET",
"https://api.example.com/endpoint",
params={"some": "param"},
headers={"some": "header"},
)

assert assertions_called
10 changes: 8 additions & 2 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ def assertions(request, **kwargs):


def assert_response(
response, json=None, reason=None, status_code=200, text=None, url=None, headers={}
response,
json=None,
reason=None,
status_code=200,
text=None,
url=None,
headers={},
):
assert type(response) == Response
assert isinstance(response, Response)
assert response.status_code == status_code
assert response.reason == reason
assert response.url == url
Expand Down