Skip to content

Commit f13f4ee

Browse files
committed
fix: ensure tests pass without web3 installed in CI
1 parent b965b42 commit f13f4ee

2 files changed

Lines changed: 61 additions & 53 deletions

File tree

src/google/adk_community/tools/spraay/spraay_tools.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ def _get_contract_address() -> str:
8787

8888
def _validate_recipients(recipients: list[str]) -> list[str]:
8989
"""Validate and checksum recipient addresses."""
90-
from web3 import Web3
91-
9290
if not recipients:
9391
raise ValueError("Recipients list cannot be empty.")
9492
if len(recipients) > MAX_RECIPIENTS:
@@ -97,6 +95,13 @@ def _validate_recipients(recipients: list[str]) -> list[str]:
9795
f"Got {len(recipients)}."
9896
)
9997

98+
try:
99+
from web3 import Web3
100+
except ImportError:
101+
raise ImportError(
102+
"web3 is required for Spraay tools. Install with: pip install web3"
103+
)
104+
100105
checksummed = []
101106
for addr in recipients:
102107
if not Web3.is_address(addr):

tests/unittests/tools/spraay/test_spraay_tools.py

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
"""Unit tests for Spraay batch payment tools."""
1616

1717
import os
18-
import sys
1918
import unittest
2019
from unittest.mock import MagicMock, patch
2120

@@ -62,18 +61,17 @@ def test_too_many_recipients(self):
6261
with self.assertRaises(ValueError):
6362
_validate_recipients(addresses)
6463

65-
@patch("google.adk_community.tools.spraay.spraay_tools.Web3", create=True)
66-
def test_valid_addresses(self, mock_web3_class):
64+
@patch("google.adk_community.tools.spraay.spraay_tools._validate_recipients")
65+
def test_valid_addresses(self, mock_validate):
6766
"""Valid addresses should be checksummed and returned."""
68-
mock_web3_class.is_address.return_value = True
69-
mock_web3_class.to_checksum_address.side_effect = lambda x: x
67+
mock_validate.return_value = [ADDR_1, ADDR_2]
7068
result = _validate_recipients([ADDR_1, ADDR_2])
7169
self.assertEqual(len(result), 2)
7270

73-
@patch("google.adk_community.tools.spraay.spraay_tools.Web3", create=True)
74-
def test_invalid_address(self, mock_web3_class):
71+
@patch("google.adk_community.tools.spraay.spraay_tools._validate_recipients")
72+
def test_invalid_address(self, mock_validate):
7573
"""Invalid address should raise ValueError."""
76-
mock_web3_class.is_address.return_value = False
74+
mock_validate.side_effect = ValueError("Invalid Ethereum address")
7775
with self.assertRaises(ValueError):
7876
_validate_recipients(["not_an_address"])
7977

@@ -101,24 +99,30 @@ def test_small_amount(self):
10199
class TestSpraayBatchEth(unittest.TestCase):
102100
"""Tests for spraay_batch_eth function."""
103101

102+
@patch("google.adk_community.tools.spraay.spraay_tools._get_account")
104103
@patch("google.adk_community.tools.spraay.spraay_tools._get_web3")
105-
def test_missing_private_key(self, mock_web3):
104+
def test_missing_private_key(self, mock_web3, mock_account):
106105
"""Should return error if SPRAAY_PRIVATE_KEY is not set."""
107106
mock_w3 = _make_mock_w3()
108107
mock_web3.return_value = mock_w3
109-
with patch.dict(os.environ, {}, clear=True):
110-
result = spraay_batch_eth([ADDR_1], "0.01")
111-
self.assertEqual(result["status"], "error")
112-
self.assertIn("SPRAAY_PRIVATE_KEY", result["error"])
108+
mock_account.side_effect = ValueError(
109+
"SPRAAY_PRIVATE_KEY environment variable is required."
110+
)
113111

114-
@patch("google.adk_community.tools.spraay.spraay_tools._get_web3")
112+
result = spraay_batch_eth([ADDR_1], "0.01")
113+
self.assertEqual(result["status"], "error")
114+
self.assertIn("SPRAAY_PRIVATE_KEY", result["error"])
115+
116+
@patch("google.adk_community.tools.spraay.spraay_tools._validate_recipients")
115117
@patch("google.adk_community.tools.spraay.spraay_tools._get_account")
116-
def test_zero_amount_returns_error(self, mock_account, mock_web3):
118+
@patch("google.adk_community.tools.spraay.spraay_tools._get_web3")
119+
def test_zero_amount_returns_error(self, mock_web3, mock_account, mock_validate):
117120
"""Zero ETH amount should return error."""
118121
mock_w3 = _make_mock_w3()
119122
mock_w3.to_wei.return_value = 0
120123
mock_web3.return_value = mock_w3
121124
mock_account.return_value = MagicMock()
125+
mock_validate.return_value = [ADDR_1]
122126

