2121from web3 .datastructures import (
2222 AttributeDict ,
2323)
24+ from web3 .middleware import (
25+ async_geth_poa_middleware ,
26+ )
2427from web3 .types import (
2528 FormattedEthSubscriptionResponse ,
2629)
3134 )
3235
3336
37+ def _mocked_recv (sub_id : str , ws_subscription_response : Dict [str , Any ]) -> bytes :
38+ # Must be same subscription id so we can know how to parse the message.
39+ # We don't have this information when mocking the response.
40+ ws_subscription_response ["params" ]["subscription" ] = sub_id
41+ encoded = FriendlyJsonSerde ().json_encode (ws_subscription_response )
42+ return to_bytes (text = encoded )
43+
44+
3445class PersistentConnectionProviderTest :
3546 @pytest .mark .asyncio
3647 @pytest .mark .parametrize (
@@ -249,16 +260,14 @@ async def test_async_eth_subscribe_mocked(
249260 assert sub_id is not None
250261 assert is_hexstr (sub_id )
251262
252- # return a coroutine that returns the response
253- async def _mocked_recv () -> bytes :
254- # Must be same subscription id so we can know how to parse the message.
255- # We don't have this information when mocking the response.
256- ws_subscription_response ["params" ]["subscription" ] = sub_id
257- encoded = FriendlyJsonSerde ().json_encode (ws_subscription_response )
258- return to_bytes (text = encoded )
263+ async def _mocked_recv_coro () -> bytes :
264+ return _mocked_recv (sub_id , ws_subscription_response )
259265
260266 actual_recv_fxn = async_w3 .provider ._ws .recv
261- async_w3 .provider ._ws .__setattr__ ("recv" , _mocked_recv )
267+ async_w3 .provider ._ws .__setattr__ (
268+ "recv" ,
269+ _mocked_recv_coro ,
270+ )
262271
263272 async for msg in async_w3 .ws .listen_to_websocket ():
264273 response = cast (FormattedEthSubscriptionResponse , msg )
@@ -270,3 +279,50 @@ async def _mocked_recv() -> bytes:
270279
271280 # reset the mocked recv
272281 async_w3 .provider ._ws .__setattr__ ("recv" , actual_recv_fxn )
282+
283+ @pytest .mark .asyncio
284+ async def test_async_geth_poa_middleware_on_eth_subscription (
285+ self ,
286+ async_w3 : "_PersistentConnectionWeb3" ,
287+ ) -> None :
288+ async_w3 .middleware_onion .inject (
289+ async_geth_poa_middleware , "poa_middleware" , layer = 0
290+ )
291+
292+ sub_id = await async_w3 .eth .subscribe ("newHeads" )
293+ assert is_hexstr (sub_id )
294+
295+ async def _mocked_recv_coro () -> bytes :
296+ return _mocked_recv (
297+ sub_id ,
298+ {
299+ "jsonrpc" : "2.0" ,
300+ "method" : "eth_subscription" ,
301+ "params" : {
302+ "subscription" : sub_id ,
303+ "result" : {
304+ "extraData" : f"0x{ '00' * 100 } " ,
305+ },
306+ },
307+ },
308+ )
309+
310+ actual_recv_fxn = async_w3 .provider ._ws .recv
311+ async_w3 .provider ._ws .__setattr__ (
312+ "recv" ,
313+ _mocked_recv_coro ,
314+ )
315+
316+ async for msg in async_w3 .ws .listen_to_websocket ():
317+ response = cast (FormattedEthSubscriptionResponse , msg )
318+ assert response .keys () == {"subscription" , "result" }
319+ assert response ["subscription" ] == sub_id
320+ assert response ["result" ]["proofOfAuthorityData" ] == HexBytes ( # type: ignore # noqa: E501
321+ f"0x{ '00' * 100 } "
322+ )
323+
324+ break
325+
326+ # reset the mocked recv
327+ async_w3 .provider ._ws .__setattr__ ("recv" , actual_recv_fxn )
328+ async_w3 .middleware_onion .remove ("poa_middleware" )
0 commit comments