ufwctl 0.1.0

Linux-only Rust library for managing UFW firewall rules
Documentation
/// Tests for IP-related public API: IpRule, IPv4/IPv6 validation.
use std::net::IpAddr;

use ufwctl::{Firewall, IpRule, Protocol, RuleStatus, UfwError};

// ---------------------------------------------------------------------------
// IpRule struct
// ---------------------------------------------------------------------------

#[test]
fn ip_rule_fields() {
    let ip: IpAddr = "192.168.1.10".parse().expect("valid ip");
    let rule = IpRule {
        ip,
        protocol: Protocol::Both,
        status: RuleStatus::Allowed,
    };
    assert_eq!(rule.ip, ip);
    assert_eq!(rule.protocol, Protocol::Both);
    assert_eq!(rule.status, RuleStatus::Allowed);
}

#[test]
fn ip_rule_equality() {
    let ip: IpAddr = "192.168.1.10".parse().expect("valid ip");
    let a = IpRule {
        ip,
        protocol: Protocol::Both,
        status: RuleStatus::Allowed,
    };
    let b = IpRule {
        ip,
        protocol: Protocol::Both,
        status: RuleStatus::Allowed,
    };
    assert_eq!(a, b);
}

#[test]
fn ip_rule_inequality_ip() {
    let a: IpAddr = "192.168.1.10".parse().expect("valid ip");
    let b: IpAddr = "10.0.0.5".parse().expect("valid ip");
    let rule_a = IpRule {
        ip: a,
        protocol: Protocol::Both,
        status: RuleStatus::Allowed,
    };
    let rule_b = IpRule {
        ip: b,
        protocol: Protocol::Both,
        status: RuleStatus::Allowed,
    };
    assert_ne!(rule_a, rule_b);
}

#[test]
fn ip_rule_debug() {
    let ip: IpAddr = "192.168.1.10".parse().expect("valid ip");
    let rule = IpRule {
        ip,
        protocol: Protocol::Both,
        status: RuleStatus::Allowed,
    };
    let s = format!("{rule:?}");
    assert!(s.contains("192.168.1.10"));
}

#[test]
fn ip_rule_clone() {
    let ip: IpAddr = "192.168.1.10".parse().expect("valid ip");
    let a = IpRule {
        ip,
        protocol: Protocol::Both,
        status: RuleStatus::Allowed,
    };
    let b = a.clone();
    assert_eq!(a, b);
}

// ---------------------------------------------------------------------------
// IPv4 validation
// ---------------------------------------------------------------------------

#[test]
fn ipv4_valid_address() {
    let fw = Firewall::new();
    assert!(fw.ipv4("192.168.1.10").is_ok());
}

#[test]
fn ipv4_rejects_ipv6() {
    let fw = Firewall::new();
    match fw.ipv4("::1") {
        Err(UfwError::InvalidIpv4(_)) => {}
        _ => panic!("expected InvalidIpv4"),
    }
}

#[test]
fn ipv4_rejects_garbage() {
    let fw = Firewall::new();
    match fw.ipv4("not-an-ip") {
        Err(UfwError::InvalidIpv4(_)) => {}
        _ => panic!("expected InvalidIpv4"),
    }
}

#[test]
fn ipv4_rejects_empty_string() {
    let fw = Firewall::new();
    assert!(fw.ipv4("").is_err());
}

#[test]
fn ipv4_rejects_cidr_notation() {
    let fw = Firewall::new();
    assert!(fw.ipv4("192.168.1.0/24").is_err());
}

// ---------------------------------------------------------------------------
// IPv6 validation
// ---------------------------------------------------------------------------

#[test]
fn ipv6_valid_loopback() {
    let fw = Firewall::new();
    assert!(fw.ipv6("::1").is_ok());
}

#[test]
fn ipv6_valid_address() {
    let fw = Firewall::new();
    assert!(fw.ipv6("2001:db8::1").is_ok());
}

#[test]
fn ipv6_rejects_ipv4() {
    let fw = Firewall::new();
    match fw.ipv6("192.168.1.10") {
        Err(UfwError::InvalidIpv6(_)) => {}
        _ => panic!("expected InvalidIpv6"),
    }
}

#[test]
fn ipv6_rejects_garbage() {
    let fw = Firewall::new();
    match fw.ipv6("not-an-ip") {
        Err(UfwError::InvalidIpv6(_)) => {}
        _ => panic!("expected InvalidIpv6"),
    }
}

#[test]
fn ipv6_rejects_empty_string() {
    let fw = Firewall::new();
    assert!(fw.ipv6("").is_err());
}