multiversx_sc_scenario/facade/
scenario_world_steps.rs

1#![allow(deprecated)]
2
3use multiversx_sc::{
4    abi::TypeAbiFrom,
5    codec::TopDecodeMulti,
6    types::{heap::Address, ContractCall},
7};
8
9use crate::{
10    api::StaticApi,
11    facade::ScenarioWorld,
12    multiversx_sc::codec::TopEncodeMulti,
13    scenario::{model::*, ScenarioRunner},
14};
15
16impl ScenarioWorld {
17    /// Imports and processes steps from an external scenario file.
18    pub fn external_steps(&mut self, step: ExternalStepsStep) -> &mut Self {
19        self.run_external_steps(&step);
20        self
21    }
22
23    /// Adds a SC call step, then executes it.
24    pub fn set_state_step(&mut self, step: SetStateStep) -> &mut Self {
25        self.run_set_state_step(&step);
26        self
27    }
28
29    /// Adds a SC call step, then executes it.
30    pub fn sc_call<S>(&mut self, mut step: S) -> &mut Self
31    where
32        S: AsMut<ScCallStep>,
33    {
34        self.run_sc_call_step(step.as_mut());
35        self
36    }
37
38    #[deprecated(
39        since = "0.49.0",
40        note = "Please use the unified transaction syntax instead."
41    )]
42    pub fn sc_call_use_raw_response<S, F>(&mut self, mut step: S, use_raw_response: F) -> &mut Self
43    where
44        S: AsMut<ScCallStep>,
45        F: FnOnce(&TxResponse),
46    {
47        self.run_sc_call_step(step.as_mut());
48        let response = unwrap_response(&step.as_mut().response);
49        use_raw_response(response);
50        self
51    }
52
53    #[deprecated(
54        since = "0.49.0",
55        note = "Please use the unified transaction syntax instead."
56    )]
57    pub fn sc_call_use_result<OriginalResult, RequestedResult, F>(
58        &mut self,
59        step: TypedScCall<OriginalResult>,
60        use_result: F,
61    ) -> &mut Self
62    where
63        OriginalResult: TopEncodeMulti,
64        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
65        F: FnOnce(TypedResponse<RequestedResult>),
66    {
67        self.sc_call_use_raw_response(step, |response| {
68            let typed_response = TypedResponse::from_raw(response);
69            use_result(typed_response);
70        })
71    }
72
73    #[deprecated(
74        since = "0.49.0",
75        note = "Please use the unified transaction syntax instead."
76    )]
77    pub fn sc_call_get_result<OriginalResult, RequestedResult>(
78        &mut self,
79        mut step: TypedScCall<OriginalResult>,
80    ) -> RequestedResult
81    where
82        OriginalResult: TopEncodeMulti,
83        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
84    {
85        self.run_sc_call_step(&mut step.sc_call_step);
86        let response = unwrap_response(&step.sc_call_step.response);
87        let typed_response = TypedResponse::from_raw(response);
88        typed_response.result.expect("SC call failed")
89    }
90
91    /// Adds a SC query step, then executes it.
92    pub fn sc_query<S>(&mut self, mut step: S) -> &mut Self
93    where
94        S: AsMut<ScQueryStep>,
95    {
96        self.run_sc_query_step(step.as_mut());
97        self
98    }
99
100    #[deprecated(
101        since = "0.49.0",
102        note = "Please use the unified transaction syntax instead."
103    )]
104    pub fn sc_query_use_raw_response<S, F>(&mut self, mut step: S, use_raw_response: F) -> &mut Self
105    where
106        S: AsMut<ScQueryStep>,
107        F: FnOnce(&TxResponse),
108    {
109        let base_step = step.as_mut();
110        self.run_sc_query_step(base_step);
111        let response = unwrap_response(&base_step.response);
112        use_raw_response(response);
113        self
114    }
115
116    #[deprecated(
117        since = "0.49.0",
118        note = "Please use the unified transaction syntax instead."
119    )]
120    pub fn sc_query_use_result<OriginalResult, RequestedResult, F>(
121        &mut self,
122        step: TypedScQuery<OriginalResult>,
123        use_result: F,
124    ) -> &mut Self
125    where
126        OriginalResult: TopEncodeMulti,
127        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
128        F: FnOnce(TypedResponse<RequestedResult>),
129    {
130        self.sc_query_use_raw_response(step, |response| {
131            let typed_response = TypedResponse::from_raw(response);
132            use_result(typed_response);
133        })
134    }
135
136    #[deprecated(
137        since = "0.49.0",
138        note = "Please use the unified transaction syntax instead."
139    )]
140    pub fn sc_query_get_result<OriginalResult, RequestedResult>(
141        &mut self,
142        mut step: TypedScQuery<OriginalResult>,
143    ) -> RequestedResult
144    where
145        OriginalResult: TopEncodeMulti,
146        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
147    {
148        self.run_sc_query_step(&mut step.sc_query_step);
149        let response = unwrap_response(&step.sc_query_step.response);
150        let typed_response = TypedResponse::from_raw(response);
151        typed_response.result.expect("SC query failed")
152    }
153
154    /// Performs a SC query to a contract, leaves no scenario trace behind.
155    ///
156    /// Meant to be used for the test to investigate the state of the contract.
157    ///
158    /// Use `mandos_sc_query` to embed the SC query in the resulting scenario.
159    pub fn quick_query<CC, RequestedResult>(&mut self, contract_call: CC) -> RequestedResult
160    where
161        CC: ContractCall<StaticApi>,
162        RequestedResult: TopDecodeMulti + TypeAbiFrom<CC::OriginalResult>,
163    {
164        self.sc_query_get_result(ScQueryStep::new().call(contract_call))
165    }
166
167    /// Adds a SC deploy step, then executes it.
168    pub fn sc_deploy<S>(&mut self, mut step: S) -> &mut Self
169    where
170        S: AsMut<ScDeployStep>,
171    {
172        self.run_sc_deploy_step(step.as_mut());
173        self
174    }
175
176    #[deprecated(
177        since = "0.49.0",
178        note = "Please use the unified transaction syntax instead."
179    )]
180    pub fn sc_deploy_use_raw_response<S, F>(
181        &mut self,
182        mut step: S,
183        use_raw_response: F,
184    ) -> &mut Self
185    where
186        S: AsMut<ScDeployStep>,
187        F: FnOnce(&TxResponse),
188    {
189        let base_step = step.as_mut();
190        self.run_sc_deploy_step(base_step);
191        let response = unwrap_response(&base_step.response);
192        use_raw_response(response);
193        self
194    }
195
196    #[deprecated(
197        since = "0.49.0",
198        note = "Please use the unified transaction syntax instead."
199    )]
200    pub fn sc_deploy_use_result<OriginalResult, RequestedResult, F>(
201        &mut self,
202        step: TypedScDeploy<OriginalResult>,
203        use_result: F,
204    ) -> &mut Self
205    where
206        OriginalResult: TopEncodeMulti,
207        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
208        F: FnOnce(Address, TypedResponse<RequestedResult>),
209    {
210        self.sc_deploy_use_raw_response(step, |response| {
211            let new_address = unwrap_new_address(response);
212            let typed_response = TypedResponse::from_raw(response);
213            use_result(new_address, typed_response);
214        })
215    }
216
217    #[deprecated(
218        since = "0.49.0",
219        note = "Please use the unified transaction syntax instead."
220    )]
221    pub fn sc_deploy_get_result<OriginalResult, RequestedResult>(
222        &mut self,
223        mut step: TypedScDeploy<OriginalResult>,
224    ) -> (Address, RequestedResult)
225    where
226        OriginalResult: TopEncodeMulti,
227        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
228    {
229        self.run_sc_deploy_step(&mut step.sc_deploy_step);
230        let response = unwrap_response(&step.sc_deploy_step.response);
231        let new_address = unwrap_new_address(response);
232        let typed_response = TypedResponse::from_raw(response);
233        (new_address, typed_response.result.unwrap())
234    }
235
236    /// Adds a simple transfer step, then executes it.
237    pub fn transfer_step(&mut self, step: TransferStep) -> &mut Self {
238        self.run_transfer_step(&step);
239        self
240    }
241
242    /// Adds a validator reward step, then executes it.
243    pub fn validator_reward_step(&mut self, step: ValidatorRewardStep) -> &mut Self {
244        self.run_validator_reward_step(&step);
245        self
246    }
247
248    /// Adds a check state step, then executes it.
249    pub fn check_state_step(&mut self, step: CheckStateStep) -> &mut Self {
250        self.run_check_state_step(&step);
251        self
252    }
253
254    /// Adds a dump state step, then executes it.
255    pub fn dump_state_step(&mut self) -> &mut Self {
256        self.run_dump_state_step();
257        self
258    }
259}
260
261impl TypedScCallExecutor for ScenarioWorld {
262    fn execute_typed_sc_call<OriginalResult, RequestedResult>(
263        &mut self,
264        typed_sc_call: TypedScCall<OriginalResult>,
265    ) -> RequestedResult
266    where
267        OriginalResult: TopEncodeMulti,
268        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
269    {
270        self.sc_call_get_result(typed_sc_call)
271    }
272}
273
274impl TypedScDeployExecutor for ScenarioWorld {
275    fn execute_typed_sc_deploy<OriginalResult, RequestedResult>(
276        &mut self,
277        typed_sc_call: TypedScDeploy<OriginalResult>,
278    ) -> (Address, RequestedResult)
279    where
280        OriginalResult: TopEncodeMulti,
281        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
282    {
283        self.sc_deploy_get_result(typed_sc_call)
284    }
285}
286
287impl TypedScQueryExecutor for ScenarioWorld {
288    /// Adds a SC query step, but sets the contract call data and returns the result.
289    ///
290    /// It also sets in the trace the expected result to be the actual returned result.
291    ///
292    /// It is the duty of the test developer to check that the result is actually correct after the call.
293    fn execute_typed_sc_query<OriginalResult, RequestedResult>(
294        &mut self,
295        typed_sc_query: TypedScQuery<OriginalResult>,
296    ) -> RequestedResult
297    where
298        OriginalResult: TopEncodeMulti,
299        RequestedResult: TopDecodeMulti + TypeAbiFrom<OriginalResult>,
300    {
301        self.sc_query_get_result(typed_sc_query)
302    }
303}
304
305fn unwrap_response(opt_response: &Option<TxResponse>) -> &TxResponse {
306    opt_response.as_ref().expect("response not processed")
307}
308
309fn unwrap_new_address(response: &TxResponse) -> Address {
310    response
311        .new_deployed_address
312        .clone()
313        .expect("missing new address after deploy")
314}