1+ """
2+ Tests for TransactionResponse behavior.
3+
4+ Includes receipt handling, record queries, and validation scenarios.
5+ """
6+
7+
8+ # pylint: disable=no-member,no-name-in-module
9+ # no-member is disabled because Protobuf uses runtime descriptors
10+ # no-name-in-module is disabled above because of the dynamic nature of the generated protobuf
11+
12+
113import pytest
214
15+
316from hiero_sdk_python .account .account_id import AccountId
417from hiero_sdk_python .exceptions import ReceiptStatusError
18+ from hiero_sdk_python .response_code import ResponseCode
19+ from hiero_sdk_python .transaction .transaction_id import TransactionId
20+ from hiero_sdk_python .transaction .transaction_receipt import TransactionReceipt
21+ from hiero_sdk_python .transaction .transaction_record import TransactionRecord
22+ from hiero_sdk_python .transaction .transaction_response import TransactionResponse
23+
24+
525from hiero_sdk_python .hapi .services import (
626 basic_types_pb2 ,
727 response_header_pb2 ,
1131 transaction_receipt_pb2 ,
1232 transaction_record_pb2 ,
1333)
34+
35+
1436from hiero_sdk_python .hapi .services .query_header_pb2 import ResponseType
1537from hiero_sdk_python .query .transaction_get_receipt_query import (
1638 TransactionGetReceiptQuery ,
1739)
1840from hiero_sdk_python .query .transaction_record_query import TransactionRecordQuery
19- from hiero_sdk_python .response_code import ResponseCode
20- from hiero_sdk_python .transaction .transaction_id import TransactionId
21- from hiero_sdk_python .transaction .transaction_receipt import TransactionReceipt
22- from hiero_sdk_python .transaction .transaction_record import TransactionRecord
23- from hiero_sdk_python .transaction .transaction_response import TransactionResponse
41+
42+
2443from tests .unit .mock_server import mock_hedera_servers
2544
45+
2646pytestmark = pytest .mark .unit
2747
2848
49+
2950@pytest .fixture
3051def transaction_response ():
3152 """Create a populated TransactionResponse for testing."""
3253 response = TransactionResponse ()
33- response .transaction_id = TransactionId .from_string ("0.0.1001@1234567890.000000001" )
54+ response .transaction_id = TransactionId .from_string (
55+ "0.0.1001@1234567890.000000001"
56+ )
3457 response .node_id = AccountId .from_string ("0.0.3" )
3558 response .validate_status = True
3659 return response
3760
3861
62+
3963def test_get_receipt_query_builds_query (transaction_response ):
4064 """Test get_receipt_query builds and returns the transaction receipt query."""
4165 query = transaction_response .get_receipt_query ()
4266
67+
4368 assert isinstance (query , TransactionGetReceiptQuery )
4469 assert query .transaction_id == transaction_response .transaction_id
4570 assert len (query .node_account_ids ) == 1
4671 assert query .node_account_ids [0 ] == transaction_response .node_id
4772
4873
74+
4975def test_get_receipt_executes_and_returns_receipt (transaction_response ):
5076 """Test get_receipt execute receipt query and return transaction receipt."""
5177 receipt_response = response_pb2 .Response (
@@ -64,27 +90,38 @@ def test_get_receipt_executes_and_returns_receipt(transaction_response):
6490 )
6591 )
6692
93+
6794 with mock_hedera_servers ([[receipt_response ]]) as client :
6895 receipt = transaction_response .get_receipt (client )
6996
97+
7098 assert isinstance (receipt , TransactionReceipt )
7199 assert receipt .status == ResponseCode .SUCCESS
72100 assert receipt .account_id .num == 1234
73101
74102
103+
75104def test_get_receipt_query_set_validate_status (transaction_response ):
76105 """Test receipt query correctly initializes with the validate_status flag."""
77106 query = transaction_response .get_receipt_query (validate_status = True )
78107
108+
79109 assert isinstance (query , TransactionGetReceiptQuery )
80- assert query .validate_status == True
110+ assert query .validate_status is True
81111 assert query .transaction_id == transaction_response .transaction_id
82112 assert len (query .node_account_ids ) == 1
83113 assert query .node_account_ids [0 ] == transaction_response .node_id
84114
85115
86- def test_get_receipt_returns_failure_status_without_validate_status (transaction_response ):
87- """Test failing status returns a receipt instead of raising an error when validation is disabled."""
116+
117+ def test_get_receipt_returns_failure_status_without_validate_status (
118+ transaction_response ,
119+ ):
120+ """Test failing status behavior.
121+
122+ Ensures a receipt is returned instead of raising an error
123+ when validation is disabled.
124+ """
88125 receipt_response = response_pb2 .Response (
89126 transactionGetReceipt = transaction_get_receipt_pb2 .TransactionGetReceiptResponse (
90127 header = response_header_pb2 .ResponseHeader (
@@ -96,12 +133,16 @@ def test_get_receipt_returns_failure_status_without_validate_status(transaction_
96133 )
97134 )
98135
136+
99137 with mock_hedera_servers ([[receipt_response ]]) as client :
100138 receipt = transaction_response .get_receipt (client )
101139
140+
102141 assert isinstance (receipt , TransactionReceipt )
103142 assert receipt .status == ResponseCode .INVALID_SIGNATURE
104143
144+
145+
105146def test_get_receipt_raises_exception_with_validate_status (transaction_response ):
106147 """Test get_receipt error is raised for non-success statuses when validation is enabled."""
107148 receipt_response = response_pb2 .Response (
@@ -115,30 +156,40 @@ def test_get_receipt_raises_exception_with_validate_status(transaction_response)
115156 )
116157 )
117158
159+
118160 with mock_hedera_servers ([[receipt_response ]]) as client :
119161 with pytest .raises (ReceiptStatusError ) as e :
120162 transaction_response .get_receipt (client , validate_status = True )
121163
164+
122165 assert e .value .status == ResponseCode .INVALID_SIGNATURE
123166
124167
168+
125169def test_get_record_query_builds_query (transaction_response ):
126170 """Test get_record_query builds and returns the transaction record query."""
127171 query = transaction_response .get_record_query ()
128172
173+
129174 assert isinstance (query , TransactionRecordQuery )
130175 assert query .transaction_id == transaction_response .transaction_id
131176 assert len (query .node_account_ids ) == 1
132177 assert query .node_account_ids [0 ] == transaction_response .node_id
133178
134179
180+
135181def test_get_record_executes_and_returns_record (transaction_response ):
136182 """Test get_record execute record query and return transaction record."""
137183 receipt = transaction_receipt_pb2 .TransactionReceipt (status = ResponseCode .SUCCESS )
184+
185+
138186 record = transaction_record_pb2 .TransactionRecord (
139- receipt = receipt , memo = "record" , transactionFee = 100
187+ receipt = receipt ,
188+ memo = "record" ,
189+ transactionFee = 100 ,
140190 )
141191
192+
142193 record_response = [
143194 [
144195 response_pb2 .Response (
@@ -163,10 +214,101 @@ def test_get_record_executes_and_returns_record(transaction_response):
163214 ]
164215 ]
165216
217+
166218 with mock_hedera_servers (record_response ) as client :
167219 result = transaction_response .get_record (client )
168220
221+
169222 assert isinstance (result , TransactionRecord )
170223 assert result .receipt .status == ResponseCode .SUCCESS
171224 assert result .transaction_fee == record .transactionFee
172225 assert result .transaction_memo == record .memo
226+
227+
228+ # Tests for TransactionResponse behavior.
229+
230+
231+ def test_transaction_response_fields (transaction_id ):
232+ """Asserting response is correctly populated."""
233+ resp = TransactionResponse ()
234+
235+
236+ # Assert public attributes exist (PRIORITY 1: protect against breaking changes)
237+ assert hasattr (resp , "transaction_id" )
238+ assert hasattr (resp , "node_id" )
239+ assert hasattr (resp , "hash" )
240+ assert hasattr (resp , "validate_status" )
241+ assert hasattr (resp , "transaction" )
242+
243+
244+ # Assert default values
245+ assert resp .hash == b""
246+ assert resp .validate_status is False
247+ assert resp .transaction is None
248+
249+
250+ resp .transaction_id = transaction_id
251+ resp .node_id = AccountId (0 , 0 , 3 )
252+
253+
254+ assert resp .transaction_id == transaction_id
255+ assert resp .node_id == AccountId (0 , 0 , 3 )
256+
257+
258+
259+ def test_transaction_response_get_receipt_is_pinned_to_submitting_node (
260+ transaction_id ,
261+ ):
262+ """
263+ Test receipt retrieval behavior with node pinning.
264+
265+ mock_hedera_servers assigns:
266+ - server[0] -> node 0.0.3
267+ - server[1] -> node 0.0.4
268+
269+
270+ We make node 0.0.3 return a NON-retryable precheck error, and node 0.0.4 return SUCCESS.
271+ If TransactionResponse.get_receipt() does not pin, it will likely hit 0.0.3 and fail.
272+ If it pins to self.node_id (0.0.4), it will succeed.
273+ """
274+ bad_node_response = response_pb2 .Response (
275+ transactionGetReceipt = transaction_get_receipt_pb2 .TransactionGetReceiptResponse (
276+ header = response_header_pb2 .ResponseHeader (
277+ nodeTransactionPrecheckCode = ResponseCode .INVALID_TRANSACTION
278+ ),
279+ receipt = transaction_receipt_pb2 .TransactionReceipt (
280+ status = ResponseCode .UNKNOWN
281+ ),
282+ )
283+ )
284+
285+
286+ good_node_response = response_pb2 .Response (
287+ transactionGetReceipt = transaction_get_receipt_pb2 .TransactionGetReceiptResponse (
288+ header = response_header_pb2 .ResponseHeader (
289+ nodeTransactionPrecheckCode = ResponseCode .OK
290+ ),
291+ receipt = transaction_receipt_pb2 .TransactionReceipt (
292+ status = ResponseCode .SUCCESS
293+ ),
294+ )
295+ )
296+
297+
298+ response_sequences = [
299+ [bad_node_response ], # node 0.0.3
300+ [good_node_response ], # node 0.0.4
301+ ]
302+
303+
304+ with mock_hedera_servers (response_sequences ) as client :
305+ resp = TransactionResponse ()
306+ resp .transaction_id = transaction_id
307+ resp .node_id = AccountId (0 , 0 , 4 )
308+
309+
310+ # # submitting node (server[1])
311+ receipt = resp .get_receipt (client )
312+
313+
314+ assert receipt .status == ResponseCode .SUCCESS
0 commit comments