Skip to content

Commit 60bfed0

Browse files
committed
test: add contract event emission tests for all state-changing functions (AnnabelJoe#330)
- energy_token: mint, transfer, burn, retire event tests - audit_registry: anchor event test (topics + data fields verified) - community_governance: propose, vote, finalize, execute event tests - Each test verifies event topic and data payload fields
1 parent e9a7338 commit 60bfed0

3 files changed

Lines changed: 182 additions & 0 deletions

File tree

  • apps/contracts

apps/contracts/audit_registry/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,4 +451,23 @@ mod tests {
451451
soroban_sdk::String::from_str(&env, "1.0.0")
452452
);
453453
}
454+
455+
// ── event emission tests (#330) ──────────────────────────────────────────
456+
457+
#[test]
458+
fn test_anchor_emits_event() {
459+
let (env, api_signer, client) = setup();
460+
let h = hash(&env);
461+
client.anchor(&api_signer, &h).unwrap();
462+
let events = env.events().all();
463+
let anchor_event = events.iter().find(|(_, topics, _)| {
464+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("anchor"), &env)]
465+
});
466+
assert!(anchor_event.is_some(), "anchor event not emitted");
467+
// data = (reading_hash, ledger_sequence, timestamp)
468+
let (_, _, data) = anchor_event.unwrap();
469+
let (emitted_hash, _ledger, _ts): (BytesN<32>, u32, u64) =
470+
soroban_sdk::FromVal::from_val(&env, &data);
471+
assert_eq!(emitted_hash, h);
472+
}
454473
}

apps/contracts/community_governance/src/lib.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,4 +1081,98 @@ mod tests {
10811081
client.finalize(&id);
10821082
assert_eq!(client.get_proposal(&id).unwrap().status, ProposalStatus::Expired);
10831083
}
1084+
1085+
// ── event emission tests (#330) ──────────────────────────────────────────
1086+
1087+
#[test]
1088+
fn test_propose_emits_event() {
1089+
let (env, _admin, client) = setup();
1090+
let proposer = Address::generate(&env);
1091+
client.propose(
1092+
&proposer,
1093+
&String::from_str(&env, "Title"),
1094+
&String::from_str(&env, "Desc"),
1095+
);
1096+
let events = env.events().all();
1097+
let propose_event = events.iter().find(|(_, topics, _)| {
1098+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("propose"), &env)]
1099+
});
1100+
assert!(propose_event.is_some(), "propose event not emitted");
1101+
let (_, _, data) = propose_event.unwrap();
1102+
let proposal_id: u32 = soroban_sdk::FromVal::from_val(&env, &data);
1103+
assert_eq!(proposal_id, 1_u32);
1104+
}
1105+
1106+
#[test]
1107+
fn test_vote_emits_event() {
1108+
let (env, _admin, client) = setup();
1109+
let proposer = Address::generate(&env);
1110+
let voter = Address::generate(&env);
1111+
let id = client.propose(
1112+
&proposer,
1113+
&String::from_str(&env, "T"),
1114+
&String::from_str(&env, "D"),
1115+
);
1116+
client.vote(&voter, &id, &true);
1117+
let events = env.events().all();
1118+
let vote_event = events.iter().find(|(_, topics, _)| {
1119+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("vote"), &env)]
1120+
});
1121+
assert!(vote_event.is_some(), "vote event not emitted");
1122+
let (_, _, data) = vote_event.unwrap();
1123+
let (pid, _voter_addr, approve): (u32, Address, bool) =
1124+
soroban_sdk::FromVal::from_val(&env, &data);
1125+
assert_eq!(pid, id);
1126+
assert!(approve);
1127+
}
1128+
1129+
#[test]
1130+
fn test_finalize_emits_event() {
1131+
let (env, _admin, client) = setup();
1132+
let proposer = Address::generate(&env);
1133+
let id = client.propose(
1134+
&proposer,
1135+
&String::from_str(&env, "T"),
1136+
&String::from_str(&env, "D"),
1137+
);
1138+
client.vote(&Address::generate(&env), &id, &true);
1139+
client.vote(&Address::generate(&env), &id, &true);
1140+
env.ledger().with_mut(|l| l.sequence_number += 101);
1141+
client.finalize(&id);
1142+
let events = env.events().all();
1143+
let final_event = events.iter().find(|(_, topics, _)| {
1144+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("final"), &env)]
1145+
});
1146+
assert!(final_event.is_some(), "finalize event not emitted");
1147+
let (_, _, data) = final_event.unwrap();
1148+
let (pid, status): (u32, ProposalStatus) = soroban_sdk::FromVal::from_val(&env, &data);
1149+
assert_eq!(pid, id);
1150+
assert_eq!(status, ProposalStatus::Passed);
1151+
}
1152+
1153+
#[test]
1154+
fn test_execute_emits_event() {
1155+
let (env, _admin, client) = setup();
1156+
let proposer = Address::generate(&env);
1157+
let id = client.propose(
1158+
&proposer,
1159+
&String::from_str(&env, "T"),
1160+
&String::from_str(&env, "D"),
1161+
);
1162+
client.vote(&Address::generate(&env), &id, &true);
1163+
client.vote(&Address::generate(&env), &id, &true);
1164+
env.ledger().with_mut(|l| l.sequence_number += 101);
1165+
client.finalize(&id);
1166+
env.ledger()
1167+
.with_mut(|l| l.sequence_number += EXECUTE_TIMELOCK_LEDGERS);
1168+
client.execute(&id);
1169+
let events = env.events().all();
1170+
let exec_event = events.iter().find(|(_, topics, _)| {
1171+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("exec"), &env)]
1172+
});
1173+
assert!(exec_event.is_some(), "execute event not emitted");
1174+
let (_, _, data) = exec_event.unwrap();
1175+
let pid: u32 = soroban_sdk::FromVal::from_val(&env, &data);
1176+
assert_eq!(pid, id);
1177+
}
10841178
}

