Files
ai-control/src-tauri/src/domain/testutil.rs
T
marcus hinz 9a99bca466 Modul-Split: Fachlogik nach domain/, OS-Code nach platform/, Tauri-Verdrahtung in app.rs/commands.rs
- lib.rs nur noch Prozessrollen-Dispatch + Panic-Tracer
- KWin-Script als KDE-Pendant zur GNOME-Extension (Popup ans Zeiger-
  Rechteck), wird von deb/rpm mit ausgeliefert
- SNI-Tray auf ksni (pure Rust), appindicator-Depends entfallen
2026-07-15 20:10:33 +02:00

94 lines
2.7 KiB
Rust

//! Gemeinsame Test-Helfer der Domänen-Module: Pseudo-Home, In-Memory-Store,
//! Kurzformen für Pool-/Projekt-Anlage.
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use std::sync::atomic::{AtomicU32, Ordering};
use crate::domain::credentials::ApikeyStore;
use crate::domain::paths::Paths;
use crate::domain::pool::{create_apikey_pool_in, create_oauth_pool_in};
use crate::domain::registry::register_project;
static N: AtomicU32 = AtomicU32::new(0);
/// Frisches Pseudo-Home pro Test; claude-projects existiert wie auf dem
/// echten System.
pub(crate) fn tmp_paths() -> Paths {
let dir = std::env::temp_dir().join(format!(
"ai-control-test-{}-{}",
std::process::id(),
N.fetch_add(1, Ordering::SeqCst)
));
fs::create_dir_all(dir.join("claude-projects")).unwrap();
Paths { home: dir }
}
/// In-Memory-ApikeyStore statt echtem Keychain.
pub(crate) struct MapStore(pub(crate) std::sync::Mutex<HashMap<String, String>>);
pub(crate) fn map_store() -> MapStore {
MapStore(std::sync::Mutex::new(HashMap::new()))
}
impl ApikeyStore for MapStore {
fn set(&self, pool: &str, key: &str) -> Result<(), String> {
self.0.lock().unwrap().insert(pool.into(), key.into());
Ok(())
}
fn has(&self, pool: &str) -> Result<bool, String> {
Ok(self.0.lock().unwrap().contains_key(pool))
}
fn delete(&self, pool: &str) -> Result<(), String> {
self.0.lock().unwrap().remove(pool);
Ok(())
}
}
/// Store ohne Keychain/Keyring — Schreiben scheitert, Lesen findet nichts.
pub(crate) struct FailStore;
impl ApikeyStore for FailStore {
fn set(&self, _pool: &str, _key: &str) -> Result<(), String> {
Err("kein Keychain".into())
}
fn has(&self, _pool: &str) -> Result<bool, String> {
Ok(false)
}
fn delete(&self, _pool: &str) -> Result<(), String> {
Ok(())
}
}
/// Liefert die Pool-ID (UUID-Ordnername).
pub(crate) fn make_oauth_pool(p: &Paths, name: &str) -> String {
create_oauth_pool_in(p, name).unwrap()
}
pub(crate) fn make_apikey_pool(
p: &Paths,
store: &dyn ApikeyStore,
name: &str,
key: &str,
) -> String {
create_apikey_pool_in(p, store, name, key, true).unwrap()
}
/// Minimal-Projekt: Ordner mit .claude/ + Registry-Eintrag.
pub(crate) fn create_project(paths: &Paths, name: &str) -> Result<(), String> {
crate::domain::check_name(name)?;
let dir = paths.projects_dir().join(name);
if dir.exists() {
return Err(format!("Projekt existiert bereits: {name}"));
}
fs::create_dir_all(dir.join(".claude"))
.map_err(|e| format!("{}: {e}", dir.join(".claude").display()))?;
register_project(paths, name, &dir)
}
pub(crate) fn mode(path: &PathBuf) -> u32 {
use std::os::unix::fs::PermissionsExt;
fs::metadata(path).unwrap().permissions().mode() & 0o777
}