#![cfg(test)]
use cosmwasm_std::testing::{mock_env, MockApi, MockStorage};
use cosmwasm_std::{coins, to_binary, Addr, Empty, Uint128};
use cw20::{Cw20Coin, Cw20Contract, Cw20ExecuteMsg};
use cw_multi_test::{App, Contract, ContractWrapper, SimpleBank};
use crate::msg::{CreateMsg, DetailsResponse, ExecuteMsg, InstantiateMsg, QueryMsg, ReceiveMsg};
fn mock_app() -> App {
let env = mock_env();
let api = Box::new(MockApi::default());
let bank = SimpleBank {};
App::new(api, env.block, bank, || Box::new(MockStorage::new()))
}
pub fn contract_escrow() -> Box<dyn Contract<Empty>> {
let contract = ContractWrapper::new(
crate::contract::execute,
crate::contract::instantiate,
crate::contract::query,
);
Box::new(contract)
}
pub fn contract_cw20() -> Box<dyn Contract<Empty>> {
let contract = ContractWrapper::new(
cw20_base::contract::execute,
cw20_base::contract::instantiate,
cw20_base::contract::query,
);
Box::new(contract)
}
#[test]
fn escrow_happy_path_cw20_tokens() {
let mut router = mock_app();
let owner = Addr::unchecked("owner");
let init_funds = coins(2000, "btc");
router.set_bank_balance(&owner, init_funds).unwrap();
let cw20_id = router.store_code(contract_cw20());
let msg = cw20_base::msg::InstantiateMsg {
name: "Cash Money".to_string(),
symbol: "CASH".to_string(),
decimals: 2,
initial_balances: vec![Cw20Coin {
address: owner.to_string(),
amount: Uint128(5000),
}],
mint: None,
};
let cash_addr = router
.instantiate_contract(cw20_id, owner.clone(), &msg, &[], "CASH")
.unwrap();
let escrow_id = router.store_code(contract_escrow());
let escrow_addr = router
.instantiate_contract(escrow_id, owner.clone(), &InstantiateMsg {}, &[], "Escrow")
.unwrap();
assert_ne!(cash_addr, escrow_addr);
let cash = Cw20Contract(cash_addr.clone());
let owner_balance = cash.balance(&router, owner.clone()).unwrap();
assert_eq!(owner_balance, Uint128(5000));
let escrow_balance = cash.balance(&router, escrow_addr.clone()).unwrap();
assert_eq!(escrow_balance, Uint128(0));
let arb = Addr::unchecked("arbiter");
let ben = String::from("beneficiary");
let id = "demo".to_string();
let create_msg = ReceiveMsg::Create(CreateMsg {
id: id.clone(),
arbiter: arb.to_string(),
recipient: ben.clone(),
end_height: None,
end_time: None,
cw20_whitelist: None,
});
let create_bin = to_binary(&create_msg).unwrap();
let send_msg = Cw20ExecuteMsg::Send {
contract: escrow_addr.to_string(),
amount: Uint128(1200),
msg: Some(create_bin),
};
let res = router
.execute_contract(owner.clone(), cash_addr.clone(), &send_msg, &[])
.unwrap();
println!("{:?}", res.attributes);
assert_eq!(6, res.attributes.len());
let owner_balance = cash.balance(&router, owner.clone()).unwrap();
assert_eq!(owner_balance, Uint128(3800));
let escrow_balance = cash.balance(&router, escrow_addr.clone()).unwrap();
assert_eq!(escrow_balance, Uint128(1200));
let details: DetailsResponse = router
.wrap()
.query_wasm_smart(&escrow_addr, &QueryMsg::Details { id: id.clone() })
.unwrap();
assert_eq!(id, details.id);
assert_eq!(arb, details.arbiter);
assert_eq!(ben, details.recipient);
assert_eq!(
vec![Cw20Coin {
address: cash_addr.to_string(),
amount: Uint128(1200)
}],
details.cw20_balance
);
let approve_msg = ExecuteMsg::Approve { id };
let _ = router
.execute_contract(arb, escrow_addr.clone(), &approve_msg, &[])
.unwrap();
let owner_balance = cash.balance(&router, owner).unwrap();
assert_eq!(owner_balance, Uint128(3800));
let escrow_balance = cash.balance(&router, escrow_addr).unwrap();
assert_eq!(escrow_balance, Uint128(0));
let ben_balance = cash.balance(&router, ben).unwrap();
assert_eq!(ben_balance, Uint128(1200));
}