Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/tests-rs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ jobs:
platform: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install cargo-near
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/latest/download/cargo-near-installer.sh | sh
- name: Install and test modules
run: |
cd ./contract-rs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests-ts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "18"
node-version: "20"
- name: Install and test modules
run: |
cd ./contract-ts
Expand Down
14 changes: 11 additions & 3 deletions contract-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ crate-type = ["cdylib", "rlib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
near-sdk = "5.1.0"
near-sdk = "5.24.0"

[dev-dependencies]
near-sdk = { version = "5.1.0", features = ["unit-testing"] }
near-workspaces = { version = "0.16.0", features = ["unstable"] }
near-sdk = { version = "5.24.0", features = ["unit-testing"] }
near-sandbox = "0.3"
near-api = "0.8"
cargo-near-build = "0.10"
tokio = { version = "1.12.0", features = ["full"] }
serde_json = "1"
testresult = "0.4.1"
# This is temporary fix for the build error since those crates with a higher version require a higher version of Rust compiler (1.88.0)
cargo-platform = "=0.3.1"
darling = "=0.20.11"
bon = "=3.8.1"
home = "=0.5.9"

[profile.release]
codegen-units = 1
Expand Down
4 changes: 2 additions & 2 deletions contract-rs/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
channel = "1.86.0"
components = ["rustfmt", "clippy", "rust-analyzer"]
targets = ["wasm32-unknown-unknown"]
323 changes: 135 additions & 188 deletions contract-rs/tests/sandbox.rs
Original file line number Diff line number Diff line change
@@ -1,195 +1,142 @@
use serde_json::json;

async fn prepare_test_environment() -> Result<(near_workspaces::Account, near_workspaces::Contract), Box<dyn std::error::Error>> {
let worker = near_workspaces::sandbox().await?;
let contract_wasm = near_workspaces::compile_project("./").await?;
let contract = worker.dev_deploy(&contract_wasm).await?;

// create accounts
let account = worker.dev_create_account().await?;

Ok((account, contract))
}
use near_api::{AccountId, NearToken};
use near_sdk::serde_json::json;

#[tokio::test]
async fn test_can_be_incremented() -> Result<(), Box<dyn std::error::Error>> {
let (account, contract) = prepare_test_environment().await?;

let counter_in_zero = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_zero.json::<u8>()?, 0);

let _ = account
.call(contract.id(), "increment")
.args_json(json!({}))
.transact()
.await?;

let _ = account
.call(contract.id(), "decrement")
.args_json(json!({}))
.transact()
.await?;

let _ = account
.call(contract.id(), "increment")
.args_json(json!({}))
.transact()
.await?;

let counter_in_one = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_one.json::<u8>()?, 1);

Ok(())
}

#[tokio::test]
async fn test_can_be_incremented_with_points() -> Result<(), Box<dyn std::error::Error>> {
let (account, contract) = prepare_test_environment().await?;

let counter_in_zero = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_zero.json::<u8>()?, 0);

let _ = account
.call(contract.id(), "increment")
.args_json(json!({"number": 10}))
.transact()
.await?;

let _ = account
.call(contract.id(), "decrement")
.args_json(json!({}))
.transact()
.await?;

let _ = account
.call(contract.id(), "increment")
.args_json(json!({}))
.transact()
.await?;

