1+ import pytest
2+ from unittest .mock import AsyncMock , MagicMock
3+ from bsv .auth .clients .auth_fetch import AuthFetch , SimplifiedFetchRequestOptions
4+ from bsv .auth .requested_certificate_set import RequestedCertificateSet
5+ from bsv .auth .auth_message import AuthMessage
6+ from bsv .auth .peer import Peer , PeerOptions
7+
8+
9+ class DummyWallet :
10+ def get_public_key (self , ctx , args , originator ):
11+ return {"publicKey" : "02a1633c..." , "derivationPrefix" : "m/0" }
12+
13+ def create_action (self , ctx , args , originator ):
14+ return {"tx" : "0100000001abcdef..." }
15+
16+ def create_signature (self , ctx , args , originator ):
17+ return {"signature" : b"dummy_signature" }
18+
19+ def verify_signature (self , ctx , args , originator ):
20+ return {"valid" : True }
21+
22+
23+ @pytest .mark .asyncio
24+ async def test_fetch_basic_request ():
25+ wallet = DummyWallet ()
26+ requested_certs = RequestedCertificateSet ()
27+ auth_fetch = AuthFetch (wallet , requested_certs )
28+ url = "https://example.com/api"
29+ config = SimplifiedFetchRequestOptions (method = "GET" , headers = {"Accept" : "application/json" })
30+
31+ # モックのPeerとTransport
32+ mock_transport = MagicMock ()
33+ mock_transport .send = AsyncMock (return_value = None )
34+ mock_transport .on_data = MagicMock (return_value = None )
35+ peer_options = PeerOptions (wallet = wallet , transport = mock_transport , certificates_to_request = requested_certs )
36+ mock_peer = Peer (peer_options )
37+ mock_peer .get_authenticated_session = AsyncMock (return_value = MagicMock (peer_nonce = "dummy" , is_authenticated = True , peer_identity_key = "dummy" ))
38+ mock_peer .to_peer = MagicMock (return_value = None ) # 同期メソッドとしてモック
39+ mock_peer .listen_for_general_messages = MagicMock (return_value = 1 )
40+ mock_peer .stop_listening_for_general_messages = MagicMock ()
41+
42+ # peersにセット
43+ auth_peer = auth_fetch .peers ["https://example.com" ] = MagicMock ()
44+ auth_peer .peer = mock_peer
45+
46+ auth_fetch .fetch (None , url , config )
47+ mock_peer .to_peer .assert_called_once ()
48+
49+ @pytest .mark .asyncio
50+ async def test_fetch_with_auth_headers ():
51+ wallet = DummyWallet ()
52+ requested_certs = RequestedCertificateSet ()
53+ auth_fetch = AuthFetch (wallet , requested_certs )
54+ url = "https://example.com/api"
55+ config = SimplifiedFetchRequestOptions (
56+ method = "POST" ,
57+ headers = {"Content-Type" : "application/json" , "X-Auth-Required" : "true" },
58+ body = b'{"test": "data"}'
59+ )
60+ mock_transport = MagicMock ()
61+ mock_transport .send = AsyncMock (return_value = None )
62+ mock_transport .on_data = MagicMock (return_value = None )
63+ peer_options = PeerOptions (wallet = wallet , transport = mock_transport , certificates_to_request = requested_certs )
64+ mock_peer = Peer (peer_options )
65+ mock_peer .get_authenticated_session = AsyncMock (return_value = MagicMock (peer_nonce = "dummy" , is_authenticated = True , peer_identity_key = "dummy" ))
66+ mock_peer .to_peer = MagicMock (return_value = None ) # 同期メソッドとしてモック
67+ mock_peer .listen_for_general_messages = MagicMock (return_value = 1 )
68+ mock_peer .stop_listening_for_general_messages = MagicMock ()
69+ auth_peer = auth_fetch .peers ["https://example.com" ] = MagicMock ()
70+ auth_peer .peer = mock_peer
71+ auth_fetch .fetch (None , url , config )
72+ mock_peer .to_peer .assert_called_once ()
73+
74+ @pytest .mark .asyncio
75+ async def test_fetch_error_handling ():
76+ wallet = DummyWallet ()
77+ requested_certs = RequestedCertificateSet ()
78+ auth_fetch = AuthFetch (wallet , requested_certs )
79+ url = "https://example.com/api"
80+ config = SimplifiedFetchRequestOptions (method = "GET" )
81+ mock_transport = MagicMock ()
82+ mock_transport .send = AsyncMock (side_effect = Exception ("Network error" ))
83+ mock_transport .on_data = MagicMock (return_value = None )
84+ peer_options = PeerOptions (wallet = wallet , transport = mock_transport , certificates_to_request = requested_certs )
85+ mock_peer = Peer (peer_options )
86+ mock_peer .get_authenticated_session = AsyncMock (return_value = MagicMock (peer_nonce = "dummy" , is_authenticated = True , peer_identity_key = "dummy" ))
87+ mock_peer .to_peer = MagicMock (side_effect = Exception ("Network error" )) # 同期メソッドとして例外
88+ mock_peer .listen_for_general_messages = MagicMock (return_value = 1 )
89+ mock_peer .stop_listening_for_general_messages = MagicMock ()
90+ auth_peer = auth_fetch .peers ["https://example.com" ] = MagicMock ()
91+ auth_peer .peer = mock_peer
92+ with pytest .raises (RuntimeError , match = "Network error" ):
93+ auth_fetch .fetch (None , url , config )
94+
95+ def test_consume_received_certificates ():
96+ wallet = DummyWallet ()
97+ requested_certs = RequestedCertificateSet ()
98+ auth_fetch = AuthFetch (wallet , requested_certs )
99+ mock_cert = {"type" : "authrite" , "validationKey" : "test_key" , "serialNumber" : "123" , "validFrom" : 1000 , "validUntil" : 2000 }
100+ auth_fetch .certificates_received = [mock_cert ]
101+ certs = auth_fetch .consume_received_certificates ()
102+ assert len (certs ) == 1
103+ assert certs [0 ]["type" ] == "authrite"
104+ assert certs [0 ]["serialNumber" ] == "123"
105+ assert len (auth_fetch .certificates_received ) == 0
106+
107+ def test_validate_request_options ():
108+ config = SimplifiedFetchRequestOptions ()
109+ assert config .method == "GET"
110+ assert isinstance (config .headers , dict )
111+ assert config .body is None
112+ assert config .retry_counter is None
113+ config = SimplifiedFetchRequestOptions (method = "POST" )
114+ assert config .method == "POST"
115+ config = SimplifiedFetchRequestOptions (headers = {"X-Test" : "value" })
116+ assert config .headers ["X-Test" ] == "value"
117+ config = SimplifiedFetchRequestOptions (body = b"test" )
118+ assert config .body == b"test"
0 commit comments