pub trait EventSubscriber<T> {
fn subscribe(
&mut self,
topic: &str,
handler: std::boxed::Box<dyn Fn(super::CloudEventsEnvelope<T>) -> crate::HexResult<()>>,
) -> crate::HexResult<()>;
fn poll(&mut self) -> crate::HexResult<std::option::Option<super::CloudEventsEnvelope<T>>>;
}
#[cfg(test)]
mod tests {
use super::*;
struct TestEvent {
id: std::string::String,
}
impl crate::domain::DomainEvent for TestEvent {
fn event_type(&self) -> &str {
"com.test.event"
}
fn aggregate_id(&self) -> std::string::String {
self.id.clone()
}
}
struct MockSubscriber {
events: std::cell::RefCell<std::vec::Vec<super::super::CloudEventsEnvelope<TestEvent>>>,
handlers: std::cell::RefCell<
std::collections::HashMap<
std::string::String,
std::boxed::Box<
dyn Fn(super::super::CloudEventsEnvelope<TestEvent>) -> crate::HexResult<()>,
>,
>,
>,
}
impl MockSubscriber {
fn new() -> Self {
Self {
events: std::cell::RefCell::new(std::vec::Vec::new()),
handlers: std::cell::RefCell::new(std::collections::HashMap::new()),
}
}
fn add_event(&self, envelope: super::super::CloudEventsEnvelope<TestEvent>) {
self.events.borrow_mut().push(envelope);
}
fn event_count(&self) -> usize {
self.events.borrow().len()
}
}
impl EventSubscriber<TestEvent> for MockSubscriber {
fn subscribe(
&mut self,
topic: &str,
handler: std::boxed::Box<
dyn Fn(super::super::CloudEventsEnvelope<TestEvent>) -> crate::HexResult<()>,
>,
) -> crate::HexResult<()> {
self
.handlers
.borrow_mut()
.insert(std::string::String::from(topic), handler);
std::result::Result::Ok(())
}
fn poll(
&mut self,
) -> crate::HexResult<std::option::Option<super::super::CloudEventsEnvelope<TestEvent>>> {
let mut events = self.events.borrow_mut();
if events.is_empty() {
std::result::Result::Ok(std::option::Option::None)
} else {
std::result::Result::Ok(std::option::Option::Some(events.remove(0)))
}
}
}
#[test]
fn test_subscribe_registers_handler() {
let mut subscriber = MockSubscriber::new();
let result = subscriber.subscribe(
"test.topic",
std::boxed::Box::new(|_envelope| std::result::Result::Ok(())),
);
std::assert!(result.is_ok());
std::assert_eq!(subscriber.handlers.borrow().len(), 1);
std::assert!(subscriber.handlers.borrow().contains_key("test.topic"));
}
#[test]
fn test_poll_returns_none_when_empty() {
let mut subscriber = MockSubscriber::new();
let result = subscriber.poll();
std::assert!(result.is_ok());
std::assert!(result.unwrap().is_none());
}
#[test]
fn test_poll_returns_event_when_available() {
let mut subscriber = MockSubscriber::new();
let event = TestEvent {
id: std::string::String::from("test-123"),
};
let envelope = super::super::CloudEventsEnvelope::from_domain_event(
std::string::String::from("evt-001"),
std::string::String::from("/test/source"),
event,
);
subscriber.add_event(envelope);
let result = subscriber.poll();
std::assert!(result.is_ok());
let polled_envelope = result.unwrap();
std::assert!(polled_envelope.is_some());
std::assert_eq!(polled_envelope.unwrap().id, "evt-001");
}
#[test]
fn test_poll_removes_event_from_queue() {
let mut subscriber = MockSubscriber::new();
let event1 = TestEvent {
id: std::string::String::from("test-1"),
};
let event2 = TestEvent {
id: std::string::String::from("test-2"),
};
subscriber.add_event(super::super::CloudEventsEnvelope::from_domain_event(
std::string::String::from("evt-001"),
std::string::String::from("/test/source"),
event1,
));
subscriber.add_event(super::super::CloudEventsEnvelope::from_domain_event(
std::string::String::from("evt-002"),
std::string::String::from("/test/source"),
event2,
));
std::assert_eq!(subscriber.event_count(), 2);
let _ = subscriber.poll();
std::assert_eq!(subscriber.event_count(), 1);
let _ = subscriber.poll();
std::assert_eq!(subscriber.event_count(), 0);
let result = subscriber.poll();
std::assert!(result.unwrap().is_none());
}
#[test]
fn test_multiple_topic_subscriptions() {
let mut subscriber = MockSubscriber::new();
let result1 = subscriber.subscribe(
"topic1",
std::boxed::Box::new(|_envelope| std::result::Result::Ok(())),
);
let result2 = subscriber.subscribe(
"topic2",
std::boxed::Box::new(|_envelope| std::result::Result::Ok(())),
);
std::assert!(result1.is_ok());
std::assert!(result2.is_ok());
std::assert_eq!(subscriber.handlers.borrow().len(), 2);
}
}