@@ -451,7 +451,7 @@ mod asset_pluggable_tests {
451451 let token_id = "token-1" . to_string ( ) ;
452452 let price = Coin :: new ( 100u128 , "uxion" ) ;
453453
454- let result = contract. on_list_plugin ( & token_id, & price, & None , & None , & mut ctx) ;
454+ let result = contract. on_list_plugin ( & token_id, & price, & None , & None , & mut ctx) ;
455455
456456 assert_eq ! (
457457 result. expect_err( "expected min price error" ) . to_string( ) ,
@@ -1154,3 +1154,153 @@ mod query_test {
11541154 } ) ) ;
11551155 }
11561156}
1157+
1158+ #[ cfg( test) ]
1159+ mod asset_pluggable_sellable_test {
1160+ use std:: collections:: HashMap ;
1161+
1162+ use crate :: {
1163+ msg:: AssetExtensionExecuteMsg ,
1164+ plugin:: { PluggableAsset , Plugin } ,
1165+ state:: { AssetConfig , ListingInfo } ,
1166+ traits:: DefaultAssetContract ,
1167+ } ;
1168+ use cosmwasm_std:: {
1169+ BankMsg , Coin , CosmosMsg , Empty ,
1170+ testing:: { message_info, mock_dependencies, mock_env} ,
1171+ } ;
1172+ use cw721:: { msg:: Cw721ExecuteMsg , state:: NftInfo } ;
1173+
1174+ #[ test]
1175+ fn buy_deducts_marketplace_and_royalty_fees ( ) {
1176+ let mut deps = mock_dependencies ( ) ;
1177+ let mut contract: DefaultAssetContract < ' static , Empty , Empty , Empty , Empty > =
1178+ Default :: default ( ) ;
1179+
1180+ let seller = deps. api . addr_make ( "seller" ) ;
1181+ let buyer = deps. api . addr_make ( "buyer" ) ;
1182+ let marketplace = deps. api . addr_make ( "marketplace" ) ;
1183+ let royalty_recipient = deps. api . addr_make ( "artist" ) ;
1184+
1185+ let price = Coin :: new ( 1_000u128 , "uxion" ) ;
1186+
1187+ let listing = ListingInfo {
1188+ id : "token-1" . to_string ( ) ,
1189+ price : price. clone ( ) ,
1190+ seller : seller. clone ( ) ,
1191+ reserved : None ,
1192+ nft_info : NftInfo {
1193+ owner : seller. clone ( ) ,
1194+ approvals : vec ! [ ] ,
1195+ token_uri : None ,
1196+ extension : Empty :: default ( ) ,
1197+ } ,
1198+ marketplace_fee_bps : Some ( 1_000 ) ,
1199+ marketplace_fee_recipient : Some ( marketplace. clone ( ) ) ,
1200+ } ;
1201+
1202+ contract
1203+ . config
1204+ . listings
1205+ . save ( deps. as_mut ( ) . storage , "token-1" , & listing)
1206+ . unwrap ( ) ;
1207+ contract
1208+ . config
1209+ . cw721_config
1210+ . nft_info
1211+ . save ( deps. as_mut ( ) . storage , "token-1" , & listing. nft_info )
1212+ . unwrap ( ) ;
1213+ contract
1214+ . config
1215+ . collection_plugins
1216+ . save (
1217+ deps. as_mut ( ) . storage ,
1218+ "Royalty" ,
1219+ & Plugin :: Royalty {
1220+ bps : 500 ,
1221+ recipient : royalty_recipient. clone ( ) ,
1222+ on_primary : true ,
1223+ } ,
1224+ )
1225+ . unwrap ( ) ;
1226+
1227+ let env = mock_env ( ) ;
1228+ let info = message_info ( & buyer, & [ price. clone ( ) ] ) ;
1229+
1230+ let res = contract
1231+ . execute_pluggable (
1232+ deps. as_mut ( ) ,
1233+ & env,
1234+ & info,
1235+ Cw721ExecuteMsg :: UpdateExtension {
1236+ msg : AssetExtensionExecuteMsg :: Buy {
1237+ token_id : "token-1" . to_string ( ) ,
1238+ recipient : None ,
1239+ } ,
1240+ } ,
1241+ )
1242+ . unwrap ( ) ;
1243+
1244+ assert_eq ! ( res. messages. len( ) , 3 ) ;
1245+
1246+ let mut marketplace_paid = None ;
1247+ let mut seller_paid = None ;
1248+ let mut royalty_paid = None ;
1249+
1250+ for msg in & res. messages {
1251+ match & msg. msg {
1252+ CosmosMsg :: Bank ( BankMsg :: Send { to_address, amount } ) => {
1253+ let coin = amount
1254+ . first ( )
1255+ . cloned ( )
1256+ . expect ( "send message must include funds" ) ;
1257+ if * to_address == marketplace. to_string ( ) {
1258+ marketplace_paid = Some ( coin) ;
1259+ } else if * to_address == seller. to_string ( ) {
1260+ seller_paid = Some ( coin) ;
1261+ } else if * to_address == royalty_recipient. to_string ( ) {
1262+ royalty_paid = Some ( coin) ;
1263+ } else {
1264+ panic ! ( "unexpected recipient {}" , to_address) ;
1265+ }
1266+ }
1267+ other => panic ! ( "unexpected message: {:?}" , other) ,
1268+ }
1269+ }
1270+
1271+ assert_eq ! (
1272+ marketplace_paid. expect( "marketplace fee" ) ,
1273+ Coin :: new( 100u128 , "uxion" ) ,
1274+ ) ;
1275+ assert_eq ! (
1276+ royalty_paid. expect( "royalty fee" ) ,
1277+ Coin :: new( 50u128 , "uxion" ) ,
1278+ ) ;
1279+ assert_eq ! (
1280+ seller_paid. expect( "seller payment" ) ,
1281+ Coin :: new( 850u128 , "uxion" ) ,
1282+ ) ;
1283+
1284+ let attrs: HashMap < _ , _ > = res
1285+ . attributes
1286+ . iter ( )
1287+ . map ( |attr| ( attr. key . clone ( ) , attr. value . clone ( ) ) )
1288+ . collect ( ) ;
1289+ assert_eq ! ( attrs. get( "marketplace_fee" ) , Some ( & "100" . to_string( ) ) ) ;
1290+ assert_eq ! (
1291+ attrs. get( "royalty_amount" ) ,
1292+ Some ( & Coin :: new( 50u128 , "uxion" ) . to_string( ) ) ,
1293+ ) ;
1294+ assert_eq ! (
1295+ attrs. get( "royalty_recipient" ) ,
1296+ Some ( & royalty_recipient. to_string( ) ) ,
1297+ ) ;
1298+
1299+ let stored_nft = AssetConfig :: < Empty > :: default ( )
1300+ . cw721_config
1301+ . nft_info
1302+ . load ( deps. as_ref ( ) . storage , "token-1" )
1303+ . unwrap ( ) ;
1304+ assert_eq ! ( stored_nft. owner, buyer) ;
1305+ }
1306+ }
0 commit comments