Skip to content

Commit

Permalink
test(law): add test for store_reply
Browse files Browse the repository at this point in the history
  • Loading branch information
bdeneux authored and amimart committed Mar 23, 2023
1 parent 314bf4a commit 3c9d30a
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 6 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ cosmwasm-std = "1.2.2"
cosmwasm-storage = "1.2.2"
cw-multi-test = "0.15.1"
cw-storage-plus = "0.15.1"
cw-utils = "1.0.1"
cw2 = "0.15.1"
schemars = "0.8.12"
serde = { version = "1.0.158", default-features = false, features = ["derive"] }
Expand Down
1 change: 1 addition & 0 deletions contracts/cw-law-stone/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ cosmwasm-std.workspace = true
cosmwasm-storage.workspace = true
cw-storage = { path = "../cw-storage" }
cw-storage-plus.workspace = true
cw-utils.worksapce = true
cw2.workspace = true
logic-bindings = { version = "0.2", path = "../../packages/logic-bindings" }
schemars.workspace = true
Expand Down
185 changes: 179 additions & 6 deletions contracts/cw-law-stone/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ use crate::ContractError::NotImplemented;
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, SubMsg,
WasmMsg,
to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, StdResult,
SubMsg, WasmMsg,
};
use cw2::set_contract_version;
use cw_storage::msg::ExecuteMsg as StorageMsg;
use cw_storage::msg::{ExecuteMsg as StorageMsg, ObjectResponse};
use cw_utils::parse_reply_execute_data;
use logic_bindings::LogicCustomQuery;

