Skip to main content

steer_core/
test_utils.rs

1//! Test utilities for steer-core
2//!
3//! This module provides helpers for testing that need to be accessible
4//! across crate boundaries.
5
6use crate::app::AppConfig;
7use crate::auth::{AuthStorage, CredentialType};
8use crate::config::LlmConfigProvider;
9use crate::config::model::ModelId;
10use crate::session::state::{
11    SessionConfig, SessionPolicyOverrides, SessionToolConfig, WorkspaceConfig,
12};
13use std::collections::HashMap;
14use std::sync::Arc;
15
16/// In-memory storage for testing - doesn't use keyring or filesystem
17pub struct InMemoryAuthStorage {
18    credentials:
19        Arc<tokio::sync::Mutex<std::collections::HashMap<String, crate::auth::Credential>>>,
20}
21
22impl Default for InMemoryAuthStorage {
23    fn default() -> Self {
24        Self::new()
25    }
26}
27
28impl InMemoryAuthStorage {
29    pub fn new() -> Self {
30        Self {
31            credentials: Arc::new(tokio::sync::Mutex::new(std::collections::HashMap::new())),
32        }
33    }
34}
35
36#[async_trait::async_trait]
37impl AuthStorage for InMemoryAuthStorage {
38    async fn get_credential(
39        &self,
40        provider: &str,
41        credential_type: CredentialType,
42    ) -> crate::auth::Result<Option<crate::auth::Credential>> {
43        let key = format!("{provider}-{credential_type}");
44        Ok(self.credentials.lock().await.get(&key).cloned())
45    }
46
47    async fn set_credential(
48        &self,
49        provider: &str,
50        credential: crate::auth::Credential,
51    ) -> crate::auth::Result<()> {
52        let key = format!("{}-{}", provider, credential.credential_type());
53        self.credentials.lock().await.insert(key, credential);
54        Ok(())
55    }
56
57    async fn remove_credential(
58        &self,
59        provider: &str,
60        credential_type: CredentialType,
61    ) -> crate::auth::Result<()> {
62        let key = format!("{provider}-{credential_type}");
63        self.credentials.lock().await.remove(&key);
64        Ok(())
65    }
66}
67
68/// Create an `LlmConfigProvider` backed by in-memory auth storage for tests
69pub fn test_llm_config_provider() -> crate::error::Result<LlmConfigProvider> {
70    let storage = Arc::new(InMemoryAuthStorage::new());
71    LlmConfigProvider::new(storage)
72}
73
74/// Convenience to build an `AppConfig` for tests with a fresh provider
75pub fn test_app_config() -> AppConfig {
76    // Use the default which is designed for tests
77    AppConfig::default()
78}
79
80/// Build a minimal read-only session config for tests.
81pub fn read_only_session_config(default_model: ModelId) -> SessionConfig {
82    SessionConfig {
83        workspace: WorkspaceConfig::Local {
84            path: std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")),
85        },
86        workspace_ref: None,
87        workspace_id: None,
88        repo_ref: None,
89        parent_session_id: None,
90        workspace_name: None,
91        tool_config: SessionToolConfig::read_only(),
92        system_prompt: None,
93        primary_agent_id: None,
94        policy_overrides: SessionPolicyOverrides::empty(),
95        metadata: HashMap::new(),
96        default_model,
97    }
98}