|
12 | 12 | import pytest |
13 | 13 | from testcontainers.core.container import DockerContainer |
14 | 14 | from web3 import Web3 |
| 15 | +from web3.providers.base import BaseProvider |
15 | 16 |
|
16 | 17 | from arkiv import Arkiv |
17 | 18 | from arkiv.account import NamedAccount |
| 19 | +from arkiv.provider import ProviderBuilder |
18 | 20 | from tests.node_container import create_container_node |
19 | 21 |
|
20 | 22 | from .utils import create_account |
@@ -46,6 +48,30 @@ def _load_env_if_available() -> None: |
46 | 48 | logger.debug("python-dotenv not available, using system environment only") |
47 | 49 |
|
48 | 50 |
|
| 51 | +def check_and_get_web3(name: str, provider: BaseProvider) -> Web3: |
| 52 | + """Create and verify a Web3 client connection.""" |
| 53 | + return verify_connection(name, Web3(provider)) |
| 54 | + |
| 55 | + |
| 56 | +def check_and_get_arkiv( |
| 57 | + name: str, provider: BaseProvider, account: NamedAccount | None = None |
| 58 | +) -> Arkiv: |
| 59 | + """Create and verify an Arkiv client connection.""" |
| 60 | + if account: |
| 61 | + return verify_connection(name, Arkiv(provider, account=account)) |
| 62 | + else: |
| 63 | + return verify_connection(name, Arkiv(provider)) |
| 64 | + |
| 65 | + |
| 66 | +def verify_connection(name: str, client: Web3) -> Web3: |
| 67 | + """Verify Web3 client connection and return checked client.""" |
| 68 | + assert client.is_connected(), ( |
| 69 | + f"{name}: Failed to connect to {client.provider.endpoint_uri}" |
| 70 | + ) # type: ignore[attr-defined] |
| 71 | + logger.info(f"{name} client connected to {client.provider.endpoint_uri}") # type: ignore[attr-defined] |
| 72 | + return client |
| 73 | + |
| 74 | + |
49 | 75 | # Load environment on import |
50 | 76 | _load_env_if_available() |
51 | 77 |
|
@@ -74,59 +100,44 @@ def arkiv_node() -> Generator[tuple[DockerContainer | None, str, str], None, Non |
74 | 100 |
|
75 | 101 |
|
76 | 102 | @pytest.fixture(scope="session") |
77 | | -def web3_client_http(arkiv_node: tuple[DockerContainer | None, str, str]) -> Web3: |
78 | | - """ |
79 | | - Provide Web3 client connected to HTTP endpoint. |
80 | | -
|
81 | | - Returns: |
82 | | - Web3 client instance connected to the arkiv node |
83 | | - """ |
| 103 | +def testcontainer_provider_http( |
| 104 | + arkiv_node: tuple[DockerContainer | None, str, str], |
| 105 | +) -> BaseProvider: |
| 106 | + """Returns testcontainer HTTPProvider using the ProviderBuilder.""" |
84 | 107 | _, http_url, _ = arkiv_node |
85 | | - client = Web3(Web3.HTTPProvider(http_url)) |
| 108 | + return ProviderBuilder().custom(http_url).build() |
86 | 109 |
|
87 | | - # Verify connection |
88 | | - assert client.is_connected(), f"Failed to connect to {http_url}" |
89 | 110 |
|
90 | | - logger.info(f"Web3 client connected to {http_url}") |
91 | | - return client |
| 111 | +@pytest.fixture(scope="session") |
| 112 | +def testcontainer_provider_ws( |
| 113 | + arkiv_node: tuple[DockerContainer | None, str, str], |
| 114 | +) -> BaseProvider: |
| 115 | + """Returns testcontainer WebSocketProvider using the ProviderBuilder.""" |
| 116 | + _, _, ws_url = arkiv_node |
| 117 | + # Note: .ws() is to make transport explicit, it is not strictly necessary as the URL scheme is ws:// or wss:// |
| 118 | + return ProviderBuilder().custom(ws_url).ws().build() |
92 | 119 |
|
93 | 120 |
|
94 | 121 | @pytest.fixture(scope="session") |
95 | | -def arkiv_ro_client_http(arkiv_node: tuple[DockerContainer | None, str, str]) -> Arkiv: |
96 | | - """ |
97 | | - Provide Arkiv client connected to HTTP endpoint. |
| 122 | +def web3_client_http(testcontainer_provider_http: BaseProvider) -> Web3: |
| 123 | + """Return Web3 client connected to HTTP endpoint.""" |
| 124 | + return check_and_get_web3("Web3 HTTP", testcontainer_provider_http) |
98 | 125 |
|
99 | | - Returns: |
100 | | - Web3 client instance connected to the arkiv node |
101 | | - """ |
102 | | - _, http_url, _ = arkiv_node |
103 | | - client = Arkiv(Web3.HTTPProvider(http_url)) |
104 | 126 |
|
105 | | - # Verify connection |
106 | | - assert client.is_connected(), f"Failed to connect Arkiv client to {http_url}" |
107 | | - |
108 | | - logger.info(f"Arkiv client connected to {http_url}") |
109 | | - return client |
| 127 | +@pytest.fixture(scope="session") |
| 128 | +def arkiv_ro_client_http(testcontainer_provider_http: BaseProvider) -> Arkiv: |
| 129 | + """Return a read only Arkiv client connected to HTTP endpoint.""" |
| 130 | + return check_and_get_arkiv("Arkiv HTTP (read only)", testcontainer_provider_http) |
110 | 131 |
|
111 | 132 |
|
112 | 133 | @pytest.fixture(scope="session") |
113 | 134 | def arkiv_client_http( |
114 | | - arkiv_node: tuple[DockerContainer | None, str, str], account_1: NamedAccount |
| 135 | + testcontainer_provider_http: BaseProvider, account_1: NamedAccount |
115 | 136 | ) -> Arkiv: |
116 | | - """ |
117 | | - Provide Arkiv client connected to HTTP endpoint. |
118 | | -
|
119 | | - Returns: |
120 | | - Web3 client instance connected to the arkiv node |
121 | | - """ |
122 | | - _, http_url, _ = arkiv_node |
123 | | - client = Arkiv(Web3.HTTPProvider(http_url), account=account_1) |
124 | | - |
125 | | - # Verify connection |
126 | | - assert client.is_connected(), f"Failed to connect Arkiv client to {http_url}" |
127 | | - |
128 | | - logger.info(f"Arkiv client connected to {http_url}") |
129 | | - return client |
| 137 | + """Return a read only Arkiv client connected to HTTP endpoint.""" |
| 138 | + return check_and_get_arkiv( |
| 139 | + "Arkiv HTTP", testcontainer_provider_http, account=account_1 |
| 140 | + ) |
130 | 141 |
|
131 | 142 |
|
132 | 143 | @pytest.fixture(scope="session") |
|
0 commit comments