use oxidized_state::{
DbRunEventRecord as RunEventRecord, DbRunRecord as RunRecord, ReleaseRecordSchema,
};
use serde_json::json;
#[test]
fn test_run_record_serialization() {
let run = RunRecord::new(
"run-123".to_string(),
"spec-abc".to_string(),
Some("git-sha".to_string()),
"agent-1".to_string(),
json!({"env": "test"}),
);
let json = serde_json::to_string(&run).expect("Failed to serialize");
assert!(json.contains("run-123"));
assert!(json.contains("RUNNING"));
assert!(json.contains("\"success\":false"));
}
#[test]
fn test_run_event_record_serialization() {
let event = RunEventRecord::new(
"run-123".to_string(),
1,
"node_entered".to_string(),
json!({"node_id": "n1"}),
);
let json = serde_json::to_string(&event).expect("Failed to serialize");
assert!(json.contains("run-123"));
assert!(json.contains("\"seq\":1"));
assert!(json.contains("node_entered"));
}
#[test]
fn test_release_record_serialization() {
let release = ReleaseRecordSchema::new(
"my-agent".to_string(),
"spec-digest".to_string(),
Some("v1.0.0".to_string()),
"alice".to_string(),
Some("Initial release".to_string()),
);
let json = serde_json::to_string(&release).expect("Failed to serialize");
assert!(json.contains("my-agent"));
assert!(json.contains("v1.0.0"));
assert!(json.contains("alice"));
}
#[test]
fn test_run_record_state_transitions() {
let mut run = RunRecord::new(
"run-123".to_string(),
"spec-abc".to_string(),
None,
"agent-1".to_string(),
json!({}),
);
assert_eq!(run.status, "RUNNING");
assert_eq!(run.total_events, 0);
assert!(!run.success);
assert!(run.completed_at.is_none());
run = run.complete(10, Some("final-digest".to_string()), 5000);
assert_eq!(run.status, "COMPLETED");
assert_eq!(run.total_events, 10);
assert!(run.success);
assert!(run.completed_at.is_some());
assert_eq!(run.final_state_digest, Some("final-digest".to_string()));
assert_eq!(run.duration_ms, 5000);
}
#[test]
fn test_run_record_fail_transition() {
let mut run = RunRecord::new(
"run-456".to_string(),
"spec-xyz".to_string(),
None,
"agent-2".to_string(),
json!({}),
);
assert_eq!(run.status, "RUNNING");
run = run.fail(3, 1500);
assert_eq!(run.status, "FAILED");
assert_eq!(run.total_events, 3);
assert!(!run.success);
assert!(run.completed_at.is_some());
assert_eq!(run.duration_ms, 1500);
}
#[test]
fn test_unique_constraint_run_id_concept() {
let run1 = RunRecord::new(
"run-123".to_string(),
"spec-a".to_string(),
None,
"agent".to_string(),
json!({}),
);
let run2 = RunRecord::new(
"run-456".to_string(),
"spec-a".to_string(),
None,
"agent".to_string(),
json!({}),
);
assert_eq!(run1.spec_digest, run2.spec_digest);
assert_ne!(run1.run_id, run2.run_id);
}
#[test]
fn test_monotonic_seq_constraint_concept() {
let event1 = RunEventRecord::new("run-123".to_string(), 1, "Started".to_string(), json!({}));
let event2 = RunEventRecord::new(
"run-123".to_string(),
2,
"Processing".to_string(),
json!({}),
);
let event3 = RunEventRecord::new("run-123".to_string(), 3, "Completed".to_string(), json!({}));
assert_eq!(event1.seq, 1);
assert_eq!(event2.seq, 2);
assert_eq!(event3.seq, 3);
assert!(event1.seq < event2.seq && event2.seq < event3.seq);
}
#[test]
fn test_index_keys_present_in_records() {
let run = RunRecord::new(
"run-123".to_string(),
"spec-abc".to_string(),
Some("abc123".to_string()),
"agent-1".to_string(),
json!({"env": "test"}),
);
assert!(!run.run_id.is_empty());
assert!(!run.spec_digest.is_empty());
assert!(run.git_sha.is_some());
assert!(!run.agent_name.is_empty());
assert!(!run.spec_digest.is_empty());
assert!(!run.run_id.is_empty());
assert!(!run.status.is_empty());
}