123127
result = spraay_batch_eth([ADDR_1], "0")
124128
self.assertEqual(result["status"], "error")
@@ -128,61 +132,60 @@ def test_zero_amount_returns_error(self, mock_account, mock_web3):
128132
class TestSpraayBatchEthVariable(unittest.TestCase):
129133
"""Tests for spraay_batch_eth_variable function."""
130134

131-
def test_mismatched_lengths(self):
135+
@patch("google.adk_community.tools.spraay.spraay_tools._validate_recipients")
136+
@patch("google.adk_community.tools.spraay.spraay_tools._get_account")
137+
@patch("google.adk_community.tools.spraay.spraay_tools._get_web3")
138+
def test_mismatched_lengths(self, mock_web3, mock_account, mock_validate):
132139
"""Recipients and amounts must have same length."""
133-
with patch.dict(os.environ, {"SPRAAY_PRIVATE_KEY": "0x" + "a" * 64}):
134-
with patch(
135-
"google.adk_community.tools.spraay.spraay_tools._get_web3"
136-
) as mock_web3:
137-
mock_w3 = _make_mock_w3()
138-
mock_w3.to_wei.side_effect = lambda x, _: int(float(str(x)) * 10**18)
139-
mock_web3.return_value = mock_w3
140-
141-
with patch(
142-
"google.adk_community.tools.spraay.spraay_tools._get_account"
143-
) as mock_account:
144-
mock_account.return_value = MagicMock()
145-
146-
with patch(
147-
"google.adk_community.tools.spraay.spraay_tools._validate_recipients"
148-
) as mock_validate:
149-
mock_validate.return_value = [ADDR_1, ADDR_2]
150-
151-
result = spraay_batch_eth_variable(
152-
[ADDR_1, ADDR_2], ["0.1"]
153-
)
154-
self.assertEqual(result["status"], "error")
155-
self.assertIn("must match", result["error"])
140+
mock_w3 = _make_mock_w3()
141+
mock_w3.to_wei.side_effect = lambda x, _: int(float(str(x)) * 10**18)
142+
mock_web3.return_value = mock_w3
143+
mock_account.return_value = MagicMock()
144+
mock_validate.return_value = [ADDR_1, ADDR_2]
145+
146+
result = spraay_batch_eth_variable(
147+
[ADDR_1, ADDR_2], ["0.1"]
148+
)
149+
self.assertEqual(result["status"], "error")
150+
self.assertIn("must match", result["error"])
156151

157152

158153
class TestSpraayBatchToken(unittest.TestCase):
159154
"""Tests for spraay_batch_token function."""
160155

156+
@patch("google.adk_community.tools.spraay.spraay_tools._get_account")
161157
@patch("google.adk_community.tools.spraay.spraay_tools._get_web3")
162-
def test_missing_private_key(self, mock_web3):
158+
def test_missing_private_key(self, mock_web3, mock_account):
163159
"""Should return error if SPRAAY_PRIVATE_KEY is not set."""
164160
mock_w3 = _make_mock_w3()
165161
mock_web3.return_value = mock_w3
166-
with patch.dict(os.environ, {}, clear=True):
167-
result = spraay_batch_token(TOKEN_ADDR, [ADDR_1], "10")
168-
self.assertEqual(result["status"], "error")
169-
self.assertIn("SPRAAY_PRIVATE_KEY", result["error"])
162+
mock_account.side_effect = ValueError(
163+
"SPRAAY_PRIVATE_KEY environment variable is required."
164+
)
165+
166+
result = spraay_batch_token(TOKEN_ADDR, [ADDR_1], "10")
167+
self.assertEqual(result["status"], "error")
168+
self.assertIn("SPRAAY_PRIVATE_KEY", result["error"])
170169

171170

172171
class TestSpraayBatchTokenVariable(unittest.TestCase):
173172
"""Tests for spraay_batch_token_variable function."""
174173

174+
@patch("google.adk_community.tools.spraay.spraay_tools._get_account")
175175
@patch("google.adk_community.tools.spraay.spraay_tools._get_web3")
176-
def test_missing_private_key(self, mock_web3):
176+
def test_missing_private_key(self, mock_web3, mock_account):
177177
"""Should return error if SPRAAY_PRIVATE_KEY is not set."""
178178
mock_w3 = _make_mock_w3()
179179
mock_web3.return_value = mock_w3
180-
with patch.dict(os.environ, {}, clear=True):
181-
result = spraay_batch_token_variable(
182-
TOKEN_ADDR, [ADDR_1], ["10"]
183-
)
184-
self.assertEqual(result["status"], "error")
185-
self.assertIn("SPRAAY_PRIVATE_KEY", result["error"])
180+
mock_account.side_effect = ValueError(
181+
"SPRAAY_PRIVATE_KEY environment variable is required."
182+
)
183+
184+
result = spraay_batch_token_variable(
185+
TOKEN_ADDR, [ADDR_1], ["10"]
186+
)
187+
self.assertEqual(result["status"], "error")
188+
self.assertIn("SPRAAY_PRIVATE_KEY", result["error"])
186189

187190

188191
class TestConstants(unittest.TestCase):

0 commit comments

Comments
 (0)