use crate::{
ado_base::AndromedaQuery,
ado_contract::ADOContract,
amp::{ADO_DB_KEY, ECONOMICS_KEY, OSMOSIS_ROUTER_KEY, VFS_KEY},
os::adodb::{ActionFee, QueryMsg as ADODBQueryMsg},
os::kernel::QueryMsg as KernelQueryMsg,
os::vfs::QueryMsg as VFSQueryMsg,
};
#[cfg(feature = "modules")]
use cosmwasm_std::SubMsg;
use cosmwasm_std::{
from_binary, from_slice,
testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR},
to_binary, Addr, Binary, Coin, ContractInfoResponse, ContractResult, OwnedDeps, Querier,
QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery,
};
#[cfg(feature = "primitive")]
use cosmwasm_std::{Decimal, Uint128};
use cw20::{BalanceResponse, Cw20QueryMsg};
pub const MOCK_CW20_CONTRACT: &str = "cw20_contract";
pub const MOCK_APP_CONTRACT: &str = "app_contract";
pub const MOCK_PRIMITIVE_CONTRACT: &str = "primitive_contract";
pub const MOCK_KERNEL_CONTRACT: &str = "kernel_contract";
pub const MOCK_VFS_CONTRACT: &str = "vfs_contract";
pub const MOCK_ADODB_CONTRACT: &str = "adodb_contract";
pub const MOCK_ADO_PUBLISHER: &str = "ado_publisher";
pub const MOCK_OSMOSIS_ROUTER_CONTRACT: &str = "osmosis_router";
pub const MOCK_ECONOMICS_CONTRACT: &str = "economics_contract";
pub const MOCK_RATES_CONTRACT: &str = "rates_contract";
pub const MOCK_ADDRESS_LIST_CONTRACT: &str = "address_list_contract";
pub const INVALID_CONTRACT: &str = "invalid_contract";
pub const FAKE_VFS_PATH: &str = "/f";
pub const FAKE_ADODB_KEY: &str = "fake_adodb_key";
pub const MOCK_ACTION: &str = "action";
pub const UNWHITELISTED_ADDRESS: &str = "unwhitelisted_address";
pub const RATES_EXCLUDED_ADDRESS: &str = "rates_excluded_address";
pub struct WasmMockQuerier {
pub base: MockQuerier,
}
pub fn mock_dependencies_custom(
contract_balance: &[Coin],
) -> OwnedDeps<MockStorage, MockApi, WasmMockQuerier> {
let custom_querier: WasmMockQuerier =
WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)]));
let storage = MockStorage::default();
let mut deps = OwnedDeps {
storage,
api: MockApi::default(),
querier: custom_querier,
custom_query_type: std::marker::PhantomData,
};
ADOContract::default()
.kernel_address
.save(
deps.as_mut().storage,
&Addr::unchecked(MOCK_KERNEL_CONTRACT),
)
.unwrap();
deps
}
impl Querier for WasmMockQuerier {
fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
let request: QueryRequest<cosmwasm_std::Empty> = match from_slice(bin_request) {
Ok(v) => v,
Err(e) => {
return SystemResult::Err(SystemError::InvalidRequest {
error: format!("Parsing query request: {e}"),
request: bin_request.into(),
})
}
};
self.handle_query(&request)
}
}
impl WasmMockQuerier {
pub fn handle_query(&self, request: &QueryRequest<cosmwasm_std::Empty>) -> QuerierResult {
MockAndromedaQuerier::default().handle_query(&self.base, request)
}
pub fn new(base: MockQuerier) -> Self {
WasmMockQuerier { base }
}
}
#[derive(Default)]
pub struct MockAndromedaQuerier {}
impl MockAndromedaQuerier {
pub fn handle_query(
self,
querier: &MockQuerier,
request: &QueryRequest<cosmwasm_std::Empty>,
) -> QuerierResult {
match &request {
QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => {
match contract_addr.as_str() {
MOCK_CW20_CONTRACT => self.handle_cw20_query(msg),
MOCK_APP_CONTRACT => self.handle_app_query(msg),
#[cfg(feature = "primitive")]
MOCK_PRIMITIVE_CONTRACT => self.handle_primitive_query(msg),
MOCK_KERNEL_CONTRACT => self.handle_kernel_query(msg),
MOCK_VFS_CONTRACT => self.handle_vfs_query(msg),
MOCK_ADODB_CONTRACT => self.handle_adodb_query(msg),
#[cfg(feature = "modules")]
MOCK_ADDRESS_LIST_CONTRACT => self.handle_address_list_query(msg),
_ => match from_binary::<AndromedaQuery>(msg) {
Ok(msg) => self.handle_ado_query(msg),
_ => panic!("Unsupported query for contract: {}", contract_addr),
},
}
}
QueryRequest::Wasm(WasmQuery::Raw { contract_addr, key }) => {
match contract_addr.as_str() {
MOCK_KERNEL_CONTRACT => self.handle_kernel_raw_query(key),
MOCK_VFS_CONTRACT => self.handle_kernel_raw_query(key),
MOCK_ADODB_CONTRACT => self.handle_adodb_raw_query(key),
_ => panic!("Unsupported query for contract: {}", contract_addr),
}
}
QueryRequest::Wasm(WasmQuery::ContractInfo { contract_addr }) => {
let mut resp = ContractInfoResponse::default();
resp.code_id = match contract_addr.as_str() {
INVALID_CONTRACT => 2,
_ => 1,
};
SystemResult::Ok(ContractResult::Ok(to_binary(&resp).unwrap()))
}
_ => querier.handle_query(request),
}
}
fn handle_kernel_query(&self, msg: &Binary) -> QuerierResult {
match from_binary(msg).unwrap() {
KernelQueryMsg::KeyAddress { key } => match key.as_str() {
VFS_KEY => {
SystemResult::Ok(ContractResult::Ok(to_binary(&MOCK_VFS_CONTRACT).unwrap()))
}
ADO_DB_KEY => {
SystemResult::Ok(ContractResult::Ok(to_binary(&MOCK_ADODB_CONTRACT).unwrap()))
}
&_ => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
},
KernelQueryMsg::VerifyAddress { address } => match address.as_str() {
INVALID_CONTRACT => {
SystemResult::Ok(ContractResult::Err("Invalid Address".to_string()))
}
_ => SystemResult::Ok(ContractResult::Ok(to_binary(&true).unwrap())),
},
}
}
fn handle_vfs_query(&self, msg: &Binary) -> QuerierResult {
match from_binary(msg).unwrap() {
VFSQueryMsg::ResolvePath { path } => match path.as_str() {
FAKE_VFS_PATH => SystemResult::Ok(ContractResult::Err("Invalid Path".to_string())),
_ => SystemResult::Ok(ContractResult::Ok(to_binary(&path).unwrap())),
},
VFSQueryMsg::GetUsername { address } => {
SystemResult::Ok(ContractResult::Ok(to_binary(&address).unwrap()))
}
}
}
fn handle_app_query(&self, _msg: &Binary) -> QuerierResult {
todo!()
}
fn handle_adodb_query(&self, msg: &Binary) -> QuerierResult {
match from_binary(msg).unwrap() {
ADODBQueryMsg::ADOType { code_id } => match code_id {
1 => SystemResult::Ok(ContractResult::Ok(to_binary(&"ADOType").unwrap())),
_ => SystemResult::Ok(ContractResult::Err("Invalid Code ID".to_string())),
},
ADODBQueryMsg::CodeId { key } => match key.as_str() {
FAKE_ADODB_KEY => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
_ => SystemResult::Ok(ContractResult::Ok(to_binary(&1).unwrap())),
},
_ => SystemResult::Ok(ContractResult::Err("Not implemented".to_string())),
}
}
#[cfg(feature = "primitive")]
fn handle_primitive_query(&self, msg: &Binary) -> QuerierResult {
match from_binary(msg).unwrap() {
QueryMsg::AndrQuery(AndromedaQuery::Get(data)) => {
let res = match data {
None => GetValueResponse {
key: "default".to_string(),
value: Primitive::Decimal(Decimal::zero()),
},
Some(data) => {
let key: String = from_binary(&data).unwrap();
match key.as_str() {
"String" => GetValueResponse {
key,
value: Primitive::String("Value".to_string()),
},
"Uint128" => GetValueResponse {
key,
value: Primitive::Uint128(Uint128::new(10)),
},
"Decimal" => GetValueResponse {
key,
value: Primitive::Decimal(Decimal::percent(1)),
},
"Coin" => GetValueResponse {
key,
value: Primitive::Coin(Coin::new(100, "uusd")),
},
"Bool" => GetValueResponse {
key,
value: Primitive::Bool(true),
},
"Vec" => GetValueResponse {
key,
value: Primitive::Vec(vec![Primitive::from("String".to_string())]),
},
_ => {
return SystemResult::Ok(ContractResult::Err(
"Not Found".to_string(),
))
}
}
}
};
SystemResult::Ok(ContractResult::Ok(to_binary(&res).unwrap()))
}
_ => panic!("Unsupported Query"),
}
}
#[cfg(feature = "modules")]
fn handle_address_list_query(&self, msg: &Binary) -> QuerierResult {
use cosmwasm_std::Response;
use crate::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse};
match from_binary(msg).unwrap() {
HookMsg::AndrHook(hook) => match hook {
AndromedaHook::OnExecute { sender, .. } => match sender.as_str() {
UNWHITELISTED_ADDRESS => {
SystemResult::Ok(ContractResult::Err("Unwhitelisted Address".to_string()))
}
_ => SystemResult::Ok(ContractResult::Ok(
to_binary::<Response>(&Response::default()).unwrap(),
)),
},
AndromedaHook::OnFundsTransfer { .. } => SystemResult::Ok(ContractResult::Ok(
to_binary(&OnFundsTransferResponse::default()).unwrap(),
)),
AndromedaHook::OnTokenTransfer { .. } => SystemResult::Ok(ContractResult::Ok(
to_binary::<Response>(&Response::default()).unwrap(),
)),
},
}
}
#[cfg(feature = "modules")]
fn _handle_rates_query(&self, msg: &Binary) -> QuerierResult {
use cosmwasm_std::Response;
use crate::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse};
match from_binary(msg).unwrap() {
HookMsg::AndrHook(hook) => match hook {
AndromedaHook::OnExecute { .. } => SystemResult::Ok(ContractResult::Ok(
to_binary::<Response>(&Response::default()).unwrap(),
)),
AndromedaHook::OnFundsTransfer { sender, .. } => {
if sender.as_str() == RATES_EXCLUDED_ADDRESS {
return SystemResult::Ok(ContractResult::Ok(
to_binary(&OnFundsTransferResponse::default()).unwrap(),
));
}
todo!("Implement Rates Query")
}
AndromedaHook::OnTokenTransfer { .. } => SystemResult::Ok(ContractResult::Ok(
to_binary::<Response>(&Response::default()).unwrap(),
)),
},
}
}
fn handle_cw20_query(&self, msg: &Binary) -> QuerierResult {
match from_binary(msg).unwrap() {
Cw20QueryMsg::Balance { .. } => {
let balance_response = BalanceResponse {
balance: 10u128.into(),
};
SystemResult::Ok(ContractResult::Ok(to_binary(&balance_response).unwrap()))
}
_ => panic!("Unsupported Query"),
}
}
pub fn handle_kernel_raw_query(&self, key: &Binary) -> QuerierResult {
let key_vec = key.as_slice();
let key_str = String::from_utf8(key_vec.to_vec()).unwrap();
if key_str.contains("kernel_addresses") {
let split = key_str.split("kernel_addresses");
let key = split.last();
if let Some(key) = key {
match key {
VFS_KEY => SystemResult::Ok(ContractResult::Ok(
to_binary(&MOCK_VFS_CONTRACT.to_string()).unwrap(),
)),
ADO_DB_KEY => SystemResult::Ok(ContractResult::Ok(
to_binary(&MOCK_ADODB_CONTRACT.to_string()).unwrap(),
)),
OSMOSIS_ROUTER_KEY => SystemResult::Ok(ContractResult::Ok(
to_binary(&MOCK_OSMOSIS_ROUTER_CONTRACT.to_string()).unwrap(),
)),
ECONOMICS_KEY => SystemResult::Ok(ContractResult::Ok(
to_binary(&MOCK_ECONOMICS_CONTRACT.to_string()).unwrap(),
)),
_ => panic!("Invalid Kernel Address Key"),
}
} else {
panic!("Invalid Kernel Address Raw Query")
}
} else {
panic!("Invalid Kernel Raw Query")
}
}
pub fn handle_adodb_raw_query(&self, key: &Binary) -> QuerierResult {
let key_vec = key.as_slice();
let key_str = String::from_utf8(key_vec.to_vec()).unwrap();
if key_str.contains("code_id") {
let split = key_str.split("code_id");
let key = split.last();
if let Some(key) = key {
match key {
FAKE_ADODB_KEY => {
SystemResult::Ok(ContractResult::Err("Invalid Key".to_string()))
}
_ => SystemResult::Ok(ContractResult::Ok(to_binary(&1).unwrap())),
}
} else {
panic!("Invalid ADODB Raw Query")
}
} else if key_str.contains("action_fees") {
let split = key_str.split("action_fees");
let key = split.last();
match key {
Some(key) => {
if key.contains("ADOTypeaction") {
SystemResult::Ok(ContractResult::Ok(
to_binary(&ActionFee::new(
MOCK_ACTION.to_string(),
"uusd".to_string(),
Uint128::from(10u128),
))
.unwrap(),
))
} else {
SystemResult::Ok(ContractResult::Err("Invalid Key".to_string()))
}
}
None => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
}
} else if key_str.contains("ado_type") {
let split = key_str.split("ado_type");
let key = split.last();
match key {
Some("1") => SystemResult::Ok(ContractResult::Ok(to_binary("ADOType").unwrap())),
Some(_) => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
None => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
}
} else if key_str.contains("publisher") {
let split = key_str.split("ado_type");
let key = split.last();
match key {
Some(key) => match key {
FAKE_ADODB_KEY => {
SystemResult::Ok(ContractResult::Err("Invalid Key".to_string()))
}
_ => {
SystemResult::Ok(ContractResult::Ok(to_binary(MOCK_ADO_PUBLISHER).unwrap()))
}
},
None => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
}
} else {
panic!("Invalid ADODB Raw Query")
}
}
pub fn handle_ado_query(&self, msg: AndromedaQuery) -> QuerierResult {
match msg {
AndromedaQuery::AppContract {} => SystemResult::Ok(ContractResult::Ok(
to_binary(&MOCK_APP_CONTRACT.to_string()).unwrap(),
)),
_ => panic!("Unsupported ADO query"),
}
}
}
#[cfg(feature = "modules")]
pub fn calculate_mock_rates_response() -> (Vec<SubMsg>, Vec<Coin>) {
todo!("Implement after readding rates contract");
}