diff --git a/src/components/operations.cairo b/src/components/operations.cairo index b1cee96..c21b66e 100644 --- a/src/components/operations.cairo +++ b/src/components/operations.cairo @@ -79,6 +79,16 @@ pub mod OperationsComponent { // Check if stored loan has matching ID and is not in a terminal state loan.id == loan_id && loan.status != LoanStatus::NOT_INITIALIZED } + + fn can_renegotiate_loan(self: @ComponentState, loan_id: u256) -> bool { + if (!self.is_valid_loan(loan_id)) { + return false; + } + + let loan = self.get_loan(loan_id); + + loan.status != LoanStatus::FORECLOSED && loan.status != LoanStatus::REPAID + } } #[generate_trait] diff --git a/src/interfaces/ioperations.cairo b/src/interfaces/ioperations.cairo index 21ed0c7..3accc0a 100644 --- a/src/interfaces/ioperations.cairo +++ b/src/interfaces/ioperations.cairo @@ -5,5 +5,5 @@ pub trait IOperations { fn get_loan(self: @TContractState, loan_id: u256) -> Loan; fn is_active_loan(self: @TContractState, loan_id: u256) -> bool; fn is_valid_loan(self: @TContractState, loan_id: u256) -> bool; + fn can_renegotiate_loan(self: @TContractState, loan_id: u256) -> bool; } - diff --git a/src/tests/test_operations.cairo b/src/tests/test_operations.cairo index 397ef99..dbdeb67 100644 --- a/src/tests/test_operations.cairo +++ b/src/tests/test_operations.cairo @@ -1,6 +1,5 @@ use starknet::{ContractAddress}; use starknet::storage::{StoragePointerWriteAccess, StoragePathEntry}; -use trajectfi::components::operations::OperationsComponent; use trajectfi::components::operations::OperationsComponent::{OperationsImpl}; use trajectfi::types::{Loan, LoanStatus}; @@ -335,3 +334,68 @@ fn create_test_loan(id: u256, status: LoanStatus) -> Loan { status, } } + +#[test] +fn test_can_renegotiate_active_loan() { + // Setup test environment + let mut state: MockOperationsContract::ContractState = + MockOperationsContract::contract_state_for_testing(); + + // Create an active loan + let loan_id = 1_u256; + let valid_loan = create_test_loan(loan_id, LoanStatus::ONGOING); + state.operations.loans.entry(loan_id).write(valid_loan); + state.operations.loan_exists.entry(loan_id).write(true); + + // Verify an active loan can be renegotiated + let result = state.can_renegotiate_loan(loan_id); + assert(result, 'Loan should be renegotiable'); +} + +#[test] +fn test_can_renegotiate_repaid_loan() { + // Setup test environment + let mut state: MockOperationsContract::ContractState = + MockOperationsContract::contract_state_for_testing(); + + // Create a repaid loan + let loan_id = 1_u256; + let valid_loan = create_test_loan(loan_id, LoanStatus::REPAID); + state.operations.loans.entry(loan_id).write(valid_loan); + state.operations.loan_exists.entry(loan_id).write(true); + + // Verify a repaid loan cannot be renegotiated + let result = state.can_renegotiate_loan(loan_id); + assert(!result, 'Loan should not be renegotiable'); +} + +#[test] +fn test_can_renegotiate_foreclosed_loan() { + // Setup test environment + let mut state: MockOperationsContract::ContractState = + MockOperationsContract::contract_state_for_testing(); + + // Create a foreclosed loan + let loan_id = 1_u256; + let valid_loan = create_test_loan(loan_id, LoanStatus::FORECLOSED); + state.operations.loans.entry(loan_id).write(valid_loan); + state.operations.loan_exists.entry(loan_id).write(true); + + // Verify a foreclosed loan cannot be renegotiated + let result = state.can_renegotiate_loan(loan_id); + assert(!result, 'Loan should not be renegotiable'); +} + +#[test] +fn test_can_renegotiate_invalid_id_loan() { + // Setup test environment + let mut state: MockOperationsContract::ContractState = + MockOperationsContract::contract_state_for_testing(); + + // Use a loan ID that does not exist + let invalid_id = 99_u256; + + // Verify an uninitialized loan cannot be renegotiated + let result = state.can_renegotiate_loan(invalid_id); + assert(!result, 'Loan should not be renegotiable'); +}