codewhale-tui 0.9.8

Terminal UI for open-source and open-weight coding models
Documentation
use super::*;
use crate::tools::spec::ToolContext;
use std::path::PathBuf;

struct ArtifactRootRestore(Option<PathBuf>);

impl Drop for ArtifactRootRestore {
    fn drop(&mut self) {
        crate::artifacts::set_test_artifact_sessions_root(self.0.take());
    }
}

fn runtime() -> tokio::runtime::Runtime {
    tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .expect("test runtime")
}

#[test]
fn raw_pdf_production_path_preserves_exact_bytes_without_extractor() {
    let _lock = crate::artifacts::TEST_ARTIFACT_SESSIONS_GUARD
        .lock()
        .unwrap_or_else(|error| error.into_inner());
    let temporary = tempfile::tempdir().expect("artifact root");
    let prior =
        crate::artifacts::set_test_artifact_sessions_root(Some(temporary.path().join("sessions")));
    let _restore = ArtifactRootRestore(prior);
    let bytes = b"%PDF-1.7\nraw fixture that is intentionally not parseable\n%%EOF";
    let missing = temporary.path().join("definitely-not-pdftotext");
    let document = runtime()
        .block_on(extract_fetched_document(
            Format::Raw,
            "https://example.com/raw.pdf",
            "application/pdf",
            bytes,
            true,
            None,
            PdfTextCommand::test(missing.as_os_str(), Duration::from_millis(50), None),
        ))
        .expect("signed raw PDF must bypass the missing extractor");
    let (content, artifact) = render_extracted(
        "https://example.com/raw.pdf",
        "application/pdf",
        Format::Raw,
        document,
        bytes,
        &ToolContext::new("."),
    )
    .expect("raw PDF preservation must not require pdftotext");
    let artifact = artifact.expect("raw PDF artifact");
    assert!(content.contains("PDF response saved"), "{content}");
    assert_eq!(std::fs::read(artifact.absolute_path).unwrap(), bytes);
}

#[test]
fn raw_pdf_spoofs_and_contradictory_media_mime_create_no_artifact() {
    let _lock = crate::artifacts::TEST_ARTIFACT_SESSIONS_GUARD
        .lock()
        .unwrap_or_else(|error| error.into_inner());
    let temporary = tempfile::tempdir().expect("artifact root");
    let sessions = temporary.path().join("sessions");
    let prior = crate::artifacts::set_test_artifact_sessions_root(Some(sessions.clone()));
    let _restore = ArtifactRootRestore(prior);
    let missing = temporary.path().join("definitely-not-pdftotext");
    let request = PdfTextCommand::test(missing.as_os_str(), Duration::from_millis(50), None);
    let runtime = runtime();

    for (url, content_type, bytes, expected) in [
        (
            "https://example.com/download",
            "application/pdf",
            b"plain text pretending to be a PDF".as_slice(),
            "PDF signature",
        ),
        (
            "https://example.com/spoof.pdf",
            "text/plain",
            b"plain text pretending to be a PDF".as_slice(),
            "PDF signature",
        ),
        (
            "https://example.com/signed",
            "image/png",
            b"%PDF-1.7\n%%EOF".as_slice(),
            "did not match its PDF bytes",
        ),
    ] {
        let error = runtime
            .block_on(extract_fetched_document(
                Format::Raw,
                url,
                content_type,
                bytes,
                true,
                None,
                request,
            ))
            .expect_err("invalid PDF response must fail before raw preservation");
        assert!(error.to_string().contains(expected), "{error}");
    }
    assert!(
        !sessions.exists(),
        "rejected bytes must not create artifacts"
    );
}

#[tokio::test]
async fn fetched_pdf_missing_helper_is_a_failed_typed_outcome() {
    let temporary = tempfile::tempdir().expect("tempdir");
    let missing = temporary.path().join("definitely-not-pdftotext");
    let error = extract_fetched_document(
        Format::Text,
        "https://example.com/document.pdf",
        "application/pdf",
        b"%PDF-1.7\n%%EOF",
        true,
        None,
        PdfTextCommand::test(missing.as_os_str(), Duration::from_secs(1), None),
    )
    .await
    .expect_err("missing helper must fail the fetched PDF call");
    let payload = match &error {
        ToolError::NotAvailable { message } => {
            serde_json::from_str::<Value>(message).expect("structured unavailable payload")
        }
        other => panic!("unexpected error: {other:?}"),
    };
    assert_eq!(payload["type"], "binary_unavailable");
    assert_eq!(
        crate::tools::spec::ToolExecutionOutcome::from_legacy(Err(error)).status,
        crate::tools::spec::ToolTerminalStatus::Failed
    );
}