From 3f7660aeb68addb4a5eda1d3a2c337d425556472 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Tue, 15 Aug 2023 22:37:58 +0300 Subject: [PATCH 01/13] Add calls to BaseResponse --- responses/__init__.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/responses/__init__.py b/responses/__init__.py index 2666b7c8..6c6edefa 100644 --- a/responses/__init__.py +++ b/responses/__init__.py @@ -394,7 +394,7 @@ def __init__( ) self.match: "_MatcherIterable" = match - self.call_count: int = 0 + self._calls: CallList = CallList() self.passthrough = passthrough def __eq__(self, other: Any) -> bool: @@ -503,6 +503,14 @@ def matches(self, request: "PreparedRequest") -> Tuple[bool, str]: return True, "" + @property + def call_count(self) -> int: + return len(self._calls) + + @property + def calls(self) -> CallList: + return self._calls + def _form_response( body: Union[BufferedReader, BytesIO], @@ -1064,13 +1072,13 @@ def _on_request( request, match.get_response(request) ) except BaseException as response: - match.call_count += 1 + match.calls.add(request, response) self._calls.add(request, response) raise if resp_callback: response = resp_callback(response) # type: ignore[misc] - match.call_count += 1 + match.calls.add(request, response) self._calls.add(request, response) # type: ignore[misc] retries = retries or adapter.max_retries From 77ca5974989b7c51ab2a8c957d24254c23a68262 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Fri, 18 Aug 2023 00:24:05 +0300 Subject: [PATCH 02/13] Reuse calls for matched BaseResponse and add add_call method into CallList --- responses/__init__.py | 9 +++- responses/tests/test_responses.py | 83 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/responses/__init__.py b/responses/__init__.py index 6c6edefa..35fb18eb 100644 --- a/responses/__init__.py +++ b/responses/__init__.py @@ -255,6 +255,9 @@ def __getitem__(self, idx: Union[int, slice]) -> Union[Call, List[Call]]: def add(self, request: "PreparedRequest", response: _Body) -> None: self._calls.append(Call(request, response)) + def add_call(self, call: Call) -> None: + self._calls.append(call) + def reset(self) -> None: self._calls = [] @@ -1072,14 +1075,16 @@ def _on_request( request, match.get_response(request) ) except BaseException as response: - match.calls.add(request, response) + next_index = len(self._calls) self._calls.add(request, response) + match.calls.add_call(self._calls[next_index]) raise if resp_callback: response = resp_callback(response) # type: ignore[misc] - match.calls.add(request, response) + next_index = len(self._calls) self._calls.add(request, response) # type: ignore[misc] + match.calls.add_call(self._calls[next_index]) retries = retries or adapter.max_retries # first validate that current request is eligible to be retried. diff --git a/responses/tests/test_responses.py b/responses/tests/test_responses.py index cbcee548..7e320c66 100644 --- a/responses/tests/test_responses.py +++ b/responses/tests/test_responses.py @@ -1,6 +1,7 @@ # coding: utf-8 import inspect +import json import os import re import warnings @@ -1988,6 +1989,88 @@ def run(): assert_reset() +def test_response_and_requests_mock_calls_are_equal(): + @responses.activate + def run(): + rsp = responses.add(responses.GET, "http://www.example.com") + rsp2 = responses.add(responses.GET, "http://www.example.com/1") + + requests.get("http://www.example.com") + requests.get("http://www.example.com/1") + + assert len(responses.calls) == 2 + assert rsp.call_count == 1 + assert rsp.calls[0] is responses.calls[0] + assert rsp2.call_count == 1 + assert rsp2.calls[0] is responses.calls[1] + + run() + assert_reset() + + +def test_response_call_request(): + @responses.activate + def run(): + rsp = responses.add(responses.GET, "http://www.example.com") + rsp2 = responses.add( + responses.PUT, "http://www.foo.bar/42/", json={"id": 42, "name": "Bazz"} + ) + + requests.get("http://www.example.com") + requests.get("http://www.example.com?hello=world") + requests.put( + "http://www.foo.bar/42/", + json={"name": "Bazz"}, + ) + + assert rsp.call_count == 2 + request = rsp.calls[0].request + assert request.url == "http://www.example.com/" + assert request.method == "GET" + request = rsp.calls[1].request + assert request.url == "http://www.example.com/?hello=world" + assert request.method == "GET" + assert rsp2.call_count == 1 + request = rsp2.calls[0].request + assert request.url == "http://www.foo.bar/42/" + assert request.method == "PUT" + request_payload = json.loads(request.body) + assert request_payload == {"name": "Bazz"} + + run() + assert_reset() + + +def test_response_call_response(): + @responses.activate + def run(): + rsp = responses.add(responses.GET, "http://www.example.com", body=b"test") + rsp2 = responses.add( + responses.POST, + "http://www.foo.bar/42/", + json={"id": 42, "name": "Bazz"}, + status=201, + ) + + requests.get("http://www.example.com") + requests.post( + "http://www.foo.bar/42/", + json={"name": "Bazz"}, + ) + + assert rsp.call_count == 1 + response = rsp.calls[0].response + assert response.content == b"test" + assert response.status_code == 200 + assert rsp2.call_count == 1 + response = rsp2.calls[0].response + assert response.json() == {"id": 42, "name": "Bazz"} + assert response.status_code == 201 + + run() + assert_reset() + + def test_fail_request_error(): """ Validate that exception is raised if request URL/Method/kwargs don't match From 566968843f03137875994673b59e162f3e0a956c Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Fri, 25 Aug 2023 00:16:41 +0300 Subject: [PATCH 03/13] Reuse call object with add_call & add example of usage Response.calls into README --- README.rst | 47 +++++++++++++++++++++++++++++++++++++++++++ responses/__init__.py | 12 +++++------ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 7d790eb0..04207d05 100644 --- a/README.rst +++ b/README.rst @@ -1079,6 +1079,53 @@ Assert that the request was called exactly n times. responses.assert_call_count("http://www.example.com?hello=world", 1) is True +Assert Request Calls data +------------------ + +``Request`` object has ``calls`` list which elements correspond to ``Call`` objects +in the global list of ``Registry``. + +.. code-block:: python + + import responses + import requests + + + @responses.activate + def test_assert_calls_on_resp(): + rsp = responses.add(responses.GET, "http://www.example.com") + rsp2 = responses.add( + responses.PUT, "http://foo.bar/42/", json={"id": 42, "name": "Bazz"} + ) + + requests.get("http://www.example.com") + requests.get("http://www.example.com?hello=world") + requests.put( + "http://foo.bar/42/", + json={"name": "Bazz"}, + ) + + assert len(responses.calls) == 3 # total calls count + # Assert calls to the 1st resource ("http://www.example.com"): + assert rsp.call_count == 2 + assert rsp.calls[0] is responses.calls[0] + assert rsp.calls[1] is responses.calls[1] + request = rsp.calls[0].request + assert request.url == "http://www.example.com/" + assert request.method == "GET" + request = rsp.calls[1].request + assert request.url == "http://www.example.com/?hello=world" + assert request.method == "GET" + # Assert calls to the 2nd resource (http://foo.bar): + assert rsp2.call_count == 1 + assert rsp2.calls[0] is responses.calls[2] + request = rsp2.calls[0].request + assert request.url == "http://foo.bar/42/" + assert request.method == "PUT" + request_payload = json.loads(request.body) + assert request_payload == {"name": "Bazz"} + + Multiple Responses ------------------ diff --git a/responses/__init__.py b/responses/__init__.py index b4251de2..f8831803 100644 --- a/responses/__init__.py +++ b/responses/__init__.py @@ -1073,16 +1073,16 @@ def _on_request( request, match.get_response(request) ) except BaseException as response: - next_index = len(self._calls) - self._calls.add(request, response) - match.calls.add_call(self._calls[next_index]) + call = Call(request, response) + self._calls.add_call(call) + match.calls.add_call(call) raise if resp_callback: response = resp_callback(response) # type: ignore[misc] - next_index = len(self._calls) - self._calls.add(request, response) # type: ignore[misc] - match.calls.add_call(self._calls[next_index]) + call = Call(request, response) + self._calls.add_call(call) + match.calls.add_call(call) retries = retries or adapter.max_retries # first validate that current request is eligible to be retried. From 7f7085eb7410845bf2cf704e5ac95579f1f93560 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Tue, 26 Sep 2023 20:11:26 +0300 Subject: [PATCH 04/13] Update README.rst Co-authored-by: Maksim Beliaev --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 04207d05..75940e0c 100644 --- a/README.rst +++ b/README.rst @@ -1094,8 +1094,8 @@ in the global list of ``Registry``. @responses.activate def test_assert_calls_on_resp(): rsp = responses.add(responses.GET, "http://www.example.com") - rsp2 = responses.add( - responses.PUT, "http://foo.bar/42/", json={"id": 42, "name": "Bazz"} + rsp2 = responses.put( + "http://foo.bar/42/", json={"id": 42, "name": "Bazz"} ) requests.get("http://www.example.com") From 0e515ff1b5a4c869de4b7fc917d37d3dd93c3724 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Tue, 26 Sep 2023 20:31:45 +0300 Subject: [PATCH 05/13] Add CHANGELOG entry --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 59a59252..18dfb191 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ 0.24.0 ------ +* Added `BaseResponse.calls` to access calls data of a separate mocked request. See #664 * Added support for re.Pattern based header matching. * Added support for gzipped response bodies to `json_params_matcher`. * Moved types-pyyaml dependency to `tests_requires` From d78499dbff0145cc961c997529d674281af8e2e0 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Wed, 27 Sep 2023 00:04:43 +0300 Subject: [PATCH 06/13] Change example in README --- README.rst | 78 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 28 deletions(-) diff --git a/README.rst b/README.rst index 75940e0c..1f3be396 100644 --- a/README.rst +++ b/README.rst @@ -1083,47 +1083,69 @@ Assert Request Calls data ------------------ ``Request`` object has ``calls`` list which elements correspond to ``Call`` objects -in the global list of ``Registry``. +in the global list of ``Registry``. This can be useful when the order of requests is not +guaranteed, but you need to check their correctness, for example in multithreaded +applications. .. code-block:: python + import concurrent.futures import responses import requests @responses.activate def test_assert_calls_on_resp(): - rsp = responses.add(responses.GET, "http://www.example.com") - rsp2 = responses.put( - "http://foo.bar/42/", json={"id": 42, "name": "Bazz"} + uid_with_permissions = [ + ("0123", {"client": True, "admin": False, "disabled": False}), + ("1234", {"client": False, "admin": True, "disabled": False}), + ("2345", {"client": False, "admin": False, "disabled": True}), + ] + rsp0123 = responses.patch( + "http://www.foo.bar/0123/", + json={"OK": True, "uid": "0123"}, + status=200, ) - - requests.get("http://www.example.com") - requests.get("http://www.example.com?hello=world") - requests.put( - "http://foo.bar/42/", - json={"name": "Bazz"}, + rsp1234 = responses.patch( + "http://www.foo.bar/1234/", + json={"OK": False, "uid": "1234"}, + status=400, + ) + rsp2345 = responses.patch( + "http://www.foo.bar/2345/", + json={"OK": True, "uid": "2345"}, + status=200, ) + def update_permissions(uid, permissions): + url = f"http://www.foo.bar/{uid}/" + response = requests.patch(url, json=permissions) + return response + + with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: + future_to_uid = { + executor.submit(update_permissions, uid, permissions): uid + for (uid, permissions) in uid_with_permissions + } + for future in concurrent.futures.as_completed(future_to_uid): + uid = future_to_uid[future] + response = future.result() + print("%s updated with %d status code" % (uid, response.status_code)) + assert len(responses.calls) == 3 # total calls count - # Assert calls to the 1st resource ("http://www.example.com"): - assert rsp.call_count == 2 - assert rsp.calls[0] is responses.calls[0] - assert rsp.calls[1] is responses.calls[1] - request = rsp.calls[0].request - assert request.url == "http://www.example.com/" - assert request.method == "GET" - request = rsp.calls[1].request - assert request.url == "http://www.example.com/?hello=world" - assert request.method == "GET" - # Assert calls to the 2nd resource (http://foo.bar): - assert rsp2.call_count == 1 - assert rsp2.calls[0] is responses.calls[2] - request = rsp2.calls[0].request - assert request.url == "http://foo.bar/42/" - assert request.method == "PUT" - request_payload = json.loads(request.body) - assert request_payload == {"name": "Bazz"} + + assert rsp0123.call_count == 1 + assert rsp0123.calls[0] in responses.calls + assert json.loads(rsp0123.calls[0].request.body) == {"client": True, "admin": False, "disabled": False} + + assert rsp1234.call_count == 1 + assert rsp1234.calls[0] in responses.calls + assert json.loads(rsp1234.calls[0].request.body) == {"client": False, "admin": True, "disabled": False} + assert rsp1234.calls[0].response.json() == {"OK": False, "uid": "1234"} + + assert rsp2345.call_count == 1 + assert rsp2345.calls[0] in responses.calls + assert json.loads(rsp2345.calls[0].request.body) == {"client": False, "admin": False, "disabled": True} Multiple Responses From aa29301167161e5da5e4146eccaa4246159b7567 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Fri, 20 Oct 2023 11:09:15 +0300 Subject: [PATCH 07/13] Fix for blacken-docs linter --- README.rst | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 1f3be396..d98ca6a7 100644 --- a/README.rst +++ b/README.rst @@ -1136,16 +1136,28 @@ applications. assert rsp0123.call_count == 1 assert rsp0123.calls[0] in responses.calls - assert json.loads(rsp0123.calls[0].request.body) == {"client": True, "admin": False, "disabled": False} + assert json.loads(rsp0123.calls[0].request.body) == { + "client": True, + "admin": False, + "disabled": False, + } assert rsp1234.call_count == 1 assert rsp1234.calls[0] in responses.calls - assert json.loads(rsp1234.calls[0].request.body) == {"client": False, "admin": True, "disabled": False} + assert json.loads(rsp1234.calls[0].request.body) == { + "client": False, + "admin": True, + "disabled": False, + } assert rsp1234.calls[0].response.json() == {"OK": False, "uid": "1234"} assert rsp2345.call_count == 1 assert rsp2345.calls[0] in responses.calls - assert json.loads(rsp2345.calls[0].request.body) == {"client": False, "admin": False, "disabled": True} + assert json.loads(rsp2345.calls[0].request.body) == { + "client": False, + "admin": False, + "disabled": True, + } Multiple Responses From d1b065016e3622cefb83fba8fc86ab05f2a4d6d0 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Fri, 20 Oct 2023 23:45:20 +0300 Subject: [PATCH 08/13] Add ignore comment for mypy --- responses/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/responses/__init__.py b/responses/__init__.py index 5e97bf67..71eb5a1a 100644 --- a/responses/__init__.py +++ b/responses/__init__.py @@ -1103,7 +1103,7 @@ def _on_request( if resp_callback: response = resp_callback(response) # type: ignore[misc] - call = Call(request, response) + call = Call(request, response) # type: ignore[misc] self._calls.add_call(call) match.calls.add_call(call) From f6a7dd300bfdafb35728156e050f83b31e741aa2 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Sat, 21 Oct 2023 00:17:33 +0300 Subject: [PATCH 09/13] Add ignore comments for mypy --- responses/__init__.py | 18 ++++++++++++------ responses/matchers.py | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/responses/__init__.py b/responses/__init__.py index 71eb5a1a..636bdb83 100644 --- a/responses/__init__.py +++ b/responses/__init__.py @@ -42,17 +42,23 @@ from typing import Literal # type: ignore # pragma: no cover try: - from requests.packages.urllib3.response import HTTPResponse + from requests.packages.urllib3.response import ( + HTTPResponse, # type: ignore[import-untyped] + ) except ImportError: # pragma: no cover from urllib3.response import HTTPResponse # pragma: no cover try: - from requests.packages.urllib3.connection import HTTPHeaderDict + from requests.packages.urllib3.connection import ( + HTTPHeaderDict, # type: ignore[import-untyped] + ) except ImportError: # pragma: no cover from urllib3.response import HTTPHeaderDict try: - from requests.packages.urllib3.util.url import parse_url + from requests.packages.urllib3.util.url import ( + parse_url, # type: ignore[import-untyped] + ) except ImportError: # pragma: no cover from urllib3.util.url import parse_url # pragma: no cover @@ -252,11 +258,11 @@ def __len__(self) -> int: return len(self._calls) @overload - def __getitem__(self, idx: int) -> Call: + def __getitem__(self, idx: int) -> Call: # type: ignore[misc] """Overload when get a single item.""" @overload - def __getitem__(self, idx: slice) -> List[Call]: + def __getitem__(self, idx: slice) -> List[Call]: # type: ignore[misc] """Overload when a slice is requested.""" def __getitem__(self, idx: Union[int, slice]) -> Union[Call, List[Call]]: @@ -978,7 +984,7 @@ def activate(self, func: "_F" = ...) -> "_F": """Overload for scenario when 'responses.activate' is used.""" @overload - def activate( + def activate( # type: ignore[misc] self, *, registry: Type[Any] = ..., diff --git a/responses/matchers.py b/responses/matchers.py index 43773cb2..dd53ea7f 100644 --- a/responses/matchers.py +++ b/responses/matchers.py @@ -13,7 +13,7 @@ from urllib.parse import urlparse from requests import PreparedRequest -from requests.packages.urllib3.util.url import parse_url +from requests.packages.urllib3.util.url import parse_url # type: ignore[import-untyped] def _create_key_val_str(input_dict: Union[Dict[Any, Any], Any]) -> str: From 654c6072f228ab35a09a2281f3e3ecdd66b3136c Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Mon, 23 Oct 2023 20:23:39 +0300 Subject: [PATCH 10/13] Make tests readable --- responses/tests/test_responses.py | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/responses/tests/test_responses.py b/responses/tests/test_responses.py index 59c42b88..d2bc70c5 100644 --- a/responses/tests/test_responses.py +++ b/responses/tests/test_responses.py @@ -2058,31 +2058,31 @@ def run(): def test_response_call_request(): @responses.activate def run(): - rsp = responses.add(responses.GET, "http://www.example.com") + rsp1 = responses.add(responses.GET, "http://www.example.com") rsp2 = responses.add( responses.PUT, "http://www.foo.bar/42/", json={"id": 42, "name": "Bazz"} ) + request_payload = {"name": "Bazz"} requests.get("http://www.example.com") requests.get("http://www.example.com?hello=world") requests.put( "http://www.foo.bar/42/", - json={"name": "Bazz"}, + json=request_payload, ) - assert rsp.call_count == 2 - request = rsp.calls[0].request - assert request.url == "http://www.example.com/" - assert request.method == "GET" - request = rsp.calls[1].request - assert request.url == "http://www.example.com/?hello=world" - assert request.method == "GET" + assert rsp1.call_count == 2 + rsp1_request1 = rsp1.calls[0].request + assert rsp1_request1.url == "http://www.example.com/" + assert rsp1_request1.method == "GET" + rsp1_request2 = rsp1.calls[1].request + assert rsp1_request2.url == "http://www.example.com/?hello=world" + assert rsp1_request2.method == "GET" assert rsp2.call_count == 1 - request = rsp2.calls[0].request - assert request.url == "http://www.foo.bar/42/" - assert request.method == "PUT" - request_payload = json.loads(request.body) - assert request_payload == {"name": "Bazz"} + rsp2_request1 = rsp2.calls[0].request + assert rsp2_request1.url == "http://www.foo.bar/42/" + assert rsp2_request1.method == "PUT" + assert json.loads(rsp2_request1.body) == request_payload run() assert_reset() @@ -2091,7 +2091,7 @@ def run(): def test_response_call_response(): @responses.activate def run(): - rsp = responses.add(responses.GET, "http://www.example.com", body=b"test") + rsp1 = responses.add(responses.GET, "http://www.example.com", body=b"test") rsp2 = responses.add( responses.POST, "http://www.foo.bar/42/", @@ -2105,14 +2105,14 @@ def run(): json={"name": "Bazz"}, ) - assert rsp.call_count == 1 - response = rsp.calls[0].response - assert response.content == b"test" - assert response.status_code == 200 + assert rsp1.call_count == 1 + rsp1_response = rsp1.calls[0].response + assert rsp1_response.content == b"test" + assert rsp1_response.status_code == 200 assert rsp2.call_count == 1 - response = rsp2.calls[0].response - assert response.json() == {"id": 42, "name": "Bazz"} - assert response.status_code == 201 + rsp2_response = rsp2.calls[0].response + assert rsp2_response.json() == {"id": 42, "name": "Bazz"} + assert rsp2_response.status_code == 201 run() assert_reset() From 41bb479991f1663961600671aabb2dd71ed1f054 Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Mon, 23 Oct 2023 22:38:36 +0300 Subject: [PATCH 11/13] Simplify readme example --- README.rst | 66 ++++++++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 47 deletions(-) diff --git a/README.rst b/README.rst index ec75944f..1f9dde7f 100644 --- a/README.rst +++ b/README.rst @@ -1096,36 +1096,19 @@ applications. @responses.activate def test_assert_calls_on_resp(): - uid_with_permissions = [ - ("0123", {"client": True, "admin": False, "disabled": False}), - ("1234", {"client": False, "admin": True, "disabled": False}), - ("2345", {"client": False, "admin": False, "disabled": True}), - ] - rsp0123 = responses.patch( - "http://www.foo.bar/0123/", - json={"OK": True, "uid": "0123"}, - status=200, - ) - rsp1234 = responses.patch( - "http://www.foo.bar/1234/", - json={"OK": False, "uid": "1234"}, - status=400, - ) - rsp2345 = responses.patch( - "http://www.foo.bar/2345/", - json={"OK": True, "uid": "2345"}, - status=200, - ) + rsp1 = responses.patch("http://www.foo.bar/1/", status=200) + rsp2 = responses.patch("http://www.foo.bar/2/", status=400) + rsp3 = responses.patch("http://www.foo.bar/3/", status=200) - def update_permissions(uid, permissions): + def update_user(uid, is_active): url = f"http://www.foo.bar/{uid}/" - response = requests.patch(url, json=permissions) + response = requests.patch(url, json={"is_active": is_active}) return response with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: future_to_uid = { - executor.submit(update_permissions, uid, permissions): uid - for (uid, permissions) in uid_with_permissions + executor.submit(update_user, uid, is_active): uid + for (uid, is_active) in [("3", True), ("2", True), ("1", False)] } for future in concurrent.futures.as_completed(future_to_uid): uid = future_to_uid[future] @@ -1134,31 +1117,20 @@ applications. assert len(responses.calls) == 3 # total calls count - assert rsp0123.call_count == 1 - assert rsp0123.calls[0] in responses.calls - assert json.loads(rsp0123.calls[0].request.body) == { - "client": True, - "admin": False, - "disabled": False, - } + assert rsp1.call_count == 1 + assert rsp1.calls[0] in responses.calls + assert rsp1.calls[0].response.status_code == 200 + assert json.loads(rsp1.calls[0].request.body) == {"is_active": False} - assert rsp1234.call_count == 1 - assert rsp1234.calls[0] in responses.calls - assert json.loads(rsp1234.calls[0].request.body) == { - "client": False, - "admin": True, - "disabled": False, - } - assert rsp1234.calls[0].response.json() == {"OK": False, "uid": "1234"} - - assert rsp2345.call_count == 1 - assert rsp2345.calls[0] in responses.calls - assert json.loads(rsp2345.calls[0].request.body) == { - "client": False, - "admin": False, - "disabled": True, - } + assert rsp2.call_count == 1 + assert rsp2.calls[0] in responses.calls + assert rsp2.calls[0].response.status_code == 400 + assert json.loads(rsp2.calls[0].request.body) == {"is_active": True} + assert rsp3.call_count == 1 + assert rsp3.calls[0] in responses.calls + assert rsp3.calls[0].response.status_code == 200 + assert json.loads(rsp3.calls[0].request.body) == {"is_active": True} Multiple Responses ------------------ From 51f4e56730833542f5b2c0b3f1d841dc93cb7b7c Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Mon, 23 Oct 2023 23:06:08 +0300 Subject: [PATCH 12/13] Use f-string in readme --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 1f9dde7f..3ce35b51 100644 --- a/README.rst +++ b/README.rst @@ -1113,7 +1113,7 @@ applications. for future in concurrent.futures.as_completed(future_to_uid): uid = future_to_uid[future] response = future.result() - print("%s updated with %d status code" % (uid, response.status_code)) + print(f"{uid} updated with {response.status_code} status code") assert len(responses.calls) == 3 # total calls count From ea1144dbca860b1a6be61343c0e4a3a14fad88bf Mon Sep 17 00:00:00 2001 From: Stanislav Tomilov Date: Tue, 24 Oct 2023 10:02:10 +0300 Subject: [PATCH 13/13] Simplify new tests --- responses/tests/test_responses.py | 83 ++++++------------------------- 1 file changed, 15 insertions(+), 68 deletions(-) diff --git a/responses/tests/test_responses.py b/responses/tests/test_responses.py index d2bc70c5..7d3af31e 100644 --- a/responses/tests/test_responses.py +++ b/responses/tests/test_responses.py @@ -1,5 +1,4 @@ import inspect -import json import os import re import warnings @@ -2036,83 +2035,31 @@ def run(): assert_reset() -def test_response_and_requests_mock_calls_are_equal(): +def test_response_calls_and_registry_calls_are_equal(): @responses.activate def run(): - rsp = responses.add(responses.GET, "http://www.example.com") + rsp1 = responses.add(responses.GET, "http://www.example.com") rsp2 = responses.add(responses.GET, "http://www.example.com/1") + rsp3 = responses.add( + responses.GET, "http://www.example.com/2" + ) # won't be requested requests.get("http://www.example.com") requests.get("http://www.example.com/1") - - assert len(responses.calls) == 2 - assert rsp.call_count == 1 - assert rsp.calls[0] is responses.calls[0] - assert rsp2.call_count == 1 - assert rsp2.calls[0] is responses.calls[1] - - run() - assert_reset() - - -def test_response_call_request(): - @responses.activate - def run(): - rsp1 = responses.add(responses.GET, "http://www.example.com") - rsp2 = responses.add( - responses.PUT, "http://www.foo.bar/42/", json={"id": 42, "name": "Bazz"} - ) - request_payload = {"name": "Bazz"} - requests.get("http://www.example.com") - requests.get("http://www.example.com?hello=world") - requests.put( - "http://www.foo.bar/42/", - json=request_payload, - ) - - assert rsp1.call_count == 2 - rsp1_request1 = rsp1.calls[0].request - assert rsp1_request1.url == "http://www.example.com/" - assert rsp1_request1.method == "GET" - rsp1_request2 = rsp1.calls[1].request - assert rsp1_request2.url == "http://www.example.com/?hello=world" - assert rsp1_request2.method == "GET" - assert rsp2.call_count == 1 - rsp2_request1 = rsp2.calls[0].request - assert rsp2_request1.url == "http://www.foo.bar/42/" - assert rsp2_request1.method == "PUT" - assert json.loads(rsp2_request1.body) == request_payload - - run() - assert_reset() - - -def test_response_call_response(): - @responses.activate - def run(): - rsp1 = responses.add(responses.GET, "http://www.example.com", body=b"test") - rsp2 = responses.add( - responses.POST, - "http://www.foo.bar/42/", - json={"id": 42, "name": "Bazz"}, - status=201, - ) - requests.get("http://www.example.com") - requests.post( - "http://www.foo.bar/42/", - json={"name": "Bazz"}, + assert len(responses.calls) == len(rsp1.calls) + len(rsp2.calls) + len( + rsp3.calls ) - - assert rsp1.call_count == 1 - rsp1_response = rsp1.calls[0].response - assert rsp1_response.content == b"test" - assert rsp1_response.status_code == 200 + assert rsp1.call_count == 2 + assert len(rsp1.calls) == 2 + assert rsp1.calls[0] is responses.calls[0] + assert rsp1.calls[1] is responses.calls[2] assert rsp2.call_count == 1 - rsp2_response = rsp2.calls[0].response - assert rsp2_response.json() == {"id": 42, "name": "Bazz"} - assert rsp2_response.status_code == 201 + assert len(rsp2.calls) == 1 + assert rsp2.calls[0] is responses.calls[1] + assert rsp3.call_count == 0 + assert len(rsp3.calls) == 0 run() assert_reset()