//! L1 tests for [`TokioBroadcastEventBus`]: a published [`DomainEvent`] is
//! received both through the blocking `subscribe()` [`EventStream`] and through
//! the async `raw_receiver()` used by the Tauri event relay.

use domain::events::DomainEvent;
use domain::ports::EventBus;
use domain::ProjectId;
use infrastructure::TokioBroadcastEventBus;
use uuid::Uuid;

fn sample_event() -> DomainEvent {
    DomainEvent::ProjectCreated {
        project_id: ProjectId::from_uuid(Uuid::nil()),
    }
}

#[tokio::test]
async fn raw_receiver_gets_published_event() {
    let bus = TokioBroadcastEventBus::new();
    let mut rx = bus.raw_receiver();

    bus.publish(sample_event());

    let got = rx.recv().await.expect("event received");
    assert_eq!(got, sample_event());
}

#[tokio::test]
async fn raw_receiver_fans_out_to_multiple_subscribers() {
    let bus = TokioBroadcastEventBus::new();
    let mut rx1 = bus.raw_receiver();
    let mut rx2 = bus.raw_receiver();

    bus.publish(sample_event());

    assert_eq!(rx1.recv().await.unwrap(), sample_event());
    assert_eq!(rx2.recv().await.unwrap(), sample_event());
}

#[test]
fn subscribe_blocking_stream_yields_published_event() {
    let bus = TokioBroadcastEventBus::new();
    let mut stream = bus.subscribe();
    bus.publish(sample_event());
    assert_eq!(stream.next(), Some(sample_event()));
}

#[tokio::test]
async fn publish_without_subscribers_is_noop() {
    let bus = TokioBroadcastEventBus::new();
    // No receiver registered: publish must not panic.
    bus.publish(sample_event());
}
