Skip to content

Commit c9cc329

Browse files
test(dpp): cover state transitions, token config, perpetual distribution (#3512)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f038dac commit c9cc329

27 files changed

Lines changed: 5367 additions & 0 deletions

File tree

‎packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/apply_token_configuration_item/v0/mod.rs‎

Lines changed: 438 additions & 0 deletions
Large diffs are not rendered by default.

‎packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/authorized_action_takers_for_configuration_item/v0/mod.rs‎

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,229 @@ impl TokenConfigurationV0 {
121121
}
122122
}
123123
}
124+
125+
#[cfg(test)]
126+
mod tests {
127+
use super::*;
128+
use crate::data_contract::associated_token::token_configuration::accessors::v0::{
129+
TokenConfigurationV0Getters, TokenConfigurationV0Setters,
130+
};
131+
use crate::data_contract::associated_token::token_configuration_convention::v0::TokenConfigurationConventionV0;
132+
use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention;
133+
use crate::data_contract::associated_token::token_marketplace_rules::v0::TokenTradeMode;
134+
use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0;
135+
use crate::data_contract::change_control_rules::ChangeControlRules;
136+
use platform_value::Identifier;
137+
138+
fn config_with_all_owner_rules() -> TokenConfigurationV0 {
139+
let mut c = TokenConfigurationV0::default_most_restrictive();
140+
// Assign each rule's authorized_to_make_change / admin_action_takers to a
141+
// distinguishable value so we can verify dispatch.
142+
let auth = AuthorizedActionTakers::ContractOwner;
143+
let admin = AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]));
144+
let rules = ChangeControlRules::V0(ChangeControlRulesV0 {
145+
authorized_to_make_change: auth,
146+
admin_action_takers: admin,
147+
changing_authorized_action_takers_to_no_one_allowed: true,
148+
changing_admin_action_takers_to_no_one_allowed: true,
149+
self_changing_admin_action_takers_allowed: true,
150+
});
151+
c.set_conventions_change_rules(rules.clone());
152+
c.set_max_supply_change_rules(rules.clone());
153+
c.set_manual_minting_rules(rules.clone());
154+
c.set_manual_burning_rules(rules.clone());
155+
c.set_freeze_rules(rules.clone());
156+
c.set_unfreeze_rules(rules.clone());
157+
c.set_destroy_frozen_funds_rules(rules.clone());
158+
c.set_emergency_action_rules(rules.clone());
159+
c
160+
}
161+
162+
#[test]
163+
fn no_change_returns_no_one() {
164+
let c = TokenConfigurationV0::default_most_restrictive();
165+
let result = c.authorized_action_takers_for_configuration_item(
166+
&TokenConfigurationChangeItem::TokenConfigurationNoChange,
167+
);
168+
assert_eq!(result, AuthorizedActionTakers::NoOne);
169+
}
170+
171+
#[test]
172+
fn conventions_item_returns_authorized_to_make_change() {
173+
let c = config_with_all_owner_rules();
174+
let conv = TokenConfigurationConvention::V0(TokenConfigurationConventionV0 {
175+
localizations: Default::default(),
176+
decimals: 8,
177+
});
178+
let result = c.authorized_action_takers_for_configuration_item(
179+
&TokenConfigurationChangeItem::Conventions(conv),
180+
);
181+
assert_eq!(result, AuthorizedActionTakers::ContractOwner);
182+
}
183+
184+
#[test]
185+
fn conventions_control_group_returns_admin_action_takers() {
186+
let c = config_with_all_owner_rules();
187+
let result = c.authorized_action_takers_for_configuration_item(
188+
&TokenConfigurationChangeItem::ConventionsControlGroup(AuthorizedActionTakers::NoOne),
189+
);
190+
// conventions_change_rules.admin_action_takers = Identity(9)
191+
assert_eq!(
192+
result,
193+
AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]))
194+
);
195+
}
196+
197+
#[test]
198+
fn conventions_admin_group_returns_admin_action_takers() {
199+
let c = config_with_all_owner_rules();
200+
let result = c.authorized_action_takers_for_configuration_item(
201+
&TokenConfigurationChangeItem::ConventionsAdminGroup(AuthorizedActionTakers::NoOne),
202+
);
203+
assert_eq!(
204+
result,
205+
AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]))
206+
);
207+
}
208+
209+
#[test]
210+
fn max_supply_returns_authorized_to_make_change() {
211+
let c = config_with_all_owner_rules();
212+
let result = c.authorized_action_takers_for_configuration_item(
213+
&TokenConfigurationChangeItem::MaxSupply(Some(42)),
214+
);
215+
assert_eq!(result, AuthorizedActionTakers::ContractOwner);
216+
}
217+
218+
#[test]
219+
fn max_supply_control_and_admin_return_admin() {
220+
let c = config_with_all_owner_rules();
221+
let expected = AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]));
222+
let r1 = c.authorized_action_takers_for_configuration_item(
223+
&TokenConfigurationChangeItem::MaxSupplyControlGroup(AuthorizedActionTakers::NoOne),
224+
);
225+
let r2 = c.authorized_action_takers_for_configuration_item(
226+
&TokenConfigurationChangeItem::MaxSupplyAdminGroup(AuthorizedActionTakers::NoOne),
227+
);
228+
assert_eq!(r1, expected);
229+
assert_eq!(r2, expected);
230+
}
231+
232+
#[test]
233+
fn manual_minting_returns_admin_not_authorized() {
234+
// Note: ManualMinting in authorized_action_takers_for_configuration_item
235+
// returns admin_action_takers (not authorized_to_make_change) per the
236+
// implementation. Ensure that dispatch is correct.
237+
let c = config_with_all_owner_rules();
238+
let result = c.authorized_action_takers_for_configuration_item(
239+
&TokenConfigurationChangeItem::ManualMinting(AuthorizedActionTakers::NoOne),
240+
);
241+
assert_eq!(
242+
result,
243+
AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]))
244+
);
245+
}
246+
247+
#[test]
248+
fn freeze_returns_admin_action_takers() {
249+
let c = config_with_all_owner_rules();
250+
let result = c.authorized_action_takers_for_configuration_item(
251+
&TokenConfigurationChangeItem::Freeze(AuthorizedActionTakers::NoOne),
252+
);
253+
assert_eq!(
254+
result,
255+
AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]))
256+
);
257+
}
258+
259+
#[test]
260+
fn destroy_frozen_funds_returns_admin_action_takers() {
261+
let c = config_with_all_owner_rules();
262+
let result = c.authorized_action_takers_for_configuration_item(
263+
&TokenConfigurationChangeItem::DestroyFrozenFunds(AuthorizedActionTakers::NoOne),
264+
);
265+
assert_eq!(
266+
result,
267+
AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]))
268+
);
269+
}
270+
271+
#[test]
272+
fn main_control_group_always_returns_no_one() {
273+
// Per implementation, MainControlGroup change items always return NoOne,
274+
// regardless of config. This is important because modifying the main
275+
// control group is governed by main_control_group_can_be_modified, not
276+
// by any of the change_control_rules.
277+
let c = config_with_all_owner_rules();
278+
let result = c.authorized_action_takers_for_configuration_item(
279+
&TokenConfigurationChangeItem::MainControlGroup(Some(3)),
280+
);
281+
assert_eq!(result, AuthorizedActionTakers::NoOne);
282+
}
283+
284+
#[test]
285+
fn marketplace_trade_mode_returns_authorized_to_make_change() {
286+
let c = TokenConfigurationV0::default_most_restrictive();
287+
let result = c.authorized_action_takers_for_configuration_item(
288+
&TokenConfigurationChangeItem::MarketplaceTradeMode(TokenTradeMode::NotTradeable),
289+
);
290+
// default rules are NoOne
291+
assert_eq!(result, AuthorizedActionTakers::NoOne);
292+
}
293+
294+
#[test]
295+
fn perpetual_distribution_returns_authorized_to_make_change() {
296+
let c = TokenConfigurationV0::default_most_restrictive();
297+
let r = c.authorized_action_takers_for_configuration_item(
298+
&TokenConfigurationChangeItem::PerpetualDistribution(None),
299+
);
300+
// default distribution rules authorized_to_make_change is NoOne
301+
assert_eq!(r, AuthorizedActionTakers::NoOne);
302+
}
303+
304+
#[test]
305+
fn new_tokens_destination_identity_returns_authorized_to_make_change() {
306+
let c = TokenConfigurationV0::default_most_restrictive();
307+
let r = c.authorized_action_takers_for_configuration_item(
308+
&TokenConfigurationChangeItem::NewTokensDestinationIdentity(None),
309+
);
310+
assert_eq!(r, AuthorizedActionTakers::NoOne);
311+
}
312+
313+
#[test]
314+
fn minting_allow_choosing_destination_returns_authorized_to_make_change() {
315+
let c = TokenConfigurationV0::default_most_restrictive();
316+
let r = c.authorized_action_takers_for_configuration_item(
317+
&TokenConfigurationChangeItem::MintingAllowChoosingDestination(true),
318+
);
319+
assert_eq!(r, AuthorizedActionTakers::NoOne);
320+
}
321+
322+
#[test]
323+
fn unfreeze_and_admin_both_return_admin() {
324+
let c = config_with_all_owner_rules();
325+
let r1 = c.authorized_action_takers_for_configuration_item(
326+
&TokenConfigurationChangeItem::Unfreeze(AuthorizedActionTakers::NoOne),
327+
);
328+
let r2 = c.authorized_action_takers_for_configuration_item(
329+
&TokenConfigurationChangeItem::UnfreezeAdminGroup(AuthorizedActionTakers::NoOne),
330+
);
331+
let expected = AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]));
332+
assert_eq!(r1, expected);
333+
assert_eq!(r2, expected);
334+
}
335+
336+
#[test]
337+
fn emergency_action_and_admin_both_return_admin() {
338+
let c = config_with_all_owner_rules();
339+
let r1 = c.authorized_action_takers_for_configuration_item(
340+
&TokenConfigurationChangeItem::EmergencyAction(AuthorizedActionTakers::NoOne),
341+
);
342+
let r2 = c.authorized_action_takers_for_configuration_item(
343+
&TokenConfigurationChangeItem::EmergencyActionAdminGroup(AuthorizedActionTakers::NoOne),
344+
);
345+
let expected = AuthorizedActionTakers::Identity(Identifier::from([9u8; 32]));
346+
assert_eq!(r1, expected);
347+
assert_eq!(r2, expected);
348+
}
349+
}

0 commit comments

Comments
 (0)