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.
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 accountGetOrderById(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:
PlaceOrders()
followed by GetOrders()
:First placing an order:
```rust
let mut orders: Vec
// Make order1 let price = Decimal::raw(100); let quantity = Decimal::raw(1000); let pricedenom = "USDC".tostring(); let assetdenom = "ATOM".tostring(); let ordertype = OrderType::Market; let positiondirection = PositionDirection::Long; let data = "".tostring(); let statusdescription = "order1".to_string();
let order1: Order = Order { price: price, quantity: quantity, pricedenom: pricedenom.clone(), assetdenom: assetdenom.clone(), ordertype: ordertype, positiondirection: positiondirection, data: data, statusdescription: statusdescription, }; orders.push(order1);
let res = app .executemulti( Addr::unchecked(ADMIN), vec![CosmosMsg::Custom(SeiMsg::PlaceOrders { orders: orders, funds: funds, contractaddress: Addr::unchecked(&contract_addr), })], ) .unwrap(); ```
Then querying:
```rust let res: GetOrdersResponse = app .wrap() .querywasmsmart( seitesteraddr.clone(), &QueryMsg::GetOrders { contractaddress: contractaddr.tostring(), account: seitesteraddr.tostring(), }, ) .unwrap();
asserteq!(res.orders.len(), 1); asserteq!(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();
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 pairsOracleTwaps(lookback_seconds)
: returns the TWAP of all pairs for the provided lookback_seconds
Examples:
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();