Jesús Pérez 09a97ac8f5
chore: update platform submodule to monorepo crates structure
Platform restructured into crates/, added AI service and detector,
       migrated control-center-ui to Leptos 0.8
2026-01-08 21:32:59 +00:00

461 lines
15 KiB
Rust

#[cfg(test)]
#[allow(clippy::module_inception)]
mod tests {
use std::collections::HashMap;
use std::path::PathBuf;
use tempfile::TempDir;
use crate::tools::guidance::*;
fn create_test_system_status() -> SystemStatus {
let paths = SystemPaths {
provisioning_root: PathBuf::from("/test"),
workspace_dir: Some(PathBuf::from("/test/workspace")),
docs_dir: PathBuf::from("/test/docs"),
config_dir: PathBuf::from("/test/config"),
};
SystemStatus {
nushell_version: Some("0.107.1".to_string()),
workspace_configured: true,
providers: vec!["aws".to_string(), "upcloud".to_string()],
orchestrator_running: true,
services_status: HashMap::new(),
issues: Vec::new(),
paths,
metadata: HashMap::new(),
}
}
#[test]
fn test_system_status_creation() {
let status = create_test_system_status();
assert!(status.nushell_version.is_some());
assert_eq!(status.providers.len(), 2);
assert!(status.workspace_configured);
assert!(status.orchestrator_running);
}
#[test]
fn test_issue_severity_ordering() {
assert!(IssueSeverity::Critical > IssueSeverity::Error);
assert!(IssueSeverity::Error > IssueSeverity::Warning);
assert!(IssueSeverity::Warning > IssueSeverity::Info);
}
#[test]
fn test_health_status_variants() {
let statuses = [
HealthStatus::Healthy,
HealthStatus::Degraded,
HealthStatus::Unhealthy,
HealthStatus::Unknown,
];
assert_eq!(statuses.len(), 4);
assert_eq!(HealthStatus::Healthy, HealthStatus::Healthy);
}
#[test]
fn test_risk_level_variants() {
let risk_low = RiskLevel::Low;
let risk_medium = RiskLevel::Medium;
let risk_high = RiskLevel::High;
assert_eq!(risk_low, RiskLevel::Low);
assert_ne!(risk_low, risk_high);
}
#[test]
fn test_next_action_priority() {
let action = NextAction {
command: "test".to_string(),
description: "test action".to_string(),
docs_link: "docs/test.md".to_string(),
expected_outcome: "success".to_string(),
priority: 1,
};
assert_eq!(action.priority, 1);
assert!(!action.command.is_empty());
}
#[test]
fn test_doc_reference_relevance() {
let doc = DocReference {
path: "docs/test.md".to_string(),
title: "Test Document".to_string(),
snippet: "This is a test snippet".to_string(),
relevance: 0.95,
section: Some("Introduction".to_string()),
};
assert!(doc.relevance > 0.9);
assert!(doc.relevance <= 1.0);
}
#[test]
fn test_validation_result_with_errors() {
let result = ValidationResult {
valid: false,
errors: vec![ValidationError {
message: "Test error".to_string(),
path: "config.toml".to_string(),
line: Some(10),
fix: Some("Fix it".to_string()),
}],
warnings: Vec::new(),
suggestions: Vec::new(),
docs: Vec::new(),
};
assert!(!result.valid);
assert_eq!(result.errors.len(), 1);
assert_eq!(result.errors[0].line, Some(10));
}
#[test]
fn test_diagnosis_with_fixes() {
let diagnosis = Diagnosis {
error: "Nushell not found".to_string(),
root_cause: "Nushell is not installed".to_string(),
fixes: vec![Fix {
description: "Install Nushell".to_string(),
commands: vec!["brew install nushell".to_string()],
expected_outcome: "Nushell installed".to_string(),
risk: RiskLevel::Low,
}],
related_docs: Vec::new(),
confidence: 0.95,
};
assert_eq!(diagnosis.fixes.len(), 1);
assert!(diagnosis.confidence > 0.9);
assert_eq!(diagnosis.fixes[0].risk, RiskLevel::Low);
}
#[test]
fn test_system_status_tool_creation() {
let _tool = SystemStatusTool::new(PathBuf::from("/test"));
// Tool created successfully - type check is the test
}
#[test]
fn test_next_action_tool_creation() {
let _tool = NextActionTool::new(PathBuf::from("/test"));
// Tool created successfully - type check is the test
}
#[test]
fn test_doc_finder_tool_creation() {
let _tool = DocFinderTool::new(PathBuf::from("/test"));
// Tool created successfully - type check is the test
}
#[test]
fn test_troubleshooter_tool_creation() {
let _tool = TroubleshooterTool::new(PathBuf::from("/test"));
// Tool created successfully - type check is the test
}
#[test]
fn test_config_validator_tool_creation() {
let _tool = ConfigValidatorTool::new(PathBuf::from("/test"));
// Tool created successfully - type check is the test
}
#[test]
fn test_system_status_with_issues() {
let mut status = create_test_system_status();
status.issues.push(Issue {
severity: IssueSeverity::Warning,
category: "Configuration".to_string(),
description: "Test warning".to_string(),
fix: Some("Run command".to_string()),
docs_link: Some("docs/help.md".to_string()),
});
assert_eq!(status.issues.len(), 1);
assert_eq!(status.issues[0].severity, IssueSeverity::Warning);
}
#[test]
fn test_service_status_healthy() {
let service = ServiceStatus {
name: "orchestrator".to_string(),
running: true,
version: Some("1.0.0".to_string()),
health: HealthStatus::Healthy,
last_checked: "2025-10-10T00:00:00Z".to_string(),
};
assert!(service.running);
assert_eq!(service.health, HealthStatus::Healthy);
assert!(service.version.is_some());
}
#[test]
fn test_next_action_tool_suggest_with_critical_issue() {
let tool = NextActionTool::new(PathBuf::from("/test"));
let mut status = create_test_system_status();
// Add critical issue
status.issues.push(Issue {
severity: IssueSeverity::Critical,
category: "Prerequisites".to_string(),
description: "Nushell not installed".to_string(),
fix: Some("brew install nushell".to_string()),
docs_link: Some("docs/setup.md".to_string()),
});
let result = tool.suggest_next_action(&status);
assert!(result.is_ok());
let action = result.unwrap();
assert_eq!(action.priority, 1);
assert!(action.command.contains("brew install nushell"));
}
#[test]
fn test_next_action_tool_workspace_not_configured() {
let tool = NextActionTool::new(PathBuf::from("/test"));
let mut status = create_test_system_status();
status.workspace_configured = false;
let result = tool.suggest_next_action(&status);
assert!(result.is_ok());
let action = result.unwrap();
assert_eq!(action.priority, 2);
assert!(action.command.contains("workspace init"));
}
#[test]
fn test_next_action_tool_no_providers() {
let tool = NextActionTool::new(PathBuf::from("/test"));
let mut status = create_test_system_status();
status.providers.clear();
let result = tool.suggest_next_action(&status);
assert!(result.is_ok());
let action = result.unwrap();
assert_eq!(action.priority, 3);
assert!(action.command.contains("discover providers"));
}
#[test]
fn test_next_action_tool_orchestrator_not_running() {
let tool = NextActionTool::new(PathBuf::from("/test"));
let mut status = create_test_system_status();
status.orchestrator_running = false;
let result = tool.suggest_next_action(&status);
assert!(result.is_ok());
let action = result.unwrap();
assert_eq!(action.priority, 4);
assert!(action.command.contains("orchestrator"));
}
#[test]
fn test_troubleshooter_nushell_error() {
let tool = TroubleshooterTool::new(PathBuf::from("/test"));
let status = create_test_system_status();
let result = tool.diagnose_issue("command not found: nu", &status);
assert!(result.is_ok());
let diagnosis = result.unwrap();
assert!(diagnosis.confidence > 0.9);
assert!(diagnosis.root_cause.contains("Nushell"));
assert!(!diagnosis.fixes.is_empty());
}
#[test]
fn test_troubleshooter_workspace_error() {
let tool = TroubleshooterTool::new(PathBuf::from("/test"));
let status = create_test_system_status();
let result = tool.diagnose_issue("workspace not found", &status);
assert!(result.is_ok());
let diagnosis = result.unwrap();
assert!(diagnosis.confidence > 0.8);
assert!(diagnosis.fixes.iter().any(|f| f
.commands
.iter()
.any(|c: &String| c.contains("workspace init"))));
}
#[test]
fn test_troubleshooter_orchestrator_error() {
let tool = TroubleshooterTool::new(PathBuf::from("/test"));
let status = create_test_system_status();
let result = tool.diagnose_issue("connection refused to orchestrator", &status);
assert!(result.is_ok());
let diagnosis = result.unwrap();
assert!(diagnosis.confidence > 0.8);
assert!(diagnosis
.fixes
.iter()
.any(|f| f.description.contains("orchestrator")));
}
#[test]
fn test_troubleshooter_provider_error() {
let tool = TroubleshooterTool::new(PathBuf::from("/test"));
let status = create_test_system_status();
let result = tool.diagnose_issue("provider aws not configured", &status);
assert!(result.is_ok());
let diagnosis = result.unwrap();
assert!(!diagnosis.fixes.is_empty());
}
#[test]
fn test_config_validator_nonexistent_file() {
let tool = ConfigValidatorTool::new(PathBuf::from("/test"));
let result = tool.validate_config("nonexistent.toml");
assert!(result.is_ok());
let validation = result.unwrap();
assert!(!validation.valid);
assert!(!validation.errors.is_empty());
}
#[test]
fn test_multiple_next_actions() {
let tool = NextActionTool::new(PathBuf::from("/test"));
let mut status = create_test_system_status();
// Add multiple issues
status.issues.push(Issue {
severity: IssueSeverity::Critical,
category: "Prerequisites".to_string(),
description: "Critical issue 1".to_string(),
fix: Some("fix 1".to_string()),
docs_link: None,
});
status.issues.push(Issue {
severity: IssueSeverity::Critical,
category: "Prerequisites".to_string(),
description: "Critical issue 2".to_string(),
fix: Some("fix 2".to_string()),
docs_link: None,
});
let result = tool.suggest_multiple_actions(&status, 3);
assert!(result.is_ok());
let actions = result.unwrap();
assert!(actions.len() <= 3);
assert!(actions.iter().all(|a| a.priority <= 2));
}
#[test]
fn test_system_paths_structure() {
let paths = SystemPaths {
provisioning_root: PathBuf::from("/usr/local/provisioning"),
workspace_dir: Some(PathBuf::from("/workspace")),
docs_dir: PathBuf::from("/usr/local/provisioning/docs"),
config_dir: PathBuf::from("/usr/local/provisioning/config"),
};
assert_eq!(
paths.provisioning_root,
PathBuf::from("/usr/local/provisioning")
);
assert!(paths.workspace_dir.is_some());
}
#[test]
fn test_fix_risk_levels() {
let low_risk_fix = Fix {
description: "Safe fix".to_string(),
commands: vec!["echo test".to_string()],
expected_outcome: "Success".to_string(),
risk: RiskLevel::Low,
};
let high_risk_fix = Fix {
description: "Dangerous fix".to_string(),
commands: vec!["rm -rf /".to_string()],
expected_outcome: "Disaster".to_string(),
risk: RiskLevel::High,
};
assert_eq!(low_risk_fix.risk, RiskLevel::Low);
assert_eq!(high_risk_fix.risk, RiskLevel::High);
assert_ne!(low_risk_fix.risk, high_risk_fix.risk);
}
#[test]
fn test_validation_with_warnings_only() {
let result = ValidationResult {
valid: true,
errors: Vec::new(),
warnings: vec![ValidationWarning {
message: "Consider updating".to_string(),
path: "config.yaml".to_string(),
recommendation: "Use newer format".to_string(),
}],
suggestions: vec!["Use TOML instead".to_string()],
docs: Vec::new(),
};
assert!(result.valid);
assert!(result.errors.is_empty());
assert_eq!(result.warnings.len(), 1);
assert_eq!(result.suggestions.len(), 1);
}
#[test]
fn test_serialization_system_status() {
let status = create_test_system_status();
let json = serde_json::to_string(&status);
assert!(json.is_ok());
let deserialized: Result<SystemStatus, _> = serde_json::from_str(&json.unwrap());
assert!(deserialized.is_ok());
}
#[test]
fn test_serialization_next_action() {
let action = NextAction {
command: "test command".to_string(),
description: "test description".to_string(),
docs_link: "docs/test.md".to_string(),
expected_outcome: "success".to_string(),
priority: 1,
};
let json = serde_json::to_string(&action);
assert!(json.is_ok());
let deserialized: Result<NextAction, _> = serde_json::from_str(&json.unwrap());
assert!(deserialized.is_ok());
}
#[test]
fn test_serialization_diagnosis() {
let diagnosis = Diagnosis {
error: "test error".to_string(),
root_cause: "test cause".to_string(),
fixes: Vec::new(),
related_docs: Vec::new(),
confidence: 0.5,
};
let json = serde_json::to_string(&diagnosis);
assert!(json.is_ok());
let deserialized: Result<Diagnosis, _> = serde_json::from_str(&json.unwrap());
assert!(deserialized.is_ok());
}
}