Skip to content

Commit 67f2aa3

Browse files
authored
Merge pull request #565 from hashgraph/sr/more-e2e-tests
2 parents a3204cd + 058642d commit 67f2aa3

File tree

21 files changed

+3661
-13
lines changed

21 files changed

+3661
-13
lines changed

src/token/custom_fees/mod.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,22 @@ pub struct CustomFee<Fee> {
6363
/// The account to receive the custom fee.
6464
pub fee_collector_account_id: Option<AccountId>,
6565

66+
/// If true, fee fcollectors are not charged this fee for transfers.
6667
pub all_collectors_are_exempt: bool,
6768
}
6869

6970
impl AnyCustomFee {
71+
/// Create `AnyCustomFee` from protobuf-encoded `bytes`.
72+
///
73+
/// # Errors
74+
/// - [`Error::FromProtobuf`](crate::Error::FromProtobuf) if decoding the bytes fails to produce a valid protobuf.
75+
/// - [`Error::FromProtobuf`](crate::Error::FromProtobuf) if decoding the protobuf fails.
7076
pub fn from_bytes(bytes: &[u8]) -> crate::Result<Self> {
7177
FromProtobuf::from_bytes(bytes)
7278
}
7379

80+
/// Convert `self` to a protobuf-encoded [`Vec<u8>`].
81+
#[must_use]
7482
pub fn to_bytes(&self) -> Vec<u8> {
7583
ToProtobuf::to_bytes(self)
7684
}
@@ -206,30 +214,26 @@ pub struct FixedFeeData {
206214

207215
/// The denomination of the fee; taken as hbar if left unset and, in a TokenCreate, taken as the id
208216
/// of the newly created token if set to the sentinel value of 0.0.0
209-
pub denominating_token_id: TokenId,
217+
pub denominating_token_id: Option<TokenId>,
210218
}
211219

212220
impl FixedFeeData {
213221
#[must_use]
214222
pub fn from_hbar(amount: Hbar) -> Self {
215-
Self {
216-
amount: amount.to_tinybars(),
217-
denominating_token_id: TokenId { shard: 0, realm: 0, num: 0, checksum: None },
218-
}
223+
Self { amount: amount.to_tinybars(), denominating_token_id: None }
219224
}
220225

221226
#[must_use]
222227
pub fn get_hbar(&self) -> Option<Hbar> {
223-
(self.denominating_token_id == TokenId { shard: 0, realm: 0, num: 0, checksum: None })
224-
.then(|| Hbar::from_tinybars(self.amount))
228+
self.denominating_token_id.is_none().then(|| Hbar::from_tinybars(self.amount))
225229
}
226230
}
227231

228232
impl FromProtobuf<services::FixedFee> for FixedFeeData {
229233
fn from_protobuf(pb: services::FixedFee) -> crate::Result<Self> {
230234
Ok(Self {
231235
amount: pb.amount,
232-
denominating_token_id: TokenId::from_protobuf(pb_getf!(pb, denominating_token_id)?)?,
236+
denominating_token_id: Option::from_protobuf(pb.denominating_token_id)?,
233237
})
234238
}
235239
}
@@ -240,7 +244,7 @@ impl ToProtobuf for FixedFeeData {
240244
fn to_protobuf(&self) -> Self::Protobuf {
241245
Self::Protobuf {
242246
amount: self.amount,
243-
denominating_token_id: Some(self.denominating_token_id.to_protobuf()),
247+
denominating_token_id: self.denominating_token_id.to_protobuf(),
244248
}
245249
}
246250
}

src/token/custom_fees/tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
fn custom_fee_can_convert_to_protobuf() -> anyhow::Result<()> {
2121
let custom_fee = AnyCustomFee {
2222
fee_collector_account_id: Some(AccountId::from(1)),
23-
fee: FixedFeeData { denominating_token_id: TokenId::from(2), amount: 1000 }.into(),
23+
fee: FixedFeeData { denominating_token_id: Some(TokenId::from(2)), amount: 1000 }.into(),
2424
all_collectors_are_exempt: true,
2525
};
2626

@@ -61,7 +61,7 @@ fn custom_fixed_fee_can_be_created_from_protobuf() -> anyhow::Result<()> {
6161
#[test]
6262
fn fee_can_convert_to_protobuf() -> anyhow::Result<()> {
6363
let amount = 1000;
64-
let fee = Fee::Fixed(FixedFeeData { amount, denominating_token_id: TokenId::from(1) });
64+
let fee = Fee::Fixed(FixedFeeData { amount, denominating_token_id: Some(TokenId::from(1)) });
6565

6666
let fee_proto = fee.to_protobuf();
6767

@@ -98,7 +98,7 @@ fn fee_can_be_created_from_protobuf() -> anyhow::Result<()> {
9898
#[test]
9999
fn fixed_fee_can_convert_to_protobuf() -> anyhow::Result<()> {
100100
let amount = 1000;
101-
let fixed_fee = FixedFeeData { amount, denominating_token_id: TokenId::from(2) };
101+
let fixed_fee = FixedFeeData { amount, denominating_token_id: Some(TokenId::from(2)) };
102102

103103
let fixed_fee_proto = fixed_fee.to_protobuf();
104104

@@ -169,7 +169,7 @@ fn fractional_fee_can_be_created_from_protobuf() -> anyhow::Result<()> {
169169

170170
#[test]
171171
fn royalty_fee_can_convert_to_protobuf() -> anyhow::Result<()> {
172-
let fallback_fee = FixedFeeData { denominating_token_id: TokenId::from(1), amount: 1000 };
172+
let fallback_fee = FixedFeeData { denominating_token_id: Some(TokenId::from(1)), amount: 1000 };
173173
let exchange_value_fraction: Fraction = (1, 2).into();
174174

175175
let royalty_fee =

tests/e2e/account/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use hedera::{
1111
PrivateKey,
1212
};
1313

14+
#[derive(Clone)]
1415
pub struct Account {
1516
pub key: PrivateKey,
1617
pub id: AccountId,

tests/e2e/token/associate.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use assert_matches::assert_matches;
2+
use hedera::{
3+
Hbar,
4+
Status,
5+
TokenAssociateTransaction,
6+
};
7+
8+
use crate::account::Account;
9+
use crate::common::{
10+
setup_nonfree,
11+
TestEnvironment,
12+
};
13+
14+
#[tokio::test]
15+
async fn basic() -> 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(0), &client),
22+
Account::create(Hbar::new(0), &client)
23+
)?;
24+
25+
let token = super::FungibleToken::create(&client, &alice, 0).await?;
26+
27+
TokenAssociateTransaction::new()
28+
.account_id(bob.id)
29+
.token_ids([token.id])
30+
.freeze_with(&client)?
31+
.sign(bob.key.clone())
32+
.execute(&client)
33+
.await?
34+
.get_receipt(&client)
35+
.await?;
36+
37+
token.delete(&client).await?;
38+
39+
tokio::try_join!(alice.delete(&client), bob.delete(&client))?;
40+
41+
Ok(())
42+
}
43+
44+
#[tokio::test]
45+
async fn missing_token_id() -> anyhow::Result<()> {
46+
let Some(TestEnvironment { config, client }) = setup_nonfree() else {
47+
return Ok(())
48+
};
49+
50+
let Some(op) = &config.operator else {
51+
log::debug!("skipping test due to lack of operator");
52+
return Ok(())
53+
};
54+
55+
TokenAssociateTransaction::new()
56+
.account_id(op.account_id)
57+
.freeze_with(&client)?
58+
.execute(&client)
59+
.await?
60+
.get_receipt(&client)
61+
.await?;
62+
63+
Ok(())
64+
}
65+
66+
#[tokio::test]
67+
async fn missing_account_id_fails() -> anyhow::Result<()> {
68+
let Some(TestEnvironment { config: _, client }) = setup_nonfree() else {
69+
return Ok(())
70+
};
71+
72+
let res = TokenAssociateTransaction::new().execute(&client).await;
73+
74+
assert_matches!(
75+
res,
76+
Err(hedera::Error::TransactionPreCheckStatus {
77+
status: Status::InvalidAccountId,
78+
transaction_id: _
79+
})
80+
);
81+
82+
Ok(())
83+
}
84+
85+
#[tokio::test]
86+
async fn missing_signature_fails() -> anyhow::Result<()> {
87+
let Some(TestEnvironment { config: _, client }) = setup_nonfree() else {
88+
return Ok(())
89+
};
90+
91+
let account = Account::create(Hbar::new(0), &client).await?;
92+
93+
let res = TokenAssociateTransaction::new()
94+
.account_id(account.id)
95+
.freeze_with(&client)?
96+
.execute(&client)
97+
.await?
98+
.get_receipt(&client)
99+
.await;
100+
101+
assert_matches!(
102+
res,
103+
Err(hedera::Error::ReceiptStatus { status: Status::InvalidSignature, transaction_id: _ })
104+
);
105+
106+
account.delete(&client).await?;
107+
108+
Ok(())
109+
}

0 commit comments

Comments
 (0)