## Integration Tests ### General Setup Example tests are provided in `sei_cosmwasm_integration_tests.rs`. The tests use `setup_test()` which utilize `cw_multi_test` to instantiate a wrapper version of a cosmwasm contract, for example, `sei_tester` which can be found in this repo under `contracts/sei_tester`. A typical integration test will start with: ```rust let mut app = mock_app(init_default_balances, vec![]); let sei_tester_addr = setup_test(&mut app); ``` followed by relevant any relevant `Msg` to execute or `Query` to run. To execute a `MsgToExecute` you can use `execute()` or `execute_multi()`: ```rust app .execute_multi( addr_to_use, vec![CosmosMsg::Custom(SeiMsg::MsgToExecute { ... })], ) .unwrap(); ``` To query `MsgToQuery` you can use `query_wasm_smart()`: ```rust app .wrap() .query_wasm_smart( contract_addr, &QueryMsg::MsgToQuery { ... }, ) ``` Module functionality is mocked at the chain level, more details on each module can be found below. ### Dex Module You can interact with a mocked version of the dex module in the following ways: Messages: - `PlaceOrders(orders, funds, contract_address)`: places the corresponding `orders` for the `contract_address`. Each order follows the `Order` struct and has an `order_id`. - `CancelOrders(order_ids, contract_address)`: cancels the particular `order_ids` for the `contract_address`. Queries: - `GetOrders(contract_address, account)`: returns `orders` for a given account - `GetOrderById(contract_address, price_denom, asset_denom, id)`: returns particular `order` based on `id` and `price_denom`, and `asset_denom`. - `OrderSimulation(contract_address, order)`: retuns the simulation of an `order` against the existing placed orders for a given `contract_address`. Examples: - Below is an example where you make an order and call `PlaceOrders()` followed by `GetOrders()`: First placing an order: ```rust let mut orders: Vec = Vec::new(); let mut funds = Vec::::new(); let contract_addr = "example_contract".to_string(); // Make order1 let price = Decimal::raw(100); let quantity = Decimal::raw(1000); let price_denom = "USDC".to_string(); let asset_denom = "ATOM".to_string(); let order_type = OrderType::Market; let position_direction = PositionDirection::Long; let data = "".to_string(); let status_description = "order1".to_string(); let order1: Order = Order { price: price, quantity: quantity, price_denom: price_denom.clone(), asset_denom: asset_denom.clone(), order_type: order_type, position_direction: position_direction, data: data, status_description: status_description, }; orders.push(order1); let res = app .execute_multi( Addr::unchecked(ADMIN), vec![CosmosMsg::Custom(SeiMsg::PlaceOrders { orders: orders, funds: funds, contract_address: Addr::unchecked(&contract_addr), })], ) .unwrap(); ``` Then querying: ```rust let res: GetOrdersResponse = app .wrap() .query_wasm_smart( sei_tester_addr.clone(), &QueryMsg::GetOrders { contract_address: contract_addr.to_string(), account: sei_tester_addr.to_string(), }, ) .unwrap(); assert_eq!(res.orders.len(), 1); assert_eq!(res.orders[0].id, 0); assert_eq!(res.orders[0].status, OrderStatus::Placed); ... ``` To simulate an order: ```rust let res: OrderSimulationResponse = app .wrap() .query(&QueryRequest::Custom(SeiQueryWrapper { route: SeiRoute::Dex, query_data: SeiQuery::OrderSimulation { contract_address: Addr::unchecked(contract_addr.to_string()), order: Order { price: Decimal::raw(100), quantity: Decimal::raw(10000), price_denom: "USDC".to_string(), asset_denom: "ATOM".to_string(), order_type: OrderType::Limit, position_direction: PositionDirection::Short, data: "".to_string(), status_description: "test_order".to_string(), nominal: Decimal::zero(), }, }, })) .unwrap(); ``` ### Oracle Module The oracle module should only be interacted with after initializing the app with a price history of assets: ```rust let app = mock_app( init_default_balances, vec![ DenomOracleExchangeRatePair { denom: "uusdc".to_string(), oracle_exchange_rate: OracleExchangeRate { exchange_rate: Decimal::percent(80), last_update: Uint64::zero(), }, }, DenomOracleExchangeRatePair { denom: "usei".to_string(), oracle_exchange_rate: OracleExchangeRate { exchange_rate: Decimal::percent(70), last_update: Uint64::zero(), }, }, DenomOracleExchangeRatePair { denom: "uusdc".to_string(), oracle_exchange_rate: OracleExchangeRate { exchange_rate: Decimal::percent(90), last_update: Uint64::new(1), }, }, ], ); ``` Queries: - `ExchangeRates()`: returns the most recent exchange rates of all pairs - `OracleTwaps(lookback_seconds)`: returns the TWAP of all pairs for the provided `lookback_seconds` Examples: - Below are two examples of querying the oracle module: ExchangeRates: ```rust let res: ExchangeRatesResponse = app .wrap() .query(&QueryRequest::Custom(SeiQueryWrapper { route: SeiRoute::Oracle, query_data: SeiQuery::ExchangeRates {}, })) .unwrap(); ``` OracleTwaps: ```rust let res: OracleTwapsResponse = app .wrap() .query(&QueryRequest::Custom(SeiQueryWrapper { route: SeiRoute::Oracle, query_data: SeiQuery::OracleTwaps { lookback_seconds: 10, }, })) .unwrap(); ```