test(infra): intégration handlers Tauri managed_temp_* + routage idea_managed_temp_* — #191

This commit is contained in:
2026-08-13 14:23:03 +02:00
parent 1b7ff56419
commit cc5a324bf8
2 changed files with 286 additions and 2 deletions

View File

@ -565,19 +565,20 @@ mod tests {
#[derive(Default)]
struct FakeManagedTempTools {
calls: Mutex<Vec<(String, String, Value)>>,
calls: Mutex<Vec<(String, String, String, Value)>>,
}
#[async_trait]
impl ManagedTempToolProvider for FakeManagedTempTools {
async fn handle_managed_temp_tool(
&self,
_project: &Project,
project: &Project,
requester: &str,
name: &str,
arguments: Value,
) -> Result<Value, ManagedTempToolError> {
self.calls.lock().unwrap().push((
project.root.as_str().to_owned(),
requester.to_owned(),
name.to_owned(),
arguments.clone(),
@ -953,4 +954,176 @@ mod tests {
let _ = std::fs::remove_dir_all(temp);
}
#[tokio::test]
async fn openai_managed_temp_read_tool_routes_to_provider_with_project_and_requester() {
let temp = std::env::temp_dir().join(format!(
"idea-app-tauri-openai-managed-temp-read-{}",
Uuid::new_v4()
));
let core = backend::BackendCore::build(temp.clone());
let requester = AgentId::from_uuid(Uuid::from_u128(85)).to_string();
let managed_temp_tools = fake_managed_temp_tools();
let invoker = AppOpenAiToolInvoker::new(
Arc::clone(&core.orchestrator_service),
Arc::new(FakeProjects::with(project())) as Arc<dyn ProjectStore>,
Arc::new(FakePolicies::default()),
mcp_permissions(ProjectMcpToolPermissions::default()),
Arc::new(FakeTicketTools::default()),
Arc::new(FakeTemplateTools::default()),
managed_temp_tools.clone(),
);
let result = invoker
.call(
"idea_managed_temp_resolve",
&json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester,
"handle": "lease_123",
})
.to_string(),
)
.await
.expect("managed temp resolve must route to the dedicated provider");
let result: Value = serde_json::from_str(&result).unwrap();
assert_eq!(result["requester"], json!(requester));
assert_eq!(result["handle"], "lease_123");
let calls = managed_temp_tools.calls.lock().unwrap();
assert_eq!(calls.len(), 1);
assert_eq!(calls[0].0, "/tmp/project");
assert_eq!(calls[0].1, requester);
assert_eq!(calls[0].2, "idea_managed_temp_resolve");
assert_eq!(
calls[0].3,
json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester,
"handle": "lease_123"
})
);
let _ = std::fs::remove_dir_all(temp);
}
#[tokio::test]
async fn openai_managed_temp_write_tools_route_only_when_explicitly_allowed() {
let temp = std::env::temp_dir().join(format!(
"idea-app-tauri-openai-managed-temp-write-{}",
Uuid::new_v4()
));
let core = backend::BackendCore::build(temp.clone());
let agent = AgentId::from_uuid(Uuid::from_u128(86));
let requester = agent.to_string();
let managed_temp_tools = fake_managed_temp_tools();
let invoker = AppOpenAiToolInvoker::new(
Arc::clone(&core.orchestrator_service),
Arc::new(FakeProjects::with(project())) as Arc<dyn ProjectStore>,
Arc::new(FakePolicies::default()),
mcp_permissions(allow_doc(
agent,
&[
"idea_managed_temp_allocate",
"idea_managed_temp_release",
"idea_managed_temp_gc",
],
)),
Arc::new(FakeTicketTools::default()),
Arc::new(FakeTemplateTools::default()),
managed_temp_tools.clone(),
);
let allocate = invoker
.call(
"idea_managed_temp_allocate",
&json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester,
"kind": "directory",
"purpose": "scratch",
})
.to_string(),
)
.await
.expect("explicit allowlist should route allocate");
let allocate: Value = serde_json::from_str(&allocate).unwrap();
assert_eq!(allocate["requester"], json!(requester));
invoker
.call(
"idea_managed_temp_release",
&json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester,
"handle": "lease_123",
})
.to_string(),
)
.await
.expect("explicit allowlist should route release");
invoker
.call(
"idea_managed_temp_gc",
&json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester,
})
.to_string(),
)
.await
.expect("explicit allowlist should route gc");
let calls = managed_temp_tools.calls.lock().unwrap();
assert_eq!(calls.len(), 3);
assert_eq!(calls[0].0, "/tmp/project");
assert_eq!(calls[0].1, requester);
assert_eq!(calls[0].2, "idea_managed_temp_allocate");
assert_eq!(
calls[0].3,
json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester,
"kind": "directory",
"purpose": "scratch"
})
);
assert_eq!(calls[1].2, "idea_managed_temp_release");
assert_eq!(
calls[1].3,
json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester,
"handle": "lease_123"
})
);
assert_eq!(calls[2].2, "idea_managed_temp_gc");
assert_eq!(
calls[2].3,
json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester
})
);
let denied = invoker
.call(
"idea_managed_temp_resolve",
&json!({
PROJECT_ROOT_ARG: "/tmp/project",
REQUESTER_ARG: requester,
"handle": "lease_123",
})
.to_string(),
)
.await
.expect_err("non-allowlisted managed temp tool must be rejected");
assert!(
matches!(denied, ToolInvocationError::Rejected(ref message) if message.contains("idea_managed_temp_resolve")),
"expected readable rejection, got {denied:?}"
);
let _ = std::fs::remove_dir_all(temp);
}
}