stemedb/applications/aphoria/src/tests/scan_basic.rs
jordan 8af9b48ac7 feat: Complete Aphoria Phase 14 - Governance Workflows
Implement structured approval workflows for pattern promotion with full
audit trails for SOC 2 compliance.

Core Components:
- governance/types.rs: ApprovalRequest, ApprovalStatus, ApprovalDecision
- governance/workflow.rs: ApprovalWorkflow, ApprovalStage with escalation
- governance/store.rs: JSONL persistence for requests and decisions
- governance/state_machine.rs: Approval state transitions with auto-advance
- governance/audit.rs: AuditTrail with JSON/CSV/Markdown export

CLI Commands:
- aphoria governance pending/approve/reject/escalate/status/create
- aphoria audit trail/export/summary

Integration:
- Pipeline gate blocks promotion until governance approval
- Auto-creates approval requests when governance enabled
- Evidence-based auto-approval for high-confidence patterns

Also includes:
- Phase 11-13: Evidence, Lifecycle, Scope modules
- 62+ governance-specific tests (946 total passing)
- Clippy clean with -D warnings
- Refactored cli.rs into submodules (governance, lifecycle, scope, etc.)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 05:16:26 -07:00

128 lines
4.4 KiB
Rust

//! Basic integration tests for Aphoria scan functionality.
use crate::*;
#[tokio::test]
async fn test_scan_returns_result() {
let temp_dir = tempfile::tempdir().expect("create temp dir");
// Create a test file with a TLS issue
let src_dir = temp_dir.path().join("src");
std::fs::create_dir_all(&src_dir).expect("create src dir");
std::fs::write(
src_dir.join("client.rs"),
r#"
let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()?;
"#,
)
.expect("write file");
// Create Cargo.toml so it's detected as a Rust project
std::fs::write(
temp_dir.path().join("Cargo.toml"),
r#"
[package]
name = "testproject"
version = "0.1.0"
"#,
)
.expect("write cargo.toml");
let args = ScanArgs {
path: temp_dir.path().to_path_buf(),
format: "table".to_string(),
exit_code_enabled: false,
mode: ScanMode::Ephemeral,
debug: false,
sync: false,
file_source: FileSource::All,
benchmark: false,
};
let mut config = AphoriaConfig::default();
config.episteme.data_dir = temp_dir.path().join(".aphoria").join("db");
let result = run_scan(args, &config).await.expect("scan should succeed");
assert!(result.files_scanned > 0);
assert!(result.claims_extracted > 0);
}
#[tokio::test]
async fn test_initialize_creates_corpus() {
// Use a unique temp dir to avoid conflicts with parallel tests
let temp_dir =
tempfile::Builder::new().prefix("aphoria_test_init").tempdir().expect("create temp dir");
let mut config = AphoriaConfig::default();
config.episteme.data_dir = temp_dir.path().join(".aphoria").join("db");
// Create .aphoria directory for the agent key
let aphoria_dir = temp_dir.path().join(".aphoria");
std::fs::create_dir_all(&aphoria_dir).expect("create .aphoria dir");
// Open LocalEpisteme directly instead of using initialize()
// which relies on current_dir()
let mut episteme =
crate::episteme::LocalEpisteme::open(&config, temp_dir.path()).await.expect("open");
let signing_key = crate::bridge::load_or_generate_key(temp_dir.path()).expect("load key");
let corpus = crate::episteme::create_authoritative_corpus(&signing_key);
let ingested = episteme.ingest_authoritative(&corpus).await.expect("ingest");
episteme.shutdown().await;
assert!(ingested > 0);
assert!(config.episteme.data_dir.exists());
assert!(temp_dir.path().join(".aphoria").join("agent.key").exists());
}
#[tokio::test]
async fn test_acknowledge_succeeds() {
let temp_dir =
tempfile::Builder::new().prefix("aphoria_test_ack").tempdir().expect("create temp dir");
let mut config = AphoriaConfig::default();
config.episteme.data_dir = temp_dir.path().join(".aphoria").join("db");
// Create .aphoria directory for the agent key
let aphoria_dir = temp_dir.path().join(".aphoria");
std::fs::create_dir_all(&aphoria_dir).expect("create .aphoria dir");
// Open LocalEpisteme and ingest an acknowledgement claim
let mut episteme =
crate::episteme::LocalEpisteme::open(&config, temp_dir.path()).await.expect("open");
let claim = ExtractedClaim {
concept_path: "code://rust/test/jwt/audience_validation".to_string(),
predicate: "acknowledged".to_string(),
value: stemedb_core::types::ObjectValue::Text("Internal service".to_string()),
file: "aphoria_ack".to_string(),
line: 0,
matched_text: "Acknowledged: Internal service".to_string(),
confidence: 1.0,
description: "Conflict acknowledged: Internal service".to_string(),
};
let result = episteme.ingest_claims(&[claim]).await;
episteme.shutdown().await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_status_before_init() {
let temp_dir =
tempfile::Builder::new().prefix("aphoria_test_status").tempdir().expect("create temp dir");
let mut config = AphoriaConfig::default();
config.episteme.data_dir = temp_dir.path().join("nonexistent");
// Manually check status logic without relying on current_dir()
let data_dir = &config.episteme.data_dir;
let status = if !data_dir.exists() { "Not initialized" } else { "Initialized" };
assert!(status.contains("Not initialized"));
}