udb 0.3.0

Universal Data Broker — a Rust gRPC broker over multiple databases (Postgres, MySQL, SQLite, MongoDB, ClickHouse, Cassandra, MSSQL, Redis, Qdrant, S3, Neo4j, …) with per-tenant RLS, 2PC, sagas, and CDC.
Documentation
use super::*;

#[test]
fn parse_args_recognizes_doctor_without_proto_root() {
    let args = vec!["doctor".to_string()];
    let (command, proto_root, namespace, serve_addr) = parse_args(&args);

    assert!(matches!(command, Command::Doctor { .. }));
    assert_eq!(proto_root, "proto");
    assert_eq!(namespace, "");
    assert_eq!(serve_addr, "0.0.0.0:50051");
}

#[test]
fn parse_args_recognizes_health_check() {
    let args = vec!["health-check".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(command, Command::HealthCheck));
}

#[test]
fn parse_args_recognizes_doctor_human() {
    let args = vec!["doctor".to_string(), "--human".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(
        command,
        Command::Doctor {
            output_mode: DoctorOutputMode::Human,
            ..
        }
    ));
}

#[test]
fn parse_args_recognizes_doctor_probe() {
    let args = vec!["doctor".to_string(), "--probe".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(
        command,
        Command::Doctor {
            with_probes: true,
            ..
        }
    ));
}

#[test]
fn parse_args_recognizes_init_project() {
    let args = vec!["init-project".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(command, Command::InitProject));
}

#[test]
fn parse_args_recognizes_dev_defaults() {
    let args = vec!["dev".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(
        command,
        Command::Dev {
            action: DevAction::Up,
            service: None,
            confirmed: false,
        }
    ));
}

#[test]
fn parse_args_recognizes_dev_logs_service() {
    let args = vec![
        "dev".to_string(),
        "logs".to_string(),
        "postgres".to_string(),
    ];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(
        command,
        Command::Dev {
            action: DevAction::Logs,
            service: Some(service),
            ..
        } if service == "postgres"
    ));
}

#[test]
fn parse_args_recognizes_dev_reset_confirmation() {
    let args = vec!["dev".to_string(), "reset".to_string(), "--yes".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(
        command,
        Command::Dev {
            action: DevAction::Reset,
            confirmed: true,
            ..
        }
    ));
}

#[test]
fn parse_args_recognizes_admin_verify_audit_limit() {
    let args = vec![
        "admin".to_string(),
        "verify-audit".to_string(),
        "--limit".to_string(),
        "250".to_string(),
    ];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(command, Command::AdminVerifyAudit { limit: 250 }));
}

#[test]
fn parse_args_recognizes_manifest_export() {
    let args = vec!["manifest-export".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(command, Command::ManifestExport));
}

#[test]
fn parse_args_recognizes_policy_lint() {
    let args = vec!["policy-lint".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(command, Command::PolicyLint));
}

#[test]
fn parse_args_recognizes_auth_commands() {
    let args = vec![
        "auth".to_string(),
        "api-key".to_string(),
        "create".to_string(),
        "--owner".to_string(),
        "svc.search".to_string(),
        "--scope".to_string(),
        "catalog:read".to_string(),
        "--scope".to_string(),
        "catalog:write".to_string(),
    ];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(
        command,
        Command::Auth(AuthCommand::ApiKeyCreate {
            owner_id,
            scopes,
            ..
        }) if owner_id == "svc.search" && scopes.len() == 2
    ));
}

#[test]
fn parse_args_recognizes_auth_policy_lint() {
    let args = vec!["auth".to_string(), "policy".to_string(), "lint".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(command, Command::Auth(AuthCommand::PolicyLint)));
}

#[test]
fn parse_args_recognizes_field_mask_preview() {
    let args = vec!["field-mask-preview".to_string()];
    let (command, _, _, _) = parse_args(&args);
    assert!(matches!(command, Command::FieldMaskPreview));
}

#[test]
fn lint_policies_empty_set_returns_deny_by_default_warning() {
    use udb::lint_policies;
    let findings = lint_policies(&[]);
    assert_eq!(findings.len(), 1);
    assert_eq!(findings[0].category, "deny_by_default");
}

#[test]
fn lint_policies_detects_broad_wildcard_deny() {
    use udb::{AbacPolicy, PolicyEffect, lint_policies};
    let policies = vec![AbacPolicy {
        effect: PolicyEffect::Deny,
        service_identity: "svc-a".to_string(),
        tenant_id: "*".to_string(),
        purpose: "read".to_string(),
        message_type: "User".to_string(),
        operation: "Select".to_string(),
        required_scope: "udb:read".to_string(),
    }];
    let findings = lint_policies(&policies);
    assert!(findings.iter().any(|f| f.category == "broad_wildcard"));
}

#[test]
fn lint_policies_detects_shadowed_allow() {
    use udb::{AbacPolicy, PolicyEffect, lint_policies};
    let p = AbacPolicy {
        effect: PolicyEffect::Allow,
        service_identity: "svc-a".to_string(),
        tenant_id: "t1".to_string(),
        purpose: "read".to_string(),
        message_type: "User".to_string(),
        operation: "Select".to_string(),
        required_scope: "udb:read".to_string(),
    };
    let policies = vec![p.clone(), p];
    let findings = lint_policies(&policies);
    assert!(findings.iter().any(|f| f.category == "shadowed_policy"));
}