notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 4e494e218e1d128f3582e5c8580b6b56361f40cb
parent 99bdc743961889f608ed2c1d7cb239bbc605263a
Author: kernelkind <kernelkind@gmail.com>
Date:   Thu, 19 Feb 2026 13:30:32 -0500

test(scoped-subs): verify owner-slot stability and lifecycle drop

Add unit tests ensuring owner keys map to stable slots, distinct owners allocate distinct slots, and dropping an owner removes both mapping and runtime-owned subscriptions.

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Mcrates/notedeck/src/scoped_sub_owners.rs | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+), 0 deletions(-)

diff --git a/crates/notedeck/src/scoped_sub_owners.rs b/crates/notedeck/src/scoped_sub_owners.rs @@ -132,3 +132,59 @@ impl ScopedSubOwners { self.slots_by_owner.is_empty() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::EguiWakeup; + use enostr::OutboxPool; + + /// Verifies the same owner key always resolves to the same runtime slot. + #[test] + fn ensure_slot_is_stable_for_owner() { + let mut owners = ScopedSubOwners::default(); + let mut runtime = ScopedSubRuntime::default(); + + let owner = SubOwnerKey::builder("threads").with(42u64).finish(); + let a = owners.ensure_slot(&mut runtime, owner); + let b = owners.ensure_slot(&mut runtime, owner); + + assert_eq!(a, b); + assert_eq!(owners.len(), 1); + } + + /// Ensures different owner keys allocate distinct runtime slots. + #[test] + fn ensure_slot_distinguishes_different_owners() { + let mut owners = ScopedSubOwners::default(); + let mut runtime = ScopedSubRuntime::default(); + + let owner_a = SubOwnerKey::builder("threads").with(1u64).finish(); + let owner_b = SubOwnerKey::builder("threads").with(2u64).finish(); + + let slot_a = owners.ensure_slot(&mut runtime, owner_a); + let slot_b = owners.ensure_slot(&mut runtime, owner_b); + + assert_ne!(slot_a, slot_b); + assert_eq!(owners.len(), 2); + } + + /// Verifies dropping an owner removes its slot mapping and is idempotent. + #[test] + fn drop_owner_removes_mapping_and_runtime_slot() { + let mut owners = ScopedSubOwners::default(); + let mut runtime = ScopedSubRuntime::default(); + let mut pool = OutboxPool::default(); + let mut outbox = + enostr::OutboxSessionHandler::new(&mut pool, EguiWakeup::new(egui::Context::default())); + + let owner = SubOwnerKey::builder("onboarding").finish(); + let _slot = owners.ensure_slot(&mut runtime, owner); + + assert!(owners.drop_owner(&mut runtime, &mut outbox, owner)); + assert!(!owners.slots_by_owner.contains_key(&owner)); + assert!(owners.is_empty()); + + assert!(!owners.drop_owner(&mut runtime, &mut outbox, owner)); + } +}