mod common;
use std::fs;
use tempfile::TempDir;
#[ test ]
fn test_show_parser_accepts_no_args()
{
let output = common::clg_cmd()
.args( [ ".show" ] )
.output()
.unwrap();
let stderr = String::from_utf8_lossy( &output.stderr );
assert!(
!stderr.contains( "required argument" ) && !stderr.contains( "session_id"),
"Parser should not require session_id parameter. stderr: {stderr}"
);
}
#[ test ]
fn test_show_with_session_id_and_project()
{
use claude_storage_core::encode_path;
let storage = TempDir::new().unwrap();
let project_path = TempDir::new().unwrap();
let encoded = encode_path( project_path.path() ).unwrap();
let project_dir = storage.path().join( "projects" ).join( &encoded );
fs::create_dir_all( &project_dir ).unwrap();
let session_id = "test-session-specific";
let file = project_dir.join( format!( "{session_id}.jsonl" ) );
fs::write( &file, r#"{"type":"user","text":"specific test entry"}
{"type":"assistant","text":"specific response"}"# ).unwrap();
let output = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", storage.path() )
.args( [
".show",
&format!( "session_id::{session_id}" ),
&format!( "project::{}", project_path.path().display() )
] )
.output()
.unwrap();
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!(
output.status.success(),
"Command should succeed. stderr: {stderr}"
);
assert!(
stdout.contains( session_id ),
"Should display session ID. stdout: {stdout}"
);
assert!(
stdout.contains( "Entries:" ) || stdout.contains( '2' ),
"Should show entry count. stdout: {stdout}"
);
}
#[ test ]
fn test_show_with_project_only()
{
use claude_storage_core::encode_path;
let storage = TempDir::new().unwrap();
let project_path = TempDir::new().unwrap();
let encoded = encode_path( project_path.path() ).unwrap();
let project_dir = storage.path().join( "projects" ).join( &encoded );
fs::create_dir_all( &project_dir ).unwrap();
let sessions = vec![ "session-a", "session-b", "session-c" ];
for session_id in &sessions
{
let file = project_dir.join( format!( "{session_id}.jsonl" ) );
fs::write( &file, r#"{"type":"user","text":"test"}"# ).unwrap();
}
let output = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", storage.path() )
.args( [ ".show", &format!( "project::{}", project_path.path().display() ) ] )
.output()
.unwrap();
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!(
output.status.success(),
"Command should succeed. stderr: {stderr}"
);
assert!(
stdout.contains( &project_path.path().to_string_lossy().to_string() )
|| stdout.contains( "Project:" ),
"Should display project info. stdout: {stdout}"
);
for session_id in &sessions
{
assert!(
stdout.contains( session_id ),
"Should list session {session_id}. stdout: {stdout}"
);
}
}
#[ test ]
fn test_show_with_both_params()
{
use claude_storage_core::encode_path;
let storage = TempDir::new().unwrap();
let project_path = TempDir::new().unwrap();
let encoded = encode_path( project_path.path() ).unwrap();
let project_dir = storage.path().join( "projects" ).join( &encoded );
fs::create_dir_all( &project_dir ).unwrap();
let session_id = "test-both-params";
let file = project_dir.join( format!( "{session_id}.jsonl" ) );
fs::write( &file, r#"{"type":"user","text":"test entry"}"# ).unwrap();
let output = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", storage.path() )
.args( [
".show",
&format!( "session_id::{session_id}" ),
&format!( "project::{}", project_path.path().display() )
] )
.output()
.unwrap();
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!(
output.status.success(),
"Command should succeed (regression test). stderr: {stderr}"
);
assert!(
stdout.contains( session_id ),
"Should display session ID. stdout: {stdout}"
);
}
#[ test ]
fn test_show_error_for_nonexistent_project()
{
let output = common::clg_cmd()
.args( [ ".show", "project::/nonexistent/test-path-show-error" ] )
.output()
.unwrap();
let stderr = String::from_utf8_lossy( &output.stderr );
assert!(
!output.status.success(),
"Should fail for non-existent project"
);
assert!(
stderr.contains( "not found" ) || stderr.contains( "Project" ) || stderr.contains( "No project" ),
"Should have clear error message. stderr: {stderr}"
);
}
#[ test ]
fn test_show_project_parser_accepts_no_args()
{
let output = common::clg_cmd()
.args( [ ".show.project" ] )
.output()
.unwrap();
let stderr = String::from_utf8_lossy( &output.stderr );
assert!(
!stderr.contains( "required argument" ),
"Parser should not require project parameter. stderr: {stderr}"
);
}
#[ test ]
fn test_show_partial_uuid_matching()
{
use claude_storage_core::encode_path;
let storage = TempDir::new().unwrap();
let project_path = TempDir::new().unwrap();
let encoded = encode_path( project_path.path() ).unwrap();
let project_dir = storage.path().join( "projects" ).join( &encoded );
fs::create_dir_all( &project_dir ).unwrap();
let full_uuid = "79f86582-1435-442c-935a-13f8d874918a";
let partial_uuid = "79f86582"; let file = project_dir.join( format!( "{full_uuid}.jsonl" ) );
fs::write( &file, r#"{"type":"user","uuid":"uuid-001","parentUuid":null,"timestamp":"2025-11-29T10:00:00Z","cwd":"/tmp/test","sessionId":"test-session","version":"2.0.0","gitBranch":"master","userType":"external","isSidechain":false,"message":{"role":"user","content":"test partial uuid matching"}}
{"type":"assistant","uuid":"uuid-002","parentUuid":"uuid-001","timestamp":"2025-11-29T10:00:01Z","cwd":"/tmp/test","sessionId":"test-session","version":"2.0.0","gitBranch":"master","userType":"external","isSidechain":false,"message":{"role":"assistant","content":[{"type":"text","text":"this should be findable with partial ID"}]}}"# ).unwrap();
let output_full = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", storage.path() )
.args( [
".show",
&format!( "session_id::{full_uuid}" ),
&format!( "project::{}", project_path.path().display() )
] )
.output()
.unwrap();
let stdout_full = String::from_utf8_lossy( &output_full.stdout );
let stderr_full = String::from_utf8_lossy( &output_full.stderr );
assert!(
output_full.status.success(),
"Full UUID should work. stderr: {stderr_full}"
);
assert!(
stdout_full.contains( full_uuid ) || stdout_full.contains( "Session:" ),
"Should show session with full UUID. stdout: {stdout_full}"
);
let output_partial = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", storage.path() )
.args( [
".show",
&format!( "session_id::{partial_uuid}" ),
&format!( "project::{}", project_path.path().display() )
] )
.output()
.unwrap();
let stdout_partial = String::from_utf8_lossy( &output_partial.stdout );
let stderr_partial = String::from_utf8_lossy( &output_partial.stderr );
assert!(
output_partial.status.success(),
"Partial UUID (first 8 chars) should work. stderr: {stderr_partial}"
);
assert!(
stdout_partial.contains( full_uuid ) || stdout_partial.contains( "Session:" ),
"Should find session using partial UUID. stdout: {stdout_partial}"
);
assert!(
stdout_partial.contains( "partial uuid matching" ),
"Should show session content. stdout: {stdout_partial}"
);
}
#[ test ]
fn test_show_session_single_entry_header_says_entry_not_entries()
{
let storage = TempDir::new().unwrap();
let project_path = TempDir::new().unwrap();
let session_id = "028a0000-1111-2222-3333-444444444444";
common::write_path_project_session(
storage.path(),
project_path.path(),
session_id,
1,
);
let output = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", storage.path() )
.args( [
".show",
&format!( "session_id::{session_id}" ),
&format!( "project::{}", project_path.path().display() ),
] )
.output()
.expect( "Failed to execute .show" );
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!(
output.status.success(),
".show with 1-entry session should succeed. stderr: {stderr}"
);
assert!(
stdout.contains( "(1 entry)" ),
"1-entry session header should say '(1 entry)' not '(1 entries)'. stdout: {stdout}"
);
assert!(
!stdout.contains( "(1 entries)" ),
"1-entry session header must NOT say '(1 entries)'. stdout: {stdout}"
);
}
#[ test ]
fn test_show_session_multi_entry_header_still_says_entries()
{
let storage = TempDir::new().unwrap();
let project_path = TempDir::new().unwrap();
let session_id = "028b0000-1111-2222-3333-444444444444";
common::write_path_project_session(
storage.path(),
project_path.path(),
session_id,
3,
);
let output = common::clg_cmd()
.env( "CLAUDE_STORAGE_ROOT", storage.path() )
.args( [
".show",
&format!( "session_id::{session_id}" ),
&format!( "project::{}", project_path.path().display() ),
] )
.output()
.expect( "Failed to execute .show" );
let stdout = String::from_utf8_lossy( &output.stdout );
let stderr = String::from_utf8_lossy( &output.stderr );
assert!(
output.status.success(),
".show with 3-entry session should succeed. stderr: {stderr}"
);
assert!(
stdout.contains( "(3 entries)" ),
"3-entry session header should say '(3 entries)'. stdout: {stdout}"
);
}