Skip to content

Commit

Permalink
AgentRole - Test
Browse files Browse the repository at this point in the history
  • Loading branch information
EgeCaner committed Jan 6, 2025
1 parent b7fc454 commit 9db3af0
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ name = "mocks"
version = "0.1.0"
dependencies = [
"compliance",
"openzeppelin_access",
"openzeppelin_token",
"roles",
"snforge_std",
]

Expand Down Expand Up @@ -127,6 +129,7 @@ dependencies = [
name = "roles"
version = "0.1.0"
dependencies = [
"mocks",
"onchain_id",
"openzeppelin_access",
"openzeppelin_introspection",
Expand Down
3 changes: 3 additions & 0 deletions crates/mocks/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ edition = "2024_07"
[dependencies]
starknet.workspace = true
compliance = { path = "../compliance"}
roles = { path = "../roles"}
openzeppelin_token.workspace = true
openzeppelin_access.workspace = true

[dev-dependencies]
snforge_std.workspace = true

Expand Down
1 change: 1 addition & 0 deletions crates/mocks/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod mock_abstract_module;
pub mod mock_agent_role;
pub mod mock_contract;
40 changes: 40 additions & 0 deletions crates/mocks/src/mock_agent_role.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#[starknet::contract]
mod MockAgentRole {
use openzeppelin_access::ownable::OwnableComponent;
use roles::agent_role::AgentRoleComponent;
use starknet::ContractAddress;

component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);

#[abi(embed_v0)]
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;

component!(path: AgentRoleComponent, storage: agent_role, event: AgentRoleEvent);

#[abi(embed_v0)]
impl AgentRoleImpl = AgentRoleComponent::AgentRoleImpl<ContractState>;
impl AgentRoleInternalImpl = AgentRoleComponent::InternalImpl<ContractState>;

#[storage]
struct Storage {
#[substorage(v0)]
ownable: OwnableComponent::Storage,
#[substorage(v0)]
agent_role: AgentRoleComponent::Storage,
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
OwnableEvent: OwnableComponent::Event,
#[flat]
AgentRoleEvent: AgentRoleComponent::Event,
}

#[constructor]
fn constructor(ref self: ContractState, owner: ContractAddress) {
self.ownable.initializer(owner);
}
}
2 changes: 2 additions & 0 deletions crates/roles/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ openzeppelin_introspection.workspace = true
token = { path = "../token"}
registry = { path = "../registry"}
onchain_id = {path = "../onchain_id"}
mocks = { path = "../mocks"}

[dev-dependencies]
snforge_std.workspace = true

[[target.starknet-contract]]
sierra = true
build-external-contracts = ["mocks::*"]

[tool]
fmt.workspace = true
Expand Down
10 changes: 8 additions & 2 deletions crates/roles/src/agent_role.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,18 @@ pub mod AgentRoleComponent {

fn _add_agent(ref self: ComponentState<TContractState>, agent: ContractAddress) {
assert(agent.is_non_zero(), 'Agent address zero!');
self.AgentRole_agents.entry(agent).write(true);
let agent_storage_path = self.AgentRole_agents.entry(agent);
assert(!agent_storage_path.read(), 'Agent already registered');
agent_storage_path.write(true);
self.emit(AgentAdded { agent });
}

fn _remove_agent(ref self: ComponentState<TContractState>, agent: ContractAddress) {
assert(agent.is_non_zero(), 'Agent address zero!');
self.AgentRole_agents.entry(agent).write(false);
let agent_storage_path = self.AgentRole_agents.entry(agent);
assert(agent_storage_path.read(), 'Agent not registered');
agent_storage_path.write(false);
self.emit(AgentRemoved { agent });
}
}
}
130 changes: 130 additions & 0 deletions crates/roles/tests/agent_role_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use roles::agent_role::IAgentRoleDispatcher;
use snforge_std::{ContractClassTrait, DeclareResultTrait, declare};

