diff --git a/.github/workflows/tests-rs.yml b/.github/workflows/tests-rs.yml index 2c58700..96e34ad 100644 --- a/.github/workflows/tests-rs.yml +++ b/.github/workflows/tests-rs.yml @@ -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 diff --git a/.github/workflows/tests-ts.yml b/.github/workflows/tests-ts.yml index d070592..a06b46b 100644 --- a/.github/workflows/tests-ts.yml +++ b/.github/workflows/tests-ts.yml @@ -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 diff --git a/contract-rs/Cargo.toml b/contract-rs/Cargo.toml index 9a984b6..85e5a91 100644 --- a/contract-rs/Cargo.toml +++ b/contract-rs/Cargo.toml @@ -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 diff --git a/contract-rs/rust-toolchain.toml b/contract-rs/rust-toolchain.toml index a82ade3..5ff54e3 100644 --- a/contract-rs/rust-toolchain.toml +++ b/contract-rs/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "stable" -components = ["rustfmt"] +channel = "1.86.0" +components = ["rustfmt", "clippy", "rust-analyzer"] targets = ["wasm32-unknown-unknown"] diff --git a/contract-rs/tests/sandbox.rs b/contract-rs/tests/sandbox.rs index 6bc5a58..85cabfa 100644 --- a/contract-rs/tests/sandbox.rs +++ b/contract-rs/tests/sandbox.rs @@ -1,195 +1,142 @@ -use serde_json::json; - -async fn prepare_test_environment() -> Result<(near_workspaces::Account, near_workspaces::Contract), Box> { - 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> { - 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::()?, 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::()?, 1); - - Ok(()) -} - -#[tokio::test] -async fn test_can_be_incremented_with_points() -> Result<(), Box> { - 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::()?, 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::()?, 10); +async fn test_contract_is_operational() -> Result<(), Box> { + // 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> { - - 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::()?,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::()?,-11); - - Ok(()) -} - -#[tokio::test] -async fn test_can_be_decremented_with_points() -> Result<(), Box> { - - 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::()?,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::()?,-2); - - Ok(()) -} - -#[tokio::test] -async fn test_can_be_reset() -> Result<(), Box> { - - 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::()?,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::()?,0); - - Ok(()) +async fn create_subaccount( + sandbox: &near_sandbox::Sandbox, + name: &str, +) -> testresult::TestResult { + 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)) }