From 3fe1e471c3deada2b69d91ed00217e85e8c76c09 Mon Sep 17 00:00:00 2001 From: Stuart Reed Date: Thu, 15 Jun 2023 13:20:43 -0600 Subject: [PATCH 1/2] Initial tests for formatting middlewares --- .../middleware/test_formatting_middleware.py | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 tests/core/middleware/test_formatting_middleware.py diff --git a/tests/core/middleware/test_formatting_middleware.py b/tests/core/middleware/test_formatting_middleware.py new file mode 100644 index 0000000000..a277339577 --- /dev/null +++ b/tests/core/middleware/test_formatting_middleware.py @@ -0,0 +1,109 @@ +import pytest +from unittest.mock import ( + Mock, +) + +from web3 import ( + Web3, +) +from web3.middleware import ( + construct_error_generator_middleware, + construct_formatting_middleware, + construct_result_generator_middleware, +) +from web3.providers.base import ( + BaseProvider, +) +from web3.types import ( + RPCEndpoint, +) + + +class DummyProvider(BaseProvider): + def make_request(self, method, params): + raise NotImplementedError(f"Cannot make request for {method}:{params}") + + +@pytest.fixture +def w3(): + return Web3(provider=DummyProvider(), middlewares=[]) + + +def test_formatting_middleware(w3): + # No formatters by default + w3.middleware_onion.add(construct_formatting_middleware()) + w3.middleware_onion.add( + construct_result_generator_middleware( + { + "test_endpoint": lambda method, params: "done", + } + ) + ) + + expected = "done" + actual = w3.manager.request_blocking("test_endpoint", []) + assert actual == expected + + +def test_formatting_middleware_no_method(w3): + w3.middleware_onion.add(construct_formatting_middleware()) + + # Formatting middleware requires an endpoint + with pytest.raises(NotImplementedError): + w3.manager.request_blocking("test_endpoint", []) + + +def test_formatting_middleware_request_formatters(w3): + callable_mock = Mock() + w3.middleware_onion.add( + construct_result_generator_middleware( + {RPCEndpoint("test_endpoint"): lambda method, params: "done"} + ) + ) + + w3.middleware_onion.add( + construct_formatting_middleware( + request_formatters={RPCEndpoint("test_endpoint"): callable_mock} + ) + ) + + expected = "done" + actual = w3.manager.request_blocking("test_endpoint", ["param1"]) + + callable_mock.assert_called_once_with(["param1"]) + assert actual == expected + + +def test_formatting_middleware_result_formatters(w3): + w3.middleware_onion.add( + construct_result_generator_middleware( + {RPCEndpoint("test_endpoint"): lambda method, params: "done"} + ) + ) + w3.middleware_onion.add( + construct_formatting_middleware( + result_formatters={RPCEndpoint("test_endpoint"): lambda x: f"STATUS:{x}"} + ) + ) + + expected = "STATUS:done" + actual = w3.manager.request_blocking("test_endpoint", []) + assert actual == expected + + +def test_formatting_middleware_error_formatters(w3): + w3.middleware_onion.add( + construct_error_generator_middleware( + {RPCEndpoint("test_endpoint"): lambda method, params: "error"} + ) + ) + w3.middleware_onion.add( + construct_formatting_middleware( + result_formatters={RPCEndpoint("test_endpoint"): lambda x: f"STATUS:{x}"} + ) + ) + + expected = "error" + with pytest.raises(ValueError) as err: + w3.manager.request_blocking("test_endpoint", []) + assert str(err.value) == expected \ No newline at end of file From 973ea10ef8517f994a3f7222d2045ccd3e9f126b Mon Sep 17 00:00:00 2001 From: Stuart Reed Date: Mon, 19 Jun 2023 15:38:30 -0600 Subject: [PATCH 2/2] Skip formatting response when None --- newsfragments/2546.bugfix.rst | 1 + .../middleware/test_formatting_middleware.py | 19 ++++++++++++++++++- web3/middleware/formatting.py | 6 +++++- 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 newsfragments/2546.bugfix.rst diff --git a/newsfragments/2546.bugfix.rst b/newsfragments/2546.bugfix.rst new file mode 100644 index 0000000000..bd8a380b87 --- /dev/null +++ b/newsfragments/2546.bugfix.rst @@ -0,0 +1 @@ +Handle `None` in the formatting middleware \ No newline at end of file diff --git a/tests/core/middleware/test_formatting_middleware.py b/tests/core/middleware/test_formatting_middleware.py index a277339577..8f7f9ca807 100644 --- a/tests/core/middleware/test_formatting_middleware.py +++ b/tests/core/middleware/test_formatting_middleware.py @@ -91,6 +91,23 @@ def test_formatting_middleware_result_formatters(w3): assert actual == expected +def test_formatting_middleware_result_formatters_for_none(w3): + w3.middleware_onion.add( + construct_result_generator_middleware( + {RPCEndpoint("test_endpoint"): lambda method, params: None} + ) + ) + w3.middleware_onion.add( + construct_formatting_middleware( + result_formatters={RPCEndpoint("test_endpoint"): lambda x: hex(x)} + ) + ) + + expected = None + actual = w3.manager.request_blocking("test_endpoint", []) + assert actual == expected + + def test_formatting_middleware_error_formatters(w3): w3.middleware_onion.add( construct_error_generator_middleware( @@ -106,4 +123,4 @@ def test_formatting_middleware_error_formatters(w3): expected = "error" with pytest.raises(ValueError) as err: w3.manager.request_blocking("test_endpoint", []) - assert str(err.value) == expected \ No newline at end of file + assert str(err.value) == expected diff --git a/web3/middleware/formatting.py b/web3/middleware/formatting.py index d6637085d8..c036877850 100644 --- a/web3/middleware/formatting.py +++ b/web3/middleware/formatting.py @@ -50,7 +50,11 @@ def _format_response( response, response_type, method_response_formatter(appropriate_response) ) - if "result" in response and method in result_formatters: + if ( + "result" in response + and response["result"] is not None + and method in result_formatters + ): return _format_response("result", result_formatters[method]) elif "error" in response and method in error_formatters: return _format_response("error", error_formatters[method])