test(infra): intégration handlers Tauri managed_temp_* + routage idea_managed_temp_* — #191
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user