apps/contracts/energy_token/src/lib.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,4 +1013,73 @@ mod tests {
10131013
client.mint(&user, &1_i128);
10141014
assert_eq!(client.balance(&user), 1_i128);
10151015
}
1016+
1017+
// ── event emission tests (#330) ──────────────────────────────────────────
1018+
1019+
#[test]
1020+
fn test_mint_emits_event() {
1021+
let (env, client) = setup();
1022+
let user = Address::generate(&env);
1023+
client.mint(&user, &500_i128);
1024+
let events = env.events().all();
1025+
// Find the mint event: topic = ("mint",), data = (to, amount)
1026+
let mint_event = events.iter().find(|(_, topics, _)| {
1027+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("mint"), &env)]
1028+
});
1029+
assert!(mint_event.is_some(), "mint event not emitted");
1030+
let (_, _, data) = mint_event.unwrap();
1031+
let (to, amount): (Address, i128) = soroban_sdk::FromVal::from_val(&env, &data);
1032+
assert_eq!(to, user);
1033+
assert_eq!(amount, 500_i128);
1034+
}
1035+
1036+
#[test]
1037+
fn test_transfer_emits_event() {
1038+
let (env, client) = setup();
1039+
let a = Address::generate(&env);
1040+
let b = Address::generate(&env);
1041+
client.mint(&a, &1000_i128);
1042+
env.events().all(); // clear
1043+
client.transfer(&a, &b, &300_i128);
1044+
let events = env.events().all();
1045+
let transfer_event = events.iter().find(|(_, topics, _)| {
1046+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("transfer"), &env)]
1047+
});
1048+
assert!(transfer_event.is_some(), "transfer event not emitted");
1049+
let (_, _, data) = transfer_event.unwrap();
1050+
let (from, to, amount): (Address, Address, i128) = soroban_sdk::FromVal::from_val(&env, &data);
1051+
assert_eq!(from, a);
1052+
assert_eq!(to, b);
1053+
assert_eq!(amount, 300_i128);
1054+
}
1055+
1056+
#[test]
1057+
fn test_retire_emits_event() {
1058+
let (env, client) = setup();
1059+
let user = Address::generate(&env);
1060+
client.mint(&user, &1000_i128);
1061+
client.retire(&user, &String::from_str(&env, "REC compliance"));
1062+
let events = env.events().all();
1063+
let retire_event = events.iter().find(|(_, topics, _)| {
1064+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("retire"), &env)]
1065+
});
1066+
assert!(retire_event.is_some(), "retire event not emitted");
1067+
}
1068+
1069+
#[test]
1070+
fn test_burn_emits_event() {
1071+
let (env, client) = setup();
1072+
let user = Address::generate(&env);
1073+
client.mint(&user, &1000_i128);
1074+
client.burn(&user, &200_i128);
1075+
let events = env.events().all();
1076+
let burn_event = events.iter().find(|(_, topics, _)| {
1077+
topics == &soroban_sdk::vec![&env, soroban_sdk::IntoVal::<Env, soroban_sdk::Val>::into_val(&symbol_short!("burn"), &env)]
1078+
});
1079+
assert!(burn_event.is_some(), "burn event not emitted");
1080+
let (_, _, data) = burn_event.unwrap();
1081+
let (from, amount): (Address, i128) = soroban_sdk::FromVal::from_val(&env, &data);
1082+
assert_eq!(from, user);
1083+
assert_eq!(amount, 200_i128);
1084+
}
10161085
}

0 commit comments

Comments
 (0)