• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

safe-global / safe-eth-py / 18643788944

20 Oct 2025 06:10AM UTC coverage: 89.949% (-4.0%) from 93.927%
18643788944

Pull #2055

github

web-flow
Merge bca00d803 into 8eac6367d
Pull Request #2055: Bump psycopg[binary] from 3.2.9 to 3.2.11

9227 of 10258 relevant lines covered (89.95%)

1.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

58.33
/safe_eth/eth/tests/clients/test_etherscan_client_v2.py
1
import os
2✔
2
import unittest
2✔
3

4
from django.test import TestCase
2✔
5

6
import pytest
2✔
7

8
from ... import EthereumNetwork
2✔
9
from ...clients import EtherscanClientV2, EtherscanRateLimitError
2✔
10
from ...clients.etherscan_client_v2 import AsyncEtherscanClientV2
2✔
11
from .mocks import sourcify_safe_metadata
2✔
12

13

14
class TestEtherscanClientV2(TestCase):
2✔
15
    @classmethod
2✔
16
    def get_etherscan_api(cls, network: EthereumNetwork):
2✔
17
        etherscan_api_key_variable_name = "ETHERSCAN_API_KEY"
2✔
18
        etherscan_api_key = os.environ.get(etherscan_api_key_variable_name)
2✔
19
        if not etherscan_api_key:
2✔
20
            pytest.skip(f"{etherscan_api_key_variable_name} needs to be defined")
2✔
21

22
        return EtherscanClientV2(network, api_key=etherscan_api_key)
×
23

24
    @pytest.mark.flaky(reruns=5)
2✔
25
    def test_etherscan_get_abi(self):
2✔
26
        try:
2✔
27
            etherscan_api = self.get_etherscan_api(EthereumNetwork.MAINNET)
2✔
28
            safe_master_copy_abi = sourcify_safe_metadata["output"]["abi"]
×
29
            safe_master_copy_address = "0x6851D6fDFAfD08c0295C392436245E5bc78B0185"
×
30
            self.assertEqual(
×
31
                etherscan_api.get_contract_abi(safe_master_copy_address),
32
                safe_master_copy_abi,
33
            )
34

35
            contract_metadata = etherscan_api.get_contract_metadata(
×
36
                safe_master_copy_address
37
            )
38
            self.assertEqual(contract_metadata.name, "GnosisSafe")
×
39
            self.assertEqual(contract_metadata.abi, safe_master_copy_abi)
×
40
            self.assertIsNone(contract_metadata.implementation)
×
41

42
            random_address = "0xaE32496491b53841efb51829d6f886387708F99a"
×
43
            self.assertIsNone(etherscan_api.get_contract_abi(random_address))
×
44
            self.assertIsNone(etherscan_api.get_contract_metadata(random_address))
×
45
        except EtherscanRateLimitError:
2✔
46
            self.skipTest("Etherscan rate limit reached")
×
47

48
    @pytest.mark.flaky(reruns=5)
2✔
49
    def test_etherscan_get_contract_metadata(self):
2✔
50
        try:
2✔
51
            etherscan_api = self.get_etherscan_api(EthereumNetwork.MAINNET)
2✔
52
            proxy_address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
×
53

54
            contract_metadata = etherscan_api.get_contract_metadata(proxy_address)
×
55
            self.assertEqual(contract_metadata.name, "FiatTokenProxy")
×
56
            self.assertEqual(
×
57
                contract_metadata.implementation,
58
                "0x43506849d7c04f9138d1a2050bbf3a0c054402dd",
59
            )
60

61
        except EtherscanRateLimitError:
2✔
62
            self.skipTest("Etherscan rate limit reached")
×
63

64
    @pytest.mark.flaky(reruns=5)
2✔
65
    def test_is_supported_network(self):
2✔
66
        try:
2✔
67
            self.assertTrue(
2✔
68
                EtherscanClientV2.is_supported_network(EthereumNetwork.GNOSIS)
69
            )
70
            self.assertFalse(
2✔
71
                EtherscanClientV2.is_supported_network(EthereumNetwork.UNKNOWN)
72
            )
73
        except EtherscanRateLimitError:
×
74
            self.skipTest("Etherscan rate limit reached")
×
75

76

77
class TestAsyncEtherscanClientV2(unittest.IsolatedAsyncioTestCase):
2✔
78
    @classmethod
2✔
79
    def get_etherscan_api(cls, network: EthereumNetwork):
2✔
80
        etherscan_api_key_variable_name = "ETHERSCAN_API_KEY"
2✔
81
        etherscan_api_key = os.environ.get(etherscan_api_key_variable_name)
2✔
82
        if not etherscan_api_key:
2✔
83
            pytest.skip(f"{etherscan_api_key_variable_name} needs to be defined")
2✔
84

85
        return AsyncEtherscanClientV2(network, api_key=etherscan_api_key)
×
86

87
    @pytest.mark.flaky(reruns=5)
2✔
88
    async def test_async_etherscan_get_abi(self):
2✔
89
        try:
2✔
90
            etherscan_api = self.get_etherscan_api(EthereumNetwork.MAINNET)
2✔
91
            safe_master_copy_abi = sourcify_safe_metadata["output"]["abi"]
×
92
            safe_master_copy_address = "0x6851D6fDFAfD08c0295C392436245E5bc78B0185"
×
93
            self.assertEqual(
×
94
                await etherscan_api.async_get_contract_abi(safe_master_copy_address),
95
                safe_master_copy_abi,
96
            )
97

98
            contract_metadata = await etherscan_api.async_get_contract_metadata(
×
99
                safe_master_copy_address
100
            )
101
            self.assertEqual(contract_metadata.name, "GnosisSafe")
×
102
            self.assertEqual(contract_metadata.abi, safe_master_copy_abi)
×
103

104
            random_address = "0xaE32496491b53841efb51829d6f886387708F99a"
×
105
            self.assertIsNone(
×
106
                await etherscan_api.async_get_contract_abi(random_address)
107
            )
108
            self.assertIsNone(
×
109
                await etherscan_api.async_get_contract_metadata(random_address)
110
            )
111
        except EtherscanRateLimitError:
2✔
112
            self.skipTest("Etherscan rate limit reached")
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc