diff --git a/crates/turborepo-api-client/src/lib.rs b/crates/turborepo-api-client/src/lib.rs index 5ac83d60bff27..c27618b37dd3b 100644 --- a/crates/turborepo-api-client/src/lib.rs +++ b/crates/turborepo-api-client/src/lib.rs @@ -783,10 +783,11 @@ mod test { use anyhow::Result; use bytes::Bytes; use insta::assert_snapshot; + use turborepo_vercel_api::telemetry::{TelemetryEvent, TelemetryGenericEvent}; use turborepo_vercel_api_mock::start_test_server; use url::Url; - use crate::{APIClient, CacheClient, Client}; + use crate::{telemetry::TelemetryClient, APIClient, AnonAPIClient, CacheClient, Client}; #[tokio::test] async fn test_do_preflight() -> Result<()> { @@ -911,4 +912,88 @@ mod test { Ok(()) } + + #[tokio::test] + async fn test_record_telemetry_success() -> Result<()> { + let port = port_scanner::request_open_port().unwrap(); + let handle = tokio::spawn(start_test_server(port)); + let base_url = format!("http://localhost:{}", port); + + let client = AnonAPIClient::new(&base_url, 10, "2.0.0")?; + + let events = vec![ + TelemetryEvent::Generic(TelemetryGenericEvent { + id: "test-id-1".to_string(), + key: "test_key".to_string(), + value: "test_value".to_string(), + parent_id: None, + }), + TelemetryEvent::Generic(TelemetryGenericEvent { + id: "test-id-2".to_string(), + key: "test_key_2".to_string(), + value: "test_value_2".to_string(), + parent_id: Some("test-id-1".to_string()), + }), + ]; + + let result = client + .record_telemetry(events, "test-telemetry-id", "test-session-id") + .await; + + assert!(result.is_ok()); + + handle.abort(); + let _ = handle.await; + + Ok(()) + } + + #[tokio::test] + async fn test_record_telemetry_empty_events() -> Result<()> { + let port = port_scanner::request_open_port().unwrap(); + let handle = tokio::spawn(start_test_server(port)); + let base_url = format!("http://localhost:{}", port); + + let client = AnonAPIClient::new(&base_url, 10, "2.0.0")?; + + let events = vec![]; + + let result = client + .record_telemetry(events, "test-telemetry-id", "test-session-id") + .await; + + assert!(result.is_ok()); + + handle.abort(); + let _ = handle.await; + + Ok(()) + } + + #[tokio::test] + async fn test_record_telemetry_with_different_event_types() -> Result<()> { + let port = port_scanner::request_open_port().unwrap(); + let handle = tokio::spawn(start_test_server(port)); + let base_url = format!("http://localhost:{}", port); + + let client = AnonAPIClient::new(&base_url, 10, "2.0.0")?; + + let events = vec![TelemetryEvent::Generic(TelemetryGenericEvent { + id: "generic-id".to_string(), + key: "generic_key".to_string(), + value: "generic_value".to_string(), + parent_id: None, + })]; + + let result = client + .record_telemetry(events, "test-telemetry-id", "test-session-id") + .await; + + assert!(result.is_ok()); + + handle.abort(); + let _ = handle.await; + + Ok(()) + } } diff --git a/crates/turborepo-vercel-api-mock/src/lib.rs b/crates/turborepo-vercel-api-mock/src/lib.rs index 2cb6a87584280..367ccab88a54c 100644 --- a/crates/turborepo-vercel-api-mock/src/lib.rs +++ b/crates/turborepo-vercel-api-mock/src/lib.rs @@ -13,8 +13,8 @@ use axum::{ use futures_util::StreamExt; use tokio::{net::TcpListener, sync::Mutex}; use turborepo_vercel_api::{ - AnalyticsEvent, CachingStatus, CachingStatusResponse, Membership, Role, Team, TeamsResponse, - User, UserResponse, VerificationResponse, + telemetry::TelemetryEvent, AnalyticsEvent, CachingStatus, CachingStatusResponse, Membership, + Role, Team, TeamsResponse, User, UserResponse, VerificationResponse, }; pub const EXPECTED_TOKEN: &str = "expected_token"; @@ -41,6 +41,8 @@ pub async fn start_test_server(port: u16) -> Result<()> { let get_analytics_events_ref = Arc::new(Mutex::new(Vec::new())); let post_analytics_events_ref = get_analytics_events_ref.clone(); + let telemetry_events_ref = Arc::new(Mutex::new(Vec::new())); + let app = Router::new() .route( "/v2/user", @@ -223,6 +225,15 @@ pub async fn start_test_server(port: u16) -> Result<()> { headers }), + ) + .route( + "/api/turborepo/v1/events", + post( + |Json(telemetry_events): Json>| async move { + telemetry_events_ref.lock().await.extend(telemetry_events); + StatusCode::OK + }, + ), ); let addr = SocketAddr::from(([127, 0, 0, 1], port));