Skip to content

Commit 831ca0d

Browse files
authored
test(erc721): add unit tests (OpenZeppelin#142)
Resolves OpenZeppelin#69
1 parent 2c9a3bd commit 831ca0d

File tree

15 files changed

+1485
-91
lines changed

15 files changed

+1485
-91
lines changed

contracts/src/access/control.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -384,11 +384,8 @@ impl AccessControl {
384384

385385
#[cfg(all(test, feature = "std"))]
386386
mod tests {
387-
use alloy_primitives::{address, Address, U256};
388-
use stylus_sdk::{
389-
msg,
390-
storage::{StorageMap, StorageType},
391-
};
387+
use alloy_primitives::{address, Address};
388+
use stylus_sdk::msg;
392389

393390
use super::{AccessControl, Error};
394391

contracts/src/token/erc20/extensions/capped.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ impl Capped {
5454

5555
#[cfg(all(test, feature = "std"))]
5656
mod tests {
57-
use alloy_primitives::{uint, U256};
58-
use stylus_sdk::storage::{StorageType, StorageU256};
57+
use alloy_primitives::uint;
5958

6059
use super::Capped;
6160

contracts/src/token/erc20/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ impl Erc20 {
499499
#[cfg(all(test, feature = "std"))]
500500
mod tests {
501501
use alloy_primitives::{address, uint, Address, U256};
502-
use stylus_sdk::{msg, storage::StorageType};
502+
use stylus_sdk::msg;
503503

504504
use super::{Erc20, Error, IErc20};
505505

contracts/src/token/erc721/extensions/burnable.rs

+110-17
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ mod tests {
5252

5353
use super::IErc721Burnable;
5454
use crate::token::erc721::{
55-
tests::random_token_id, Erc721, Error, IErc721,
55+
tests::random_token_id, ERC721InsufficientApproval,
56+
ERC721NonexistentToken, Erc721, Error, IErc721,
5657
};
5758

5859
const BOB: Address = address!("F4EaCDAbEf3c8f1EdE91b6f2A6840bc2E4DD3526");
@@ -70,21 +71,94 @@ mod tests {
7071
.expect("should return the balance of Alice");
7172

7273
let result = contract.burn(token_id);
74+
assert!(result.is_ok());
75+
7376
let balance = contract
7477
.balance_of(alice)
7578
.expect("should return the balance of Alice");
7679

77-
let err = contract.owner_of(token_id).unwrap_err();
80+
assert_eq!(initial_balance - one, balance);
81+
82+
let err = contract
83+
.owner_of(token_id)
84+
.expect_err("should return Error::NonexistentToken");
85+
86+
assert!(matches!(
87+
err,
88+
Error::NonexistentToken (ERC721NonexistentToken{
89+
token_id: t_id
90+
}) if t_id == token_id
91+
));
92+
}
93+
94+
#[motsu::test]
95+
fn burns_with_approval(contract: Erc721) {
96+
let alice = msg::sender();
97+
let token_id = random_token_id();
98+
99+
contract._mint(BOB, token_id).expect("should mint a token for Bob");
100+
101+
let initial_balance =
102+
contract.balance_of(BOB).expect("should return the balance of Bob");
78103

79-
assert!(matches!(err, Error::NonexistentToken(_)));
104+
contract._token_approvals.setter(token_id).set(alice);
80105

106+
let result = contract.burn(token_id);
81107
assert!(result.is_ok());
82108

83-
assert_eq!(initial_balance - one, balance);
109+
let err = contract
110+
.owner_of(token_id)
111+
.expect_err("should return Error::NonexistentToken");
112+
113+
assert!(matches!(
114+
err,
115+
Error::NonexistentToken (ERC721NonexistentToken{
116+
token_id: t_id
117+
}) if t_id == token_id
118+
));
119+
120+
let balance =
121+
contract.balance_of(BOB).expect("should return the balance of Bob");
122+
123+
assert_eq!(initial_balance - uint!(1_U256), balance);
84124
}
85125

86126
#[motsu::test]
87-
fn get_approved_errors_when_previous_approval_burned(contract: Erc721) {
127+
fn burns_with_approval_for_all(contract: Erc721) {
128+
let alice = msg::sender();
129+
let token_id = random_token_id();
130+
131+
contract._mint(BOB, token_id).expect("should mint a token for Bob");
132+
133+
let initial_balance =
134+
contract.balance_of(BOB).expect("should return the balance of Bob");
135+
136+
// As we cannot change `msg::sender()`, we need to use this workaround.
137+
contract._operator_approvals.setter(BOB).setter(alice).set(true);
138+
139+
let result = contract.burn(token_id);
140+
141+
assert!(result.is_ok());
142+
143+
let err = contract
144+
.owner_of(token_id)
145+
.expect_err("should return Error::NonexistentToken");
146+
147+
assert!(matches!(
148+
err,
149+
Error::NonexistentToken (ERC721NonexistentToken{
150+
token_id: t_id
151+
}) if t_id == token_id
152+
));
153+
154+
let balance =
155+
contract.balance_of(BOB).expect("should return the balance of Bob");
156+
157+
assert_eq!(initial_balance - uint!(1_U256), balance);
158+
}
159+
160+
#[motsu::test]
161+
fn error_when_get_approved_of_previous_approval_burned(contract: Erc721) {
88162
let alice = msg::sender();
89163
let token_id = random_token_id();
90164

@@ -95,31 +169,50 @@ mod tests {
95169

96170
contract.burn(token_id).expect("should burn previously minted token");
97171

98-
let err = contract.get_approved(token_id).unwrap_err();
172+
let err = contract
173+
.get_approved(token_id)
174+
.expect_err("should return Error::NonexistentToken");
99175

100-
assert!(matches!(err, Error::NonexistentToken(_)));
176+
assert!(matches!(
177+
err,
178+
Error::NonexistentToken (ERC721NonexistentToken{
179+
token_id: t_id
180+
}) if t_id == token_id
181+
));
101182
}
102183

103184
#[motsu::test]
104-
fn burn_errors_when_no_previous_approval(contract: Erc721) {
185+
fn error_when_burn_without_approval(contract: Erc721) {
105186
let token_id = random_token_id();
106187

107188
contract._mint(BOB, token_id).expect("should mint a token for Bob");
108189

109-
let err = contract.burn(token_id).unwrap_err();
110-
111-
assert!(matches!(err, Error::InsufficientApproval(_)));
190+
let err = contract
191+
.burn(token_id)
192+
.expect_err("should not burn unapproved token");
193+
194+
assert!(matches!(
195+
err,
196+
Error::InsufficientApproval(ERC721InsufficientApproval {
197+
operator,
198+
token_id: t_id,
199+
}) if operator == msg::sender() && t_id == token_id
200+
));
112201
}
113202

114203
#[motsu::test]
115-
fn burn_errors_when_unknown_token(contract: Erc721) {
116-
let alice = msg::sender();
204+
fn error_when_burn_nonexistent_token(contract: Erc721) {
117205
let token_id = random_token_id();
118206

119-
contract._mint(alice, token_id).expect("should mint a token for Alice");
120-
121-
let err = contract.burn(token_id + uint!(1_U256)).unwrap_err();
207+
let err = contract
208+
.burn(token_id)
209+
.expect_err("should return Error::NonexistentToken");
122210

123-
assert!(matches!(err, Error::NonexistentToken(_)));
211+
assert!(matches!(
212+
err,
213+
Error::NonexistentToken (ERC721NonexistentToken{
214+
token_id: t_id
215+
}) if t_id == token_id
216+
));
124217
}
125218
}

contracts/src/token/erc721/extensions/enumerable.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,7 @@ impl Erc721Enumerable {
309309
#[cfg(all(test, feature = "std"))]
310310
mod tests {
311311
use alloy_primitives::{address, uint, Address, U256};
312-
use stylus_sdk::{
313-
msg,
314-
prelude::StorageType,
315-
storage::{StorageMap, StorageVec},
316-
};
312+
use stylus_sdk::msg;
317313

318314
use super::{Erc721Enumerable, Error, IErc721Enumerable};
319315
use crate::token::erc721::{tests::random_token_id, Erc721, IErc721};
@@ -326,9 +322,7 @@ mod tests {
326322
}
327323

328324
#[motsu::test]
329-
fn token_by_index_errors_when_index_out_of_bound(
330-
contract: Erc721Enumerable,
331-
) {
325+
fn error_when_token_by_index_is_out_of_bound(contract: Erc721Enumerable) {
332326
assert_eq!(U256::ZERO, contract.total_supply());
333327

334328
let token_idx = uint!(2024_U256);
@@ -453,7 +447,9 @@ mod tests {
453447
}
454448

455449
#[motsu::test]
456-
fn token_of_owner_errors_index_out_of_bound(contract: Erc721Enumerable) {
450+
fn error_when_token_of_owner_for_index_out_of_bound(
451+
contract: Erc721Enumerable,
452+
) {
457453
let alice = msg::sender();
458454
let mut erc721 = Erc721::default();
459455
assert_eq!(
@@ -478,7 +474,7 @@ mod tests {
478474
}
479475

480476
#[motsu::test]
481-
fn token_of_owner_errors_owner_does_not_own_any_token(
477+
fn error_when_token_of_owner_does_not_own_any_token(
482478
contract: Erc721Enumerable,
483479
) {
484480
let erc721 = Erc721::default();

contracts/src/token/erc721/extensions/uri_storage.rs

-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ impl Erc721UriStorage {
6666
#[cfg(all(test, feature = "std"))]
6767
mod tests {
6868
use alloy_primitives::U256;
69-
use stylus_sdk::{prelude::StorageType, storage::StorageMap};
7069

7170
use super::Erc721UriStorage;
7271

0 commit comments

Comments
 (0)