|
| 1 | +//! Unit tests for `get_total_key_supply` scoping per creator (issue #701). |
| 2 | +//! |
| 3 | +//! Verifies that supply is tracked independently per creator and does not bleed |
| 4 | +//! across registrations. Covers the acceptance criteria: |
| 5 | +//! - Supply scoped correctly per creator |
| 6 | +//! - Creator A supply unaffected by creator B buys |
| 7 | +//! - Sell correctly decrements supply |
| 8 | +//! - Unregistered creator returns `NotRegistered` from the checked supply view |
| 9 | +
|
| 10 | +mod contract_test_env; |
| 11 | + |
| 12 | +use contract_test_env::{ |
| 13 | + register_creator_keys, register_test_creator, set_pricing_and_fees, |
| 14 | + test_env_with_auths, |
| 15 | +}; |
| 16 | +use creator_keys::ContractError; |
| 17 | +use soroban_sdk::testutils::Address as _; |
| 18 | + |
| 19 | +/// Buy `count` keys for `buyer` from `creator`, fetching a live quote before each purchase. |
| 20 | +fn buy_n_keys( |
| 21 | + client: &creator_keys::CreatorKeysContractClient<'_>, |
| 22 | + creator: &soroban_sdk::Address, |
| 23 | + buyer: &soroban_sdk::Address, |
| 24 | + count: u32, |
| 25 | +) { |
| 26 | + for _ in 0..count { |
| 27 | + let quote = client.get_buy_quote(creator); |
| 28 | + client.buy_key(creator, buyer, "e.total_amount, &None); |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +#[test] |
| 33 | +fn test_supply_scoped_per_creator_after_ten_buys() { |
| 34 | + let env = test_env_with_auths(); |
| 35 | + let (client, _) = register_creator_keys(&env); |
| 36 | + set_pricing_and_fees(&env, &client, 1_000_i128, 9_000, 1_000); |
| 37 | + |
| 38 | + let creator_a = register_test_creator(&env, &client, "alice"); |
| 39 | + let buyer_a = soroban_sdk::Address::generate(&env); |
| 40 | + |
| 41 | + buy_n_keys(&client, &creator_a, &buyer_a, 10); |
| 42 | + |
| 43 | + assert_eq!(client.get_total_key_supply(&creator_a), 10); |
| 44 | +} |
| 45 | + |
| 46 | +#[test] |
| 47 | +fn test_supply_scoped_per_creator_after_five_buys() { |
| 48 | + let env = test_env_with_auths(); |
| 49 | + let (client, _) = register_creator_keys(&env); |
| 50 | + set_pricing_and_fees(&env, &client, 1_000_i128, 9_000, 1_000); |
| 51 | + |
| 52 | + let creator_b = register_test_creator(&env, &client, "bob"); |
| 53 | + let buyer_b = soroban_sdk::Address::generate(&env); |
| 54 | + |
| 55 | + buy_n_keys(&client, &creator_b, &buyer_b, 5); |
| 56 | + |
| 57 | + assert_eq!(client.get_total_key_supply(&creator_b), 5); |
| 58 | +} |
| 59 | + |
| 60 | +#[test] |
| 61 | +fn test_creator_a_supply_unaffected_by_creator_b_buys() { |
| 62 | + let env = test_env_with_auths(); |
| 63 | + let (client, _) = register_creator_keys(&env); |
| 64 | + set_pricing_and_fees(&env, &client, 1_000_i128, 9_000, 1_000); |
| 65 | + |
| 66 | + let creator_a = register_test_creator(&env, &client, "alice"); |
| 67 | + let creator_b = register_test_creator(&env, &client, "bob"); |
| 68 | + let buyer_a = soroban_sdk::Address::generate(&env); |
| 69 | + let buyer_b = soroban_sdk::Address::generate(&env); |
| 70 | + |
| 71 | + buy_n_keys(&client, &creator_a, &buyer_a, 10); |
| 72 | + assert_eq!(client.get_total_key_supply(&creator_a), 10); |
| 73 | + |
| 74 | + buy_n_keys(&client, &creator_b, &buyer_b, 5); |
| 75 | + assert_eq!(client.get_total_key_supply(&creator_b), 5); |
| 76 | + |
| 77 | + // Creator A supply must still be 10 after creator B bought 5 keys |
| 78 | + assert_eq!( |
| 79 | + client.get_total_key_supply(&creator_a), |
| 80 | + 10, |
| 81 | + "creator A supply changed after creator B buys" |
| 82 | + ); |
| 83 | +} |
| 84 | + |
| 85 | +#[test] |
| 86 | +fn test_sell_decrements_creator_a_supply() { |
| 87 | + let env = test_env_with_auths(); |
| 88 | + let (client, _) = register_creator_keys(&env); |
| 89 | + set_pricing_and_fees(&env, &client, 1_000_i128, 9_000, 1_000); |
| 90 | + |
| 91 | + let creator_a = register_test_creator(&env, &client, "alice"); |
| 92 | + let buyer_a = soroban_sdk::Address::generate(&env); |
| 93 | + |
| 94 | + buy_n_keys(&client, &creator_a, &buyer_a, 10); |
| 95 | + assert_eq!(client.get_total_key_supply(&creator_a), 10); |
| 96 | + |
| 97 | + // Sell 3 keys — supply should drop to 7 |
| 98 | + for _ in 0..3 { |
| 99 | + client.sell_key(&creator_a, &buyer_a, &None); |
| 100 | + } |
| 101 | + |
| 102 | + assert_eq!(client.get_total_key_supply(&creator_a), 7); |
| 103 | +} |
| 104 | + |
| 105 | +#[test] |
| 106 | +fn test_sell_does_not_affect_other_creator_supply() { |
| 107 | + let env = test_env_with_auths(); |
| 108 | + let (client, _) = register_creator_keys(&env); |
| 109 | + set_pricing_and_fees(&env, &client, 1_000_i128, 9_000, 1_000); |
| 110 | + |
| 111 | + let creator_a = register_test_creator(&env, &client, "alice"); |
| 112 | + let creator_b = register_test_creator(&env, &client, "bob"); |
| 113 | + let buyer_a = soroban_sdk::Address::generate(&env); |
| 114 | + let buyer_b = soroban_sdk::Address::generate(&env); |
| 115 | + |
| 116 | + buy_n_keys(&client, &creator_a, &buyer_a, 10); |
| 117 | + buy_n_keys(&client, &creator_b, &buyer_b, 5); |
| 118 | + |
| 119 | + for _ in 0..3 { |
| 120 | + client.sell_key(&creator_a, &buyer_a, &None); |
| 121 | + } |
| 122 | + |
| 123 | + assert_eq!(client.get_total_key_supply(&creator_a), 7); |
| 124 | + // Creator B supply must be unchanged |
| 125 | + assert_eq!( |
| 126 | + client.get_total_key_supply(&creator_b), |
| 127 | + 5, |
| 128 | + "creator B supply changed after creator A sold keys" |
| 129 | + ); |
| 130 | +} |
| 131 | + |
| 132 | +#[test] |
| 133 | +fn test_unregistered_creator_returns_not_registered_error() { |
| 134 | + let env = test_env_with_auths(); |
| 135 | + let (client, _) = register_creator_keys(&env); |
| 136 | + set_pricing_and_fees(&env, &client, 1_000_i128, 9_000, 1_000); |
| 137 | + |
| 138 | + let unregistered = soroban_sdk::Address::generate(&env); |
| 139 | + |
| 140 | + let result = client.try_get_creator_supply(&unregistered); |
| 141 | + assert_eq!(result, Err(Ok(ContractError::NotRegistered))); |
| 142 | +} |
0 commit comments