subx_cli/config/
test_service.rs1use crate::config::service::ConfigService;
8use crate::error::SubXError;
9use crate::{Result, config::Config};
10use std::path::{Path, PathBuf};
11
12pub struct TestConfigService {
18 fixed_config: Config,
19}
20
21impl TestConfigService {
22 pub fn new(config: Config) -> Self {
28 Self {
29 fixed_config: config,
30 }
31 }
32
33 pub fn with_defaults() -> Self {
37 Self::new(Config::default())
38 }
39
40 pub fn with_ai_settings(provider: &str, model: &str) -> Self {
47 let mut config = Config::default();
48 config.ai.provider = provider.to_string();
49 config.ai.model = model.to_string();
50 Self::new(config)
51 }
52
53 pub fn with_ai_settings_and_key(provider: &str, model: &str, api_key: &str) -> Self {
61 let mut config = Config::default();
62 config.ai.provider = provider.to_string();
63 config.ai.model = model.to_string();
64 config.ai.api_key = Some(api_key.to_string());
65 Self::new(config)
66 }
67
68 pub fn with_sync_settings(correlation_threshold: f32, max_offset: f32) -> Self {
75 let mut config = Config::default();
76 config.sync.correlation_threshold = correlation_threshold;
77 config.sync.max_offset_seconds = max_offset;
78 Self::new(config)
79 }
80
81 pub fn with_parallel_settings(max_workers: usize, queue_size: usize) -> Self {
88 let mut config = Config::default();
89 config.general.max_concurrent_jobs = max_workers;
90 config.parallel.task_queue_size = queue_size;
91 Self::new(config)
92 }
93
94 pub fn config(&self) -> &Config {
98 &self.fixed_config
99 }
100
101 pub fn config_mut(&mut self) -> &mut Config {
105 &mut self.fixed_config
106 }
107}
108
109impl ConfigService for TestConfigService {
110 fn get_config(&self) -> Result<Config> {
111 Ok(self.fixed_config.clone())
112 }
113
114 fn reload(&self) -> Result<()> {
115 Ok(())
117 }
118
119 fn save_config(&self) -> Result<()> {
120 Ok(())
122 }
123
124 fn save_config_to_file(&self, _path: &Path) -> Result<()> {
125 Ok(())
127 }
128
129 fn get_config_file_path(&self) -> Result<PathBuf> {
130 Ok(PathBuf::from("/tmp/subx_test_config.toml"))
132 }
133
134 fn get_config_value(&self, key: &str) -> Result<String> {
135 let config = &self.fixed_config;
138 let parts: Vec<&str> = key.split('.').collect();
139 match parts.as_slice() {
140 ["ai", "provider"] => Ok(config.ai.provider.clone()),
141 ["ai", "model"] => Ok(config.ai.model.clone()),
142 ["ai", "api_key"] => Ok(config.ai.api_key.clone().unwrap_or_default()),
143 ["ai", "base_url"] => Ok(config.ai.base_url.clone()),
144 ["ai", "temperature"] => Ok(config.ai.temperature.to_string()),
145 ["formats", "default_output"] => Ok(config.formats.default_output.clone()),
146 ["formats", "default_encoding"] => Ok(config.formats.default_encoding.clone()),
147 ["sync", "max_offset_seconds"] => Ok(config.sync.max_offset_seconds.to_string()),
148 ["sync", "correlation_threshold"] => Ok(config.sync.correlation_threshold.to_string()),
149 ["general", "backup_enabled"] => Ok(config.general.backup_enabled.to_string()),
150 ["general", "max_concurrent_jobs"] => {
151 Ok(config.general.max_concurrent_jobs.to_string())
152 }
153 ["parallel", "max_workers"] => Ok(config.parallel.max_workers.to_string()),
154 ["parallel", "chunk_size"] => Ok(config.parallel.chunk_size.to_string()),
155 _ => Err(SubXError::config(format!(
156 "Unknown configuration key: {}",
157 key
158 ))),
159 }
160 }
161
162 fn reset_to_defaults(&self) -> Result<()> {
163 Ok(())
166 }
167}
168
169impl Default for TestConfigService {
170 fn default() -> Self {
171 Self::with_defaults()
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178
179 #[test]
180 fn test_config_service_with_defaults() {
181 let service = TestConfigService::with_defaults();
182 let config = service.get_config().unwrap();
183
184 assert_eq!(config.ai.provider, "openai");
185 assert_eq!(config.ai.model, "gpt-4.1-mini");
186 }
187
188 #[test]
189 fn test_config_service_with_ai_settings() {
190 let service = TestConfigService::with_ai_settings("anthropic", "claude-3");
191 let config = service.get_config().unwrap();
192
193 assert_eq!(config.ai.provider, "anthropic");
194 assert_eq!(config.ai.model, "claude-3");
195 }
196
197 #[test]
198 fn test_config_service_with_ai_settings_and_key() {
199 let service =
200 TestConfigService::with_ai_settings_and_key("openai", "gpt-4.1", "test-api-key");
201 let config = service.get_config().unwrap();
202
203 assert_eq!(config.ai.provider, "openai");
204 assert_eq!(config.ai.model, "gpt-4.1");
205 assert_eq!(config.ai.api_key, Some("test-api-key".to_string()));
206 }
207
208 #[test]
209 fn test_config_service_with_sync_settings() {
210 let service = TestConfigService::with_sync_settings(0.8, 45.0);
211 let config = service.get_config().unwrap();
212
213 assert_eq!(config.sync.correlation_threshold, 0.8);
214 assert_eq!(config.sync.max_offset_seconds, 45.0);
215 }
216
217 #[test]
218 fn test_config_service_with_parallel_settings() {
219 let service = TestConfigService::with_parallel_settings(8, 200);
220 let config = service.get_config().unwrap();
221
222 assert_eq!(config.general.max_concurrent_jobs, 8);
223 assert_eq!(config.parallel.task_queue_size, 200);
224 }
225
226 #[test]
227 fn test_config_service_reload() {
228 let service = TestConfigService::with_defaults();
229
230 assert!(service.reload().is_ok());
232 }
233
234 #[test]
235 fn test_config_service_direct_access() {
236 let mut service = TestConfigService::with_defaults();
237
238 assert_eq!(service.config().ai.provider, "openai");
240
241 service.config_mut().ai.provider = "modified".to_string();
243 assert_eq!(service.config().ai.provider, "modified");
244
245 let config = service.get_config().unwrap();
246 assert_eq!(config.ai.provider, "modified");
247 }
248}