|
1 | | -use chrono::Utc; |
2 | | -use near_sdk::near; |
3 | | -use near_workspaces::types::{AccountId, Gas, NearToken}; |
4 | | -use serde_json::json; |
| 1 | +use near_api::{AccountId, NearGas, NearToken}; |
| 2 | +use near_sdk::serde_json::json; |
5 | 3 |
|
6 | | -#[near(serializers = [json])] |
7 | | -#[derive(Clone)] |
| 4 | +#[derive(near_sdk::serde::Deserialize)] |
| 5 | +#[serde(crate = "near_sdk::serde")] |
8 | 6 | pub struct Bid { |
9 | 7 | pub bidder: AccountId, |
10 | 8 | pub bid: NearToken, |
11 | 9 | } |
12 | 10 |
|
13 | | -const TEN_NEAR: NearToken = NearToken::from_near(10); |
14 | | - |
15 | 11 | #[tokio::test] |
16 | | -async fn test_contract_is_operational() -> Result<(), Box<dyn std::error::Error>> { |
17 | | - let sandbox = near_workspaces::sandbox().await?; |
| 12 | +async fn test_contract_is_operational() -> testresult::TestResult<()> { |
| 13 | + // Build the contract wasm file |
| 14 | + let contract_wasm_path = cargo_near_build::build_with_cli(Default::default())?; |
| 15 | + let contract_wasm = std::fs::read(contract_wasm_path)?; |
18 | 16 |
|
19 | | - let root = sandbox.root_account()?; |
| 17 | + // Initialize the sandbox |
| 18 | + let sandbox = near_sandbox::Sandbox::start_sandbox().await?; |
| 19 | + let sandbox_network = |
| 20 | + near_api::NetworkConfig::from_rpc_url("sandbox", sandbox.rpc_addr.parse()?); |
20 | 21 |
|
21 | 22 | // Create accounts |
22 | | - let alice = create_subaccount(&root, "alice").await?; |
23 | | - let bob = create_subaccount(&root, "bob").await?; |
24 | | - let auctioneer = create_subaccount(&root, "auctioneer").await?; |
25 | | - let contract_account = create_subaccount(&root, "contract").await?; |
26 | | - |
27 | | - // Deploy and initialize contract |
28 | | - let contract_wasm = near_workspaces::compile_project("./").await?; |
29 | | - let contract = contract_account.deploy(&contract_wasm).await?.unwrap(); |
30 | | - |
31 | | - let now = Utc::now().timestamp(); |
| 23 | + let alice = create_subaccount(&sandbox, "alice.sandbox").await?; |
| 24 | + let bob = create_subaccount(&sandbox, "bob.sandbox").await?; |
| 25 | + let auctioneer = create_subaccount(&sandbox, "auctioneer.sandbox").await?; |
| 26 | + let contract = create_subaccount(&sandbox, "contract.sandbox") |
| 27 | + .await? |
| 28 | + .as_contract(); |
| 29 | + |
| 30 | + // Initialize signer for the contract deployment |
| 31 | + let signer = near_api::Signer::from_secret_key( |
| 32 | + near_sandbox::config::DEFAULT_GENESIS_ACCOUNT_PRIVATE_KEY |
| 33 | + .parse() |
| 34 | + .unwrap(), |
| 35 | + )?; |
| 36 | + |
| 37 | + // Calculate the end time for the auction as a parameter for the init function |
| 38 | + let now = std::time::SystemTime::now() |
| 39 | + .duration_since(std::time::SystemTime::UNIX_EPOCH)? |
| 40 | + .as_secs(); |
32 | 41 | let a_minute_from_now = (now + 60) * 1000000000; |
33 | 42 |
|
34 | | - let init = contract |
35 | | - .call("init") |
36 | | - .args_json(json!({"end_time": a_minute_from_now.to_string(),"auctioneer":auctioneer.id()})) |
37 | | - .transact() |
38 | | - .await?; |
39 | | - |
40 | | - assert!(init.is_success()); |
| 43 | + // Deploy the contract with the init call |
| 44 | + near_api::Contract::deploy(contract.account_id().clone()) |
| 45 | + .use_code(contract_wasm) |
| 46 | + .with_init_call( |
| 47 | + "init", |
| 48 | + json!({"end_time": a_minute_from_now.to_string(), "auctioneer": auctioneer.account_id()}), |
| 49 | + )? |
| 50 | + .with_signer(signer.clone()) |
| 51 | + .send_to(&sandbox_network) |
| 52 | + .await? |
| 53 | + .assert_success(); |
41 | 54 |
|
42 | 55 | // Alice makes first bid |
43 | | - let alice_bid = alice |
44 | | - .call(contract.id(), "bid") |
| 56 | + contract |
| 57 | + .call_function("bid", ()) |
| 58 | + .transaction() |
45 | 59 | .deposit(NearToken::from_near(1)) |
46 | | - .transact() |
47 | | - .await?; |
48 | | - |
49 | | - assert!(alice_bid.is_success()); |
| 60 | + .with_signer(alice.account_id().clone(), signer.clone()) |
| 61 | + .send_to(&sandbox_network) |
| 62 | + .await? |
| 63 | + .assert_success(); |
50 | 64 |
|
51 | | - let highest_bid_json = contract.view("get_highest_bid").await?; |
52 | | - let highest_bid: Bid = highest_bid_json.json::<Bid>()?; |
| 65 | + // For now, the highest bid is the Alice's bid |
| 66 | + let highest_bid: Bid = contract |
| 67 | + .call_function("get_highest_bid", ()) |
| 68 | + .read_only() |
| 69 | + .fetch_from(&sandbox_network) |
| 70 | + .await? |
| 71 | + .data; |
53 | 72 | assert_eq!(highest_bid.bid, NearToken::from_near(1)); |
54 | | - assert_eq!(highest_bid.bidder, *alice.id()); |
| 73 | + assert_eq!(&highest_bid.bidder, alice.account_id()); |
55 | 74 |
|
56 | | - let alice_balance = alice.view_account().await?.balance; |
| 75 | + let alice_balance = alice |
| 76 | + .tokens() |
| 77 | + .near_balance() |
| 78 | + .fetch_from(&sandbox_network) |
| 79 | + .await? |
| 80 | + .total; |
57 | 81 |
|
58 | | - // Bob makes a higher bid |
59 | | - let bob_bid = bob |
60 | | - .call(contract.id(), "bid") |
| 82 | + // Now, Bob makes a higher bid |
| 83 | + contract |
| 84 | + .call_function("bid", ()) |
| 85 | + .transaction() |
61 | 86 | .deposit(NearToken::from_near(2)) |
62 | | - .transact() |
63 | | - .await?; |
64 | | - |
65 | | - assert!(bob_bid.is_success()); |
| 87 | + .with_signer(bob.account_id().clone(), signer.clone()) |
| 88 | + .send_to(&sandbox_network) |
| 89 | + .await? |
| 90 | + .assert_success(); |
66 | 91 |
|
67 | | - let highest_bid_json = contract.view("get_highest_bid").await?; |
68 | | - let highest_bid: Bid = highest_bid_json.json::<Bid>()?; |
| 92 | + // Now, the highest bid is the Bob's bid |
| 93 | + let highest_bid: Bid = contract |
| 94 | + .call_function("get_highest_bid", ()) |
| 95 | + .read_only() |
| 96 | + .fetch_from(&sandbox_network) |
| 97 | + .await? |
| 98 | + .data; |
69 | 99 | assert_eq!(highest_bid.bid, NearToken::from_near(2)); |
70 | | - assert_eq!(highest_bid.bidder, *bob.id()); |
| 100 | + assert_eq!(&highest_bid.bidder, bob.account_id()); |
71 | 101 |
|
72 | | - // Check that Alice was returned her bid |
73 | | - let new_alice_balance = alice.view_account().await?.balance; |
| 102 | + // Check that Alice was refunded her bid |
| 103 | + let new_alice_balance = alice |
| 104 | + .tokens() |
| 105 | + .near_balance() |
| 106 | + .fetch_from(&sandbox_network) |
| 107 | + .await? |
| 108 | + .total; |
74 | 109 | assert!(new_alice_balance == alice_balance.saturating_add(NearToken::from_near(1))); |
75 | 110 |
|
76 | 111 | // Alice tries to make a bid with less NEAR than the previous |
77 | | - let alice_bid = alice |
78 | | - .call(contract.id(), "bid") |
| 112 | + contract |
| 113 | + .call_function("bid", ()) |
| 114 | + .transaction() |
79 | 115 | .deposit(NearToken::from_near(1)) |
80 | | - .transact() |
81 | | - .await?; |
82 | | - |
83 | | - assert!(alice_bid.is_failure()); |
| 116 | + .with_signer(alice.account_id().clone(), signer.clone()) |
| 117 | + .send_to(&sandbox_network) |
| 118 | + .await? |
| 119 | + .assert_failure(); |
84 | 120 |
|
85 | 121 | // Auctioneer claims auction but did not finish |
86 | | - let auctioneer_claim = auctioneer |
87 | | - .call(contract_account.id(), "claim") |
88 | | - .args_json(json!({})) |
89 | | - .gas(Gas::from_tgas(300)) |
90 | | - .transact() |
91 | | - .await?; |
92 | | - |
93 | | - assert!(auctioneer_claim.is_failure()); |
| 122 | + contract |
| 123 | + .call_function("claim", ()) |
| 124 | + .transaction() |
| 125 | + .gas(NearGas::from_tgas(30)) |
| 126 | + .with_signer(auctioneer.account_id().clone(), signer.clone()) |
| 127 | + .send_to(&sandbox_network) |
| 128 | + .await? |
| 129 | + .assert_failure(); |
94 | 130 |
|
95 | 131 | // Fast forward 200 blocks |
96 | 132 | let blocks_to_advance = 200; |
97 | 133 | sandbox.fast_forward(blocks_to_advance).await?; |
98 | 134 |
|
99 | 135 | // Auctioneer claims the auction |
100 | | - let auctioneer_claim = auctioneer |
101 | | - .call(contract_account.id(), "claim") |
102 | | - .args_json(json!({})) |
103 | | - .gas(Gas::from_tgas(300)) |
104 | | - .transact() |
105 | | - .await?; |
106 | | - |
107 | | - assert!(auctioneer_claim.is_success()); |
| 136 | + contract |
| 137 | + .call_function("claim", ()) |
| 138 | + .transaction() |
| 139 | + .gas(NearGas::from_tgas(30)) |
| 140 | + .with_signer(auctioneer.account_id().clone(), signer.clone()) |
| 141 | + .send_to(&sandbox_network) |
| 142 | + .await? |
| 143 | + .assert_success(); |
108 | 144 |
|
109 | 145 | // Checks the auctioneer has the correct balance |
110 | | - let auctioneer_balance = auctioneer.view_account().await?.balance; |
| 146 | + let auctioneer_balance = auctioneer |
| 147 | + .tokens() |
| 148 | + .near_balance() |
| 149 | + .fetch_from(&sandbox_network) |
| 150 | + .await? |
| 151 | + .total; |
111 | 152 | assert!(auctioneer_balance <= NearToken::from_near(12)); |
112 | 153 | assert!(auctioneer_balance > NearToken::from_millinear(11990)); |
113 | 154 |
|
114 | 155 | // Auctioneer tries to claim the auction again |
115 | | - let auctioneer_claim = auctioneer |
116 | | - .call(contract_account.id(), "claim") |
117 | | - .args_json(json!({})) |
118 | | - .gas(Gas::from_tgas(300)) |
119 | | - .transact() |
120 | | - .await?; |
121 | | - |
122 | | - assert!(auctioneer_claim.is_failure()); |
| 156 | + contract |
| 157 | + .call_function("claim", ()) |
| 158 | + .transaction() |
| 159 | + .gas(NearGas::from_tgas(30)) |
| 160 | + .with_signer(auctioneer.account_id().clone(), signer.clone()) |
| 161 | + .send_to(&sandbox_network) |
| 162 | + .await? |
| 163 | + .assert_failure(); |
123 | 164 |
|
124 | 165 | // Alice tries to make a bid when the auction is over |
125 | | - let alice_bid = alice |
126 | | - .call(contract.id(), "bid") |
127 | | - .deposit(NearToken::from_near(3)) |
128 | | - .transact() |
129 | | - .await?; |
130 | | - |
131 | | - assert!(alice_bid.is_failure()); |
| 166 | + contract |
| 167 | + .call_function("bid", ()) |
| 168 | + .transaction() |
| 169 | + .deposit(NearToken::from_near(1)) |
| 170 | + .with_signer(alice.account_id().clone(), signer.clone()) |
| 171 | + .send_to(&sandbox_network) |
| 172 | + .await? |
| 173 | + .assert_failure(); |
132 | 174 |
|
133 | 175 | Ok(()) |
134 | 176 | } |
135 | 177 |
|
136 | 178 | async fn create_subaccount( |
137 | | - root: &near_workspaces::Account, |
| 179 | + sandbox: &near_sandbox::Sandbox, |
138 | 180 | name: &str, |
139 | | -) -> Result<near_workspaces::Account, Box<dyn std::error::Error>> { |
140 | | - let subaccount = root |
141 | | - .create_subaccount(name) |
142 | | - .initial_balance(TEN_NEAR) |
143 | | - .transact() |
144 | | - .await? |
145 | | - .unwrap(); |
146 | | - |
147 | | - Ok(subaccount) |
| 181 | +) -> testresult::TestResult<near_api::Account> { |
| 182 | + let account_id: AccountId = name.parse().unwrap(); |
| 183 | + sandbox |
| 184 | + .create_account(account_id.clone()) |
| 185 | + .initial_balance(NearToken::from_near(10)) |
| 186 | + .send() |
| 187 | + .await?; |
| 188 | + Ok(near_api::Account(account_id)) |
148 | 189 | } |
0 commit comments