From 91f7580c1c6bbe7295f9ae194ffefae281f30000 Mon Sep 17 00:00:00 2001 From: Linus Huzell Date: Wed, 28 Feb 2024 11:39:30 +0100 Subject: [PATCH 01/11] Change asserts to check for the same object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lennart Fridén --- tests/fake_adapter_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/fake_adapter_test.py b/tests/fake_adapter_test.py index f731aba..da6e3d1 100644 --- a/tests/fake_adapter_test.py +++ b/tests/fake_adapter_test.py @@ -14,7 +14,7 @@ def test_fake_adapter(): adapter = FakeAdapter(response) assert isinstance(adapter, BaseAdapter) assert not adapter.closed - assert adapter.send(PreparedRequest()) == response + assert adapter.send(PreparedRequest()) is response assert adapter.close() is None assert adapter.closed @@ -47,8 +47,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(): @@ -66,8 +66,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(): From 33a11b628fcb0e7fc02fce6cc970577a07c36aab Mon Sep 17 00:00:00 2001 From: Linus Huzell Date: Wed, 28 Feb 2024 11:46:28 +0100 Subject: [PATCH 02/11] Add request to response in FakeAdapter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lennart Fridén --- src/requtests/fake_adapter.py | 4 +++- tests/fake_adapter_test.py | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/requtests/fake_adapter.py b/src/requtests/fake_adapter.py index c0ea5da..1b59003 100644 --- a/src/requtests/fake_adapter.py +++ b/src/requtests/fake_adapter.py @@ -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): diff --git a/tests/fake_adapter_test.py b/tests/fake_adapter_test.py index da6e3d1..39b3286 100644 --- a/tests/fake_adapter_test.py +++ b/tests/fake_adapter_test.py @@ -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()) is 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(): From c3984e07133b4a71c84b8844dc4503d0699c3f6a Mon Sep 17 00:00:00 2001 From: Linus Huzell Date: Wed, 28 Feb 2024 11:50:43 +0100 Subject: [PATCH 03/11] Bump version to 1.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lennart Fridén --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index f95db53..c839db1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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 From 474f85f0054f9f50f002466bd7bff9fd915f9e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lennart=20Frid=C3=A9n?= Date: Wed, 28 Feb 2024 12:17:25 +0100 Subject: [PATCH 04/11] Tidy up the assert_response helper function Co-authored-by: Linus Huzell --- tests/test_utils.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index c575145..96e8f6c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -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 From 20ec55989eb13e1bebc0bf534649f5c7d960401d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lennart=20Frid=C3=A9n?= Date: Wed, 28 Feb 2024 12:18:26 +0100 Subject: [PATCH 05/11] Bump version to 2.0.0 This indicates the potentially breaking changes we're about to implement. Co-authored-by: Linus Huzell --- README.md | 4 ++-- src/requtests/__init__.py | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 704de66..e730592 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ Test helpers for the [requests](https://docs.python-requests.org) library ## Installation -Install the package `requtests` version `1.1+` from PyPI. -The recommended `requirements.txt` line is `requtests~=1.1`. +Install the package `requtests` version `2.0+` from PyPI. +The recommended `requirements.txt` line is `requtests~=2.0`. ### `FakeAdapter` diff --git a/src/requtests/__init__.py b/src/requtests/__init__.py index f64ebc5..940652a 100644 --- a/src/requtests/__init__.py +++ b/src/requtests/__init__.py @@ -25,6 +25,4 @@ "fake_request_with_response", "fake_response", ] -__version__ = "1.1.0" - -VERSION = __version__ +__version__ = "2.0.0" From b9acfce30403b4c22634f1f057df683030e7a635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lennart=20Frid=C3=A9n?= Date: Thu, 29 Feb 2024 14:30:41 +0100 Subject: [PATCH 06/11] Use FakeAdapter from fake_request Co-authored-by: Linus Huzell --- src/requtests/fake_request.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/requtests/fake_request.py b/src/requtests/fake_request.py index df9d4d7..059a35d 100644 --- a/src/requtests/fake_request.py +++ b/src/requtests/fake_request.py @@ -1,4 +1,6 @@ from functools import partial +from requests import Session +from requtests.fake_adapter import FakeAdapter from requtests.fake_response import fake_response @@ -42,9 +44,7 @@ def fake_request(*responses): 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) + session = Session() + session.get_adapter = lambda url: adapter + return session.request From 2054ddd54eb451ba6bc59a557e209e693b2a596e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lennart=20Frid=C3=A9n?= Date: Thu, 29 Feb 2024 14:30:57 +0100 Subject: [PATCH 07/11] WIP: support assertions in fake_request [ci skip] Co-authored-by: Linus Huzell --- tests/fake_request_test.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/fake_request_test.py b/tests/fake_request_test.py index 363890b..a98f441 100644 --- a/tests/fake_request_test.py +++ b/tests/fake_request_test.py @@ -1,4 +1,5 @@ -from requtests import fake_request_with_response, fake_response, fake_request +import pytest +from requtests import fake_request, fake_request_with_response, fake_response from tests.test_utils import assert_response @@ -21,6 +22,11 @@ def test_fake_request(): ) +@pytest.mark.skip(reason="Pending") +def test_fake_request_with_assertions(): + pass + + def test_fake_request_with_response(): response_config = { "json": {"some": "data"}, @@ -37,3 +43,8 @@ def test_fake_request_with_response(): headers={"some": "header"}, ) assert_response(response, **response_config) + + +@pytest.mark.skip(reason="Pending") +def test_fake_request_with_response_with_assertions(): + pass From ccae4949a485485f3e448e01ae8cc0b082f65fcc Mon Sep 17 00:00:00 2001 From: Linus Huzell Date: Thu, 29 Feb 2024 14:47:53 +0100 Subject: [PATCH 08/11] fake_request takes assertions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lennart Fridén --- src/requtests/fake_request.py | 4 ++-- tests/fake_request_test.py | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/requtests/fake_request.py b/src/requtests/fake_request.py index 059a35d..dd656b0 100644 --- a/src/requtests/fake_request.py +++ b/src/requtests/fake_request.py @@ -39,12 +39,12 @@ def fake_request_with_response(**response_config): return fake_request(fake_response(**response_config)) -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. """ - adapter = FakeAdapter(*responses) + adapter = FakeAdapter(*responses, assertions=assertions) session = Session() session.get_adapter = lambda url: adapter return session.request diff --git a/tests/fake_request_test.py b/tests/fake_request_test.py index a98f441..d38c765 100644 --- a/tests/fake_request_test.py +++ b/tests/fake_request_test.py @@ -1,4 +1,6 @@ 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 @@ -22,9 +24,17 @@ def test_fake_request(): ) -@pytest.mark.skip(reason="Pending") def test_fake_request_with_assertions(): - pass + 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(): From 13ebe3c395777827c4b2080bfc3cc56e80dbd83f Mon Sep 17 00:00:00 2001 From: Linus Huzell Date: Thu, 29 Feb 2024 14:51:19 +0100 Subject: [PATCH 09/11] fake_request_with_response takes assertions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lennart Fridén --- src/requtests/fake_request.py | 4 ++-- tests/fake_request_test.py | 25 +++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/requtests/fake_request.py b/src/requtests/fake_request.py index dd656b0..f4e56d0 100644 --- a/src/requtests/fake_request.py +++ b/src/requtests/fake_request.py @@ -32,11 +32,11 @@ def fake_put(*responses): return partial(fake_request(*responses), "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, assertions=None): diff --git a/tests/fake_request_test.py b/tests/fake_request_test.py index d38c765..4cf3818 100644 --- a/tests/fake_request_test.py +++ b/tests/fake_request_test.py @@ -55,6 +55,27 @@ def test_fake_request_with_response(): assert_response(response, **response_config) -@pytest.mark.skip(reason="Pending") def test_fake_request_with_response_with_assertions(): - pass + 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 From 5b515cc9626a2d1f6741c5a40c6d3d2e5c8f275f Mon Sep 17 00:00:00 2001 From: Linus Huzell Date: Thu, 29 Feb 2024 14:54:20 +0100 Subject: [PATCH 10/11] fake_http_verbs takes assertions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lennart Fridén --- src/requtests/fake_request.py | 28 ++++++++++++++-------------- tests/fake_http_verbs_test.py | 12 +++++++++++- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/requtests/fake_request.py b/src/requtests/fake_request.py index f4e56d0..61ba322 100644 --- a/src/requtests/fake_request.py +++ b/src/requtests/fake_request.py @@ -4,32 +4,32 @@ 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(assertions=None, **response_config): diff --git a/tests/fake_http_verbs_test.py b/tests/fake_http_verbs_test.py index 508dc75..7476b96 100644 --- a/tests/fake_http_verbs_test.py +++ b/tests/fake_http_verbs_test.py @@ -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,) @@ -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 From 4a456fff4aed5b6938120304f2c245b44bdd4b25 Mon Sep 17 00:00:00 2001 From: Linus Huzell Date: Thu, 29 Feb 2024 15:00:56 +0100 Subject: [PATCH 11/11] Revert "Bump version to 2.0.0" This reverts commit 20ec55989eb13e1bebc0bf534649f5c7d960401d. --- README.md | 4 ++-- src/requtests/__init__.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e730592..704de66 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ Test helpers for the [requests](https://docs.python-requests.org) library ## Installation -Install the package `requtests` version `2.0+` from PyPI. -The recommended `requirements.txt` line is `requtests~=2.0`. +Install the package `requtests` version `1.1+` from PyPI. +The recommended `requirements.txt` line is `requtests~=1.1`. ### `FakeAdapter` diff --git a/src/requtests/__init__.py b/src/requtests/__init__.py index 940652a..f64ebc5 100644 --- a/src/requtests/__init__.py +++ b/src/requtests/__init__.py @@ -25,4 +25,6 @@ "fake_request_with_response", "fake_response", ] -__version__ = "2.0.0" +__version__ = "1.1.0" + +VERSION = __version__