use crate::error::ContractError;
Expand Down Expand Up @@ -59,11 +60,40 @@ pub fn query(_deps: Deps<'_>, _env: Env, _msg: QueryMsg) -> StdResult<Binary> {
Err(StdError::generic_err("Not implemented"))
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn reply(
deps: DepsMut<'_, LogicCustomQuery>,
env: Env,
msg: Reply,
) -> Result<Response, ContractError> {
match msg.id {
STORE_PROGRAM_REPLY_ID => reply::store_program_reply(deps, env, msg),
_ => Err(StdError::generic_err("Not implemented").into()),
}
}

pub mod reply {
use super::*;

pub fn store_program_reply(
_deps: DepsMut<'_, LogicCustomQuery>,
_env: Env,
msg: Reply,
) -> Result<Response, ContractError> {
let _ = parse_reply_execute_data(msg)?;
Err(StdError::generic_err("Not implemented").into())
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::state::{DEPENDENCIES, PROGRAM};
use cosmwasm_std::testing::{mock_env, mock_info, MockQuerierCustomHandlerResult};
use cosmwasm_std::{from_binary, to_binary, CosmosMsg, SystemError, SystemResult};
use cosmwasm_std::{
from_binary, to_binary, CosmosMsg, Order, SubMsgResponse, SubMsgResult, SystemError,
SystemResult,
};
use logic_bindings::testing::mock::mock_dependencies_with_logic_handler;
use logic_bindings::{
Answer, AskResponse, LogicCustomQuery, Result as LogicResult, Substitution, Term,
Expand Down Expand Up @@ -108,7 +138,7 @@ mod tests {
#[test]
fn proper_initialization() {
let mut deps = mock_dependencies_with_logic_handler(|request| {
custom_logic_handler_with_dependencies(vec!["file1".to_string()], request)
custom_logic_handler_with_dependencies(vec![], request)
});
let program = to_binary("foo(_) :- true.").unwrap();

Expand All @@ -132,7 +162,7 @@ mod tests {
match result {
StorageMsg::StoreObject { data, pin } => {
assert_eq!(data, program);
assert!(pin);
assert!(pin, "the main program should be pinned");
}
_ => assert!(false, "storage message should be a StoreObject message"),
}
Expand All @@ -142,4 +172,147 @@ mod tests {
_ => assert!(false, "cosmos sub message should be a Wasm message execute"),
}
}

struct StoreTestCase {
dependencies: Vec<(String, String, String)>, // URI, contract address, object id
object_id: String,
}

#[test]
fn store_program_reply() {
let cases = vec![
StoreTestCase {
dependencies: vec![
(
"cosmwasm:okp41dclchlcttf2uektxyryg0c6yau63eml5q9uq03myg44ml8cxpxnqavca4s?query=%7B%22object_data%22%3A%7B%22id%22%3A%20%224cbe36399aabfcc7158ee7a66cbfffa525bb0ceab33d1ff2cff08759fe0a9b05%22%7D%7D".to_string(),
"okp41dclchlcttf2uektxyryg0c6yau63eml5q9uq03myg44ml8cxpxnqavca4s".to_string(),
"4cbe36399aabfcc7158ee7a66cbfffa525bb0ceab33d1ff2cff08759fe0a9b05".to_string()
),
],
object_id: "0689c526187c6785dfcce28f8df19138da292598dc19548a852de1792062f271"
.to_string(),
},
StoreTestCase {
dependencies: vec![],
object_id: "4cbe36399aabfcc7158ee7a66cbfffa525bb0ceab33d1ff2cff08759fe0a9b05"
.to_string(),
},
StoreTestCase {
dependencies: vec![
(
"cosmwasm:okp41dclchlcttf2uektxyryg0c6yau63eml5q9uq03myg44ml8cxpxnqavca4s?query=%7B%22object_data%22%3A%7B%22id%22%3A%20%224cbe36399aabfcc7158ee7a66cbfffa525bb0ceab33d1ff2cff08759fe0a9b05%22%7D%7D".to_string(),
"okp41dclchlcttf2uektxyryg0c6yau63eml5q9uq03myg44ml8cxpxnqavca4s".to_string(), // contract addr
"4cbe36399aabfcc7158ee7a66cbfffa525bb0ceab33d1ff2cff08759fe0a9b05".to_string() // object id
),
(
"cosmwasm:okp41dclchlcttf2uektxyryg0c6yau63eml5q9uq03myg44ml8cxpxnqavca4s?query=%7B%22object_data%22%3A%7B%22id%22%3A%20%220689c526187c6785dfcce28f8df19138da292598dc19548a852de1792062f271%22%7D%7D".to_string(),
"okp41dclchlcttf2uektxyryg0c6yau63eml5q9uq03myg44ml8cxpxnqavca4s".to_string(), // contract addr
"0689c526187c6785dfcce28f8df19138da292598dc19548a852de1792062f271".to_string() // object id
),
],
object_id: "0689c526187c6785dfcce28f8df19138da292598dc19548a852de1792062f271"
.to_string(),
},
];

for case in cases {
let uris = Box::new(
case.dependencies
.clone()
.into_iter()
.map(|(uri, _, _)| uri)
.collect::<Vec<String>>(),
);
let mut deps = mock_dependencies_with_logic_handler(move |request| {
custom_logic_handler_with_dependencies(uris.to_vec(), request)
});

let object = ObjectResponse {
id: case.object_id.clone(),
owner: "creator".to_string(),
is_pinned: true,
size: Default::default(),
};
let reply = Reply {
id: STORE_PROGRAM_REPLY_ID,
result: SubMsgResult::Ok(SubMsgResponse {
events: vec![],
data: Some(to_binary(&object).unwrap()),
}),
};
let res = reply::store_program_reply(deps.as_mut(), mock_env(), reply).unwrap();

let program = PROGRAM.load(&deps.storage).unwrap();
assert_eq!(case.object_id.clone(), program.object_id);

let deps_len_requirement = case.dependencies.len();

if deps_len_requirement > 0 {
assert_eq!(
deps_len_requirement,
DEPENDENCIES
.keys_raw(&deps.storage, None, None, Order::Ascending)
.count()
);
for (_, contract_addr, object_id) in case.dependencies {
let o = DEPENDENCIES.load(&deps.storage, object_id.as_str());
assert!(
o.is_ok(),
"dependencies should contains each object id dependencies as key"
);
let o = o.unwrap();
assert_eq!(
o.object_id, object_id,
"dependencies should contains each object id dependencies as key"
);
assert_eq!(
o.storage_address, contract_addr,
"dependencies should contains each object id dependencies as key"
);
}
}

assert_eq!(
deps_len_requirement,
res.messages.len(),
"response should contains any sub message as dependencies"
);

let objects_pinned: Vec<String> = res
.messages
.into_iter()
.flat_map(|sub_msg| -> Option<String> {
match &sub_msg.msg {
CosmosMsg::Wasm(wasm_msg) => match wasm_msg {
WasmMsg::Execute { msg, .. } => {
let result: StorageMsg = from_binary(msg).unwrap();
match result {
StorageMsg::PinObject { id } => Some(id),
_ => {
assert!(false, "should contains only PinObject message(s)");
None
}
}
}
_ => {
assert!(false, "wasm message should be a Storage message");
None
}
},
_ => {
assert!(false, "cosmos sub message should be a Wasm message execute");
None
}
}
})
.collect();

for object in objects_pinned {
assert!(
DEPENDENCIES.has(&deps.storage, object.as_str()),
"each dependencies should be pinned by a PinObject message"
)
}
}
}
}
4 changes: 4 additions & 0 deletions contracts/cw-law-stone/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cosmwasm_std::StdError;
use cw_utils::ParseReplyError;
use thiserror::Error;

#[derive(Error, Debug)]
Expand All @@ -8,4 +9,7 @@ pub enum ContractError {

#[error("Not implemented")]
NotImplemented {},

#[error("{0}")]
Parse(#[from] ParseReplyError),
}

0 comments on commit 3c9d30a

Please sign in to comment.