|
1 | | -import unittest.mock |
| 1 | +from unittest.mock import MagicMock |
2 | 2 |
|
3 | 3 | from async_substrate_interface.sync_substrate import SubstrateInterface |
4 | 4 | from async_substrate_interface.types import ScaleObj |
5 | 5 |
|
6 | 6 |
|
7 | 7 | def test_runtime_call(monkeypatch): |
8 | | - monkeypatch.setattr( |
9 | | - "async_substrate_interface.sync_substrate.connect", unittest.mock.MagicMock() |
10 | | - ) |
11 | | - |
12 | | - substrate = SubstrateInterface( |
13 | | - "ws://localhost", |
14 | | - _mock=True, |
15 | | - ) |
16 | | - substrate._metadata = unittest.mock.Mock() |
17 | | - substrate.metadata_v15 = unittest.mock.Mock( |
18 | | - **{ |
19 | | - "value.return_value": { |
20 | | - "apis": [ |
| 8 | + substrate = SubstrateInterface("ws://localhost", _mock=True) |
| 9 | + fake_runtime = MagicMock() |
| 10 | + fake_metadata_v15 = MagicMock() |
| 11 | + fake_metadata_v15.value.return_value = { |
| 12 | + "apis": [ |
| 13 | + { |
| 14 | + "name": "SubstrateApi", |
| 15 | + "methods": [ |
21 | 16 | { |
22 | | - "name": "SubstrateApi", |
23 | | - "methods": [ |
24 | | - { |
25 | | - "name": "SubstrateMethod", |
26 | | - "inputs": [], |
27 | | - "output": "1", |
28 | | - }, |
29 | | - ], |
| 17 | + "name": "SubstrateMethod", |
| 18 | + "inputs": [], |
| 19 | + "output": "1", |
30 | 20 | }, |
31 | 21 | ], |
32 | 22 | }, |
33 | | - } |
34 | | - ) |
35 | | - substrate.rpc_request = unittest.mock.Mock( |
36 | | - return_value={ |
37 | | - "result": "0x00", |
| 23 | + ], |
| 24 | + "types": { |
| 25 | + "types": [ |
| 26 | + { |
| 27 | + "id": "1", |
| 28 | + "type": { |
| 29 | + "path": ["Vec"], |
| 30 | + "def": {"sequence": {"type": "4"}}, |
| 31 | + }, |
| 32 | + }, |
| 33 | + ] |
38 | 34 | }, |
| 35 | + } |
| 36 | + fake_runtime.metadata_v15 = fake_metadata_v15 |
| 37 | + substrate.init_runtime = MagicMock(return_value=fake_runtime) |
| 38 | + |
| 39 | + # Patch encode_scale (should not be called in this test since no inputs) |
| 40 | + substrate.encode_scale = MagicMock() |
| 41 | + |
| 42 | + # Patch decode_scale to produce a dummy value |
| 43 | + substrate.decode_scale = MagicMock(return_value="decoded_result") |
| 44 | + |
| 45 | + # Patch RPC request with correct behavior |
| 46 | + substrate.rpc_request = MagicMock( |
| 47 | + side_effect=lambda method, params: { |
| 48 | + "result": "0x00" if method == "state_call" else {"parentHash": "0xDEADBEEF"} |
| 49 | + } |
39 | 50 | ) |
40 | | - substrate.decode_scale = unittest.mock.Mock() |
41 | 51 |
|
| 52 | + # Patch get_block_runtime_info |
| 53 | + substrate.get_block_runtime_info = MagicMock(return_value={"specVersion": "1"}) |
| 54 | + |
| 55 | + # Run the call |
42 | 56 | result = substrate.runtime_call( |
43 | 57 | "SubstrateApi", |
44 | 58 | "SubstrateMethod", |
45 | 59 | ) |
46 | 60 |
|
| 61 | + # Validate the result is wrapped in ScaleObj |
47 | 62 | assert isinstance(result, ScaleObj) |
48 | | - assert result.value is substrate.decode_scale.return_value |
| 63 | + assert result.value == "decoded_result" |
49 | 64 |
|
50 | | - substrate.rpc_request.assert_called_once_with( |
51 | | - "state_call", |
52 | | - ["SubstrateApi_SubstrateMethod", "", None], |
53 | | - ) |
| 65 | + # Check decode_scale called correctly |
54 | 66 | substrate.decode_scale.assert_called_once_with("scale_info::1", b"\x00") |
| 67 | + |
| 68 | + # encode_scale should not be called since no inputs |
| 69 | + substrate.encode_scale.assert_not_called() |
| 70 | + |
| 71 | + # Check RPC request called for the state_call |
| 72 | + substrate.rpc_request.assert_any_call( |
| 73 | + "state_call", ["SubstrateApi_SubstrateMethod", "", None] |
| 74 | + ) |
0 commit comments