Skip to content

Commit

Permalink
Sort of get test-tube tests working for custom factory
Browse files Browse the repository at this point in the history
  • Loading branch information
Jake Hartnell committed Sep 13, 2023
1 parent 7b5e097 commit 32d86ee
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion contracts/voting/dao-voting-token-staked/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ library = []
# cargo test --features "test-tube"
test-tube = []
# when writing tests you may wish to enable test-tube as a default feature
# default = ["test-tube"]
default = ["test-tube"]

[dependencies]
cosmwasm-std = { workspace = true, features = ["cosmwasm_1_1"] }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use cosmwasm_std::{Addr, Coin, Uint128};
use cosmwasm_std::{to_binary, Addr, Coin, Decimal, Uint128, WasmMsg};
use cw_tokenfactory_issuer::msg::DenomUnit;
use dao_voting::threshold::{ActiveThreshold, ActiveThresholdError};
use cw_utils::Duration;
use dao_interface::state::{Admin, ModuleInstantiateInfo};
use dao_testing::test_tube::dao_dao_core::DaoCore;
use dao_voting::{
pre_propose::PreProposeInfo,
threshold::{ActiveThreshold, ActiveThresholdError, PercentageThreshold, Threshold},
};
use osmosis_std::types::cosmos::bank::v1beta1::QueryBalanceRequest;
use osmosis_test_tube::{Account, OsmosisTestApp};

Expand All @@ -10,7 +16,7 @@ use crate::{
ContractError,
};

use super::test_env::{TestEnv, TestEnvBuilder};
use super::test_env::{TestEnv, TestEnvBuilder, DENOM};

#[test]
fn test_full_integration_correct_setup() {
Expand Down Expand Up @@ -311,3 +317,95 @@ fn test_instantiate_no_initial_balances_fails() {
TokenVotingContract::execute_submessage_error(ContractError::InitialBalancesError {})
);
}

#[test]
fn test_factory() {
let app = OsmosisTestApp::new();
let env = TestEnvBuilder::new();
let TestEnv {
tf_issuer,
vp_contract,
proposal_single,
custom_factory,
accounts,
..
} = env.full_dao_setup(&app);

// TODO refactor so there is a function that just takes the message
// Instantiate a new voting contract using the factory pattern
let msg = dao_interface::msg::InstantiateMsg {
dao_uri: None,
admin: None,
name: "DAO DAO".to_string(),
description: "A DAO that makes DAO tooling".to_string(),
image_url: None,
automatically_add_cw20s: false,
automatically_add_cw721s: false,
voting_module_instantiate_info: ModuleInstantiateInfo {
code_id: vp_contract.code_id,
msg: to_binary(&InstantiateMsg {
token_info: TokenInfo::Factory(
to_binary(&WasmMsg::Execute {
contract_addr: custom_factory.unwrap().contract_addr.to_string(),
msg: to_binary(
&dao_test_custom_factory::msg::ExecuteMsg::TokenFactoryFactory(
dao_test_custom_factory::NewTokenInfo {
token_issuer_code_id: tf_issuer.code_id,
subdenom: DENOM.to_string(),
metadata: None,
initial_balances: vec![
dao_test_custom_factory::InitialBalance {
address: accounts[0].address(),
amount: Uint128::new(100),
},
],
initial_dao_balance: None,
},
),
)
.unwrap(),
funds: vec![],
})
.unwrap(),
),
unstaking_duration: Some(Duration::Time(2)),
active_threshold: Some(ActiveThreshold::AbsoluteCount {
count: Uint128::new(75),
}),
})
.unwrap(),
admin: Some(Admin::CoreModule {}),
funds: vec![],
label: "DAO DAO Voting Module".to_string(),
},
proposal_modules_instantiate_info: vec![ModuleInstantiateInfo {
code_id: proposal_single.unwrap().code_id,
msg: to_binary(&dao_proposal_single::msg::InstantiateMsg {
min_voting_period: None,
threshold: Threshold::ThresholdQuorum {
threshold: PercentageThreshold::Majority {},
quorum: PercentageThreshold::Percent(Decimal::percent(35)),
},
max_voting_period: Duration::Time(432000),
allow_revoting: false,
only_members_execute: true,
close_proposal_on_execution_failure: false,
pre_propose_info: PreProposeInfo::AnyoneMayPropose {},
})
.unwrap(),
admin: Some(Admin::CoreModule {}),
funds: vec![],
label: "DAO DAO Proposal Module".to_string(),
}],
initial_items: None,
};

// Instantiate DAO
let dao = DaoCore::new(&app, &msg, &accounts[0]).unwrap();

// TODO query voting module

// TODO query denom

// TODO query token contract
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use dao_voting::{

use dao_testing::test_tube::{
cw_tokenfactory_issuer::TokenfactoryIssuer, dao_dao_core::DaoCore,
dao_proposal_single::DaoProposalSingle,
dao_proposal_single::DaoProposalSingle, dao_test_custom_factory::CustomFactoryContract,
};
use dao_voting::threshold::ActiveThreshold;
use osmosis_std::types::{
Expand All @@ -41,6 +41,7 @@ pub struct TestEnv<'a> {
pub app: &'a OsmosisTestApp,
pub dao: Option<DaoCore<'a>>,
pub proposal_single: Option<DaoProposalSingle<'a>>,
pub custom_factory: Option<CustomFactoryContract<'a>>,
pub vp_contract: TokenVotingContract<'a>,
pub tf_issuer: TokenfactoryIssuer<'a>,
pub accounts: Vec<SigningAccount>,
Expand Down Expand Up @@ -168,6 +169,7 @@ impl TestEnvBuilder {
accounts,
dao: None,
proposal_single: None,
custom_factory: None,
tf_issuer,
vp_contract,
}
Expand Down Expand Up @@ -227,6 +229,7 @@ impl TestEnvBuilder {
})
.unwrap(),
admin: Some(Admin::CoreModule {}),
funds: vec![],
label: "DAO DAO Voting Module".to_string(),
},
proposal_modules_instantiate_info: vec![ModuleInstantiateInfo {
Expand All @@ -245,6 +248,7 @@ impl TestEnvBuilder {
})
.unwrap(),
admin: Some(Admin::CoreModule {}),
funds: vec![],
label: "DAO DAO Proposal Module".to_string(),
}],
initial_items: None,
Expand Down Expand Up @@ -277,11 +281,20 @@ impl TestEnvBuilder {
TokenVotingContract::query(&vp_contract, &QueryMsg::TokenContract {}).unwrap();
let tf_issuer = TokenfactoryIssuer::new_with_values(app, issuer_id, issuer_addr).unwrap();

// Instantiate Custom Factory
let custom_factory = CustomFactoryContract::new(
app,
&dao_test_custom_factory::msg::InstantiateMsg {},
&accounts[0],
)
.unwrap();

TestEnv {
app,
dao: Some(dao),
vp_contract,
proposal_single: Some(proposal_single),
custom_factory: Some(custom_factory),
tf_issuer,
accounts,
}
Expand Down
1 change: 1 addition & 0 deletions packages/dao-testing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ dao-pre-propose-multiple = { workspace = true }
dao-pre-propose-single = { workspace = true }
dao-proposal-condorcet = { workspace = true }
dao-proposal-single = { workspace = true }
dao-test-custom-factory = { workspace = true }
dao-voting = { workspace = true }
dao-voting-cw20-balance = { workspace = true }
dao-voting-cw20-staked = { workspace = true }
Expand Down
129 changes: 129 additions & 0 deletions packages/dao-testing/src/test_tube/dao_test_custom_factory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
use cosmwasm_std::Coin;
use dao_test_custom_factory::{
msg::{ExecuteMsg, InstantiateMsg, QueryMsg},
ContractError,
};
use osmosis_test_tube::{
osmosis_std::types::cosmwasm::wasm::v1::MsgExecuteContractResponse, Account, Module,
OsmosisTestApp, RunnerError, RunnerExecuteResult, SigningAccount, Wasm,
};
use serde::de::DeserializeOwned;
use std::fmt::Debug;
use std::path::PathBuf;

#[derive(Debug)]
pub struct CustomFactoryContract<'a> {
pub app: &'a OsmosisTestApp,
pub code_id: u64,
pub contract_addr: String,
}

