• 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

47.73
/safe_eth/eth/tests/account_abstraction/test_e2e_bundler_client.py
1
import os
2✔
2

3
from django.test import TestCase
2✔
4

5
import pytest
2✔
6

7
from safe_eth.util.util import to_0x_hex_str
2✔
8

9
from ...account_abstraction import BundlerClient, UserOperation, UserOperationReceipt
2✔
10
from ...account_abstraction.user_operation import UserOperationV07
2✔
11
from ..mocks.mock_bundler import (
2✔
12
    safe_4337_chain_id_mock,
13
    safe_4337_user_operation_hash_mock,
14
    user_operation_mock,
15
    user_operation_receipt_mock,
16
    user_operation_v07_chain_id,
17
    user_operation_v07_hash,
18
)
19

20

21
class TestE2EBundlerClient(TestCase):
2✔
22
    def setUp(self):
2✔
23
        bundler_client_variable_name = "ETHEREUM_4337_BUNDLER_URL"
2✔
24
        bundler_client_url = os.environ.get(bundler_client_variable_name)
2✔
25
        if not bundler_client_url:
2✔
26
            pytest.skip(f"{bundler_client_variable_name} needs to be defined")
2✔
27

28
        self.bundler = BundlerClient(bundler_client_url)
×
29

30
    def test_get_chain_id(self):
2✔
31
        self.assertGreater(self.bundler.get_chain_id(), 0)
×
32

33
    def test_get_user_operation_by_hash(self):
2✔
34
        user_operation_hash = to_0x_hex_str(safe_4337_user_operation_hash_mock)
×
35

36
        expected_user_operation = UserOperation.from_bundler_response(
×
37
            user_operation_hash, user_operation_mock["result"]
38
        )
39
        user_operation = self.bundler.get_user_operation_by_hash(user_operation_hash)
×
40
        self.assertEqual(
×
41
            user_operation,
42
            expected_user_operation,
43
        )
44
        self.assertEqual(
×
45
            to_0x_hex_str(
46
                user_operation.calculate_user_operation_hash(safe_4337_chain_id_mock)
47
            ),
48
            user_operation_hash,
49
        )
50

51
    def test_get_user_operation_V07_by_hash(self):
2✔
52
        """
53
        Test UserOperation v0.7
54
        """
55
        user_operation_hash = to_0x_hex_str(user_operation_v07_hash)
×
56
        user_operation = self.bundler.get_user_operation_by_hash(user_operation_hash)
×
57
        self.assertIsInstance(user_operation, UserOperationV07)
×
58
        self.assertEqual(
×
59
            to_0x_hex_str(
60
                user_operation.calculate_user_operation_hash(
61
                    user_operation_v07_chain_id
62
                )
63
            ),
64
            user_operation_hash,
65
        )
66

67
    @pytest.mark.xfail(reason="Unexpected and not documented changes on bundler")
2✔
68
    def test_get_user_operation_receipt(self):
2✔
69
        user_operation_hash = to_0x_hex_str(safe_4337_user_operation_hash_mock)
×
70
        expected_user_operation_receipt = UserOperationReceipt.from_bundler_response(
×
71
            user_operation_receipt_mock["result"]
72
        )
73

74
        self.assertEqual(
×
75
            self.bundler.get_user_operation_receipt(user_operation_hash),
76
            expected_user_operation_receipt,
77
        )
78

79
    @pytest.mark.xfail(reason="Some bundlers don't support batch requests")
2✔
80
    def test_get_user_operation_and_receipt(self):
2✔
81
        user_operation_hash = to_0x_hex_str(safe_4337_user_operation_hash_mock)
×
82

83
        expected_user_operation = UserOperation.from_bundler_response(
×
84
            user_operation_hash, user_operation_mock["result"]
85
        )
86
        expected_user_operation_receipt = UserOperationReceipt.from_bundler_response(
×
87
            user_operation_receipt_mock["result"]
88
        )
89
        (
×
90
            user_operation,
91
            user_operation_receipt,
92
        ) = self.bundler.get_user_operation_and_receipt(user_operation_hash)
93
        self.assertEqual(
×
94
            user_operation,
95
            expected_user_operation,
96
        )
97
        self.assertEqual(
×
98
            user_operation_receipt,
99
            expected_user_operation_receipt,
100
        )
101

102
    def test_supported_entry_points(self):
2✔
103
        supported_entry_points = self.bundler.supported_entry_points()
×
104
        self.assertIn(len(supported_entry_points), (1, 2))
×
105
        self.assertIn(
×
106
            "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", supported_entry_points
107
        )
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