use super::*;
#[test]
fn genuine_user_string_content() {
let r = parse(r#"{"type":"user","message":{"role":"user","content":"hello"}}"#);
assert!(r.is_genuine_user());
}
#[test]
fn tool_result_carrier_is_not_genuine_user() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"x","content":"ok"}]}}"#,
);
assert!(!r.is_genuine_user());
}
#[test]
fn compaction_summary_is_not_genuine_user() {
let r = parse(
r#"{"type":"user","isCompactSummary":true,"message":{"role":"user","content":"summary..."}}"#,
);
assert!(!r.is_genuine_user());
}
#[test]
fn is_meta_user_is_not_genuine_user() {
let r = parse(
r#"{"type":"user","isMeta":true,"message":{"role":"user","content":"Continue from where you left off."}}"#,
);
assert!(!r.is_genuine_user());
assert!(r.genuine_user_text().is_none());
}
#[test]
fn is_meta_local_command_caveat_excluded() {
let r = parse(
r#"{"type":"user","isMeta":true,"message":{"role":"user","content":"<local-command-caveat>Caveat: ...</local-command-caveat>"}}"#,
);
assert!(!r.is_genuine_user());
}
#[test]
fn is_genuine_user_false_for_non_user_type() {
let r = parse(
r#"{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"hi"}]}}"#,
);
assert!(!r.is_genuine_user());
}
#[test]
fn is_genuine_user_false_when_message_absent() {
let r = parse(r#"{"type":"user","uuid":"x"}"#);
assert!(!r.is_genuine_user());
}
#[test]
fn is_genuine_user_false_when_role_not_user() {
let r = parse(r#"{"type":"user","message":{"role":"assistant","content":"hi"}}"#);
assert!(!r.is_genuine_user());
}
#[test]
fn is_genuine_user_false_when_content_absent() {
let r = parse(r#"{"type":"user","message":{"role":"user"}}"#);
assert!(!r.is_genuine_user());
assert!(r.genuine_user_text().is_none());
}
#[test]
fn is_genuine_user_false_for_blocks_without_text() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":[{"type":"image","source":{}}]}}"#,
);
assert!(!r.is_genuine_user());
}
#[test]
fn interrupt_marker_plain_is_not_genuine_user() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":[{"type":"text","text":"[Request interrupted by user]"}]}}"#,
);
assert!(
!r.is_genuine_user(),
"interrupt marker must not open a turn"
);
assert!(!r.opens_turn());
}
#[test]
fn interrupt_marker_for_tool_use_is_not_genuine_user() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":[{"type":"text","text":"[Request interrupted by user for tool use]"}]}}"#,
);
assert!(!r.is_genuine_user());
assert!(!r.opens_turn());
}
#[test]
fn interrupt_marker_as_string_content_is_not_genuine_user() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":"[Request interrupted by user]"}}"#,
);
assert!(!r.is_genuine_user());
}
#[test]
fn text_that_merely_contains_interrupt_phrase_is_still_genuine() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":"why did i see [Request interrupted by user] earlier?"}}"#,
);
assert!(
r.is_genuine_user(),
"a message merely containing the phrase is still a human turn"
);
}
#[test]
fn local_command_stdout_is_not_genuine_user() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":"<local-command-stdout>✓ Updated oh-my-claudecode.</local-command-stdout>"}}"#,
);
assert!(!r.is_genuine_user());
assert!(!r.opens_turn());
}
#[test]
fn command_name_wrapper_is_not_genuine_user() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":"<command-name>/compact</command-name>\n<command-message>compact</command-message>\n<command-args></command-args>"}}"#,
);
assert!(
!r.is_genuine_user(),
"slash-command wrapper must not open a turn"
);
assert!(!r.opens_turn());
assert!(r.slash_command_args().is_none());
}
#[test]
fn command_name_wrapper_with_args_recovers_prose() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":"<command-name>/compact</command-name>\n<command-message>compact</command-message>\n<command-args> Just shipped spec-batch-14, summarize</command-args>"}}"#,
);
assert!(!r.is_genuine_user());
assert_eq!(
r.slash_command_args().as_deref(),
Some("Just shipped spec-batch-14, summarize")
);
assert_eq!(
r.reconstructed_user_text(None).as_deref(),
Some("/compact Just shipped spec-batch-14, summarize")
);
}
#[test]
fn command_message_first_wrapper_detected_and_recovered() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":"<command-message>csift</command-message>\n<command-name>/csift</command-name>\n<command-args>what changed in v5?</command-args>"}}"#,
);
assert!(!r.is_genuine_user(), "wrapper is never the human");
assert_eq!(r.slash_command_name().as_deref(), Some("/csift"));
assert_eq!(
r.slash_command_args().as_deref(),
Some("what changed in v5?")
);
assert_eq!(
r.reconstructed_user_text(None).as_deref(),
Some("/csift what changed in v5?")
);
assert_eq!(
r.classify(&ClassifyCtx::top_level()),
vec![Class::UserMessage, Class::CommandInvocation]
);
let bare = parse(
r#"{"type":"user","message":{"role":"user","content":"<command-message>compact</command-message>\n<command-name>/compact</command-name>\n<command-args></command-args>"}}"#,
);
assert!(!bare.is_genuine_user());
assert_eq!(
bare.classify(&ClassifyCtx::top_level()),
vec![Class::CommandInvocation]
);
}
#[test]
fn command_name_wrapper_with_multibyte_args_is_codepoint_safe() {
let r = parse(
r#"{"type":"user","message":{"role":"user","content":"<command-name>/compact</command-name>\n<command-args>🤖 just shipped the batch, summarize 🎉</command-args>"}}"#,
);
assert_eq!(
r.slash_command_args().as_deref(),
Some("🤖 just shipped the batch, summarize 🎉")
);
}
#[test]
fn opens_turn_matches_genuine_user() {
let genuine = parse(r#"{"type":"user","message":{"role":"user","content":"hi"}}"#);
assert!(genuine.opens_turn());
let carrier = parse(
r#"{"type":"user","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"x","content":"ok"}]}}"#,
);
assert!(!carrier.opens_turn());
}
#[test]
fn is_synthetic_user_marker_matches_each_form() {
assert!(is_synthetic_user_marker("[Request interrupted by user]"));
assert!(is_synthetic_user_marker(
"[Request interrupted by user for tool use]"
));
assert!(is_synthetic_user_marker("<local-command-stdout>anything"));
assert!(is_synthetic_user_marker("<command-name>/x</command-name>"));
assert!(!is_synthetic_user_marker("a normal human message"));
assert!(!is_synthetic_user_marker(
"[Request interrupted by user] and then I said more"
));
}