Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions apps/contracts/audit_registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,4 +451,23 @@ mod tests {
soroban_sdk::String::from_str(&env, "1.0.0")
);
}

// ── event emission tests (#330) ──────────────────────────────────────────

#[test]
fn test_anchor_emits_event() {
let (env, api_signer, client) = setup();
let h = hash(&env);
client.anchor(&api_signer, &h).unwrap();
let events = env.events().all();
let anchor_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("anchor"), &env)]
});
assert!(anchor_event.is_some(), "anchor event not emitted");
// data = (reading_hash, ledger_sequence, timestamp)
let (_, _, data) = anchor_event.unwrap();
let (emitted_hash, _ledger, _ts): (BytesN<32>, u32, u64) =
soroban_sdk::FromVal::from_val(&env, &data);
assert_eq!(emitted_hash, h);
}
}
94 changes: 94 additions & 0 deletions apps/contracts/community_governance/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1081,4 +1081,98 @@ mod tests {
client.finalize(&id);
assert_eq!(client.get_proposal(&id).unwrap().status, ProposalStatus::Expired);
}

// ── event emission tests (#330) ──────────────────────────────────────────

#[test]
fn test_propose_emits_event() {
let (env, _admin, client) = setup();
let proposer = Address::generate(&env);
client.propose(
&proposer,
&String::from_str(&env, "Title"),
&String::from_str(&env, "Desc"),
);
let events = env.events().all();
let propose_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("propose"), &env)]
});
assert!(propose_event.is_some(), "propose event not emitted");
let (_, _, data) = propose_event.unwrap();
let proposal_id: u32 = soroban_sdk::FromVal::from_val(&env, &data);
assert_eq!(proposal_id, 1_u32);
}

#[test]
fn test_vote_emits_event() {
let (env, _admin, client) = setup();
let proposer = Address::generate(&env);
let voter = Address::generate(&env);
let id = client.propose(
&proposer,
&String::from_str(&env, "T"),
&String::from_str(&env, "D"),
);
client.vote(&voter, &id, &true);
let events = env.events().all();
let vote_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("vote"), &env)]
});
assert!(vote_event.is_some(), "vote event not emitted");
let (_, _, data) = vote_event.unwrap();
let (pid, _voter_addr, approve): (u32, Address, bool) =
soroban_sdk::FromVal::from_val(&env, &data);
assert_eq!(pid, id);
assert!(approve);
}

#[test]
fn test_finalize_emits_event() {
let (env, _admin, client) = setup();
let proposer = Address::generate(&env);
let id = client.propose(
&proposer,
&String::from_str(&env, "T"),
&String::from_str(&env, "D"),
);
client.vote(&Address::generate(&env), &id, &true);
client.vote(&Address::generate(&env), &id, &true);
env.ledger().with_mut(|l| l.sequence_number += 101);
client.finalize(&id);
let events = env.events().all();
let final_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("final"), &env)]
});
assert!(final_event.is_some(), "finalize event not emitted");
let (_, _, data) = final_event.unwrap();
let (pid, status): (u32, ProposalStatus) = soroban_sdk::FromVal::from_val(&env, &data);
assert_eq!(pid, id);
assert_eq!(status, ProposalStatus::Passed);
}

#[test]
fn test_execute_emits_event() {
let (env, _admin, client) = setup();
let proposer = Address::generate(&env);
let id = client.propose(
&proposer,
&String::from_str(&env, "T"),
&String::from_str(&env, "D"),
);
client.vote(&Address::generate(&env), &id, &true);
client.vote(&Address::generate(&env), &id, &true);
env.ledger().with_mut(|l| l.sequence_number += 101);
client.finalize(&id);
env.ledger()
.with_mut(|l| l.sequence_number += EXECUTE_TIMELOCK_LEDGERS);
client.execute(&id);
let events = env.events().all();
let exec_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("exec"), &env)]
});
assert!(exec_event.is_some(), "execute event not emitted");
let (_, _, data) = exec_event.unwrap();
let pid: u32 = soroban_sdk::FromVal::from_val(&env, &data);
assert_eq!(pid, id);
}
}
69 changes: 69 additions & 0 deletions apps/contracts/energy_token/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,4 +1013,73 @@ mod tests {
client.mint(&user, &1_i128);
assert_eq!(client.balance(&user), 1_i128);
}

// ── event emission tests (#330) ──────────────────────────────────────────

#[test]
fn test_mint_emits_event() {
let (env, client) = setup();
let user = Address::generate(&env);
client.mint(&user, &500_i128);
let events = env.events().all();
// Find the mint event: topic = ("mint",), data = (to, amount)
let mint_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("mint"), &env)]
});
assert!(mint_event.is_some(), "mint event not emitted");
let (_, _, data) = mint_event.unwrap();
let (to, amount): (Address, i128) = soroban_sdk::FromVal::from_val(&env, &data);
assert_eq!(to, user);
assert_eq!(amount, 500_i128);
}

#[test]
fn test_transfer_emits_event() {
let (env, client) = setup();
let a = Address::generate(&env);
let b = Address::generate(&env);
client.mint(&a, &1000_i128);
env.events().all(); // clear
client.transfer(&a, &b, &300_i128);
let events = env.events().all();
let transfer_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("transfer"), &env)]
});
assert!(transfer_event.is_some(), "transfer event not emitted");
let (_, _, data) = transfer_event.unwrap();
let (from, to, amount): (Address, Address, i128) = soroban_sdk::FromVal::from_val(&env, &data);
assert_eq!(from, a);
assert_eq!(to, b);
assert_eq!(amount, 300_i128);
}

#[test]
fn test_retire_emits_event() {
let (env, client) = setup();
let user = Address::generate(&env);
client.mint(&user, &1000_i128);
client.retire(&user, &String::from_str(&env, "REC compliance"));
let events = env.events().all();
let retire_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("retire"), &env)]
});
assert!(retire_event.is_some(), "retire event not emitted");
}

#[test]
fn test_burn_emits_event() {
let (env, client) = setup();
let user = Address::generate(&env);
client.mint(&user, &1000_i128);
client.burn(&user, &200_i128);
let events = env.events().all();
let burn_event = events.iter().find(|(_, topics, _)| {
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("burn"), &env)]
});
assert!(burn_event.is_some(), "burn event not emitted");
let (_, _, data) = burn_event.unwrap();
let (from, amount): (Address, i128) = soroban_sdk::FromVal::from_val(&env, &data);
assert_eq!(from, user);
assert_eq!(amount, 200_i128);
}
}
Loading