Skip to content

Commit 0099b53

Browse files
authored
Merge pull request #529 from hashgraph/sr/e2e-tests
2 parents 2c27ab2 + 27fc416 commit 0099b53

32 files changed

+3273
-69
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ parking_lot = "0.12.0"
9595

9696
[dev-dependencies.tokio]
9797
version = "1.24.2"
98-
features = ["rt-multi-thread", "macros"]
98+
features = ["rt-multi-thread", "macros", "parking_lot"]
9999

100100
[dev-dependencies.env_logger]
101101
version = "0.10.0"

src/error.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,6 @@ pub enum Error {
6868
transaction_id: Box<TransactionId>,
6969
},
7070

71-
/// A transaction failed pre-check.
72-
///
73-
/// The transaction had no `transaction_id`.
74-
///
75-
/// Caused by `status` being an error.
76-
#[error("transaction without transaction id failed pre-check with status `{status:?}`")]
77-
TransactionNoIdPreCheckStatus {
78-
/// The `Status` that caused the [`Transaction`](crate::Transaction) to fail pre-check.
79-
status: Status,
80-
},
81-
8271
/// A [`Query`](crate::Query) for `transaction_id` failed pre-check.
8372
///
8473
/// Caused by `status` being an error.

src/execute.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ where
227227
let mut transaction_id = executable
228228
.requires_transaction_id()
229229
.then_some(explicit_transaction_id)
230-
.flatten()
231-
.or_else(|| ctx.operator_account_id.map(TransactionId::generate));
230+
.map(|it| it.or_else(|| ctx.operator_account_id.map(TransactionId::generate)))
231+
.flatten();
232232

233233
// if we were explicitly given a list of nodes to use, we iterate through each
234234
// of the given nodes (in a random order)

