use super::track_event_request_batches; use crate::events::CodexAcceptedLineFingerprintsEventParams; use crate::events::CodexAcceptedLineFingerprintsEventRequest; use crate::events::SkillInvocationEventParams; use crate::events::SkillInvocationEventRequest; use crate::events::TrackEventRequest; use crate::events::TrackEventsRequest; use crate::facts::InvocationType; use serde_json::json; #[test] fn track_event_request_batches_only_isolates_accepted_line_fingerprint_events() { let events = [ sample_regular_track_event("thread-1"), sample_regular_track_event("thread-2"), sample_accepted_line_fingerprint_event("thread-3"), sample_accepted_line_fingerprint_event("thread-4"), sample_regular_track_event("thread-5"), sample_regular_track_event("thread-6"), ]; let events = events.iter().collect::>(); let batches = track_event_request_batches(&events); assert_eq!(batches.len(), 4); assert_eq!(batches[0].len(), 2); assert_eq!(batches[1].len(), 1); assert_eq!(batches[2].len(), 1); assert_eq!(batches[3].len(), 2); assert!(batches[1][0].should_send_in_isolated_request()); assert!(batches[2][0].should_send_in_isolated_request()); } #[test] fn track_events_request_serializes_borrowed_events() { let event = sample_regular_track_event("thread-1"); let events = [&event]; let payload = serde_json::to_value(TrackEventsRequest { events: &events }) .expect("serialize track events request"); assert_eq!( payload, json!({ "events": [serde_json::to_value(&event).expect("serialize track event")] }) ); } fn sample_accepted_line_fingerprint_event(thread_id: &str) -> TrackEventRequest { TrackEventRequest::AcceptedLineFingerprints(Box::new( CodexAcceptedLineFingerprintsEventRequest { event_type: "codex_accepted_line_fingerprints", event_params: CodexAcceptedLineFingerprintsEventParams { event_type: "codex.accepted_line_fingerprints", turn_id: "turn-1".to_string(), thread_id: thread_id.to_string(), product_surface: Some("codex".to_string()), model_slug: Some("gpt-5.1-codex".to_string()), completed_at: 1, repo_hash: None, accepted_added_lines: 1, accepted_deleted_lines: 0, line_fingerprints: Vec::new(), }, }, )) } fn sample_regular_track_event(thread_id: &str) -> TrackEventRequest { TrackEventRequest::SkillInvocation(SkillInvocationEventRequest { event_type: "skill_invocation", skill_id: format!("skill-{thread_id}"), skill_name: "doc".to_string(), event_params: SkillInvocationEventParams { product_client_id: None, skill_scope: None, plugin_id: None, repo_url: None, thread_id: Some(thread_id.to_string()), turn_id: Some("turn-1".to_string()), invoke_type: Some(InvocationType::Explicit), model_slug: Some("gpt-5.1-codex".to_string()), }, }) }