use std::path::PathBuf;
use chrono::Utc;
use super::{record_to_json, record_to_summary};
use crate::session_manager::{ManagedSessionId, ManagedSessionState, SessionRecord};
fn make_record(source_id: Option<&str>) -> SessionRecord {
SessionRecord {
id: ManagedSessionId::new(),
tmux_name: "tmpm-test-session".into(),
cwd: PathBuf::from("/tmp/test"),
task: "test task".into(),
state: ManagedSessionState::Active,
created_at: Utc::now(),
last_activity_at: None,
workspace_path: None,
repo_url: None,
branch: None,
pending_decision: None,
proposed_default: None,
correlation: Default::default(),
runtime: Default::default(),
ephemeral: false,
workspace_owned: false,
source_id: source_id.map(String::from),
claude_session_id: None,
scrollback_path: None,
last_cwd: None,
}
}
#[test]
fn serializers_include_source_id() {
let r = make_record(Some("owner/repo"));
let json = record_to_json(&r);
assert_eq!(
json["source_id"].as_str(),
Some("owner/repo"),
"record_to_json must serialize source_id when present"
);
let summary = record_to_summary(&r);
assert_eq!(
summary.source_id.as_deref(),
Some("owner/repo"),
"record_to_summary must include source_id when present"
);
let r_none = make_record(None);
let json_none = record_to_json(&r_none);
assert!(
json_none["source_id"].is_null(),
"record_to_json must serialize source_id as null when absent, got {:?}",
json_none["source_id"]
);
let summary_none = record_to_summary(&r_none);
assert_eq!(
summary_none.source_id, None,
"record_to_summary must carry None source_id when absent"
);
}
#[test]
fn decommission_workspace_removed_reflects_ownership() {
use super::{DecommissionResponse, SessionSummary};
let owned_summary = SessionSummary {
id: "abc-123".into(),
name: "tmpm-test".into(),
state: "decommissioned".into(),
workspace_path: None, repo_url: None,
branch: None,
created_at: "2025-06-28T00:00:00Z".into(),
last_activity_at: None,
pending_decision: None,
proposed_default: None,
source_id: None,
task: None,
cwd: None,
claude_session_id: None,
};
let resp_owned = DecommissionResponse {
summary: owned_summary,
workspace_removed: true,
workspace_path_was: Some("/workspaces/trusty-mpm/session-abc".into()),
};
let json = serde_json::to_value(&resp_owned).unwrap();
assert_eq!(json["workspace_removed"], true, "owned: must be true");
assert_eq!(
json["workspace_path_was"].as_str(),
Some("/workspaces/trusty-mpm/session-abc"),
"owned: workspace_path_was must be present"
);
let unowned_summary = SessionSummary {
id: "xyz-456".into(),
name: "tmpm-adopted".into(),
state: "decommissioned".into(),
workspace_path: None,
repo_url: None,
branch: None,
created_at: "2025-06-28T00:00:00Z".into(),
last_activity_at: None,
pending_decision: None,
proposed_default: None,
source_id: None,
task: None,
cwd: None,
claude_session_id: None,
};
let resp_unowned = DecommissionResponse {
summary: unowned_summary,
workspace_removed: false,
workspace_path_was: None,
};
let json2 = serde_json::to_value(&resp_unowned).unwrap();
assert_eq!(json2["workspace_removed"], false, "unowned: must be false");
assert!(
json2.get("workspace_path_was").is_none(),
"unowned: workspace_path_was must be absent (skip_serializing_if = None)"
);
}