fn setup() -> IAgentRoleDispatcher {
let agent_role_contract = declare("MockAgentRole").unwrap().contract_class();
let (deployed_address, _) = agent_role_contract
.deploy(@array![starknet::get_contract_address().into()])
.unwrap();
IAgentRoleDispatcher { contract_address: deployed_address }
}

pub mod add_agent {
use core::num::traits::Zero;
use roles::agent_role::{AgentRoleComponent, IAgentRoleDispatcherTrait};
use snforge_std::{
EventSpyAssertionsTrait, spy_events, start_cheat_caller_address, stop_cheat_caller_address,
};
use super::setup;

#[test]
#[should_panic(expected: 'Caller is not the owner')]
fn test_should_reverts_when_sender_is_not_the_owner() {
let agent_role = setup();
start_cheat_caller_address(
agent_role.contract_address, starknet::contract_address_const::<'NOT_OWNER'>(),
);
agent_role.add_agent(starknet::contract_address_const::<'AGENT'>());
stop_cheat_caller_address(agent_role.contract_address);
}

#[test]
#[should_panic(expected: 'Agent address zero!')]
fn test_should_reverts_when_address_to_add_is_zero_address() {
let agent_role = setup();

agent_role.add_agent(Zero::zero());
}

#[test]
fn test_should_add_the_agent() {
let agent_role = setup();
let agent = starknet::contract_address_const::<'AGENT'>();

let mut spy = spy_events();
agent_role.add_agent(agent);

assert(agent_role.is_agent(agent), 'Agent not registered');
spy
.assert_emitted(
@array![
(
agent_role.contract_address,
AgentRoleComponent::Event::AgentAdded(
AgentRoleComponent::AgentAdded { agent },
),
),
],
);
}

#[test]
#[should_panic(expected: 'Agent already registered')]
fn test_should_reverts_when_address_to_add_is_already_an_agent() {
let agent_role = setup();
let agent = starknet::contract_address_const::<'AGENT'>();

agent_role.add_agent(agent);
/// Registering twice should panic
agent_role.add_agent(agent);
}
}

pub mod remove_agent {
use core::num::traits::Zero;
use roles::agent_role::{AgentRoleComponent, IAgentRoleDispatcherTrait};
use snforge_std::{
EventSpyAssertionsTrait, spy_events, start_cheat_caller_address, stop_cheat_caller_address,
};
use super::setup;

#[test]
#[should_panic(expected: 'Caller is not the owner')]
fn test_should_reverts_when_sender_is_not_the_owner() {
let agent_role = setup();
start_cheat_caller_address(
agent_role.contract_address, starknet::contract_address_const::<'NOT_OWNER'>(),
);
agent_role.remove_agent(starknet::contract_address_const::<'AGENT'>());
stop_cheat_caller_address(agent_role.contract_address);
}

#[test]
#[should_panic(expected: 'Agent address zero!')]
fn test_should_reverts_when_address_to_remove_is_zero_address() {
let agent_role = setup();

agent_role.remove_agent(Zero::zero());
}

#[test]
#[should_panic(expected: 'Agent not registered')]
fn test_should_reverts_when_address_to_remove_is_not_an_agent() {
let agent_role = setup();

agent_role.remove_agent(starknet::contract_address_const::<'AGENT'>());
}

#[test]
fn test_should_remove_the_agent_when_address_to_remove_is_an_agent_address() {
let agent_role = setup();
let agent = starknet::contract_address_const::<'AGENT'>();
agent_role.add_agent(agent);

let mut spy = spy_events();
agent_role.remove_agent(agent);

assert(!agent_role.is_agent(agent), 'Agent not removed');
spy
.assert_emitted(
@array![
(
agent_role.contract_address,
AgentRoleComponent::Event::AgentRemoved(
AgentRoleComponent::AgentRemoved { agent },
),
),
],
);
}
}
1 change: 1 addition & 0 deletions crates/roles/tests/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod agent_role_test;

0 comments on commit 9db3af0

Please sign in to comment.