impl<'a> CustomFactoryContract<'a> {
pub fn new(
app: &'a OsmosisTestApp,
instantiate_msg: &InstantiateMsg,
signer: &SigningAccount,
) -> Result<Self, RunnerError> {
let wasm = Wasm::new(app);
let token_creation_fee = Coin::new(10000000, "uosmo");

let code_id = wasm
.store_code(&Self::get_wasm_byte_code(), None, signer)?
.data
.code_id;

let contract_addr = wasm
.instantiate(
code_id,
&instantiate_msg,
Some(&signer.address()),
None,
&[token_creation_fee],
signer,
)?
.data
.address;

Ok(Self {
app,
code_id,
contract_addr,
})
}

pub fn new_with_values(
app: &'a OsmosisTestApp,
code_id: u64,
contract_addr: String,
) -> Result<Self, RunnerError> {
Ok(Self {
app,
code_id,
contract_addr,
})
}

/// uploads contract and returns a code ID
pub fn upload(app: &OsmosisTestApp, signer: &SigningAccount) -> Result<u64, RunnerError> {
let wasm = Wasm::new(app);

let code_id = wasm
.store_code(&Self::get_wasm_byte_code(), None, signer)?
.data
.code_id;

Ok(code_id)
}

// executes
pub fn execute(
&self,
execute_msg: &ExecuteMsg,
funds: &[Coin],
signer: &SigningAccount,
) -> RunnerExecuteResult<MsgExecuteContractResponse> {
let wasm = Wasm::new(self.app);
wasm.execute(&self.contract_addr, execute_msg, funds, signer)
}

// queries
pub fn query<T>(&self, query_msg: &QueryMsg) -> Result<T, RunnerError>
where
T: DeserializeOwned,
{
let wasm = Wasm::new(self.app);
wasm.query(&self.contract_addr, query_msg)
}

fn get_wasm_byte_code() -> Vec<u8> {
let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let byte_code = std::fs::read(
manifest_path
.join("..")
.join("..")
.join("artifacts")
.join("dao_test_custom_factory.wasm"),
);
match byte_code {
Ok(byte_code) => byte_code,
// On arm processors, the above path is not found, so we try the following path
Err(_) => std::fs::read(
manifest_path
.join("..")
.join("..")
.join("artifacts")
.join("dao_test_custom_factory-aarch64.wasm"),
)
.unwrap(),
}
}

pub fn execute_error(err: ContractError) -> RunnerError {
RunnerError::ExecuteError {
msg: format!(
"failed to execute message; message index: 0: {}: execute wasm contract failed",
err
),
}
}
}
3 changes: 3 additions & 0 deletions packages/dao-testing/src/test_tube/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ pub mod dao_dao_core;

#[cfg(feature = "test-tube")]
pub mod dao_proposal_single;

#[cfg(feature = "test-tube")]
pub mod dao_test_custom_factory;

0 comments on commit 32d86ee

Please sign in to comment.