Skip to content

Commit dbca4a2

Browse files
test: refactor transaction response tests to eliminate duplication (hiero-ledger#2096)
Signed-off-by: tech0priyanshu <priyanshuyadv101106@gmail.com> Co-authored-by: exploreriii <133720349+exploreriii@users.noreply.github.com>
1 parent d1bae92 commit dbca4a2

3 files changed

Lines changed: 154 additions & 99 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
1111

1212
### Tests
1313
- Refactor `mock_server` setup for network level TLS handling and added thread safety
14+
- Refactor `transaction_response_test.py` by organizing the tests into `test_transaction_response.py` and `transaction_response_test.py`. (#2066)
15+
1416

1517

1618
### Examples

tests/unit/test_transaction_response.py

Lines changed: 0 additions & 89 deletions
This file was deleted.

tests/unit/transaction_response_test.py

Lines changed: 152 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
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+
113
import pytest
214

15+
316
from hiero_sdk_python.account.account_id import AccountId
417
from 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+
525
from hiero_sdk_python.hapi.services import (
626
basic_types_pb2,
727
response_header_pb2,
@@ -11,41 +31,47 @@
1131
transaction_receipt_pb2,
1232
transaction_record_pb2,
1333
)
34+
35+
1436
from hiero_sdk_python.hapi.services.query_header_pb2 import ResponseType
1537
from hiero_sdk_python.query.transaction_get_receipt_query import (
1638
TransactionGetReceiptQuery,
1739
)
1840
from 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+
2443
from tests.unit.mock_server import mock_hedera_servers
2544

45+
2646
pytestmark = pytest.mark.unit
2747

2848

49+
2950
@pytest.fixture
3051
def 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+
3963
def 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+
4975
def 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+
75104
def 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+
105146
def 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+
125169
def 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+
135181
def 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

Comments
 (0)