abstract_testing/
lib.rs

1pub(crate) mod abstract_mock_querier;
2pub mod map_tester;
3pub mod mock_ans;
4pub(crate) mod mock_querier;
5
6use abstract_std::account::{ConfigResponse as AccountConfigResponse, QueryMsg as AccountQueryMsg};
7use abstract_std::objects::ABSTRACT_ACCOUNT_ID;
8use abstract_std::registry;
9use abstract_std::{
10    account::state::ACCOUNT_ID,
11    account::state::ACCOUNT_MODULES,
12    objects::{
13        module::{ModuleInfo, ModuleVersion},
14        module_reference::ModuleReference,
15        ownership,
16    },
17    registry::state::{ACCOUNT_ADDRESSES, REGISTERED_MODULES},
18    ACCOUNT,
19};
20use cosmwasm_std::{
21    from_json,
22    testing::{MockApi, MockQuerier, MockStorage},
23    to_json_binary, Addr, Binary, Empty, OwnedDeps,
24};
25use cosmwasm_std::{ContractInfo, Env};
26pub use mock_ans::MockAnsHost;
27pub use mock_querier::{
28    map_key, raw_map_key, wrap_querier, MockQuerierBuilder, MockQuerierOwnership,
29};
30use module::{TEST_MODULE_ID, TEST_MODULE_RESPONSE};
31use prelude::*;
32pub type MockDeps = OwnedDeps<MockStorage, MockApi, MockQuerier>;
33
34pub fn abstract_mock_querier_builder(mock_api: MockApi) -> MockQuerierBuilder {
35    let raw_handler = move |contract: &Addr, key: &Binary| {
36        let abstr = AbstractMockAddrs::new(mock_api);
37
38        if contract == abstr.account.addr() {
39            // Return the default value
40            Ok(Binary::default())
41        } else if contract == abstr.registry {
42            // Default value
43            Ok(Binary::default())
44        } else {
45            let str_key = std::str::from_utf8(key.as_slice()).unwrap();
46
47            Err(format!(
48                "attempt to query {} with key {}",
49                contract, str_key
50            ))
51        }
52    };
53    let abstr = AbstractMockAddrs::new(mock_api);
54
55    MockQuerierBuilder::new(mock_api)
56        .with_fallback_raw_handler(raw_handler)
57        .with_contract_map_entry(
58            &abstr.registry,
59            ACCOUNT_ADDRESSES,
60            (&ABSTRACT_ACCOUNT_ID, abstr.account.clone()),
61        )
62        .with_contract_item(
63            &abstr.registry,
64            registry::state::CONFIG,
65            &registry::Config {
66                security_enabled: false,
67                namespace_registration_fee: None,
68            },
69        )
70        .with_contract_map_entry(
71            &abstr.registry,
72            REGISTERED_MODULES,
73            (
74                &ModuleInfo::from_id(ACCOUNT, ModuleVersion::Version(TEST_VERSION.into())).unwrap(),
75                ModuleReference::Account(1),
76            ),
77        )
78        .with_contract_map_entry(
79            // Adding a map module inside the registry
80            &abstr.registry,
81            REGISTERED_MODULES,
82            (
83                &ModuleInfo::from_id(TEST_MODULE_ID, ModuleVersion::Version(TEST_VERSION.into()))
84                    .unwrap(),
85                ModuleReference::App(2),
86            ),
87        )
88        .with_contract_item(abstr.account.addr(), ACCOUNT_ID, &ABSTRACT_ACCOUNT_ID)
89        .with_contract_version(abstr.account.addr(), ACCOUNT, TEST_VERSION)
90        .with_smart_handler(&abstr.module_address, |msg| {
91            let Empty {} = from_json(msg).unwrap();
92            Ok(to_json_binary(TEST_MODULE_RESPONSE).unwrap())
93        })
94        .with_contract_map_entry(
95            abstr.account.addr(),
96            ACCOUNT_MODULES,
97            (TEST_MODULE_ID, abstr.module_address),
98        )
99        .with_smart_handler(abstr.account.addr(), move |msg| {
100            let abstr = AbstractMockAddrs::new(mock_api);
101            match from_json(msg).unwrap() {
102                AccountQueryMsg::Config {} => {
103                    let resp = AccountConfigResponse {
104                        registry_address: abstr.registry,
105                        module_factory_address: abstr.module_factory,
106                        account_id: ABSTRACT_ACCOUNT_ID, // mock value, not used
107                        is_suspended: false,
108                        whitelisted_addresses: vec![],
109                    };
110                    Ok(to_json_binary(&resp).unwrap())
111                }
112                AccountQueryMsg::Ownership {} => {
113                    let resp = ownership::Ownership {
114                        owner: ownership::GovernanceDetails::Monarchy {
115                            monarch: abstr.owner,
116                        },
117                        pending_expiry: None,
118                        pending_owner: None,
119                    };
120                    Ok(to_json_binary(&resp).unwrap())
121                }
122                _ => panic!("unexpected message"),
123            }
124        })
125        .with_owner(abstr.account.addr(), Some(&abstr.owner))
126}
127
128/// A mock querier that returns the following responses for the following **RAW** contract -> queries:
129/// - ABSTRACT_ACCOUNT
130///   - "admin" -> TEST_OWNER
131///   - "modules:TEST_MODULE_ID" -> TEST_MODULE_ADDRESS
132///   - "account_id" -> ABSTRACT_ACCOUNT_ID
133/// - REGISTRY
134///   - "account" -> { ABSTRACT_ACCOUNT }
135///
136/// Also it returns query responses for
137/// - [`cosmwasm_std::WasmQuery::ContractInfo`]
138///   - $contract_address -> ContractInfoResponse { creator: api.addr_make([`crate::OWNER`]), code_id: 1, admin: $contract_address}
139/// - [`cosmwasm_std::WasmQuery::CodeInfo`]
140///   - $code_id -> CodeInfoResponse { code_id: $code_id, creator: api.addr_make([`crate::OWNER`]), checksum: [`abstract_std::native_addrs::BLOB_CHECKSUM`]}
141pub fn abstract_mock_querier(mock_api: MockApi) -> MockQuerier {
142    abstract_mock_querier_builder(mock_api).build()
143}
144
145/// cosmwasm_std::mock_env_validated(deps.api), but address generated with MockApi
146pub fn mock_env_validated(mock_api: MockApi) -> Env {
147    Env {
148        contract: ContractInfo {
149            address: mock_api.addr_make(cosmwasm_std::testing::MOCK_CONTRACT_ADDR),
150        },
151        ..cosmwasm_std::testing::mock_env()
152    }
153}
154
155/// use the package version as test version, breaks tests otherwise.
156pub const TEST_VERSION: &str = env!("CARGO_PKG_VERSION");
157pub mod addresses {
158    use abstract_std::{native_addrs, registry::Account};
159    use cosmwasm_std::{instantiate2_address, testing::MockApi, Addr, Api};
160
161    // Test addr makers
162    const ADMIN_ACCOUNT: &str = "admin_account_address";
163    const TEST_ACCOUNT: &str = "account_address";
164
165    pub fn admin_account(mock_api: MockApi) -> Account {
166        Account::new(mock_api.addr_make(ADMIN_ACCOUNT))
167    }
168
169    pub fn test_account(mock_api: MockApi) -> Account {
170        Account::new(mock_api.addr_make(TEST_ACCOUNT))
171    }
172
173    impl AbstractMockAddrs {
174        pub fn new(mock_api: MockApi) -> AbstractMockAddrs {
175            let owner = mock_api.addr_make(crate::OWNER);
176            let owner_canon = mock_api.addr_canonicalize(owner.as_str()).unwrap();
177            let ans_host = instantiate2_address(
178                &native_addrs::BLOB_CHECKSUM,
179                &owner_canon,
180                native_addrs::ANS_HOST_SALT,
181            )
182            .unwrap();
183            let registry = instantiate2_address(
184                &native_addrs::BLOB_CHECKSUM,
185                &owner_canon,
186                native_addrs::REGISTRY_SALT,
187            )
188            .unwrap();
189            let module_factory = instantiate2_address(
190                &native_addrs::BLOB_CHECKSUM,
191                &owner_canon,
192                native_addrs::MODULE_FACTORY_SALT,
193            )
194            .unwrap();
195
196            AbstractMockAddrs {
197                owner,
198                ans_host: mock_api.addr_humanize(&ans_host).unwrap(),
199                registry: mock_api.addr_humanize(&registry).unwrap(),
200                module_factory: mock_api.addr_humanize(&module_factory).unwrap(),
201                account: admin_account(mock_api),
202                module_address: mock_api.addr_make("module"),
203            }
204        }
205    }
206
207    #[derive(Debug, Clone)]
208    pub struct AbstractMockAddrs {
209        pub owner: Addr,
210        pub ans_host: Addr,
211        pub registry: Addr,
212        pub module_factory: Addr,
213        pub module_address: Addr,
214        pub account: Account,
215    }
216}
217
218pub mod ans {
219    pub const TEST_CHAIN: &str = "chain";
220    pub const TEST_DEX: &str = "test_dex";
221    pub const TEST_ASSET_1: &str = "chain>asset1";
222    pub const TEST_ASSET_2: &str = "chain>asset2";
223    pub const TEST_LP_TOKEN_NAME: &str = "test_dex/chain>asset1,chain>asset2";
224    pub const TEST_UNIQUE_ID: u64 = 69u64;
225    pub const TTOKEN: &str = "test_token";
226    pub const EUR_USD_PAIR: &str = "dex:eur_usd_pair";
227    pub const EUR_USD_LP: &str = "dex/eur,usd";
228    pub const TTOKEN_EUR_PAIR: &str = "dex:wynd_eur_pair";
229    pub const TTOKEN_EUR_LP: &str = "dex/wynd,eur";
230    pub const EUR: &str = "eur";
231    pub const USD: &str = "usd";
232}
233
234pub mod module {
235    pub const TEST_MODULE_ID: &str = "tester:test-module-id";
236    pub const TEST_WITH_DEP_MODULE_ID: &str = "tester-dependency:test-depending-module-id";
237    pub const TEST_WITH_DEP_NAMESPACE: &str = "tester-dependency";
238    pub const TEST_MODULE_NAME: &str = "test-module-id";
239    pub const TEST_NAMESPACE: &str = "tester";
240
241    pub const TEST_MODULE_RESPONSE: &str = "test_module_response";
242}
243pub mod prelude {
244    pub use super::{abstract_mock_querier, abstract_mock_querier_builder, mock_env_validated};
245    pub use abstract_mock_querier::AbstractMockQuerier;
246    use abstract_std::objects::{AccountId, AccountTrace};
247    pub use addresses::*;
248    pub use ans::*;
249    pub use cosmwasm_std::{
250        from_json,
251        testing::{MockApi as CwMockApi, MockQuerier, MockStorage},
252        to_json_binary,
253    };
254    pub use mock_querier::{map_key, raw_map_key, wrap_querier, MockQuerierBuilder};
255    pub use module::*;
256
257    use super::*;
258    pub use super::{MockAnsHost, MockDeps, TEST_VERSION};
259    pub const OWNER: &str = "owner";
260    pub const TEST_ACCOUNT_ID: AccountId = AccountId::const_new(1, AccountTrace::Local);
261}