use nstreams_core::namespace::StreamNamespace;
use nstreams_core::store::EventStore;
use nstreams_core::stream::ReadStreamBackend;
use nstreams_core::Namespace;
use nstreams_core::testing::{collect_delivered, payload, TestHarness};
use nstreams_core::REQUEST_ID_PREFIX;
#[tokio::test]
async fn subscribe_replays_history_with_request_id() {
let harness = TestHarness::new();
let namespace = StreamNamespace::from("events.test");
harness
.store
.persist_next(&namespace, &payload(serde_json::json!({"n": 1})))
.await
.unwrap();
harness
.store
.persist_next(&namespace, &payload(serde_json::json!({"n": 2})))
.await
.unwrap();
let mut subscription = harness.handler.subscribe(&namespace, 10).await.unwrap();
assert!(subscription.request_id().starts_with(REQUEST_ID_PREFIX));
let events = collect_delivered(&mut subscription, 2).await;
assert_eq!(events[0].request_id, subscription.request_id());
assert_eq!(events[1].request_id, subscription.request_id());
assert_eq!(events[0].version, 1);
assert_eq!(events[1].version, 2);
let first: serde_json::Value = serde_json::from_slice(&events[0].payload).unwrap();
assert_eq!(first["n"], 1);
}
#[tokio::test]
async fn subscribe_bootstraps_read_stream_on_first_use() {
let harness = TestHarness::new();
let namespace = StreamNamespace::from("events.bootstrap");
harness
.store
.persist_next(&namespace, &payload(serde_json::json!({"boot": true})))
.await
.unwrap();
assert!(!harness.handler.is_read_stream_ready(&namespace).await);
harness.handler.subscribe(&namespace, 1).await.unwrap();
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
assert!(harness.handler.is_read_stream_ready(&namespace).await);
assert!(harness.read_stream.stream_exists(&namespace).await.unwrap());
}
#[tokio::test]
async fn subscribe_tails_live_events_after_history() {
let harness = TestHarness::new();
let namespace = StreamNamespace::from("events.live");
harness
.store
.persist_next(&namespace, &payload(serde_json::json!({"phase": "history"})))
.await
.unwrap();
let mut subscription = harness.handler.subscribe(&namespace, 10).await.unwrap();
let history = collect_delivered(&mut subscription, 1).await;
assert_eq!(history[0].version, 1);
let live = nstreams_core::event::StreamEvent {
namespace: namespace.as_str().to_string(),
version: 2,
payload: payload(serde_json::json!({"phase": "live"})),
};
harness.read_stream.push_live(namespace.as_str(), live).await;
let live_delivered = collect_delivered(&mut subscription, 1).await;
assert_eq!(live_delivered[0].version, 2);
assert_eq!(live_delivered[0].request_id, subscription.request_id());
}
#[tokio::test]
async fn subscribe_rejects_invalid_namespace() {
let harness = TestHarness::new();
let namespace = StreamNamespace::from("has space");
let result = harness.handler.subscribe(&namespace, 1).await;
assert!(matches!(
result,
Err(nstreams_core::Error::InvalidNamespace(_, _))
));
}