let counter_in_one = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_one.json::<u8>()?, 10);
async fn test_contract_is_operational() -> Result<(), Box<dyn std::error::Error>> {
// let (user_account, contract, sandbox_network, signer) = prepare_test_environment().await?;

// Build the contract wasm file
let contract_wasm_path = cargo_near_build::build_with_cli(Default::default())?;
let contract_wasm = std::fs::read(contract_wasm_path)?;

// Initialize the sandbox
let sandbox = near_sandbox::Sandbox::start_sandbox().await?;
let sandbox_network =
near_api::NetworkConfig::from_rpc_url("sandbox", sandbox.rpc_addr.parse()?);

let user_account = create_subaccount(&sandbox, "user.sandbox").await.unwrap();
let contract = create_subaccount(&sandbox, "contract.sandbox")
.await
.unwrap()
.as_contract();

let signer = near_api::Signer::from_secret_key(
near_sandbox::config::DEFAULT_GENESIS_ACCOUNT_PRIVATE_KEY
.parse()
.unwrap(),
)?;

near_api::Contract::deploy(contract.account_id().clone())
.use_code(contract_wasm)
.without_init_call()
.with_signer(signer.clone())
.send_to(&sandbox_network)
.await?
.assert_success();

// Test initial counter value
let counter_value: i8 = contract
.call_function("get_num", ())
.read_only()
.fetch_from(&sandbox_network)
.await?
.data;

assert_eq!(counter_value, 0);

// Test decrement by default value (1)
contract
.call_function("decrement", json!({}))
.transaction()
.with_signer(user_account.account_id().clone(), signer.clone())
.send_to(&sandbox_network)
.await?
.assert_success();

let counter_value: i8 = contract
.call_function("get_num", ())
.read_only()
.fetch_from(&sandbox_network)
.await?
.data;

assert_eq!(counter_value, -1);

// Test increment by default value (1)
contract
.call_function("increment", json!({}))
.transaction()
.with_signer(user_account.account_id().clone(), signer.clone())
.send_to(&sandbox_network)
.await?
.assert_success();

let counter_value: i8 = contract
.call_function("get_num", ())
.read_only()
.fetch_from(&sandbox_network)
.await?
.data;

assert_eq!(counter_value, 0);

// Test increment by specific value (10)
contract
.call_function("increment", json!({"number": 10}))
.transaction()
.with_signer(user_account.account_id().clone(), signer.clone())
.send_to(&sandbox_network)
.await?
.assert_success();

// Test decrement by specific value (5)
contract
.call_function("decrement", json!({"number": 5}))
.transaction()
.with_signer(user_account.account_id().clone(), signer.clone())
.send_to(&sandbox_network)
.await?
.assert_success();

let counter_value: i8 = contract
.call_function("get_num", ())
.read_only()
.fetch_from(&sandbox_network)
.await?
.data;

assert_eq!(counter_value, 5);

// Test reset to zero
contract
.call_function("reset", ())
.transaction()
.with_signer(user_account.account_id().clone(), signer.clone())
.send_to(&sandbox_network)
.await?
.assert_success();

let counter_value: i8 = contract
.call_function("get_num", ())
.read_only()
.fetch_from(&sandbox_network)
.await?
.data;

assert_eq!(counter_value, 0);

Ok(())
}

#[tokio::test]
async fn test_can_be_decremented() -> Result<(), Box<dyn std::error::Error>> {

let (account, contract) = prepare_test_environment().await?;
let counter_in_zero = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_zero.json::<u8>()?,0);

let _ = account
.call(contract.id(), "decrement")
.args_json(json!({}))
.transact()
.await?;

let _ = account
.call(contract.id(), "decrement")
.args_json(json!({"number":10}))
.transact()
.await?;


let counter_in_minus_one = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_minus_one.json::<i8>()?,-11);

Ok(())
}

#[tokio::test]
async fn test_can_be_decremented_with_points() -> Result<(), Box<dyn std::error::Error>> {

let (account, contract) = prepare_test_environment().await?;
let counter_in_zero = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_zero.json::<u8>()?,0);

let _ = account
.call(contract.id(), "decrement")
.args_json(json!({}))
.transact()
.await?;

let _ = account
.call(contract.id(), "decrement")
.args_json(json!({}))
.transact()
.await?;


let counter_in_minus_one = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_minus_one.json::<i8>()?,-2);

Ok(())
}

#[tokio::test]
async fn test_can_be_reset() -> Result<(), Box<dyn std::error::Error>> {

let (account, contract) = prepare_test_environment().await?;
let counter_in_zero = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_in_zero.json::<u8>()?,0);

let outcome_increment = account
.call(contract.id(), "increment")
.args_json(json!({}))
.transact()
.await?;

assert!(outcome_increment.is_success());

let outcome_reset = account
.call(contract.id(), "reset")
.args_json(json!({}))
.transact()
.await?;

assert!(outcome_reset.is_success());

let counter_reset = contract
.view("get_num")
.args_json(json!({}))
.await?;

assert_eq!(counter_reset.json::<i8>()?,0);

Ok(())
async fn create_subaccount(
sandbox: &near_sandbox::Sandbox,
name: &str,
) -> testresult::TestResult<near_api::Account> {
let account_id: AccountId = name.parse().unwrap();
sandbox
.create_account(account_id.clone())
.initial_balance(NearToken::from_near(10))
.send()
.await?;
Ok(near_api::Account(account_id))
}