src/transaction/chunked.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,11 @@ where
200200
status: services::ResponseCodeEnum,
201201
transaction_id: Option<&TransactionId>,
202202
) -> crate::Error {
203-
if let Some(transaction_id) = transaction_id {
204-
crate::Error::TransactionPreCheckStatus {
205-
status,
206-
transaction_id: Box::new(*transaction_id),
207-
}
208-
} else {
209-
crate::Error::TransactionNoIdPreCheckStatus { status }
203+
crate::Error::TransactionPreCheckStatus {
204+
status,
205+
transaction_id: Box::new(
206+
*transaction_id.expect("transactions must have transaction IDs"),
207+
),
210208
}
211209
}
212210

@@ -304,13 +302,11 @@ where
304302
status: services::ResponseCodeEnum,
305303
transaction_id: Option<&TransactionId>,
306304
) -> crate::Error {
307-
if let Some(transaction_id) = transaction_id {
308-
crate::Error::TransactionPreCheckStatus {
309-
status,
310-
transaction_id: Box::new(*transaction_id),
311-
}
312-
} else {
313-
crate::Error::TransactionNoIdPreCheckStatus { status }
305+
crate::Error::TransactionPreCheckStatus {
306+
status,
307+
transaction_id: Box::new(
308+
*transaction_id.expect("transactions must have transaction IDs"),
309+
),
314310
}
315311
}
316312

src/transaction/execute.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,11 @@ where
232232
status: crate::Status,
233233
transaction_id: Option<&TransactionId>,
234234
) -> crate::Error {
235-
if let Some(transaction_id) = transaction_id {
236-
crate::Error::TransactionPreCheckStatus {
237-
status,
238-
transaction_id: Box::new(*transaction_id),
239-
}
240-
} else {
241-
crate::Error::TransactionNoIdPreCheckStatus { status }
235+
crate::Error::TransactionPreCheckStatus {
236+
status,
237+
transaction_id: Box::new(
238+
*transaction_id.expect("transactions must have transaction IDs"),
239+
),
242240
}
243241
}
244242

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use hedera::{
2+
AccountAllowanceApproveTransaction,
3+
Hbar,
4+
TransactionId,
5+
TransferTransaction,
6+
};
7+
8+
use crate::account::Account;
9+
use crate::common::{
10+
setup_nonfree,
11+
TestEnvironment,
12+
};
13+
14+
#[tokio::test]
15+
async fn spend() -> anyhow::Result<()> {
16+
let Some(TestEnvironment { config: _, client }) = setup_nonfree() else {
17+
return Ok(());
18+
};
19+
20+
let (alice, bob) = tokio::try_join!(
21+
Account::create(Hbar::new(10), &client),
22+
Account::create(Hbar::new(10), &client)
23+
)?;
24+
25+
AccountAllowanceApproveTransaction::new()
26+
.approve_hbar_allowance(bob.id, alice.id, Hbar::new(10))
27+
.freeze_with(&client)?
28+
.sign(bob.key.clone())
29+
.execute(&client)
30+
.await?
31+
.get_receipt(&client)
32+
.await?;
33+
34+
let transfer_record = TransferTransaction::new()
35+
.hbar_transfer(client.get_operator_account_id().unwrap(), Hbar::new(5))
36+
.approved_hbar_transfer(bob.id, Hbar::new(-5))
37+
.transaction_id(TransactionId::generate(alice.id))
38+
.freeze_with(&client)?
39+
.sign(alice.key.clone())
40+
.execute(&client)
41+
.await?
42+
.get_record(&client)
43+
.await?;
44+
45+
assert!(transfer_record
46+
.transfers
47+
.iter()
48+
.any(|it| it.account_id == client.get_operator_account_id().unwrap()
49+
&& it.amount == Hbar::new(5)));
50+
51+
let _ = tokio::try_join!(alice.delete(&client), bob.delete(&client))?;
52+
53+
Ok(())
54+
}

tests/e2e/account/balance.rs

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
// todo(network tls):
2+
// - canConnectToPreviewnetWithTLS
3+
// - canConnectToTestnetWithTLS
4+
// - canConnectToMainnetWithTLS
5+
// - cannotConnectToPreviewnetWhenNetworkNameIsNullAndCertificateVerificationIsEnabled
6+
7+
use assert_matches::assert_matches;
8+
use hedera::{
9+
AccountBalanceQuery,
10+
AccountId,
11+
Hbar,
12+
Status,
13+
TokenBurnTransaction,
14+
TokenCreateTransaction,
15+
TokenDeleteTransaction,
16+
};
17+
use time::{
18+
Duration,
19+
OffsetDateTime,
20+
};
21+
22+
use crate::account::Account;
23+
use crate::common::{
24+
setup_global,
25+
setup_nonfree,
26+
TestEnvironment,
27+
};
28+
29+
#[tokio::test]
30+
async fn query() -> anyhow::Result<()> {
31+
let TestEnvironment { config, client } = setup_global();
32+
33+
let Some(op) = &config.operator else {
34+
log::debug!("skipping test due to lack of operator");
35+
36+
return Ok(())
37+
};
38+
39+
let balance = AccountBalanceQuery::new().account_id(op.account_id).execute(&client).await?;
40+
41+
log::trace!("successfully queried balance: {balance:?}");
42+
43+
anyhow::ensure!(balance.account_id == op.account_id);
44+
anyhow::ensure!(balance.hbars.to_tinybars() > 0);
45+
46+
Ok(())
47+
}
48+
49+
#[tokio::test]
50+
async fn query_cost() -> anyhow::Result<()> {
51+
let TestEnvironment { config, client } = setup_global();
52+
53+
let Some(op) = &config.operator else {
54+
log::debug!("skipping test due to lack of operator");
55+
return Ok(())
56+
};
57+
58+
let mut query = AccountBalanceQuery::new();
59+
60+
query.account_id(op.account_id).max_payment_amount(Hbar::new(1));
61+
62+
let cost = query.get_cost(&client).await?;
63+
64+
assert_eq!(cost, Hbar::ZERO);
65+
66+
let balance = query.payment_amount(cost).execute(&client).await?;
67+
68+
anyhow::ensure!(balance.account_id == op.account_id);
69+
anyhow::ensure!(balance.hbars.to_tinybars() > 0);
70+
71+
Ok(())
72+
}
73+
74+
#[tokio::test]
75+
async fn query_cost_big_max() -> anyhow::Result<()> {
76+
let TestEnvironment { config, client } = setup_global();
77+
78+
let Some(op) = &config.operator else {
79+
log::debug!("skipping test due to lack of operator");
80+
return Ok(())
81+
};
82+
83+
let mut query = AccountBalanceQuery::new();
84+
85+
query.account_id(op.account_id).max_payment_amount(Hbar::new(1000000));
86+
87+
let cost = query.get_cost(&client).await?;
88+
89+
assert_eq!(cost, Hbar::ZERO);
90+
91+
let balance = query.payment_amount(cost).execute(&client).await?;
92+
93+
anyhow::ensure!(balance.account_id == op.account_id);
94+
anyhow::ensure!(balance.hbars.to_tinybars() > 0);
95+
96+
Ok(())
97+
}
98+
99+
#[tokio::test]
100+
async fn query_cost_small_max() -> anyhow::Result<()> {
101+
let TestEnvironment { config, client } = setup_global();
102+
103+
let Some(op) = &config.operator else {
104+
log::debug!("skipping test due to lack of operator");
105+
return Ok(())
106+
};
107+
108+
let mut query = AccountBalanceQuery::new();
109+
110+
query.account_id(op.account_id).max_payment_amount(Hbar::from_tinybars(1));
111+
112+
let cost = query.get_cost(&client).await?;
113+
114+
assert_eq!(cost, Hbar::ZERO);
115+
116+
let balance = query.payment_amount(cost).execute(&client).await?;
117+
118+
anyhow::ensure!(balance.account_id == op.account_id);
119+
anyhow::ensure!(balance.hbars.to_tinybars() > 0);
120+
121+
Ok(())
122+
}
123+
124+
#[tokio::test]
125+
async fn invalid_account_id_fails() -> anyhow::Result<()> {
126+
let TestEnvironment { config: _, client } = setup_global();
127+
128+
let res = AccountBalanceQuery::new()
129+
.account_id(AccountId {
130+
shard: 1,
131+
realm: 0,
132+
num: 3,
133+
alias: None,
134+
evm_address: None,
135+
checksum: None,
136+
})
137+
.execute(&client)
138+
.await;
139+
140+
assert_matches!(
141+
res,
142+
Err(hedera::Error::QueryNoPaymentPreCheckStatus { status: Status::InvalidAccountId })
143+
);
144+
145+
Ok(())
146+
}
147+
148+
#[tokio::test]
149+
async fn query_token_balances() -> anyhow::Result<()> {
150+
let Some(TestEnvironment { config: _, client }) = setup_nonfree() else {
151+
return Ok(())
152+
};
153+
154+
let account = Account::create(Hbar::new(10), &client).await?;
155+
156+
let token_id = TokenCreateTransaction::new()
157+
.name("ffff")
158+
.symbol("f")
159+
.initial_supply(10000)
160+
.decimals(50)
161+
.treasury_account_id(account.id)
162+
.expiration_time(OffsetDateTime::now_utc() + Duration::minutes(5))
163+
.admin_key(account.key.public_key())
164+
.supply_key(account.key.public_key())
165+
.freeze_default(false)
166+
.sign(account.key.clone())
167+
.execute(&client)
168+
.await?
169+
.get_receipt(&client)
170+
.await?
171+
.token_id
172+
.unwrap();
173+
174+
let balance = AccountBalanceQuery::new().account_id(account.id).execute(&client).await?;
175+
176+
#[allow(deprecated)]
177+
{
178+
assert_eq!(balance.tokens.get(&token_id).copied(), Some(10000));
179+
assert_eq!(balance.token_decimals.get(&token_id).copied(), Some(50));
180+
}
181+
182+
TokenBurnTransaction::new()
183+
.token_id(token_id)
184+
.amount(10000_u64)
185+
.sign(account.key.clone())
186+
.execute(&client)
187+
.await?
188+
.get_receipt(&client)
189+
.await?;
190+
191+
let _ = TokenDeleteTransaction::new()
192+
.token_id(token_id)
193+
.sign(account.key.clone())
194+
.execute(&client)
195+
.await?
196+
.get_receipt(&client)
197+
.await?;
198+
199+
account.delete(&client).await?;
200+
201+
Ok(())
202+
}

0 commit comments

Comments
 (0)