735 lines
21 KiB
Rust
735 lines
21 KiB
Rust
#![cfg(test)]
|
|
use cosmwasm_std::{
|
|
from_binary,
|
|
testing::{mock_dependencies, mock_env, mock_info},
|
|
to_binary, CosmosMsg, DepsMut, Empty, Response, WasmMsg,
|
|
};
|
|
|
|
use cw721::{
|
|
Approval, ApprovalResponse, ContractInfoResponse, Cw721Query, Cw721ReceiveMsg, Expiration,
|
|
NftInfoResponse, OperatorsResponse, OwnerOfResponse,
|
|
};
|
|
|
|
use crate::{
|
|
ContractError, Cw721Contract, ExecuteMsg, Extension, InstantiateMsg, MintMsg, QueryMsg,
|
|
};
|
|
|
|
const MINTER: &str = "merlin";
|
|
const CONTRACT_NAME: &str = "Magic Power";
|
|
const SYMBOL: &str = "MGK";
|
|
|
|
fn setup_contract(deps: DepsMut<'_>) -> Cw721Contract<'static, Extension, Empty> {
|
|
let contract = Cw721Contract::default();
|
|
let msg = InstantiateMsg {
|
|
name: CONTRACT_NAME.to_string(),
|
|
symbol: SYMBOL.to_string(),
|
|
minter: String::from(MINTER),
|
|
};
|
|
let info = mock_info("creator", &[]);
|
|
let res = contract.instantiate(deps, mock_env(), info, msg).unwrap();
|
|
assert_eq!(0, res.messages.len());
|
|
contract
|
|
}
|
|
|
|
#[test]
|
|
fn proper_instantiation() {
|
|
let mut deps = mock_dependencies(&[]);
|
|
let contract = Cw721Contract::<Extension, Empty>::default();
|
|
|
|
let msg = InstantiateMsg {
|
|
name: CONTRACT_NAME.to_string(),
|
|
symbol: SYMBOL.to_string(),
|
|
minter: String::from(MINTER),
|
|
};
|
|
let info = mock_info("creator", &[]);
|
|
|
|
// we can just call .unwrap() to assert this was a success
|
|
let res = contract
|
|
.instantiate(deps.as_mut(), mock_env(), info, msg)
|
|
.unwrap();
|
|
assert_eq!(0, res.messages.len());
|
|
|
|
// it worked, let's query the state
|
|
let res = contract.minter(deps.as_ref()).unwrap();
|
|
assert_eq!(MINTER, res.minter);
|
|
let info = contract.contract_info(deps.as_ref()).unwrap();
|
|
assert_eq!(
|
|
info,
|
|
ContractInfoResponse {
|
|
name: CONTRACT_NAME.to_string(),
|
|
symbol: SYMBOL.to_string(),
|
|
}
|
|
);
|
|
|
|
let count = contract.num_tokens(deps.as_ref()).unwrap();
|
|
assert_eq!(0, count.count);
|
|
|
|
// list the token_ids
|
|
let tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap();
|
|
assert_eq!(0, tokens.tokens.len());
|
|
}
|
|
|
|
#[test]
|
|
fn minting() {
|
|
let mut deps = mock_dependencies(&[]);
|
|
let contract = setup_contract(deps.as_mut());
|
|
|
|
let token_id = "petrify".to_string();
|
|
let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string();
|
|
|
|
let mint_msg = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id.clone(),
|
|
owner: String::from("medusa"),
|
|
token_uri: Some(token_uri.clone()),
|
|
extension: None,
|
|
});
|
|
|
|
// random cannot mint
|
|
let random = mock_info("random", &[]);
|
|
let err = contract
|
|
.execute(deps.as_mut(), mock_env(), random, mint_msg.clone())
|
|
.unwrap_err();
|
|
assert_eq!(err, ContractError::Unauthorized {});
|
|
|
|
// minter can mint
|
|
let allowed = mock_info(MINTER, &[]);
|
|
let _ = contract
|
|
.execute(deps.as_mut(), mock_env(), allowed, mint_msg)
|
|
.unwrap();
|
|
|
|
// ensure num tokens increases
|
|
let count = contract.num_tokens(deps.as_ref()).unwrap();
|
|
assert_eq!(1, count.count);
|
|
|
|
// unknown nft returns error
|
|
let _ = contract
|
|
.nft_info(deps.as_ref(), "unknown".to_string())
|
|
.unwrap_err();
|
|
|
|
// this nft info is correct
|
|
let info = contract.nft_info(deps.as_ref(), token_id.clone()).unwrap();
|
|
assert_eq!(
|
|
info,
|
|
NftInfoResponse::<Extension> {
|
|
token_uri: Some(token_uri),
|
|
extension: None,
|
|
}
|
|
);
|
|
|
|
// owner info is correct
|
|
let owner = contract
|
|
.owner_of(deps.as_ref(), mock_env(), token_id.clone(), true)
|
|
.unwrap();
|
|
assert_eq!(
|
|
owner,
|
|
OwnerOfResponse {
|
|
owner: String::from("medusa"),
|
|
approvals: vec![],
|
|
}
|
|
);
|
|
|
|
// Cannot mint same token_id again
|
|
let mint_msg2 = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id.clone(),
|
|
owner: String::from("hercules"),
|
|
token_uri: None,
|
|
extension: None,
|
|
});
|
|
|
|
let allowed = mock_info(MINTER, &[]);
|
|
let err = contract
|
|
.execute(deps.as_mut(), mock_env(), allowed, mint_msg2)
|
|
.unwrap_err();
|
|
assert_eq!(err, ContractError::Claimed {});
|
|
|
|
// list the token_ids
|
|
let tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap();
|
|
assert_eq!(1, tokens.tokens.len());
|
|
assert_eq!(vec![token_id], tokens.tokens);
|
|
}
|
|
|
|
#[test]
|
|
fn burning() {
|
|
let mut deps = mock_dependencies(&[]);
|
|
let contract = setup_contract(deps.as_mut());
|
|
|
|
let token_id = "petrify".to_string();
|
|
let token_uri = "https://www.merriam-webster.com/dictionary/petrify".to_string();
|
|
|
|
let mint_msg = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id.clone(),
|
|
owner: MINTER.to_string(),
|
|
token_uri: Some(token_uri),
|
|
extension: None,
|
|
});
|
|
|
|
let burn_msg = ExecuteMsg::Burn { token_id };
|
|
|
|
// mint some NFT
|
|
let allowed = mock_info(MINTER, &[]);
|
|
let _ = contract
|
|
.execute(deps.as_mut(), mock_env(), allowed.clone(), mint_msg)
|
|
.unwrap();
|
|
|
|
// random not allowed to burn
|
|
let random = mock_info("random", &[]);
|
|
let err = contract
|
|
.execute(deps.as_mut(), mock_env(), random, burn_msg.clone())
|
|
.unwrap_err();
|
|
|
|
assert_eq!(err, ContractError::Unauthorized {});
|
|
|
|
let _ = contract
|
|
.execute(deps.as_mut(), mock_env(), allowed, burn_msg)
|
|
.unwrap();
|
|
|
|
// ensure num tokens decreases
|
|
let count = contract.num_tokens(deps.as_ref()).unwrap();
|
|
assert_eq!(0, count.count);
|
|
|
|
// trying to get nft returns error
|
|
let _ = contract
|
|
.nft_info(deps.as_ref(), "petrify".to_string())
|
|
.unwrap_err();
|
|
|
|
// list the token_ids
|
|
let tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap();
|
|
assert!(tokens.tokens.is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn transferring_nft() {
|
|
let mut deps = mock_dependencies(&[]);
|
|
let contract = setup_contract(deps.as_mut());
|
|
|
|
// Mint a token
|
|
let token_id = "melt".to_string();
|
|
let token_uri = "https://www.merriam-webster.com/dictionary/melt".to_string();
|
|
|
|
let mint_msg = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id.clone(),
|
|
owner: String::from("venus"),
|
|
token_uri: Some(token_uri),
|
|
extension: None,
|
|
});
|
|
|
|
let minter = mock_info(MINTER, &[]);
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), minter, mint_msg)
|
|
.unwrap();
|
|
|
|
// random cannot transfer
|
|
let random = mock_info("random", &[]);
|
|
let transfer_msg = ExecuteMsg::TransferNft {
|
|
recipient: String::from("random"),
|
|
token_id: token_id.clone(),
|
|
};
|
|
|
|
let err = contract
|
|
.execute(deps.as_mut(), mock_env(), random, transfer_msg)
|
|
.unwrap_err();
|
|
assert_eq!(err, ContractError::Unauthorized {});
|
|
|
|
// owner can
|
|
let random = mock_info("venus", &[]);
|
|
let transfer_msg = ExecuteMsg::TransferNft {
|
|
recipient: String::from("random"),
|
|
token_id: token_id.clone(),
|
|
};
|
|
|
|
let res = contract
|
|
.execute(deps.as_mut(), mock_env(), random, transfer_msg)
|
|
.unwrap();
|
|
|
|
assert_eq!(
|
|
res,
|
|
Response::new()
|
|
.add_attribute("action", "transfer_nft")
|
|
.add_attribute("sender", "venus")
|
|
.add_attribute("recipient", "random")
|
|
.add_attribute("token_id", token_id)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn sending_nft() {
|
|
let mut deps = mock_dependencies(&[]);
|
|
let contract = setup_contract(deps.as_mut());
|
|
|
|
// Mint a token
|
|
let token_id = "melt".to_string();
|
|
let token_uri = "https://www.merriam-webster.com/dictionary/melt".to_string();
|
|
|
|
let mint_msg = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id.clone(),
|
|
owner: String::from("venus"),
|
|
token_uri: Some(token_uri),
|
|
extension: None,
|
|
});
|
|
|
|
let minter = mock_info(MINTER, &[]);
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), minter, mint_msg)
|
|
.unwrap();
|
|
|
|
let msg = to_binary("You now have the melting power").unwrap();
|
|
let target = String::from("another_contract");
|
|
let send_msg = ExecuteMsg::SendNft {
|
|
contract: target.clone(),
|
|
token_id: token_id.clone(),
|
|
msg: msg.clone(),
|
|
};
|
|
|
|
let random = mock_info("random", &[]);
|
|
let err = contract
|
|
.execute(deps.as_mut(), mock_env(), random, send_msg.clone())
|
|
.unwrap_err();
|
|
assert_eq!(err, ContractError::Unauthorized {});
|
|
|
|
// but owner can
|
|
let random = mock_info("venus", &[]);
|
|
let res = contract
|
|
.execute(deps.as_mut(), mock_env(), random, send_msg)
|
|
.unwrap();
|
|
|
|
let payload = Cw721ReceiveMsg {
|
|
sender: String::from("venus"),
|
|
token_id: token_id.clone(),
|
|
msg,
|
|
};
|
|
let expected = payload.into_cosmos_msg(target.clone()).unwrap();
|
|
// ensure expected serializes as we think it should
|
|
match &expected {
|
|
CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, .. }) => {
|
|
assert_eq!(contract_addr, &target)
|
|
}
|
|
m => panic!("Unexpected message type: {:?}", m),
|
|
}
|
|
// and make sure this is the request sent by the contract
|
|
assert_eq!(
|
|
res,
|
|
Response::new()
|
|
.add_message(expected)
|
|
.add_attribute("action", "send_nft")
|
|
.add_attribute("sender", "venus")
|
|
.add_attribute("recipient", "another_contract")
|
|
.add_attribute("token_id", token_id)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn approving_revoking() {
|
|
let mut deps = mock_dependencies(&[]);
|
|
let contract = setup_contract(deps.as_mut());
|
|
|
|
// Mint a token
|
|
let token_id = "grow".to_string();
|
|
let token_uri = "https://www.merriam-webster.com/dictionary/grow".to_string();
|
|
|
|
let mint_msg = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id.clone(),
|
|
owner: String::from("demeter"),
|
|
token_uri: Some(token_uri),
|
|
extension: None,
|
|
});
|
|
|
|
let minter = mock_info(MINTER, &[]);
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), minter, mint_msg)
|
|
.unwrap();
|
|
|
|
// Give random transferring power
|
|
let approve_msg = ExecuteMsg::Approve {
|
|
spender: String::from("random"),
|
|
token_id: token_id.clone(),
|
|
expires: None,
|
|
};
|
|
let owner = mock_info("demeter", &[]);
|
|
let res = contract
|
|
.execute(deps.as_mut(), mock_env(), owner, approve_msg)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
Response::new()
|
|
.add_attribute("action", "approve")
|
|
.add_attribute("sender", "demeter")
|
|
.add_attribute("spender", "random")
|
|
.add_attribute("token_id", token_id.clone())
|
|
);
|
|
|
|
// test approval query
|
|
let res = contract
|
|
.approval(
|
|
deps.as_ref(),
|
|
mock_env(),
|
|
token_id.clone(),
|
|
String::from("random"),
|
|
true,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
ApprovalResponse {
|
|
approval: Approval {
|
|
spender: String::from("random"),
|
|
expires: Expiration::Never {}
|
|
}
|
|
}
|
|
);
|
|
|
|
// random can now transfer
|
|
let random = mock_info("random", &[]);
|
|
let transfer_msg = ExecuteMsg::TransferNft {
|
|
recipient: String::from("person"),
|
|
token_id: token_id.clone(),
|
|
};
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), random, transfer_msg)
|
|
.unwrap();
|
|
|
|
// Approvals are removed / cleared
|
|
let query_msg = QueryMsg::OwnerOf {
|
|
token_id: token_id.clone(),
|
|
include_expired: None,
|
|
};
|
|
let res: OwnerOfResponse = from_binary(
|
|
&contract
|
|
.query(deps.as_ref(), mock_env(), query_msg.clone())
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
OwnerOfResponse {
|
|
owner: String::from("person"),
|
|
approvals: vec![],
|
|
}
|
|
);
|
|
|
|
// Approve, revoke, and check for empty, to test revoke
|
|
let approve_msg = ExecuteMsg::Approve {
|
|
spender: String::from("random"),
|
|
token_id: token_id.clone(),
|
|
expires: None,
|
|
};
|
|
let owner = mock_info("person", &[]);
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), owner.clone(), approve_msg)
|
|
.unwrap();
|
|
|
|
let revoke_msg = ExecuteMsg::Revoke {
|
|
spender: String::from("random"),
|
|
token_id,
|
|
};
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), owner, revoke_msg)
|
|
.unwrap();
|
|
|
|
// Approvals are now removed / cleared
|
|
let res: OwnerOfResponse = from_binary(
|
|
&contract
|
|
.query(deps.as_ref(), mock_env(), query_msg)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
OwnerOfResponse {
|
|
owner: String::from("person"),
|
|
approvals: vec![],
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn approving_all_revoking_all() {
|
|
let mut deps = mock_dependencies(&[]);
|
|
let contract = setup_contract(deps.as_mut());
|
|
|
|
// Mint a couple tokens (from the same owner)
|
|
let token_id1 = "grow1".to_string();
|
|
let token_uri1 = "https://www.merriam-webster.com/dictionary/grow1".to_string();
|
|
|
|
let token_id2 = "grow2".to_string();
|
|
let token_uri2 = "https://www.merriam-webster.com/dictionary/grow2".to_string();
|
|
|
|
let mint_msg1 = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id1.clone(),
|
|
owner: String::from("demeter"),
|
|
token_uri: Some(token_uri1),
|
|
extension: None,
|
|
});
|
|
|
|
let minter = mock_info(MINTER, &[]);
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg1)
|
|
.unwrap();
|
|
|
|
let mint_msg2 = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id2.clone(),
|
|
owner: String::from("demeter"),
|
|
token_uri: Some(token_uri2),
|
|
extension: None,
|
|
});
|
|
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), minter, mint_msg2)
|
|
.unwrap();
|
|
|
|
// paginate the token_ids
|
|
let tokens = contract.all_tokens(deps.as_ref(), None, Some(1)).unwrap();
|
|
assert_eq!(1, tokens.tokens.len());
|
|
assert_eq!(vec![token_id1.clone()], tokens.tokens);
|
|
let tokens = contract
|
|
.all_tokens(deps.as_ref(), Some(token_id1.clone()), Some(3))
|
|
.unwrap();
|
|
assert_eq!(1, tokens.tokens.len());
|
|
assert_eq!(vec![token_id2.clone()], tokens.tokens);
|
|
|
|
// demeter gives random full (operator) power over her tokens
|
|
let approve_all_msg = ExecuteMsg::ApproveAll {
|
|
operator: String::from("random"),
|
|
expires: None,
|
|
};
|
|
let owner = mock_info("demeter", &[]);
|
|
let res = contract
|
|
.execute(deps.as_mut(), mock_env(), owner, approve_all_msg)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
Response::new()
|
|
.add_attribute("action", "approve_all")
|
|
.add_attribute("sender", "demeter")
|
|
.add_attribute("operator", "random")
|
|
);
|
|
|
|
// random can now transfer
|
|
let random = mock_info("random", &[]);
|
|
let transfer_msg = ExecuteMsg::TransferNft {
|
|
recipient: String::from("person"),
|
|
token_id: token_id1,
|
|
};
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), random.clone(), transfer_msg)
|
|
.unwrap();
|
|
|
|
// random can now send
|
|
let inner_msg = WasmMsg::Execute {
|
|
contract_addr: "another_contract".into(),
|
|
msg: to_binary("You now also have the growing power").unwrap(),
|
|
funds: vec![],
|
|
};
|
|
let msg: CosmosMsg = CosmosMsg::Wasm(inner_msg);
|
|
|
|
let send_msg = ExecuteMsg::SendNft {
|
|
contract: String::from("another_contract"),
|
|
token_id: token_id2,
|
|
msg: to_binary(&msg).unwrap(),
|
|
};
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), random, send_msg)
|
|
.unwrap();
|
|
|
|
// Approve_all, revoke_all, and check for empty, to test revoke_all
|
|
let approve_all_msg = ExecuteMsg::ApproveAll {
|
|
operator: String::from("operator"),
|
|
expires: None,
|
|
};
|
|
// person is now the owner of the tokens
|
|
let owner = mock_info("person", &[]);
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), owner, approve_all_msg)
|
|
.unwrap();
|
|
|
|
let res = contract
|
|
.operators(
|
|
deps.as_ref(),
|
|
mock_env(),
|
|
String::from("person"),
|
|
true,
|
|
None,
|
|
None,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
OperatorsResponse {
|
|
operators: vec![cw721::Approval {
|
|
spender: String::from("operator"),
|
|
expires: Expiration::Never {}
|
|
}]
|
|
}
|
|
);
|
|
|
|
// second approval
|
|
let buddy_expires = Expiration::AtHeight(1234567);
|
|
let approve_all_msg = ExecuteMsg::ApproveAll {
|
|
operator: String::from("buddy"),
|
|
expires: Some(buddy_expires),
|
|
};
|
|
let owner = mock_info("person", &[]);
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), owner.clone(), approve_all_msg)
|
|
.unwrap();
|
|
|
|
// and paginate queries
|
|
let res = contract
|
|
.operators(
|
|
deps.as_ref(),
|
|
mock_env(),
|
|
String::from("person"),
|
|
true,
|
|
None,
|
|
Some(1),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
OperatorsResponse {
|
|
operators: vec![cw721::Approval {
|
|
spender: String::from("buddy"),
|
|
expires: buddy_expires,
|
|
}]
|
|
}
|
|
);
|
|
let res = contract
|
|
.operators(
|
|
deps.as_ref(),
|
|
mock_env(),
|
|
String::from("person"),
|
|
true,
|
|
Some(String::from("buddy")),
|
|
Some(2),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
OperatorsResponse {
|
|
operators: vec![cw721::Approval {
|
|
spender: String::from("operator"),
|
|
expires: Expiration::Never {}
|
|
}]
|
|
}
|
|
);
|
|
|
|
let revoke_all_msg = ExecuteMsg::RevokeAll {
|
|
operator: String::from("operator"),
|
|
};
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), owner, revoke_all_msg)
|
|
.unwrap();
|
|
|
|
// Approvals are removed / cleared without affecting others
|
|
let res = contract
|
|
.operators(
|
|
deps.as_ref(),
|
|
mock_env(),
|
|
String::from("person"),
|
|
false,
|
|
None,
|
|
None,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(
|
|
res,
|
|
OperatorsResponse {
|
|
operators: vec![cw721::Approval {
|
|
spender: String::from("buddy"),
|
|
expires: buddy_expires,
|
|
}]
|
|
}
|
|
);
|
|
|
|
// ensure the filter works (nothing should be here
|
|
let mut late_env = mock_env();
|
|
late_env.block.height = 1234568; //expired
|
|
let res = contract
|
|
.operators(
|
|
deps.as_ref(),
|
|
late_env,
|
|
String::from("person"),
|
|
false,
|
|
None,
|
|
None,
|
|
)
|
|
.unwrap();
|
|
assert_eq!(0, res.operators.len());
|
|
}
|
|
|
|
#[test]
|
|
fn query_tokens_by_owner() {
|
|
let mut deps = mock_dependencies(&[]);
|
|
let contract = setup_contract(deps.as_mut());
|
|
let minter = mock_info(MINTER, &[]);
|
|
|
|
// Mint a couple tokens (from the same owner)
|
|
let token_id1 = "grow1".to_string();
|
|
let demeter = String::from("demeter");
|
|
let token_id2 = "grow2".to_string();
|
|
let ceres = String::from("ceres");
|
|
let token_id3 = "sing".to_string();
|
|
|
|
let mint_msg = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id1.clone(),
|
|
owner: demeter.clone(),
|
|
token_uri: None,
|
|
extension: None,
|
|
});
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg)
|
|
.unwrap();
|
|
|
|
let mint_msg = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id2.clone(),
|
|
owner: ceres.clone(),
|
|
token_uri: None,
|
|
extension: None,
|
|
});
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), minter.clone(), mint_msg)
|
|
.unwrap();
|
|
|
|
let mint_msg = ExecuteMsg::Mint(MintMsg::<Extension> {
|
|
token_id: token_id3.clone(),
|
|
owner: demeter.clone(),
|
|
token_uri: None,
|
|
extension: None,
|
|
});
|
|
contract
|
|
.execute(deps.as_mut(), mock_env(), minter, mint_msg)
|
|
.unwrap();
|
|
|
|
// get all tokens in order:
|
|
let expected = vec![token_id1.clone(), token_id2.clone(), token_id3.clone()];
|
|
let tokens = contract.all_tokens(deps.as_ref(), None, None).unwrap();
|
|
assert_eq!(&expected, &tokens.tokens);
|
|
// paginate
|
|
let tokens = contract.all_tokens(deps.as_ref(), None, Some(2)).unwrap();
|
|
assert_eq!(&expected[..2], &tokens.tokens[..]);
|
|
let tokens = contract
|
|
.all_tokens(deps.as_ref(), Some(expected[1].clone()), None)
|
|
.unwrap();
|
|
assert_eq!(&expected[2..], &tokens.tokens[..]);
|
|
|
|
// get by owner
|
|
let by_ceres = vec![token_id2];
|
|
let by_demeter = vec![token_id1, token_id3];
|
|
// all tokens by owner
|
|
let tokens = contract
|
|
.tokens(deps.as_ref(), demeter.clone(), None, None)
|
|
.unwrap();
|
|
assert_eq!(&by_demeter, &tokens.tokens);
|
|
let tokens = contract.tokens(deps.as_ref(), ceres, None, None).unwrap();
|
|
assert_eq!(&by_ceres, &tokens.tokens);
|
|
|
|
// paginate for demeter
|
|
let tokens = contract
|
|
.tokens(deps.as_ref(), demeter.clone(), None, Some(1))
|
|
.unwrap();
|
|
assert_eq!(&by_demeter[..1], &tokens.tokens[..]);
|
|
let tokens = contract
|
|
.tokens(deps.as_ref(), demeter, Some(by_demeter[0].clone()), Some(3))
|
|
.unwrap();
|
|
assert_eq!(&by_demeter[1..], &tokens.tokens[..]);
|
|
}
|