Skip to content

Commit

Permalink
add checking
Browse files Browse the repository at this point in the history
  • Loading branch information
jianlunz-cb committed Dec 18, 2024
1 parent 66ebef8 commit 391a4d0
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 deletions.
22 changes: 14 additions & 8 deletions cdp/smart_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Type(Enum):
ERC20 = "erc20"
ERC721 = "erc721"
ERC1155 = "erc1155"
Custom = "custom"
CUSTOM = "custom"

def __str__(self) -> str:
"""Return a string representation of the Type."""
Expand Down Expand Up @@ -124,8 +124,6 @@ def wallet_id(self) -> str | None:
The wallet ID.
"""
if self._model.is_external:
return None
return self._model.wallet_id

@property
Expand Down Expand Up @@ -156,8 +154,6 @@ def deployer_address(self) -> str | None:
The deployer address.
"""
if self._model.is_external:
return None
return self._model.deployer_address

@property
Expand Down Expand Up @@ -194,8 +190,9 @@ def options(self) -> TokenContractOptions | NFTContractOptions | MultiTokenContr
ValueError: If the smart contract type is unknown or if options are not set.
"""
if self._model.is_external:
return None
if self.is_external:
raise ValueError("SmartContract options cannot be returned for external SmartContract")

if self._model.options is None or self._model.options.actual_instance is None:
raise ValueError("Smart contract options are not set")

Expand Down Expand Up @@ -227,7 +224,7 @@ def transaction(self) -> Transaction | None:
Transaction: The transaction.
"""
if self._model.is_external:
if self.is_external:
return None
if self._transaction is None and self._model.transaction is not None:
self._update_transaction(self._model)
Expand All @@ -246,6 +243,8 @@ def sign(self, key: LocalAccount) -> "SmartContract":
ValueError: If the key is not a LocalAccount.
"""
if self.is_external:
raise ValueError("Cannot sign an external SmartContract")
if not isinstance(key, LocalAccount):
raise ValueError("key must be a LocalAccount")

Expand All @@ -262,6 +261,9 @@ def broadcast(self) -> "SmartContract":
ValueError: If the smart contract deployment is not signed.
"""
if self.is_external:
raise ValueError("Cannot broadcast an external SmartContract")

if not self.transaction.signed:
raise ValueError("Cannot broadcast unsigned SmartContract deployment")

Expand All @@ -285,6 +287,8 @@ def reload(self) -> "SmartContract":
The updated SmartContract object.
"""
if self.is_external:
raise ValueError("Cannot reload an external SmartContract")
model = Cdp.api_clients.smart_contracts.get_smart_contract(
wallet_id=self.wallet_id,
address_id=self.deployer_address,
Expand All @@ -308,6 +312,8 @@ def wait(self, interval_seconds: float = 0.2, timeout_seconds: float = 10) -> "S
TimeoutError: If the smart contract deployment times out.
"""
if self.is_external:
raise ValueError("Cannot wait for an external SmartContract")
start_time = time.time()
while self.transaction is not None and not self.transaction.terminal_state:
self.reload()
Expand Down
20 changes: 20 additions & 0 deletions tests/factories/smart_contract_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,26 @@ def _create_smart_contract_model(status="complete"):

return _create_smart_contract_model

@pytest.fixture
def external_smart_contract_factory(transaction_model_factory):
"""Create and return a factory for creating SmartContractModel fixtures."""

def _create_smart_contract_model(status="complete"):
token_options = TokenContractOptions(name="TestToken", symbol="TT", total_supply="1000000")
smart_contract_options = SmartContractOptions(actual_instance=token_options)

return SmartContract(SmartContractModel(
smart_contract_id="test-contract-id",
network_id="base-sepolia",
contract_address="0xcontractaddress",
contract_name="TestContract",
type="custom",
abi='{"abi":"data"}',
is_external=True,
))

return _create_smart_contract_model


@pytest.fixture
def smart_contract_factory(smart_contract_model_factory):
Expand Down
34 changes: 34 additions & 0 deletions tests/test_smart_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ def test_smart_contract_properties(smart_contract_factory):
)
assert smart_contract.transaction.transaction_hash == "0xtransactionhash"

def test_external_smart_contract_properties(external_smart_contract_factory):
"""Test the properties of a SmartContract object."""
smart_contract = external_smart_contract_factory()
assert smart_contract.smart_contract_id == "test-contract-id"
assert smart_contract.network_id == "base-sepolia"
assert smart_contract.contract_address == "0xcontractaddress"
assert smart_contract.type.value == SmartContract.Type.CUSTOM.value
assert smart_contract.abi == {"abi": "data"}

assert not smart_contract.wallet_id
assert not smart_contract.deployer_address
assert not smart_contract.transaction
with pytest.raises(ValueError, match="SmartContract options cannot be returned for external SmartContract"):
smart_contract.options

@patch("cdp.Cdp.api_clients")
def test_create_smart_contract(mock_api_clients, smart_contract_factory):
Expand Down Expand Up @@ -86,6 +100,11 @@ def test_broadcast_unsigned_smart_contract(smart_contract_factory):
with pytest.raises(ValueError, match="Cannot broadcast unsigned SmartContract deployment"):
smart_contract.broadcast()

def test_broadcast_external_smart_contract(external_smart_contract_factory):
"""Test the broadcasting of an external SmartContract object."""
smart_contract = external_smart_contract_factory()
with pytest.raises(ValueError, match="Cannot broadcast an external SmartContract"):
smart_contract.broadcast()

@patch("cdp.Cdp.api_clients")
def test_reload_smart_contract(mock_api_clients, smart_contract_factory):
Expand All @@ -105,6 +124,11 @@ def test_reload_smart_contract(mock_api_clients, smart_contract_factory):
)
assert smart_contract.transaction.status.value == "complete"

def test_reload_external_smart_contract(external_smart_contract_factory):
"""Test the reloading of an external SmartContract object."""
smart_contract = external_smart_contract_factory()
with pytest.raises(ValueError, match="Cannot reload an external SmartContract"):
smart_contract.reload()

@patch("cdp.Cdp.api_clients")
@patch("cdp.smart_contract.time.sleep")
Expand All @@ -131,6 +155,11 @@ def test_wait_for_smart_contract(mock_time, mock_sleep, mock_api_clients, smart_
mock_sleep.assert_has_calls([call(0.2)] * 2)
assert mock_time.call_count == 3

def test_wait_external_smart_contract(external_smart_contract_factory):
"""Test the waiting of an external SmartContract object."""
smart_contract = external_smart_contract_factory()
with pytest.raises(ValueError, match="Cannot wait for an external SmartContract"):
smart_contract.wait()

@patch("cdp.Cdp.api_clients")
@patch("cdp.smart_contract.time.sleep")
Expand Down Expand Up @@ -159,6 +188,11 @@ def test_sign_smart_contract_invalid_key(smart_contract_factory):
with pytest.raises(ValueError, match="key must be a LocalAccount"):
smart_contract.sign("invalid_key")

def test_sign_external_smart_contract(external_smart_contract_factory):
"""Test the signing of an external SmartContract object."""
smart_contract = external_smart_contract_factory()
with pytest.raises(ValueError, match="Cannot sign an external SmartContract"):
smart_contract.sign('key')

def test_smart_contract_str_representation(smart_contract_factory):
"""Test the string representation of a SmartContract object."""
Expand Down

0 comments on commit 391a4d0

Please sign in to comment.