use codetether_agent::okr::{KrOutcome, KrOutcomeType, OkrRun, OkrRunStatus};
use uuid::Uuid;
fn parse_uuid_guarded(s: &str, _context: &str) -> Option<Uuid> {
s.parse::<Uuid>().ok()
}
mod status_mapping {
use super::*;
#[test]
fn okr_run_status_includes_failed_variant() {
let failed = OkrRunStatus::Failed;
let completed = OkrRunStatus::Completed;
assert_ne!(failed, completed);
assert_eq!(failed, OkrRunStatus::Failed);
}
#[test]
fn failed_is_not_completed() {
let statuses = [
OkrRunStatus::Draft,
OkrRunStatus::PendingApproval,
OkrRunStatus::Approved,
OkrRunStatus::Denied,
OkrRunStatus::Running,
OkrRunStatus::Paused,
OkrRunStatus::WaitingApproval,
OkrRunStatus::Completed,
OkrRunStatus::Failed,
];
for (i, s1) in statuses.iter().enumerate() {
for (j, s2) in statuses.iter().enumerate() {
if i != j {
assert_ne!(s1, s2, "Statuses at {i} and {j} should be distinct");
}
}
}
}
#[test]
fn complete_sets_completed_not_failed() {
let okr_id = Uuid::new_v4();
let mut run = OkrRun::new(okr_id, "Test Run");
run.status = OkrRunStatus::Running;
run.complete();
assert_eq!(run.status, OkrRunStatus::Completed);
assert!(run.completed_at.is_some());
}
#[test]
fn failed_status_can_be_set_explicitly() {
let okr_id = Uuid::new_v4();
let mut run = OkrRun::new(okr_id, "Test Run");
run.status = OkrRunStatus::Running;
run.status = OkrRunStatus::Failed;
assert_eq!(run.status, OkrRunStatus::Failed);
assert!(run.completed_at.is_none());
}
}
mod checkpoint_correlation {
use super::*;
#[test]
fn okr_run_has_relay_checkpoint_id_field() {
let okr_id = Uuid::new_v4();
let run = OkrRun::new(okr_id, "Test Run");
assert!(run.relay_checkpoint_id.is_none());
}
#[test]
fn relay_checkpoint_id_can_be_set() {
let okr_id = Uuid::new_v4();
let mut run = OkrRun::new(okr_id, "Test Run");
let checkpoint = "checkpoint-123";
run.relay_checkpoint_id = Some(checkpoint.to_string());
assert_eq!(run.relay_checkpoint_id, Some(checkpoint.to_string()));
}
#[test]
fn relay_checkpoint_id_can_be_cleared() {
let okr_id = Uuid::new_v4();
let mut run = OkrRun::new(okr_id, "Test Run");
run.relay_checkpoint_id = Some("checkpoint-123".to_string());
run.relay_checkpoint_id = None;
assert!(run.relay_checkpoint_id.is_none());
}
#[test]
fn checkpoint_query_filters_correctly() {
let okr_id = Uuid::new_v4();
let mut run1 = OkrRun::new(okr_id, "Run 1");
let mut run2 = OkrRun::new(okr_id, "Run 2");
let run3 = OkrRun::new(okr_id, "Run 3");
run1.relay_checkpoint_id = Some("checkpoint-A".to_string());
run2.relay_checkpoint_id = Some("checkpoint-B".to_string());
let runs = vec![run1, run2, run3];
let filtered: Vec<_> = runs
.into_iter()
.filter(|r| r.relay_checkpoint_id.as_deref() == Some("checkpoint-A"))
.collect();
assert_eq!(filtered.len(), 1);
}
}
mod uuid_guard {
use super::*;
#[test]
fn valid_uuid_parses_successfully() {
let valid_uuid = "550e8400-e29b-41d4-a716-446655440000";
let result = parse_uuid_guarded(valid_uuid, "test_context");
assert!(result.is_some());
let uuid = result.unwrap();
assert_eq!(uuid.to_string(), valid_uuid);
}
#[test]
fn invalid_uuid_returns_none_not_nil() {
let invalid_uuid = "not-a-uuid";
let result = parse_uuid_guarded(invalid_uuid, "test_context");
assert!(result.is_none());
}
#[test]
fn empty_string_returns_none() {
let result = parse_uuid_guarded("", "test_context");
assert!(result.is_none());
}
#[test]
fn partial_uuid_returns_none() {
let partial = "550e8400-e29b-41d4"; let result = parse_uuid_guarded(partial, "test_context");
assert!(result.is_none());
}
#[test]
fn nil_uuid_parses_but_callers_must_validate() {
let nil_uuid = "00000000-0000-0000-0000-000000000000";
let result = parse_uuid_guarded(nil_uuid, "test_context");
assert!(result.is_some());
assert!(result.unwrap().is_nil());
}
#[test]
fn malformed_uuid_returns_none() {
let malformed = "550e8400e29b41d4a716446655440000"; let result = parse_uuid_guarded(malformed, "test_context");
let _ = result; }
}
mod kr_outcome_linkage {
use super::*;
#[test]
fn kr_outcome_has_kr_id_field() {
let kr_id = Uuid::new_v4();
let outcome = KrOutcome::new(kr_id, "Test outcome");
assert_eq!(outcome.kr_id, kr_id);
}
#[test]
fn kr_outcome_links_to_actual_kr_uuid() {
let kr_id_1 = Uuid::new_v4();
let kr_id_2 = Uuid::new_v4();
let outcome1 = KrOutcome::new(kr_id_1, "Outcome for KR 1");
let outcome2 = KrOutcome::new(kr_id_2, "Outcome for KR 2");
assert_eq!(outcome1.kr_id, kr_id_1);
assert_eq!(outcome2.kr_id, kr_id_2);
assert_ne!(outcome1.kr_id, outcome2.kr_id);
}
#[test]
fn kr_outcome_kr_id_is_not_run_id() {
let okr_id = Uuid::new_v4();
let run = OkrRun::new(okr_id, "Test Run");
let kr_id = Uuid::new_v4();
let outcome = KrOutcome::new(kr_id, "Test outcome");
assert_eq!(outcome.kr_id, kr_id);
assert_ne!(outcome.kr_id, run.id);
}
#[test]
fn guarded_parse_prevents_nil_uuid_linkage() {
let invalid_kr_id_str = "invalid-kr-id";
let result = parse_uuid_guarded(invalid_kr_id_str, "outcome_kr_link");
assert!(result.is_none());
if let Some(kr_uuid) = result {
let _outcome = KrOutcome::new(kr_uuid, "Should not be created");
panic!("Should not reach here with invalid UUID");
}
}
#[test]
fn kr_outcome_builder_pattern() {
let kr_id = Uuid::new_v4();
let outcome = KrOutcome::new(kr_id, "Delivered feature X")
.with_value(1.0)
.add_evidence("commit:abc123");
assert_eq!(outcome.kr_id, kr_id);
assert_eq!(outcome.value, Some(1.0));
assert_eq!(outcome.evidence.len(), 1);
assert_eq!(outcome.outcome_type, KrOutcomeType::Evidence);
}
#[test]
fn outcomes_can_be_added_to_run() {
let okr_id = Uuid::new_v4();
let mut run = OkrRun::new(okr_id, "Test Run");
let kr_id = Uuid::new_v4();
let outcome = KrOutcome::new(kr_id, "Test outcome");
run.outcomes.push(outcome);
assert_eq!(run.outcomes.len(), 1);
assert_eq!(run.outcomes[0].kr_id, kr_id);
}
}
mod integration {
use super::*;
#[test]
fn full_outcome_workflow_with_guards() {
let okr_id = Uuid::new_v4();
let mut run = OkrRun::new(okr_id, "Integration Test Run");
run.status = OkrRunStatus::Running;
let kr_progress = vec![
("550e8400-e29b-41d4-a716-446655440000".to_string(), 0.8),
("invalid-kr-id".to_string(), 0.5), ];
for (kr_id_str, value) in &kr_progress {
if let Some(kr_uuid) = parse_uuid_guarded(kr_id_str, "outcome_link") {
let outcome = KrOutcome::new(kr_uuid, "Test outcome").with_value(*value);
run.outcomes.push(outcome);
}
}
assert_eq!(run.outcomes.len(), 1);
assert_eq!(run.outcomes[0].value, Some(0.8));
run.status = OkrRunStatus::Failed;
assert_eq!(run.status, OkrRunStatus::Failed);
}
#[test]
fn checkpoint_lifecycle() {
let okr_id = Uuid::new_v4();
let mut run = OkrRun::new(okr_id, "Checkpoint Lifecycle Test");
assert!(run.relay_checkpoint_id.is_none());
run.relay_checkpoint_id = Some("relay-checkpoint-001".to_string());
assert_eq!(
run.relay_checkpoint_id,
Some("relay-checkpoint-001".to_string())
);
run.relay_checkpoint_id = Some("relay-checkpoint-002".to_string());
assert_eq!(
run.relay_checkpoint_id,
Some("relay-checkpoint-002".to_string())
);
run.status = OkrRunStatus::Running;
run.complete();
run.relay_checkpoint_id = None;
assert_eq!(run.status, OkrRunStatus::Completed);
assert!(run.relay_checkpoint_id.is_none());
}
}