provwasm_mocks/
querier.rs

1use std::collections::HashMap;
2use std::marker::PhantomData;
3
4use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage};
5use cosmwasm_std::{
6    from_json, Binary, Coin, Empty, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError,
7    SystemResult,
8};
9use serde::de::DeserializeOwned;
10
11use provwasm_common::MockableQuerier;
12
13pub struct MockProvenanceQuerier<C: DeserializeOwned = Empty> {
14    /// Default CosmWASM mock querier.
15    pub mock_querier: MockQuerier<C>,
16    /// Registered custom queries using proto request for testing.
17    #[allow(clippy::complexity)]
18    pub registered_custom_queries: HashMap<String, Box<dyn Fn(&Binary) -> QuerierResult>>,
19}
20
21impl MockProvenanceQuerier {
22    /// Initialize a new [`MockProvenanceQuerier`].
23    ///
24    /// `balances` - Slice of balances passed to the `bank` module, where the first element
25    /// is the user address and the second element is the user's balance.
26    pub fn new(balances: &[(&str, &[Coin])]) -> Self {
27        MockProvenanceQuerier {
28            mock_querier: MockQuerier::new(balances),
29            registered_custom_queries: HashMap::new(),
30        }
31    }
32    /// Handle the query request.
33    pub fn handle_query(&self, request: &QueryRequest<Empty>) -> QuerierResult {
34        match request {
35            QueryRequest::Stargate { path, data } => {
36                if let Some(response_fn) = self.registered_custom_queries.get(path) {
37                    return response_fn(data);
38                }
39                SystemResult::Err(SystemError::UnsupportedRequest { kind: path.into() })
40            }
41            QueryRequest::Grpc(grpc_query) => {
42                if let Some(response_fn) = self.registered_custom_queries.get(&grpc_query.path) {
43                    return response_fn(&grpc_query.data);
44                }
45                SystemResult::Err(SystemError::UnsupportedRequest {
46                    kind: grpc_query.path.to_string(),
47                })
48            }
49            _ => self.mock_querier.handle_query(request),
50        }
51    }
52}
53
54impl MockableQuerier for MockProvenanceQuerier {
55    fn register_custom_query(
56        &mut self,
57        path: String,
58        response_fn: Box<dyn Fn(&Binary) -> QuerierResult>,
59    ) {
60        self.registered_custom_queries.insert(path, response_fn);
61    }
62}
63
64impl Querier for MockProvenanceQuerier {
65    fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
66        let request: QueryRequest<Empty> = match from_json(bin_request) {
67            Ok(v) => v,
68            Err(e) => {
69                return SystemResult::Err(SystemError::InvalidRequest {
70                    error: format!("Parsing query request: {e}"),
71                    request: bin_request.into(),
72                });
73            }
74        };
75        self.handle_query(&request)
76    }
77}
78
79impl Default for MockProvenanceQuerier {
80    fn default() -> Self {
81        MockProvenanceQuerier::new(&[])
82    }
83}
84
85/// Creates an instance of [`OwnedDeps`](cosmwasm_std::OwnedDeps) with a custom [`MockProvenanceQuerier`]
86/// to allow the user to mock the query responses of one or more Provenance's modules.
87pub fn mock_provenance_dependencies_with_custom_querier(
88    querier: MockProvenanceQuerier,
89) -> OwnedDeps<MockStorage, MockApi, MockProvenanceQuerier, Empty> {
90    OwnedDeps::<_, _, _, Empty> {
91        storage: MockStorage::default(),
92        api: MockApi::default(),
93        querier,
94        custom_query_type: PhantomData,
95    }
96}
97
98/// Creates an instance of [`OwnedDeps`](cosmwasm_std::OwnedDeps) that is capable of
99/// handling queries towards Provenance's modules.
100pub fn mock_provenance_dependencies(
101) -> OwnedDeps<MockStorage, MockApi, MockProvenanceQuerier, Empty> {
102    mock_provenance_dependencies_with_custom_querier(MockProvenanceQuerier::default())
103}
104
105#[cfg(test)]
106mod test {
107    use cosmwasm_std::{coin, from_binary, BalanceResponse, BankQuery};
108
109    use super::*;
110
111    #[test]
112    fn query_with_balances_2_0() {
113        let amount = coin(12345, "denom");
114        let querier = MockProvenanceQuerier::new(&[("alice", &[amount.clone()])]);
115        let deps = mock_provenance_dependencies_with_custom_querier(querier);
116        let bin = deps
117            .querier
118            .handle_query(
119                &BankQuery::Balance {
120                    address: "alice".into(),
121                    denom: "denom".into(),
122                }
123                .into(),
124            )
125            .unwrap()
126            .unwrap();
127
128        let res: BalanceResponse = from_binary(&bin).unwrap();
129        assert_eq!(res.amount, amount);
130    }
131}