1use crate::{
2 ado_base::AndromedaQuery,
3 ado_contract::ADOContract,
4 amp::{ADO_DB_KEY, ECONOMICS_KEY, OSMOSIS_ROUTER_KEY, VFS_KEY},
5 os::kernel::QueryMsg as KernelQueryMsg,
6 os::vfs::QueryMsg as VFSQueryMsg,
7 os::{
8 adodb::{ActionFee, QueryMsg as ADODBQueryMsg},
9 kernel::ChannelInfo,
10 },
11};
12#[cfg(feature = "modules")]
13use cosmwasm_std::SubMsg;
14use cosmwasm_std::{
15 from_json,
16 testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR},
17 to_json_binary, Addr, Binary, CodeInfoResponse, Coin, ContractInfoResponse, ContractResult,
18 HexBinary, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128,
19 WasmQuery,
20};
21#[cfg(feature = "primitive")]
22use cosmwasm_std::{Decimal, Uint128};
23use cw20::{BalanceResponse, Cw20QueryMsg};
24
25pub const MOCK_CW20_CONTRACT: &str = "cw20_contract";
27pub const MOCK_ANCHOR_CONTRACT: &str = "anchor_contract";
29pub const MOCK_APP_CONTRACT: &str = "app_contract";
31pub const MOCK_PRIMITIVE_CONTRACT: &str = "primitive_contract";
33pub const MOCK_KERNEL_CONTRACT: &str = "kernel_contract";
35pub const MOCK_FAKE_KERNEL_CONTRACT: &str = "fake_kernel_contract";
37pub const MOCK_VFS_CONTRACT: &str = "vfs_contract";
39pub const MOCK_ADODB_CONTRACT: &str = "adodb_contract";
41pub const MOCK_ADO_PUBLISHER: &str = "ado_publisher";
43pub const MOCK_OSMOSIS_ROUTER_CONTRACT: &str = "osmosis_router";
45pub const MOCK_ECONOMICS_CONTRACT: &str = "economics_contract";
47
48pub const MOCK_RATES_CONTRACT: &str = "rates_contract";
50pub const MOCK_ADDRESS_LIST_CONTRACT: &str = "address_list_contract";
52
53pub const INVALID_CONTRACT: &str = "invalid_contract";
55pub const FAKE_VFS_PATH: &str = "/f";
57pub const FAKE_ADODB_KEY: &str = "fake_adodb_key";
59pub const MOCK_ACTION: &str = "action";
61pub const UNWHITELISTED_ADDRESS: &str = "unwhitelisted_address";
62pub const RATES_EXCLUDED_ADDRESS: &str = "rates_excluded_address";
63
64pub const MOCK_CHECKSUM: &str = "9af782a3a1bcbcd22dbb6a45c751551d9af782a3a1bcbcd22dbb6a45c751551d";
65
66pub const MOCK_WALLET: &str = "mock_wallet";
67
68pub struct WasmMockQuerier {
69 pub base: MockQuerier,
70}
71
72pub fn mock_dependencies_custom(
76 contract_balance: &[Coin],
77) -> OwnedDeps<MockStorage, MockApi, WasmMockQuerier> {
78 let custom_querier: WasmMockQuerier =
79 WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)]));
80 let storage = MockStorage::default();
81 let mut deps = OwnedDeps {
82 storage,
83 api: MockApi::default(),
84 querier: custom_querier,
85 custom_query_type: std::marker::PhantomData,
86 };
87 ADOContract::default()
88 .kernel_address
89 .save(
90 deps.as_mut().storage,
91 &Addr::unchecked(MOCK_KERNEL_CONTRACT),
92 )
93 .unwrap();
94 deps
95}
96
97impl Querier for WasmMockQuerier {
98 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
99 let request: QueryRequest<cosmwasm_std::Empty> = match from_json(bin_request) {
101 Ok(v) => v,
102 Err(e) => {
103 return SystemResult::Err(SystemError::InvalidRequest {
104 error: format!("Parsing query request: {e}"),
105 request: bin_request.into(),
106 })
107 }
108 };
109 self.handle_query(&request)
110 }
111}
112
113impl WasmMockQuerier {
114 pub fn handle_query(&self, request: &QueryRequest<cosmwasm_std::Empty>) -> QuerierResult {
122 MockAndromedaQuerier::default().handle_query(&self.base, request)
123 }
124
125 pub fn new(base: MockQuerier) -> Self {
126 WasmMockQuerier { base }
127 }
128}
129
130#[derive(Default)]
131pub struct MockAndromedaQuerier {}
132
133impl MockAndromedaQuerier {
134 pub fn handle_query(
135 self,
136 querier: &MockQuerier,
137 request: &QueryRequest<cosmwasm_std::Empty>,
138 ) -> QuerierResult {
139 match &request {
140 QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => {
141 match contract_addr.as_str() {
142 MOCK_CW20_CONTRACT => self.handle_cw20_query(msg),
143 MOCK_APP_CONTRACT => self.handle_app_query(msg),
144 #[cfg(feature = "primitive")]
145 MOCK_PRIMITIVE_CONTRACT => self.handle_primitive_query(msg),
146 MOCK_KERNEL_CONTRACT => self.handle_kernel_query(msg),
147 MOCK_VFS_CONTRACT => self.handle_vfs_query(msg),
148 MOCK_ADODB_CONTRACT => self.handle_adodb_query(msg),
149 #[cfg(feature = "modules")]
150 MOCK_ADDRESS_LIST_CONTRACT => self.handle_address_list_query(msg),
151 _ => match from_json::<AndromedaQuery>(msg) {
152 Ok(msg) => self.handle_ado_query(msg),
153 _ => SystemResult::Err(SystemError::InvalidRequest {
154 error: "Unsupported query".to_string(),
155 request: to_json_binary(&request).unwrap(),
156 }),
157 },
158 }
159 }
160 QueryRequest::Wasm(WasmQuery::Raw { contract_addr, key }) => {
161 match contract_addr.as_str() {
162 MOCK_KERNEL_CONTRACT => self.handle_kernel_raw_query(key, false),
164 MOCK_FAKE_KERNEL_CONTRACT => self.handle_kernel_raw_query(key, true),
165 MOCK_ADODB_CONTRACT => self.handle_adodb_raw_query(key),
166 MOCK_CW20_CONTRACT => self.handle_cw20_owner_query(key),
167 MOCK_ANCHOR_CONTRACT => self.handle_anchor_owner_query(key),
168
169 _ => self.handle_ado_raw_query(key, &Addr::unchecked(contract_addr)),
170 }
171 }
172 QueryRequest::Wasm(WasmQuery::ContractInfo { contract_addr }) => {
174 if contract_addr == MOCK_WALLET {
175 return SystemResult::Ok(ContractResult::Err(
176 "Not a valid contract".to_string(),
177 ));
178 }
179 let mut resp = ContractInfoResponse::default();
180 resp.code_id = match contract_addr.as_str() {
181 MOCK_APP_CONTRACT => 3,
182 INVALID_CONTRACT => 2,
183 _ => 1,
184 };
185 SystemResult::Ok(ContractResult::Ok(to_json_binary(&resp).unwrap()))
186 }
187 QueryRequest::Wasm(WasmQuery::CodeInfo { code_id }) => {
188 if *code_id == 2u64 {
189 return SystemResult::Ok(ContractResult::Err("Invalid Code ID".to_string()));
190 }
191 let mut resp = CodeInfoResponse::default();
192 resp.checksum = HexBinary::from_hex(MOCK_CHECKSUM).unwrap();
193 SystemResult::Ok(ContractResult::Ok(to_json_binary(&resp).unwrap()))
194 }
195 _ => querier.handle_query(request),
196 }
197 }
198
199 fn handle_cw20_owner_query(&self, _msg: &Binary) -> QuerierResult {
200 SystemResult::Ok(ContractResult::Ok(
201 to_json_binary("cosmos2contract").unwrap(),
202 ))
203 }
204
205 fn handle_anchor_owner_query(&self, _msg: &Binary) -> QuerierResult {
206 SystemResult::Ok(ContractResult::Ok(
207 to_json_binary("cosmos2contract").unwrap(),
208 ))
209 }
210
211 fn handle_kernel_query(&self, msg: &Binary) -> QuerierResult {
217 match from_json(msg).unwrap() {
218 KernelQueryMsg::KeyAddress { key } => match key.as_str() {
219 VFS_KEY => SystemResult::Ok(ContractResult::Ok(
220 to_json_binary(&MOCK_VFS_CONTRACT).unwrap(),
221 )),
222 ADO_DB_KEY => SystemResult::Ok(ContractResult::Ok(
223 to_json_binary(&MOCK_ADODB_CONTRACT).unwrap(),
224 )),
225 &_ => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
226 },
227 KernelQueryMsg::VerifyAddress { address } => match address.as_str() {
228 INVALID_CONTRACT => {
229 SystemResult::Ok(ContractResult::Err("Invalid Address".to_string()))
230 }
231 _ => SystemResult::Ok(ContractResult::Ok(to_json_binary(&true).unwrap())),
232 },
233 _ => SystemResult::Ok(ContractResult::Err("Not implemented".to_string())),
234 }
235 }
236
237 fn handle_vfs_query(&self, msg: &Binary) -> QuerierResult {
241 match from_json(msg).unwrap() {
242 VFSQueryMsg::ResolvePath { path } => match path.as_str() {
243 FAKE_VFS_PATH => SystemResult::Ok(ContractResult::Err("Invalid Path".to_string())),
244 _ => SystemResult::Ok(ContractResult::Ok(to_json_binary(&path).unwrap())),
245 },
246 VFSQueryMsg::ResolveSymlink { path } => match path.as_str() {
247 FAKE_VFS_PATH => SystemResult::Ok(ContractResult::Err("Invalid Path".to_string())),
248 _ => SystemResult::Ok(ContractResult::Ok(to_json_binary(&path).unwrap())),
249 },
250 VFSQueryMsg::SubDir { path, .. } => match path.as_str() {
251 FAKE_VFS_PATH => SystemResult::Ok(ContractResult::Err("Invalid Path".to_string())),
252 _ => SystemResult::Ok(ContractResult::Ok(to_json_binary(&path).unwrap())),
253 },
254 VFSQueryMsg::Paths { addr } => {
255 SystemResult::Ok(ContractResult::Ok(to_json_binary(&addr).unwrap()))
256 }
257 VFSQueryMsg::GetUsername { address } => {
258 SystemResult::Ok(ContractResult::Ok(to_json_binary(&address).unwrap()))
259 }
260 VFSQueryMsg::GetLibrary { address } => {
261 SystemResult::Ok(ContractResult::Ok(to_json_binary(&address).unwrap()))
262 }
263 _ => todo!(),
264 }
265 }
266
267 fn handle_app_query(&self, _msg: &Binary) -> QuerierResult {
271 todo!()
275 }
276
277 fn handle_adodb_query(&self, msg: &Binary) -> QuerierResult {
283 match from_json(msg).unwrap() {
284 ADODBQueryMsg::ADOType { code_id } => match code_id {
285 3 => SystemResult::Ok(ContractResult::Ok(to_json_binary(&"app-contract").unwrap())),
286 1 => SystemResult::Ok(ContractResult::Ok(to_json_binary(&"ADOType").unwrap())),
287 _ => SystemResult::Ok(ContractResult::Err("Invalid Code ID".to_string())),
288 },
289 ADODBQueryMsg::CodeId { key } => match key.as_str() {
290 FAKE_ADODB_KEY => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
291 _ => SystemResult::Ok(ContractResult::Ok(to_json_binary(&1).unwrap())),
292 },
293 _ => SystemResult::Ok(ContractResult::Err("Not implemented".to_string())),
294 }
295 }
296
297 #[cfg(feature = "primitive")]
298 fn handle_primitive_query(&self, msg: &Binary) -> QuerierResult {
302 match from_json(msg).unwrap() {
303 QueryMsg::AndrQuery(AndromedaQuery::Get(data)) => {
304 let res = match data {
305 None => GetValueResponse {
306 key: "default".to_string(),
307 value: Primitive::Decimal(Decimal::zero()),
308 },
309 Some(data) => {
310 let key: String = from_json(&data).unwrap();
311 match key.as_str() {
312 "String" => GetValueResponse {
313 key,
314 value: Primitive::String("Value".to_string()),
315 },
316 "Uint128" => GetValueResponse {
317 key,
318 value: Primitive::Uint128(Uint128::new(10)),
319 },
320 "Decimal" => GetValueResponse {
321 key,
322 value: Primitive::Decimal(Decimal::percent(1)),
323 },
324 "Coin" => GetValueResponse {
325 key,
326 value: Primitive::Coin(Coin::new(100, "uusd")),
327 },
328 "Bool" => GetValueResponse {
329 key,
330 value: Primitive::Bool(true),
331 },
332 "Vec" => GetValueResponse {
333 key,
334 value: Primitive::Vec(vec![Primitive::from("String".to_string())]),
335 },
336 _ => {
337 return SystemResult::Ok(ContractResult::Err(
338 "Not Found".to_string(),
339 ))
340 }
341 }
342 }
343 };
344
345 SystemResult::Ok(ContractResult::Ok(to_json_binary(&res).unwrap()))
346 }
347 _ => panic!("Unsupported Query"),
348 }
349 }
350
351 #[cfg(feature = "modules")]
352 fn handle_address_list_query(&self, msg: &Binary) -> QuerierResult {
356 use cosmwasm_std::Response;
357
358 use crate::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse};
359 match from_json(msg).unwrap() {
360 HookMsg::AndrHook(hook) => match hook {
361 AndromedaHook::OnExecute { sender, .. } => match sender.as_str() {
362 UNWHITELISTED_ADDRESS => {
363 SystemResult::Ok(ContractResult::Err("Unwhitelisted Address".to_string()))
364 }
365 _ => SystemResult::Ok(ContractResult::Ok(
366 to_json_binary::<Response>(&Response::default()).unwrap(),
367 )),
368 },
369 AndromedaHook::OnFundsTransfer { .. } => SystemResult::Ok(ContractResult::Ok(
370 to_json_binary(&OnFundsTransferResponse::default()).unwrap(),
371 )),
372 AndromedaHook::OnTokenTransfer { .. } => SystemResult::Ok(ContractResult::Ok(
373 to_json_binary::<Response>(&Response::default()).unwrap(),
374 )),
375 },
376 }
377 }
378
379 #[cfg(feature = "modules")]
380 fn _handle_rates_query(&self, msg: &Binary) -> QuerierResult {
385 use cosmwasm_std::Response;
386
387 use crate::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse};
388 match from_json(msg).unwrap() {
389 HookMsg::AndrHook(hook) => match hook {
390 AndromedaHook::OnExecute { .. } => SystemResult::Ok(ContractResult::Ok(
391 to_json_binary::<Response>(&Response::default()).unwrap(),
392 )),
393 AndromedaHook::OnFundsTransfer { sender, .. } => {
394 if sender.as_str() == RATES_EXCLUDED_ADDRESS {
395 return SystemResult::Ok(ContractResult::Ok(
396 to_json_binary(&OnFundsTransferResponse::default()).unwrap(),
397 ));
398 }
399 todo!("Implement Rates Query")
401 }
402 AndromedaHook::OnTokenTransfer { .. } => SystemResult::Ok(ContractResult::Ok(
403 to_json_binary::<Response>(&Response::default()).unwrap(),
404 )),
405 },
406 }
407 }
408
409 fn handle_cw20_query(&self, msg: &Binary) -> QuerierResult {
413 match from_json(msg).unwrap() {
414 Cw20QueryMsg::Balance { .. } => {
415 let balance_response = BalanceResponse {
416 balance: 10u128.into(),
417 };
418 SystemResult::Ok(ContractResult::Ok(
419 to_json_binary(&balance_response).unwrap(),
420 ))
421 }
422 _ => panic!("Unsupported Query"),
423 }
424 }
425
426 pub fn handle_ado_raw_query(&self, key: &Binary, contract_addr: &Addr) -> QuerierResult {
427 let key_vec = key.as_slice();
428 let key_str = String::from_utf8(key_vec.to_vec()).unwrap();
429
430 if key_str.contains("owner") {
431 return SystemResult::Ok(ContractResult::Ok(
432 to_json_binary(&Addr::unchecked("owner".to_string())).unwrap(),
433 ));
434 }
435
436 panic!("Unsupported query for contract: {contract_addr}")
437 }
438
439 pub fn handle_kernel_raw_query(&self, key: &Binary, fake: bool) -> QuerierResult {
440 let key_vec = key.as_slice();
441 let key_str = String::from_utf8(key_vec.to_vec()).unwrap();
442
443 if key_str.contains("kernel_addresses") {
444 let split = key_str.split("kernel_addresses");
445 let key = split.last();
446 if let Some(key) = key {
447 match key {
448 VFS_KEY => SystemResult::Ok(ContractResult::Ok(
449 to_json_binary(&MOCK_VFS_CONTRACT.to_string()).unwrap(),
450 )),
451 ADO_DB_KEY => SystemResult::Ok(ContractResult::Ok(
452 to_json_binary(&MOCK_ADODB_CONTRACT.to_string()).unwrap(),
453 )),
454 OSMOSIS_ROUTER_KEY => SystemResult::Ok(ContractResult::Ok(
455 to_json_binary(&MOCK_OSMOSIS_ROUTER_CONTRACT.to_string()).unwrap(),
456 )),
457 ECONOMICS_KEY => SystemResult::Ok(ContractResult::Ok(
458 to_json_binary(&MOCK_ECONOMICS_CONTRACT.to_string()).unwrap(),
459 )),
460 _ => panic!("Invalid Kernel Address Key"),
461 }
462 } else {
463 panic!("Invalid Kernel Address Raw Query")
464 }
465 } else if key_str.contains("curr_chain") {
466 let res = if fake {
467 "fake_chain".to_string()
468 } else {
469 "andromeda".to_string()
470 };
471 SystemResult::Ok(ContractResult::Ok(to_json_binary(&res).unwrap()))
472 } else if key_str.contains("channel") {
473 SystemResult::Ok(ContractResult::Ok(
474 to_json_binary(&ChannelInfo {
475 kernel_address: "kernel".to_string(),
476 ics20_channel_id: Some("1".to_string()),
477 direct_channel_id: Some("2".to_string()),
478 supported_modules: vec![],
479 })
480 .unwrap(),
481 ))
482 } else {
483 panic!("Invalid Kernel Raw Query")
484 }
485 }
486
487 pub fn handle_adodb_raw_query(&self, key: &Binary) -> QuerierResult {
488 let key_vec = key.as_slice();
489 let key_str = String::from_utf8(key_vec.to_vec()).unwrap();
490
491 if key_str.contains("code_id") {
492 let split = key_str.split("code_id");
493 let key = split.last();
494 if let Some(key) = key {
495 match key {
496 FAKE_ADODB_KEY => {
497 SystemResult::Ok(ContractResult::Err("Invalid Key".to_string()))
498 }
499 _ => SystemResult::Ok(ContractResult::Ok(to_json_binary(&1).unwrap())),
500 }
501 } else {
502 panic!("Invalid ADODB Raw Query")
503 }
504 } else if key_str.contains("action_fees") {
505 let split = key_str.split("action_fees");
506 let key = split.last();
507 match key {
508 Some(key) => {
509 if key.contains("ADOTypeaction") {
510 SystemResult::Ok(ContractResult::Ok(
511 to_json_binary(&ActionFee::new(
512 MOCK_ACTION.to_string(),
513 "native:uusd".to_string(),
514 Uint128::from(10u128),
515 ))
516 .unwrap(),
517 ))
518 } else {
519 SystemResult::Ok(ContractResult::Err("Invalid Key".to_string()))
520 }
521 }
522 None => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
523 }
524 } else if key_str.contains("ado_type") {
525 let split = key_str.split("ado_type");
526 let key = split.last();
527 if let Some(key) = key {
530 if key == "3" {
531 SystemResult::Ok(ContractResult::Ok(to_json_binary("app-contract").unwrap()))
532 } else if key == "1" {
533 SystemResult::Ok(ContractResult::Ok(to_json_binary("ADOType").unwrap()))
534 } else {
535 SystemResult::Ok(ContractResult::Ok(Binary::default()))
536 }
537 } else {
538 SystemResult::Ok(ContractResult::Err("Invalid Key".to_string()))
539 }
540 } else if key_str.contains("publisher") {
541 let split = key_str.split("ado_type");
542 let key = split.last();
543 match key {
544 Some(key) => match key {
545 FAKE_ADODB_KEY => {
546 SystemResult::Ok(ContractResult::Err("Invalid Key".to_string()))
547 }
548 _ => SystemResult::Ok(ContractResult::Ok(
549 to_json_binary(MOCK_ADO_PUBLISHER).unwrap(),
550 )),
551 },
552 None => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())),
553 }
554 } else {
555 panic!("Invalid ADODB Raw Query")
556 }
557 }
558
559 pub fn handle_ado_query(&self, msg: AndromedaQuery) -> QuerierResult {
560 match msg {
561 AndromedaQuery::AppContract {} => SystemResult::Ok(ContractResult::Ok(
562 to_json_binary(&MOCK_APP_CONTRACT.to_string()).unwrap(),
563 )),
564 _ => panic!("Unsupported ADO query"),
565 }
566 }
567}
568
569#[cfg(feature = "modules")]
570pub fn calculate_mock_rates_response() -> (Vec<SubMsg>, Vec<Coin>) {
571 todo!("Implement after readding rates contract");
572}