Levée de la réserve QA sur #108 : aucun test ciblé ne matchait réellement sur web-server et app-tauri malgré le câblage attachments tickets. - web-server: test fonctionnel via /api/invoke pour ticket_create, ticket_attachment_add, ticket_attachment_read, ticket_attachment_mark_summarized. - app-tauri: test fonctionnel via la surface publique tool/provider pour idea_ticket_create, idea_ticket_attachment_add, idea_ticket_attachment_read, idea_ticket_attachment_mark_summarized. Pas de changement de wiring produit ; assertions alignées sur le contrat public réel (contentBase64 sans padding =, summarizedBy.kind = user côté app-tauri). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
107 lines
3.6 KiB
Rust
107 lines
3.6 KiB
Rust
use std::path::PathBuf;
|
|
|
|
use app_tauri_lib::state::AppState;
|
|
use application::CreateProjectInput;
|
|
use base64::Engine as _;
|
|
use infrastructure::TicketToolProvider;
|
|
use serde_json::json;
|
|
use uuid::Uuid;
|
|
|
|
fn temp_path(tag: &str) -> PathBuf {
|
|
std::env::temp_dir().join(format!("idea-app-tauri-test-{tag}-{}", Uuid::new_v4()))
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn idea_ticket_attachment_tools_add_read_and_mark_summarized() {
|
|
let state = AppState::build(temp_path("appdata"));
|
|
let project_root = temp_path("project");
|
|
let project = state
|
|
.create_project
|
|
.execute(CreateProjectInput {
|
|
name: "App Tauri Attachments".to_owned(),
|
|
root: project_root.to_string_lossy().into_owned(),
|
|
remote: None,
|
|
default_profile_id: None,
|
|
})
|
|
.await
|
|
.expect("test project is created")
|
|
.project;
|
|
|
|
let created = state
|
|
.ticket_tool_binder
|
|
.handle_ticket_tool(
|
|
&project,
|
|
"qa-agent",
|
|
"idea_ticket_create",
|
|
json!({ "title": "Attachment over tool provider" }),
|
|
)
|
|
.await
|
|
.expect("ticket create succeeds");
|
|
let ticket_ref = created["ref"].as_str().expect("ticket ref").to_owned();
|
|
let ticket_version = created["version"].as_u64().expect("ticket version");
|
|
|
|
let source = project_root.join("tool-attachment.txt");
|
|
std::fs::write(&source, b"app tauri attachment payload")
|
|
.expect("test writes source attachment");
|
|
|
|
let attached = state
|
|
.ticket_tool_binder
|
|
.handle_ticket_tool(
|
|
&project,
|
|
"qa-agent",
|
|
"idea_ticket_attachment_add",
|
|
json!({
|
|
"ref": ticket_ref,
|
|
"path": source.to_string_lossy(),
|
|
"mime": "text/plain",
|
|
"expectedVersion": ticket_version
|
|
}),
|
|
)
|
|
.await
|
|
.expect("attachment add succeeds");
|
|
let attachment = &attached["attachments"].as_array().expect("attachments")[0];
|
|
assert_eq!(attachment["filename"], "tool-attachment.txt");
|
|
assert_eq!(attachment["mime"], "text/plain");
|
|
assert_eq!(attachment["summarizedInCarnet"], false);
|
|
let attachment_id = attachment["id"].as_str().expect("attachment id").to_owned();
|
|
let updated_version = attached["version"].as_u64().expect("updated version");
|
|
|
|
let content = state
|
|
.ticket_tool_binder
|
|
.handle_ticket_tool(
|
|
&project,
|
|
"qa-agent",
|
|
"idea_ticket_attachment_read",
|
|
json!({
|
|
"ref": ticket_ref,
|
|
"attachmentId": attachment_id
|
|
}),
|
|
)
|
|
.await
|
|
.expect("attachment read succeeds");
|
|
assert_eq!(content["attachment"]["filename"], "tool-attachment.txt");
|
|
assert_eq!(
|
|
content["contentBase64"],
|
|
base64::engine::general_purpose::STANDARD_NO_PAD.encode(b"app tauri attachment payload")
|
|
);
|
|
|
|
let summarized = state
|
|
.ticket_tool_binder
|
|
.handle_ticket_tool(
|
|
&project,
|
|
"qa-agent",
|
|
"idea_ticket_attachment_mark_summarized",
|
|
json!({
|
|
"ref": ticket_ref,
|
|
"attachmentId": content["attachment"]["id"],
|
|
"expectedVersion": updated_version
|
|
}),
|
|
)
|
|
.await
|
|
.expect("mark summarized succeeds");
|
|
let summarized_attachment = &summarized["attachments"].as_array().expect("attachments")[0];
|
|
assert_eq!(summarized_attachment["summarizedInCarnet"], true);
|
|
assert_eq!(summarized_attachment["summarizedBy"]["kind"], "user");
|
|
assert!(summarized_attachment["summarizedAt"].as_u64().is_some());
|
|
}
|