From 8086a2d0f8dad97a81fe9f6ad2665718ed03a599 Mon Sep 17 00:00:00 2001 From: Ajidokwu Sabo Date: Thu, 17 Jul 2025 14:49:47 +0100 Subject: [PATCH] chore: finalized trading test counter and reject trade --- src/interfaces/IActions.cairo | 4 +- src/model/property_model.cairo | 3 + src/systems/actions.cairo | 27 +++++- src/tests/test_world.cairo | 163 +++++++++++++++++++++++++++++++++ 4 files changed, 193 insertions(+), 4 deletions(-) diff --git a/src/interfaces/IActions.cairo b/src/interfaces/IActions.cairo index 74c3cd3..d32326f 100644 --- a/src/interfaces/IActions.cairo +++ b/src/interfaces/IActions.cairo @@ -1,7 +1,7 @@ use dojo_starter::model::game_model::{GameType, Game}; use dojo_starter::model::game_player_model::{PlayerSymbol, GamePlayer}; use dojo_starter::model::player_model::Player; -use dojo_starter::model::property_model::{Property, TradeOffer}; +use dojo_starter::model::property_model::{Property, TradeOffer, TradeOfferDetails}; use dojo_starter::model::utility_model::Utility; use dojo_starter::model::rail_road_model::RailRoad; use dojo_starter::model::community_chest_model::CommunityChest; @@ -70,6 +70,8 @@ pub trait IActions { cash_request: u256, trade_type: TradeOffer, ) -> u256; + fn approve_counter_trade(ref self: T, trade_id: u256) -> bool; + fn get_trade(self: @T, trade_id: u256) -> TradeOfferDetails; // Dice & player movement fn roll_dice(ref self: T) -> (u8, u8); diff --git a/src/model/property_model.cairo b/src/model/property_model.cairo index a2a7845..056e57d 100644 --- a/src/model/property_model.cairo +++ b/src/model/property_model.cairo @@ -22,6 +22,8 @@ pub struct TradeOfferDetails { pub cash_request: u256, pub trade_type: TradeOffer, pub status: TradeStatus, + pub is_countered: bool, + pub approve_counter: bool, } #[derive(Copy, Drop, Serde)] #[dojo::model] @@ -79,6 +81,7 @@ pub enum TradeStatus { Accepted, Rejected, Pending, + Countered, } diff --git a/src/systems/actions.cairo b/src/systems/actions.cairo index 7c717e5..c277252 100644 --- a/src/systems/actions.cairo +++ b/src/systems/actions.cairo @@ -1465,21 +1465,42 @@ pub mod actions { ); original_offer.id = original_offer.id; - original_offer.from = caller; // now the original receiver is offering - original_offer.to = original_offer.from; // the original initiator is now the receiver original_offer.game_id = game_id; original_offer.offered_property_ids = offered_property_ids; original_offer.requested_property_ids = requested_property_ids; original_offer.cash_offer = cash_offer; original_offer.cash_request = cash_request; original_offer.trade_type = trade_type; - original_offer.status = TradeStatus::Pending; + original_offer.status = TradeStatus::Countered; + original_offer.is_countered = true; world.write_model(@original_offer); original_offer.id } + fn approve_counter_trade(ref self: ContractState, trade_id: u256) -> bool { + let mut world = self.world_default(); + let caller = get_caller_address(); + + let mut offer: TradeOfferDetails = world.read_model(trade_id); + assert!(caller == offer.from, "Only the initiator can approve the counter trade"); + assert!(offer.status == TradeStatus::Countered, "Trade is not pending"); + + // Process the trade + offer.status = TradeStatus::Pending; + offer.is_countered = false; + offer.approve_counter = true; + + true + } + + fn get_trade(self: @ContractState, trade_id: u256) -> TradeOfferDetails { + let world = self.world_default(); + let trade: TradeOfferDetails = world.read_model(trade_id); + trade + } + fn sell_house_or_hotel(ref self: ContractState, property_id: u8, game_id: u256) -> bool { let mut world = self.world_default(); diff --git a/src/tests/test_world.cairo b/src/tests/test_world.cairo index a1cbef6..01a2183 100644 --- a/src/tests/test_world.cairo +++ b/src/tests/test_world.cairo @@ -3490,5 +3490,168 @@ mod tests { assert(!aji.comm_free_card, 'Section update'); assert(collins.comm_free_card, 'Section update'); } + + #[test] + fn test_offer_test_counter_trade() { + let caller_1 = contract_address_const::<'aji'>(); + let caller_2 = contract_address_const::<'collins'>(); + let username = 'Ajidokwu'; + let username_1 = 'Collins'; + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"actions").unwrap(); + let actions_system = IActionsDispatcher { contract_address }; + + testing::set_contract_address(caller_2); + actions_system.register_new_player(username_1); + + testing::set_contract_address(caller_1); + actions_system.register_new_player(username); + + testing::set_contract_address(caller_1); + actions_system.create_new_game(GameType::PublicGame, PlayerSymbol::Hat, 4); + + testing::set_contract_address(caller_2); + actions_system.join_game(PlayerSymbol::Dog, 1); + + testing::set_contract_address(caller_1); + let started = actions_system.start_game(1); + assert(started, 'Game start fail'); + + let game_p = actions_system.retrieve_game(1); + + testing::set_contract_address(caller_1); + actions_system.move_player(1, 2); + let chance = "Get Out of Jail Free"; + + let mut g = actions_system.retrieve_game(1); + let mut p = actions_system.retrieve_game_player(caller_1, 1); + + let (g, ply) = actions_system.process_community_chest_card(g.clone(), p, chance); + actions_system.finish_turn(g); + + p = actions_system.retrieve_game_player(caller_1, 1); + assert!(p.comm_free_card, "p does not have community jail card"); + + testing::set_contract_address(caller_2); + let mut offered_property_ids: Array = array![]; + let mut requested_property_ids: Array = array![]; + offered_property_ids.append(6); + requested_property_ids.append(1); + let mut trade_id = actions_system + .offer_trade( + 1, + caller_1, + offered_property_ids.clone(), + requested_property_ids.clone(), + 50, + 0, + TradeOffer::ChanceJailCardForCash, + ); + + actions_system.move_player(1, 5); + let g = actions_system.retrieve_game(1); + actions_system.finish_turn(g); + + testing::set_contract_address(caller_1); + actions_system + .counter_trade( + 1, + 1, + offered_property_ids, + requested_property_ids.clone(), + 50, + 0, + TradeOffer::CommunityJailCardForCash, + ); + + testing::set_contract_address(caller_2); + testing::set_contract_address(caller_2); + actions_system.approve_counter_trade(1); + + testing::set_contract_address(caller_1); + let s = actions_system.accept_trade(1, 1); + assert(s, 'accept failed'); + + let aji = actions_system.retrieve_game_player(caller_1, 1); + let mut collins = actions_system.retrieve_game_player(caller_2, 1); + assert(!aji.comm_free_card, 'Section update'); + assert(collins.comm_free_card, 'Section update'); + } + + #[test] + fn test_offer_test_reject_trade() { + let caller_1 = contract_address_const::<'aji'>(); + let caller_2 = contract_address_const::<'collins'>(); + let username = 'Ajidokwu'; + let username_1 = 'Collins'; + + let ndef = namespace_def(); + let mut world = spawn_test_world([ndef].span()); + world.sync_perms_and_inits(contract_defs()); + + let (contract_address, _) = world.dns(@"actions").unwrap(); + let actions_system = IActionsDispatcher { contract_address }; + + testing::set_contract_address(caller_2); + actions_system.register_new_player(username_1); + + testing::set_contract_address(caller_1); + actions_system.register_new_player(username); + + testing::set_contract_address(caller_1); + actions_system.create_new_game(GameType::PublicGame, PlayerSymbol::Hat, 4); + + testing::set_contract_address(caller_2); + actions_system.join_game(PlayerSymbol::Dog, 1); + + testing::set_contract_address(caller_1); + let started = actions_system.start_game(1); + assert(started, 'Game start fail'); + + let game_p = actions_system.retrieve_game(1); + + testing::set_contract_address(caller_1); + actions_system.move_player(1, 2); + let chance = "Get Out of Jail Free"; + + let mut g = actions_system.retrieve_game(1); + let mut p = actions_system.retrieve_game_player(caller_1, 1); + + let (g, ply) = actions_system.process_community_chest_card(g.clone(), p, chance); + actions_system.finish_turn(g); + + p = actions_system.retrieve_game_player(caller_1, 1); + assert!(p.comm_free_card, "p does not have community jail card"); + + testing::set_contract_address(caller_2); + let mut offered_property_ids: Array = array![]; + let mut requested_property_ids: Array = array![]; + offered_property_ids.append(6); + requested_property_ids.append(1); + let mut trade_id = actions_system + .offer_trade( + 1, + caller_1, + offered_property_ids.clone(), + requested_property_ids.clone(), + 50, + 0, + TradeOffer::ChanceJailCardForCash, + ); + + actions_system.move_player(1, 5); + let g = actions_system.retrieve_game(1); + actions_system.finish_turn(g); + + testing::set_contract_address(caller_1); + actions_system.reject_trade(trade_id, 1); + + let trade = actions_system.get_trade(trade_id); + assert(trade.status == TradeStatus::Rejected, 'Trade not rejected'); + } }