forked from nucypher/nucypher-contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
formalizes python package; extracts tests from nucypher
- Loading branch information
Showing
10 changed files
with
454 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import pytest | ||
|
||
from tests.utils import mock_registry_sources | ||
|
||
|
||
@pytest.fixture(scope="module", autouse=True) | ||
def auto_mock_registry_sources(module_mocker): | ||
with mock_registry_sources(mocker=module_mocker): | ||
yield |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from nucypher_contracts.domains import ChainInfo, TACoDomain | ||
|
||
TEMPORARY_DOMAIN_NAME = ":temporary-domain:" | ||
|
||
TESTERCHAIN_CHAIN_ID = 131277322940537 | ||
|
||
TESTERCHAIN_CHAIN_INFO = ChainInfo( | ||
TESTERCHAIN_CHAIN_ID, | ||
"eth-tester" | ||
) | ||
|
||
TEMPORARY_DOMAIN = TACoDomain( | ||
name=TEMPORARY_DOMAIN_NAME, | ||
eth_chain=TESTERCHAIN_CHAIN_INFO, | ||
polygon_chain=TESTERCHAIN_CHAIN_INFO, | ||
condition_chains=(TESTERCHAIN_CHAIN_INFO,), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import pytest | ||
|
||
from nucypher_contracts.registry import ContractRegistry | ||
from tests.utils import MockRegistrySource | ||
from tests.package.constants import TEMPORARY_DOMAIN, TESTERCHAIN_CHAIN_ID | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def name(): | ||
return "TestContract" | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def address(): | ||
return "0xdeadbeef" | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def abi(): | ||
return ["fake", "data"] | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def record(name, address, abi): | ||
record_data = {name: {"address": address, "abi": abi}} | ||
return record_data | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def data(record): | ||
_data = {TESTERCHAIN_CHAIN_ID: record} | ||
return _data | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def source(data): | ||
source = MockRegistrySource(domain=TEMPORARY_DOMAIN) | ||
source.data = data | ||
return source | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def registry(record, source): | ||
registry = ContractRegistry(source=source) | ||
return registry | ||
|
||
|
||
def test_registry_id_consistency(registry, source): | ||
new_registry = ContractRegistry(source=source) | ||
new_registry._data = registry._data | ||
assert new_registry.id == registry.id | ||
|
||
|
||
def test_registry_name_search(registry, name, address, abi): | ||
record = registry.search(chain_id=TESTERCHAIN_CHAIN_ID, contract_name=name) | ||
assert len(record) == 4, "Registry record is the wrong length" | ||
assert record.chain_id == TESTERCHAIN_CHAIN_ID | ||
assert record.name == name | ||
assert record.address == address | ||
assert record.abi == abi | ||
|
||
|
||
def test_registry_address_search(registry, name, address, abi): | ||
record = registry.search(chain_id=TESTERCHAIN_CHAIN_ID, contract_address=address) | ||
assert len(record) == 4, "Registry record is the wrong length" | ||
assert record.chain_id == TESTERCHAIN_CHAIN_ID | ||
assert record.name == name | ||
assert record.address == address | ||
assert record.abi == abi | ||
|
||
|
||
def test_local_registry_unknown_contract_name_search(registry): | ||
with pytest.raises(ContractRegistry.UnknownContract): | ||
registry.search( | ||
chain_id=TESTERCHAIN_CHAIN_ID, contract_name="this does not exist" | ||
) | ||
|
||
|
||
def test_local_contract_registry_ambiguous_search_terms(data, name, record, address): | ||
data[TESTERCHAIN_CHAIN_ID]["fakeContract"] = record[name] | ||
source = MockRegistrySource(domain=TEMPORARY_DOMAIN) | ||
source.data = data | ||
registry = ContractRegistry(source=source) | ||
with pytest.raises(ContractRegistry.AmbiguousSearchTerms): | ||
registry.search(chain_id=TESTERCHAIN_CHAIN_ID, contract_address=address) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import json | ||
|
||
import pytest | ||
import requests | ||
from requests import Response | ||
|
||
from nucypher_contracts import domains | ||
from nucypher_contracts.registry import ( | ||
EmbeddedRegistrySource, | ||
GithubRegistrySource, | ||
LocalRegistrySource, | ||
RegistrySource, | ||
RegistrySourceManager, | ||
) | ||
from tests.package.constants import ( | ||
TEMPORARY_DOMAIN, | ||
TEMPORARY_DOMAIN_NAME | ||
) | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def registry_data(): | ||
_registry_data = { | ||
"2958363635247": { | ||
"TestContract": {"address": "0xdeadbeef", "abi": ["fake", "data"]}, | ||
"AnotherTestContract": {"address": "0xdeadbeef", "abi": ["fake", "data"]}, | ||
}, | ||
"393742274944474": { | ||
"YetAnotherContract": {"address": "0xdeadbeef", "abi": ["fake", "data"]} | ||
}, | ||
} | ||
return _registry_data | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def mock_200_response(mocker, registry_data): | ||
mock_response = Response() | ||
mock_response.status_code = 200 | ||
mock_response._content = json.dumps(registry_data).encode("utf-8") | ||
mocker.patch.object(requests, "get", return_value=mock_response) | ||
|
||
|
||
@pytest.fixture(scope="function") | ||
def test_registry_filepath(tmpdir, registry_data): | ||
filepath = tmpdir.join("registry.json") | ||
with open(filepath, "w") as f: | ||
json.dump(registry_data, f) | ||
yield filepath | ||
filepath.remove() | ||
|
||
|
||
@pytest.mark.usefixtures("mock_200_response") | ||
def test_github_registry_source(registry_data): | ||
source = GithubRegistrySource(domain=TEMPORARY_DOMAIN) | ||
assert source.domain.name == TEMPORARY_DOMAIN_NAME | ||
assert str(source.domain) == TEMPORARY_DOMAIN_NAME | ||
assert bytes(source.domain) == TEMPORARY_DOMAIN_NAME.encode("utf-8") | ||
data = source.get() | ||
assert data == registry_data | ||
assert source.data == registry_data | ||
assert data == source.data | ||
|
||
|
||
@pytest.mark.parametrize("domain", list(domains.SUPPORTED_DOMAINS.values())) | ||
def test_get_actual_github_registry_file(domain): | ||
source = GithubRegistrySource(domain=domain) | ||
assert str(domain.eth_chain.id) in source.data | ||
assert str(domain.polygon_chain.id) in source.data | ||
|
||
|
||
def test_local_registry_source(registry_data, test_registry_filepath): | ||
source = LocalRegistrySource( | ||
filepath=test_registry_filepath, domain=TEMPORARY_DOMAIN | ||
) | ||
assert source.domain.name == TEMPORARY_DOMAIN_NAME | ||
assert str(source.domain) == TEMPORARY_DOMAIN_NAME | ||
assert bytes(source.domain) == TEMPORARY_DOMAIN_NAME.encode("utf-8") | ||
data = source.get() | ||
assert data == registry_data | ||
assert source.data == registry_data | ||
assert data == source.data | ||
|
||
|
||
def test_embedded_registry_source(registry_data, test_registry_filepath, mocker): | ||
mocker.patch.object( | ||
EmbeddedRegistrySource, | ||
"get_publication_endpoint", | ||
return_value=test_registry_filepath, | ||
) | ||
source = EmbeddedRegistrySource(domain=TEMPORARY_DOMAIN) | ||
assert source.domain.name == TEMPORARY_DOMAIN_NAME | ||
assert str(source.domain) == TEMPORARY_DOMAIN_NAME | ||
assert bytes(source.domain) == TEMPORARY_DOMAIN_NAME.encode("utf-8") | ||
data = source.get() | ||
assert data == registry_data | ||
assert source.data == registry_data | ||
assert data == source.data | ||
|
||
|
||
def test_registry_source_manager_fallback( | ||
registry_data, test_registry_filepath, mocker | ||
): | ||
github_source_get = mocker.patch.object( | ||
GithubRegistrySource, "get", side_effect=RegistrySource.Unavailable | ||
) | ||
mocker.patch.object( | ||
EmbeddedRegistrySource, | ||
"get_publication_endpoint", | ||
return_value=test_registry_filepath, | ||
) | ||
embedded_source_get = mocker.spy(EmbeddedRegistrySource, "get") | ||
RegistrySourceManager._FALLBACK_CHAIN = ( | ||
GithubRegistrySource, | ||
EmbeddedRegistrySource, | ||
) | ||
source_manager = RegistrySourceManager(domain=TEMPORARY_DOMAIN) | ||
assert source_manager.domain.name == TEMPORARY_DOMAIN_NAME | ||
assert str(source_manager.domain) == TEMPORARY_DOMAIN_NAME | ||
assert bytes(source_manager.domain) == TEMPORARY_DOMAIN_NAME.encode("utf-8") | ||
|
||
primary_sources = source_manager.get_primary_sources() | ||
assert len(primary_sources) == 1 | ||
assert primary_sources[0] == GithubRegistrySource | ||
|
||
source = source_manager.fetch_latest_publication() | ||
github_source_get.assert_called_once() | ||
embedded_source_get.assert_called_once() | ||
assert source.data == registry_data | ||
assert isinstance(source, EmbeddedRegistrySource) | ||
|
||
mocker.patch.object( | ||
EmbeddedRegistrySource, | ||
"get_publication_endpoint", | ||
side_effect=RegistrySource.Unavailable, | ||
) | ||
|
||
with pytest.raises(RegistrySourceManager.NoSourcesAvailable): | ||
source_manager.fetch_latest_publication() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import pytest | ||
|
||
from nucypher_contracts import domains | ||
from nucypher_contracts.domains import EthChain, PolygonChain | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def test_registry(module_mocker): | ||
# override fixture which mocks domains.SUPPORTED_DOMAINS | ||
yield | ||
|
||
|
||
@pytest.fixture(scope="module", autouse=True) | ||
def mock_condition_blockchains(module_mocker): | ||
# override fixture which mocks domains.get_domain | ||
yield | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"eth_chain_test", | ||
( | ||
(EthChain.MAINNET, "mainnet", 1), | ||
(EthChain.SEPOLIA, "sepolia", 11155111), | ||
), | ||
) | ||
def test_eth_chains(eth_chain_test): | ||
eth_chain, expected_name, expected_id = eth_chain_test | ||
assert eth_chain.name == expected_name | ||
assert eth_chain.id == expected_id | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"poly_chain_test", | ||
( | ||
(PolygonChain.MAINNET, "polygon", 137), | ||
(PolygonChain.MUMBAI, "mumbai", 80001), | ||
), | ||
) | ||
def test_polygon_chains(poly_chain_test): | ||
eth_chain, expected_name, expected_id = poly_chain_test | ||
assert eth_chain.name == expected_name | ||
assert eth_chain.id == expected_id | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"taco_domain_test", | ||
( | ||
( | ||
domains.MAINNET, | ||
"mainnet", | ||
EthChain.MAINNET, | ||
PolygonChain.MAINNET, | ||
(EthChain.MAINNET, PolygonChain.MAINNET), | ||
), | ||
( | ||
domains.LYNX, | ||
"lynx", | ||
EthChain.SEPOLIA, | ||
PolygonChain.MUMBAI, | ||
( | ||
EthChain.MAINNET, | ||
EthChain.SEPOLIA, | ||
PolygonChain.MUMBAI, | ||
PolygonChain.MAINNET, | ||
), | ||
), | ||
( | ||
domains.TAPIR, | ||
"tapir", | ||
EthChain.SEPOLIA, | ||
PolygonChain.MUMBAI, | ||
(EthChain.SEPOLIA, PolygonChain.MUMBAI), | ||
), | ||
), | ||
) | ||
def test_taco_domain_info(taco_domain_test): | ||
( | ||
domain_info, | ||
expected_name, | ||
expected_eth_chain, | ||
expected_polygon_chain, | ||
expected_condition_chains, | ||
) = taco_domain_test | ||
assert domain_info.name == expected_name | ||
assert domain_info.eth_chain == expected_eth_chain | ||
assert domain_info.polygon_chain == expected_polygon_chain | ||
assert domain_info.condition_chains == expected_condition_chains | ||
|
||
assert domain_info.is_testnet == (expected_name != "mainnet") | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"domain_name_test", | ||
( | ||
("mainnet", domains.MAINNET), | ||
("lynx", domains.LYNX), | ||
("tapir", domains.TAPIR), | ||
), | ||
) | ||
def test_get_domain(domain_name_test): | ||
domain_name, expected_domain_info = domain_name_test | ||
assert domains.get_domain(domain_name) == expected_domain_info | ||
|
||
|
||
def test_get_domain_unrecognized_domain_name(): | ||
with pytest.raises(domains.UnrecognizedTacoDomain): | ||
domains.get_domain("5am_In_Toronto") |
Oops, something went wrong.