diff --git a/Cargo.lock b/Cargo.lock index bccf218e5..bfd3f5f5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + [[package]] name = "autocfg" version = "1.0.1" @@ -238,8 +244,8 @@ name = "cw-controllers" version = "0.8.1" dependencies = [ "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "schemars", "serde", "thiserror", @@ -252,8 +258,8 @@ dependencies = [ "anyhow", "cosmwasm-std", "cosmwasm-storage", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "derivative", "itertools", "prost", @@ -262,6 +268,24 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw-multi-test" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecca04ea07d99e8cb7031c58ec5a7d8f581d597621353f1ecbee9e2829169d27" +dependencies = [ + "anyhow", + "cosmwasm-std", + "cosmwasm-storage", + "cw-storage-plus 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cw0 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools", + "prost", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "cw-storage-plus" version = "0.8.1" @@ -271,12 +295,35 @@ dependencies = [ "serde", ] +[[package]] +name = "cw-storage-plus" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e867b9972b83b32e00e878dfbff48299ba26618dabeb19b9c56fae176dc225" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw0" +version = "0.8.1" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus 0.8.1", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "cw0" version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c497f885a40918a02df7d938c81809965fa05cfc21b3dc591e9950237b5de0a9" dependencies = [ "cosmwasm-std", - "cw-storage-plus", "schemars", "serde", "thiserror", @@ -298,8 +345,8 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw1", "cw1-whitelist", "cw2", @@ -312,12 +359,16 @@ dependencies = [ name = "cw1-whitelist" version = "0.8.1" dependencies = [ + "anyhow", + "assert_matches", "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-multi-test 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw1", "cw2", + "derivative", "schemars", "serde", "thiserror", @@ -329,7 +380,7 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw0", + "cw0 0.8.1", "schemars", "serde", ] @@ -340,8 +391,8 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw1155", "cw2", "schemars", @@ -354,7 +405,7 @@ name = "cw2" version = "0.8.1" dependencies = [ "cosmwasm-std", - "cw-storage-plus", + "cw-storage-plus 0.8.1", "schemars", "serde", ] @@ -365,7 +416,7 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw0", + "cw0 0.8.1", "schemars", "serde", ] @@ -376,8 +427,8 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "hex 0.3.2", @@ -393,8 +444,8 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "schemars", @@ -408,8 +459,8 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "cw20-base", @@ -427,9 +478,9 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw0", + "cw-multi-test 0.8.1", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "cw20-base", @@ -444,8 +495,8 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "schemars", @@ -459,8 +510,8 @@ version = "0.7.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "hex 0.4.3", @@ -478,8 +529,8 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "cw20-base", @@ -494,7 +545,7 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw0", + "cw0 0.8.1", "schemars", "serde", ] @@ -505,9 +556,9 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw0", + "cw-multi-test 0.8.1", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "cw20-base", @@ -523,9 +574,9 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus", - "cw0", + "cw-multi-test 0.8.1", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw3", "cw4", @@ -552,8 +603,8 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw4", "schemars", @@ -568,8 +619,8 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-controllers", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw20", "cw4", @@ -584,7 +635,7 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw0", + "cw0 0.8.1", "schemars", "serde", ] @@ -595,8 +646,8 @@ version = "0.8.1" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus", - "cw0", + "cw-storage-plus 0.8.1", + "cw0 0.8.1", "cw2", "cw721", "schemars", diff --git a/contracts/cw1-whitelist/Cargo.toml b/contracts/cw1-whitelist/Cargo.toml index 0bc76e2bd..ad95d50d8 100644 --- a/contracts/cw1-whitelist/Cargo.toml +++ b/contracts/cw1-whitelist/Cargo.toml @@ -29,4 +29,8 @@ serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } [dev-dependencies] +anyhow = "1" +assert_matches = "1" cosmwasm-schema = { version = "0.16.0" } +cw-multi-test = "0.8.1" +derivative = "2" diff --git a/contracts/cw1-whitelist/src/integration_tests.rs b/contracts/cw1-whitelist/src/integration_tests.rs new file mode 100644 index 000000000..91265c7aa --- /dev/null +++ b/contracts/cw1-whitelist/src/integration_tests.rs @@ -0,0 +1,128 @@ +use crate::msg::{AdminListResponse, ExecuteMsg, InstantiateMsg, QueryMsg}; +use anyhow::{anyhow, Result}; +use assert_matches::assert_matches; +use cosmwasm_std::testing::{mock_env, MockApi, MockStorage}; +use cosmwasm_std::{to_binary, Addr, CosmosMsg, Empty, QueryRequest, StdError, WasmMsg, WasmQuery}; +use cw1::Cw1Contract; +use cw_multi_test::{App, AppResponse, BankKeeper, Contract, ContractWrapper, Executor}; +use derivative::Derivative; +use serde::{de::DeserializeOwned, Serialize}; + +fn mock_app() -> App { + let env = mock_env(); + let api = MockApi::default(); + let bank = BankKeeper::new(); + let storage = MockStorage::new(); + + App::new(api, env.block, bank, storage) +} + +fn contract_cw1() -> Box> { + let contract = ContractWrapper::new( + crate::contract::execute, + crate::contract::instantiate, + crate::contract::query, + ); + Box::new(contract) +} + +#[derive(Derivative)] +#[derivative(Debug)] +pub struct Suite { + /// Application mock + #[derivative(Debug = "ignore")] + app: App, + /// Special account + pub owner: String, + /// ID of stored code for cw1 contract + cw1_id: u64, +} + +impl Suite { + pub fn init() -> Result { + let mut app = mock_app(); + let owner = "owner".to_owned(); + let cw1_id = app.store_code(contract_cw1()); + + Ok(Suite { app, owner, cw1_id }) + } + + pub fn instantiate_cw1_contract(&mut self, admins: Vec, mutable: bool) -> Cw1Contract { + let contract = self + .app + .instantiate_contract( + self.cw1_id, + Addr::unchecked(self.owner.clone()), + &InstantiateMsg { admins, mutable }, + &[], + "Whitelist", + None, + ) + .unwrap(); + Cw1Contract(contract) + } + + pub fn execute( + &mut self, + sender_contract: Addr, + target_contract: &Addr, + msg: M, + ) -> Result + where + M: Serialize + DeserializeOwned, + { + let execute: ExecuteMsg = ExecuteMsg::Execute { + msgs: vec![CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: target_contract.to_string(), + msg: to_binary(&msg)?, + funds: vec![], + })], + }; + self.app + .execute_contract( + Addr::unchecked(self.owner.clone()), + sender_contract, + &execute, + &[], + ) + .map_err(|err| anyhow!(err)) + } + + pub fn query(&self, target_contract: Addr, msg: M) -> Result + where + M: Serialize + DeserializeOwned, + { + self.app.wrap().query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: target_contract.to_string(), + msg: to_binary(&msg).unwrap(), + })) + } +} + +#[test] +fn proxy_freeze_message() { + let mut suite = Suite::init().unwrap(); + + let first_contract = suite.instantiate_cw1_contract(vec![suite.owner.clone()], true); + let second_contract = + suite.instantiate_cw1_contract(vec![first_contract.addr().to_string()], true); + assert_ne!(second_contract, first_contract); + + let freeze_msg: ExecuteMsg = ExecuteMsg::Freeze {}; + assert_matches!( + suite.execute(first_contract.addr(), &second_contract.addr(), freeze_msg), + Ok(_) + ); + + let query_msg: QueryMsg = QueryMsg::AdminList {}; + assert_matches!( + suite.query(second_contract.addr(), query_msg), + Ok( + AdminListResponse { + mutable, + .. + }) => { + assert!(!mutable) + } + ); +} diff --git a/contracts/cw1-whitelist/src/lib.rs b/contracts/cw1-whitelist/src/lib.rs index e5ff7237e..83686a729 100644 --- a/contracts/cw1-whitelist/src/lib.rs +++ b/contracts/cw1-whitelist/src/lib.rs @@ -1,5 +1,7 @@ pub mod contract; pub mod error; +#[cfg(test)] +mod integration_tests; pub mod msg; pub mod state; diff --git a/contracts/cw721-base/src/contract.rs b/contracts/cw721-base/src/contract.rs index f2be6b800..8ceefee81 100644 --- a/contracts/cw721-base/src/contract.rs +++ b/contracts/cw721-base/src/contract.rs @@ -388,23 +388,23 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { } } -fn query_minter(deps: Deps) -> StdResult { +pub fn query_minter(deps: Deps) -> StdResult { let minter_addr = MINTER.load(deps.storage)?; Ok(MinterResponse { minter: minter_addr.to_string(), }) } -fn query_contract_info(deps: Deps) -> StdResult { +pub fn query_contract_info(deps: Deps) -> StdResult { CONTRACT_INFO.load(deps.storage) } -fn query_num_tokens(deps: Deps) -> StdResult { +pub fn query_num_tokens(deps: Deps) -> StdResult { let count = num_tokens(deps.storage)?; Ok(NumTokensResponse { count }) } -fn query_nft_info(deps: Deps, token_id: String) -> StdResult { +pub fn query_nft_info(deps: Deps, token_id: String) -> StdResult { let info = tokens().load(deps.storage, &token_id)?; Ok(NftInfoResponse { name: info.name, @@ -413,7 +413,7 @@ fn query_nft_info(deps: Deps, token_id: String) -> StdResult { }) } -fn query_owner_of( +pub fn query_owner_of( deps: Deps, env: Env, token_id: String, @@ -429,7 +429,7 @@ fn query_owner_of( const DEFAULT_LIMIT: u32 = 10; const MAX_LIMIT: u32 = 30; -fn query_all_approvals( +pub fn query_all_approvals( deps: Deps, env: Env, owner: String, @@ -459,7 +459,7 @@ fn parse_approval(item: StdResult>) -> StdResult, @@ -482,7 +482,7 @@ fn query_tokens( Ok(TokensResponse { tokens }) } -fn query_all_tokens( +pub fn query_all_tokens( deps: Deps, start_after: Option, limit: Option, @@ -499,7 +499,7 @@ fn query_all_tokens( Ok(TokensResponse { tokens: tokens? }) } -fn query_all_nft_info( +pub fn query_all_nft_info( deps: Deps, env: Env, token_id: String, diff --git a/packages/cw1/src/lib.rs b/packages/cw1/src/lib.rs index 4d5fbfadd..a21f8502e 100644 --- a/packages/cw1/src/lib.rs +++ b/packages/cw1/src/lib.rs @@ -5,11 +5,3 @@ pub mod query; pub use crate::helpers::Cw1Contract; pub use crate::msg::Cw1ExecuteMsg; pub use crate::query::{CanExecuteResponse, Cw1QueryMsg}; - -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - // test me - } -}