Skip to content

Commit

Permalink
feat: removed agency from Contract, use AgencyId; created real estate…
Browse files Browse the repository at this point in the history
… entity
  • Loading branch information
veeso committed Feb 26, 2025
1 parent 4b98d46 commit c4d6a10
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 157 deletions.
18 changes: 4 additions & 14 deletions src/deferred_data/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,7 @@ impl DeferredData {
))?;

// get caller access level
let access_level = if contract
.agency
.as_ref()
.map(|agency| agency.owner == caller())
.unwrap_or_default()
{
let access_level = if contract.agency == caller() {
RestrictionLevel::Agent
} else if let Some(signature) = signature {
Inspect::inspect_signature(&contract.id, signature.signature, signature.message)?
Expand All @@ -202,12 +197,7 @@ impl DeferredData {
let mut redacted_properties = Vec::with_capacity(contract.restricted_properties.len());

// get caller access level
let access_level = if contract
.agency
.as_ref()
.map(|agency| agency.owner == caller)
.unwrap_or_default()
{
let access_level = if contract.agency == caller {
Some(RestrictionLevel::Agent)
} else if let Some(signature) = signature {
Inspect::inspect_signature(&contract.id, signature.signature, signature.message).ok()
Expand Down Expand Up @@ -291,7 +281,7 @@ mod test {
init();

let contract = with_mock_contract(1, 100, |contract| {
contract.agency.as_mut().unwrap().owner = caller();
contract.agency = caller();
});

DeferredData::create_contract(contract.clone()).expect("Failed to create contract");
Expand Down Expand Up @@ -333,7 +323,7 @@ mod test {
init();

let contract = with_mock_contract(1, 100, |contract| {
contract.agency.as_mut().unwrap().owner = caller();
contract.agency = caller();
});

DeferredData::create_contract(contract.clone()).expect("Failed to create contract");
Expand Down
2 changes: 1 addition & 1 deletion src/deferred_data/src/app/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn mock_contract(id: u64, installments: u64) -> Contract {
},
)],
documents: vec![],
agency: Some(mock_agency()),
agency: mock_agency().owner,
expiration: "2078-01-01".to_string(),
closed: false,
}
Expand Down
5 changes: 2 additions & 3 deletions src/deferred_data/src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,8 @@ mod test {
address: H160::from_hex_str("0x253553366da8546fc250f225fe3d25d0c782303b").unwrap(),
quota: 100,
}];
contract.agency.as_mut().unwrap().owner =
Principal::from_text("v5vof-zqaaa-aaaal-ai5cq-cai")
.expect("Failed to create principal");
contract.agency = Principal::from_text("v5vof-zqaaa-aaaal-ai5cq-cai")
.expect("Failed to create principal");

// insert properties
contract.properties = vec![
Expand Down
10 changes: 2 additions & 8 deletions src/deferred_data/src/http/contract_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,13 @@ impl ContractFilter {
.properties
.iter()
.find(|(k, _)| k == name)
.map_or(false, |(_, v)| {
v.to_string().to_lowercase().contains(&value.to_lowercase())
}),
.is_some_and(|(_, v)| v.to_string().to_lowercase().contains(&value.to_lowercase())),
ContractFilter::Seller(addr) => contract
.sellers
.iter()
.any(|seller| seller.address == *addr),
ContractFilter::Buyer(addr) => contract.buyers.iter().any(|buyer| buyer == addr),
ContractFilter::Agent(agent) => contract
.agency
.as_ref()
.map(|agency| agency.owner == *agent)
.unwrap_or_default(),
ContractFilter::Agent(agent) => contract.agency == *agent,
ContractFilter::MinPrice(min_price) => contract.value >= *min_price,
ContractFilter::MaxPrice(max_price) => contract.value <= *max_price,
ContractFilter::Position {
Expand Down
11 changes: 2 additions & 9 deletions src/deferred_minter/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,7 @@ impl DeferredMinter {
if RolesManager::is_agent(caller()) {
log::debug!("caller is an agent");
let contract = Self::deferred_data().get_contract(&contract_id).await?;
if contract
.agency
.map(|agency| agency.owner != caller())
.unwrap_or(true)
{
if contract.agency != caller() {
log::debug!("caller is not the agency for the contract");
ic_cdk::trap("Unauthorized");
}
Expand Down Expand Up @@ -310,9 +306,6 @@ impl DeferredMinter {

/// Create a contract from the registration data
fn contract_from_registration(contract_id: ID, data: ContractRegistration) -> Contract {
// get agency from caller
let agency = Agents::get_agency_by_wallet(caller());

Contract {
id: contract_id,
r#type: data.r#type,
Expand All @@ -325,7 +318,7 @@ impl DeferredMinter {
properties: data.properties,
restricted_properties: data.restricted_properties,
documents: vec![],
agency,
agency: caller(),
expiration: data.expiration,
closed: false,
}
Expand Down
21 changes: 2 additions & 19 deletions src/deferred_minter/src/app/data_client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use candid::Principal;
use did::deferred::{
Agency, Contract, ContractError, DeferredDataResult, DeferredMinterError, DeferredMinterResult,
Contract, ContractError, DeferredDataResult, DeferredMinterError, DeferredMinterResult,
GenericValue, Seller,
};
use did::{H160, ID};
Expand Down Expand Up @@ -41,24 +41,7 @@ impl DeferredDataClient {
)],
restricted_properties: vec![],
documents: vec![],
agency: Some(Agency {
name: "Dummy Real estate".to_string(),
lat: None,
lng: None,
address: "Via Delle Botteghe Scure".to_string(),
city: "Rome".to_string(),
region: "Lazio".to_string(),
zip_code: "00100".to_string(),
country: "Italy".to_string(),
continent: did::deferred::Continent::Europe,
email: "email".to_string(),
website: "website".to_string(),
mobile: "mobile".to_string(),
vat: "vat".to_string(),
agent: "agent".to_string(),
logo: None,
owner: caller(),
}),
agency: caller(),
expiration: "2078-01-01".to_string(),
closed: false,
});
Expand Down
2 changes: 1 addition & 1 deletion src/deferred_minter/src/app/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn mock_contract(id: u64, installments: u64) -> Contract {
},
)],
documents: vec![],
agency: Some(mock_agency()),
agency: mock_agency().owner,
expiration: "2078-01-01".to_string(),
closed: false,
}
Expand Down
4 changes: 1 addition & 3 deletions src/deferred_minter/src/http/agents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ impl AgencyFilter {
match self {
AgencyFilter::Always => true,
AgencyFilter::HasProperty { name, value } => Self::agency_property(name, agency)
.map_or(false, |v| {
v.to_string().to_lowercase().contains(&value.to_lowercase())
}),
.is_some_and(|v| v.to_string().to_lowercase().contains(&value.to_lowercase())),
AgencyFilter::Position {
latitude,
longitude,
Expand Down
100 changes: 6 additions & 94 deletions src/did/src/deferred.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
//! Types associated to the "Deferred" canister
mod agency;
mod contract;
mod data;
mod minter;
mod real_estate;

pub type DeferredMinterResult<T> = Result<T, DeferredMinterError>;
pub type DeferredDataResult<T> = Result<T, DeferredDataError>;

pub use self::agency::{Agency, AgencyId, Continent};
pub use self::contract::{
Agency, Continent, Contract, ContractDocument, ContractDocumentData, ContractDocuments,
ContractProperties, ContractRegistration, ContractType, GenericValue,
RestrictedContractProperties, RestrictedProperty, RestrictionLevel, Seller, ID,
Contract, ContractDocument, ContractDocumentData, ContractDocuments, ContractProperties,
ContractRegistration, ContractType, GenericValue, RestrictedContractProperties,
RestrictedProperty, RestrictionLevel, Seller, ID,
};
pub use self::data::{
ConfigurationError as DataConfigurationError, ContractError as DataContractError,
Expand All @@ -20,94 +23,3 @@ pub use self::minter::{
CloseContractError, ConfigurationError, ContractError, DeferredMinterError,
DeferredMinterInitData, EcdsaError, EcdsaKey, Role, Roles,
};

#[cfg(test)]
mod test {

use candid::{Decode, Encode, Principal};
use ic_stable_structures::Storable as _;
use pretty_assertions::assert_eq;

use super::*;
use crate::{H160, ID};

#[test]
fn test_should_encode_contract() {
let contract = Contract {
id: ID::from(1_u64),
r#type: ContractType::Sell,
sellers: vec![
Seller {
address: H160::from_hex_str("0xE46A267b65Ed8CBAeBA9AdC3171063179b642E7A")
.unwrap(),
quota: 51,
},
Seller {
address: H160::from_hex_str("0xE46A267b65Ed8CBAeBA9AdC3171063179b642E7A")
.unwrap(),
quota: 49,
},
],
buyers: vec![
H160::from_hex_str("0xE46A267b65Ed8CBAeBA9AdC3171063179b642E7A").unwrap(),
H160::from_hex_str("0xE46A267b65Ed8CBAeBA9AdC3171063179b642E7A").unwrap(),
],
installments: 2,
value: 250_000,
deposit: 50_000,
currency: "EUR".to_string(),
documents: vec![],
properties: vec![(
"Rome".to_string(),
GenericValue::TextContent("Rome".to_string()),
)],
restricted_properties: vec![(
"Secret".to_string(),
RestrictedProperty {
access_list: vec![RestrictionLevel::Agent],
value: GenericValue::TextContent("Secret".to_string()),
},
)],
agency: Some(Agency {
name: "Agency".to_string(),
address: "Address".to_string(),
city: "City".to_string(),
region: "Region".to_string(),
zip_code: "Zip".to_string(),
country: "Country".to_string(),
continent: Continent::Europe,
lat: None,
lng: None,
email: "Email".to_string(),
website: "Website".to_string(),
mobile: "Mobile".to_string(),
vat: "VAT".to_string(),
agent: "Agent".to_string(),
logo: None,
owner: Principal::anonymous(),
}),
expiration: "2040-01-01".to_string(),
closed: false,
};
let data = Encode!(&contract).unwrap();
let decoded_contract = Decode!(&data, Contract).unwrap();

assert_eq!(contract.id, decoded_contract.id);
assert_eq!(contract.sellers, decoded_contract.sellers);
assert_eq!(contract.buyers, decoded_contract.buyers);
assert_eq!(contract.properties, decoded_contract.properties);
assert_eq!(contract.value, decoded_contract.value);
assert_eq!(contract.currency, decoded_contract.currency);
assert_eq!(contract.installments, decoded_contract.installments);
assert_eq!(contract.agency, decoded_contract.agency);
}

#[test]
fn test_should_encode_role() {
let role: Roles = vec![Role::Agent, Role::Custodian].into();

let data = role.to_bytes();
let decoded_role = Roles::from_bytes(data);
assert_eq!(role, decoded_role);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ use ic_stable_structures::storable::Bound;
use ic_stable_structures::Storable;
use serde::{Deserialize, Serialize};

/// Unique identifier for an agency
pub type AgencyId = Principal;

/// A sell contract for a building
#[derive(Clone, Debug, CandidType, Deserialize, Serialize, PartialEq)]
pub struct Agency {
Expand Down Expand Up @@ -86,3 +89,37 @@ impl Storable for Agency {
Decode!(&bytes, Self).unwrap()
}
}

#[cfg(test)]
mod test {

use pretty_assertions::assert_eq;

use super::*;

#[test]
fn test_should_encode_agency() {
let agency = Agency {
name: "Agency".to_string(),
address: "Address".to_string(),
city: "City".to_string(),
region: "Region".to_string(),
zip_code: "Zip".to_string(),
country: "Country".to_string(),
continent: Continent::Europe,
lat: None,
lng: None,
email: "Email".to_string(),
website: "Website".to_string(),
mobile: "Mobile".to_string(),
vat: "VAT".to_string(),
agent: "Agent".to_string(),
logo: None,
owner: Principal::anonymous(),
};
let data = Encode!(&agency).unwrap();
let decoded = Decode!(&data, Agency).unwrap();

assert_eq!(agency, decoded);
}
}
Loading

0 comments on commit c4d6a10

Please sign in to comment.