diff --git a/rust/capture/src/v0_endpoint.rs b/rust/capture/src/v0_endpoint.rs index a935ab8189c19..bd2e8d2ae3127 100644 --- a/rust/capture/src/v0_endpoint.rs +++ b/rust/capture/src/v0_endpoint.rs @@ -336,7 +336,9 @@ pub async fn process_replay_events<'a>( let snapshot_items: Vec = events .iter() .map(|e| match e.properties.get("$snapshot_data") { + // We can either have an array or single object Some(Value::Array(value)) => Ok(value.to_vec()), + // Wrap a single object in a vec to simplify processing. Some(Value::Object(value)) => Ok([Value::Object(value.clone())].to_vec()), _ => Err(CaptureError::MissingSnapshotData), }) @@ -348,13 +350,8 @@ pub async fn process_replay_events<'a>( let session_id = events[0] .properties .get("$session_id") - .ok_or(CaptureError::MissingSessionId)? - .as_str() - .ok_or(CaptureError::InvalidSessionId)?; - let window_id = events[0] - .properties - .get("$window_id") - .ok_or(CaptureError::MissingWindowId)?; + .ok_or(CaptureError::MissingSessionId)?; + let window_id = events[0].properties.get("$window_id").unwrap_or(session_id); let event = ProcessedEvent { data_type: DataType::SnapshotMain, uuid: events[0].uuid.unwrap_or_else(uuid_v7), @@ -373,7 +370,9 @@ pub async fn process_replay_events<'a>( now: context.now.clone(), sent_at: context.sent_at, token: context.token.clone(), - session_id: Some(session_id.to_string()), + session_id: Some(session_id + .as_str() + .ok_or(CaptureError::InvalidSessionId)?.to_string()), }; sink.send(event).await diff --git a/rust/capture/tests/recordings.rs b/rust/capture/tests/recordings.rs index a54638497b987..1dfd763701164 100644 --- a/rust/capture/tests/recordings.rs +++ b/rust/capture/tests/recordings.rs @@ -93,3 +93,27 @@ async fn it_rejects_bad_session_id() -> Result<()> { assert_eq!(StatusCode::BAD_REQUEST, res.status()); Ok(()) } + +#[tokio::test] +async fn it_defaults_window_id_to_session_id() -> Result<()> { + setup_tracing(); + let token = random_string("token", 16); + let distinct_id = random_string("id", 16); + let session_id = random_string("id", 16); + + let main_topic = EphemeralTopic::new().await; + let server = ServerHandle::for_recordings(&main_topic).await; + + let event = json!({ + "token": token, + "event": "testing", + "distinct_id": distinct_id, + "properties": { + "$session_id": session_id, + "$snapshot_data": [], + } + }); + let res = server.capture_recording(event.to_string()).await; + assert_eq!(StatusCode::OK, res.status()); + Ok(()) +}