@@ -3,7 +3,7 @@ use cosmwasm_std::{coin, Uint128};
33use cw721_base:: msg:: ExecuteMsg as Cw721ExecuteMsg ;
44use cw_multi_test:: Executor ;
55use xion_nft_marketplace:: helpers:: query_listing;
6- use xion_nft_marketplace:: msg:: ExecuteMsg ;
6+ use xion_nft_marketplace:: msg:: { ExecuteMsg , InstantiateMsg } ;
77
88#[ test]
99fn test_buy_item_success ( ) {
@@ -650,3 +650,94 @@ fn test_buy_reserved_for() {
650650 . unwrap ( ) ;
651651 assert_eq ! ( owner_resp. owner, reserved_buyer. to_string( ) ) ;
652652}
653+
654+ #[ test]
655+ fn test_buy_item_with_zero_marketplace_fee ( ) {
656+ let mut app = setup_app_with_balances ( ) ;
657+ let minter = app. api ( ) . addr_make ( "minter" ) ;
658+ let seller = app. api ( ) . addr_make ( "seller" ) ;
659+ let buyer = app. api ( ) . addr_make ( "buyer" ) ;
660+ let manager = app. api ( ) . addr_make ( "manager" ) ;
661+
662+ let asset_contract = setup_asset_contract ( & mut app, & minter) ;
663+
664+ // Create marketplace with zero fee and approvals disabled (direct buy path)
665+ let marketplace_code_id = app. store_code ( marketplace_contract ( ) ) ;
666+ let config_json = serde_json:: json!( {
667+ "manager" : manager. to_string( ) ,
668+ "fee_recipient" : manager. to_string( ) ,
669+ "sale_approvals" : false ,
670+ "fee_bps" : 0 ,
671+ "listing_denom" : "uxion"
672+ } ) ;
673+ let instantiate_msg = InstantiateMsg {
674+ config : serde_json:: from_value ( config_json) . unwrap ( ) ,
675+ } ;
676+ let marketplace_addr = app
677+ . instantiate_contract (
678+ marketplace_code_id,
679+ manager. clone ( ) ,
680+ & instantiate_msg,
681+ & [ ] ,
682+ "test-marketplace-zero-fee" ,
683+ None ,
684+ )
685+ . unwrap ( ) ;
686+
687+ mint_nft ( & mut app, & asset_contract, & minter, & seller, "token1" ) ;
688+
689+ let price = coin ( 1000 , "uxion" ) ;
690+
691+ let seller_balance_before = app. wrap ( ) . query_balance ( & seller, "uxion" ) . unwrap ( ) . amount ;
692+ let manager_balance_before = app. wrap ( ) . query_balance ( & manager, "uxion" ) . unwrap ( ) . amount ;
693+
694+ let listing_id = create_listing_helper (
695+ & mut app,
696+ & marketplace_addr,
697+ & asset_contract,
698+ & seller,
699+ "token1" ,
700+ price. clone ( ) ,
701+ ) ;
702+
703+ // Direct buy (no approval flow)
704+ let buy_msg = ExecuteMsg :: BuyItem {
705+ listing_id,
706+ price : price. clone ( ) ,
707+ } ;
708+
709+ let result = app. execute_contract (
710+ buyer. clone ( ) ,
711+ marketplace_addr. clone ( ) ,
712+ & buy_msg,
713+ std:: slice:: from_ref ( & price) ,
714+ ) ;
715+
716+ assert ! ( result. is_ok( ) , "Direct buy with zero fee should succeed: {:?}" , result. err( ) ) ;
717+
718+ // Seller receives full price (no fee deducted)
719+ let seller_balance_after = app. wrap ( ) . query_balance ( & seller, "uxion" ) . unwrap ( ) . amount ;
720+ assert_eq ! (
721+ seller_balance_after,
722+ seller_balance_before + price. amount,
723+ "Seller should receive full price with zero fee"
724+ ) ;
725+
726+ // Manager receives nothing
727+ let manager_balance_after = app. wrap ( ) . query_balance ( & manager, "uxion" ) . unwrap ( ) . amount ;
728+ assert_eq ! (
729+ manager_balance_after, manager_balance_before,
730+ "Manager should not receive any fee"
731+ ) ;
732+
733+ // NFT transferred to buyer
734+ let owner_query = cw721_base:: msg:: QueryMsg :: OwnerOf {
735+ token_id : "token1" . to_string ( ) ,
736+ include_expired : Some ( false ) ,
737+ } ;
738+ let owner_resp: cw721:: msg:: OwnerOfResponse = app
739+ . wrap ( )
740+ . query_wasm_smart ( asset_contract. clone ( ) , & owner_query)
741+ . unwrap ( ) ;
742+ assert_eq ! ( owner_resp. owner, buyer. to_string( ) ) ;
743+ }
0 commit comments