synta 0.1.2

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
//! Tests for time types

use synta::types::time::{GeneralizedTime, UtcTime};
use synta::{Decoder, Encoder, Encoding};

#[test]
fn test_utctime_creation() {
    // Valid UTCTime
    let time = UtcTime::new(2024, 1, 15, 10, 30, 45).unwrap();
    assert_eq!(time.year, 2024);
    assert_eq!(time.month, 1);
    assert_eq!(time.day, 15);
    assert_eq!(time.hour, 10);
    assert_eq!(time.minute, 30);
    assert_eq!(time.second, 45);

    // Test year range
    assert!(UtcTime::new(1950, 1, 1, 0, 0, 0).is_ok());
    assert!(UtcTime::new(2049, 12, 31, 23, 59, 59).is_ok());
    assert!(UtcTime::new(1949, 1, 1, 0, 0, 0).is_err());
    assert!(UtcTime::new(2050, 1, 1, 0, 0, 0).is_err());
}

#[test]
fn test_utctime_validation() {
    // Invalid month
    assert!(UtcTime::new(2024, 0, 15, 10, 30, 45).is_err());
    assert!(UtcTime::new(2024, 13, 15, 10, 30, 45).is_err());

    // Invalid day
    assert!(UtcTime::new(2024, 1, 0, 10, 30, 45).is_err());
    assert!(UtcTime::new(2024, 1, 32, 10, 30, 45).is_err());

    // Invalid hour
    assert!(UtcTime::new(2024, 1, 15, 24, 30, 45).is_err());

    // Invalid minute
    assert!(UtcTime::new(2024, 1, 15, 10, 60, 45).is_err());

    // Invalid second
    assert!(UtcTime::new(2024, 1, 15, 10, 30, 60).is_err());
}

#[test]
fn test_utctime_roundtrip() {
    let test_times = vec![
        UtcTime::new(2024, 1, 15, 10, 30, 45).unwrap(),
        UtcTime::new(1999, 12, 31, 23, 59, 59).unwrap(),
        UtcTime::new(2000, 1, 1, 0, 0, 0).unwrap(),
        UtcTime::new(1950, 6, 15, 12, 0, 0).unwrap(),
        UtcTime::new(2049, 12, 31, 23, 59, 59).unwrap(),
    ];

    for time in test_times {
        let mut encoder = Encoder::new(Encoding::Der);
        encoder.encode(&time).unwrap();
        let encoded = encoder.finish().unwrap();

        let mut decoder = Decoder::new(&encoded, Encoding::Der);
        let decoded: UtcTime = decoder.decode().unwrap();

        assert_eq!(decoded, time);
    }
}

#[test]
fn test_utctime_known_encoding() {
    // 2024-01-15 10:30:45 UTC -> 240115103045Z
    // Tag: 0x17 (UTC_TIME), Length: 13, Content: "240115103045Z"
    let time = UtcTime::new(2024, 1, 15, 10, 30, 45).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&time).unwrap();
    let encoded = encoder.finish().unwrap();

    // Verify tag and length
    assert_eq!(encoded[0], 0x17); // UTC_TIME tag
    assert_eq!(encoded[1], 13); // Length

    // Verify content
    let content = &encoded[2..];
    assert_eq!(content, b"240115103045Z");

    // Test decoding
    let mut decoder = Decoder::new(&encoded, Encoding::Der);
    let decoded: UtcTime = decoder.decode().unwrap();
    assert_eq!(decoded, time);
}

#[test]
fn test_generalizedtime_creation() {
    // Without fractional seconds
    let time = GeneralizedTime::new(2024, 1, 15, 10, 30, 45, None).unwrap();
    assert_eq!(time.year, 2024);
    assert_eq!(time.month, 1);
    assert_eq!(time.day, 15);
    assert_eq!(time.hour, 10);
    assert_eq!(time.minute, 30);
    assert_eq!(time.second, 45);
    assert_eq!(time.milliseconds, None);

    // With fractional seconds
    let time = GeneralizedTime::new(2024, 1, 15, 10, 30, 45, Some(123)).unwrap();
    assert_eq!(time.milliseconds, Some(123));
}

#[test]
fn test_generalizedtime_validation() {
    // Invalid month
    assert!(GeneralizedTime::new(2024, 0, 15, 10, 30, 45, None).is_err());
    assert!(GeneralizedTime::new(2024, 13, 15, 10, 30, 45, None).is_err());

    // Invalid day
    assert!(GeneralizedTime::new(2024, 1, 0, 10, 30, 45, None).is_err());
    assert!(GeneralizedTime::new(2024, 1, 32, 10, 30, 45, None).is_err());

    // Invalid hour
    assert!(GeneralizedTime::new(2024, 1, 15, 24, 30, 45, None).is_err());

    // Invalid minute
    assert!(GeneralizedTime::new(2024, 1, 15, 10, 60, 45, None).is_err());

    // Invalid second
    assert!(GeneralizedTime::new(2024, 1, 15, 10, 30, 60, None).is_err());

    // Invalid milliseconds
    assert!(GeneralizedTime::new(2024, 1, 15, 10, 30, 45, Some(1000)).is_err());
}

#[test]
fn test_generalizedtime_roundtrip() {
    let test_times = vec![
        GeneralizedTime::new(2024, 1, 15, 10, 30, 45, None).unwrap(),
        GeneralizedTime::new(1999, 12, 31, 23, 59, 59, None).unwrap(),
        GeneralizedTime::new(2024, 1, 15, 10, 30, 45, Some(123)).unwrap(),
        GeneralizedTime::new(2024, 1, 15, 10, 30, 45, Some(0)).unwrap(),
        GeneralizedTime::new(2024, 1, 15, 10, 30, 45, Some(999)).unwrap(),
    ];

    for time in test_times {
        let mut encoder = Encoder::new(Encoding::Der);
        encoder.encode(&time).unwrap();
        let encoded = encoder.finish().unwrap();

        let mut decoder = Decoder::new(&encoded, Encoding::Der);
        let decoded: GeneralizedTime = decoder.decode().unwrap();

        assert_eq!(decoded, time);
    }
}

#[test]
fn test_generalizedtime_known_encoding() {
    // 2024-01-15 10:30:45 UTC -> 20240115103045Z
    // Tag: 0x18 (GENERALIZED_TIME), Length: 15, Content: "20240115103045Z"
    let time = GeneralizedTime::new(2024, 1, 15, 10, 30, 45, None).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&time).unwrap();
    let encoded = encoder.finish().unwrap();

    // Verify tag and length
    assert_eq!(encoded[0], 0x18); // GENERALIZED_TIME tag
    assert_eq!(encoded[1], 15); // Length

    // Verify content
    let content = &encoded[2..];
    assert_eq!(content, b"20240115103045Z");

    // Test decoding
    let mut decoder = Decoder::new(&encoded, Encoding::Der);
    let decoded: GeneralizedTime = decoder.decode().unwrap();
    assert_eq!(decoded, time);
}

#[test]
fn test_generalizedtime_with_milliseconds_encoding() {
    // 2024-01-15 10:30:45.123 UTC -> 20240115103045.123Z
    // Tag: 0x18 (GENERALIZED_TIME), Length: 19, Content: "20240115103045.123Z"
    let time = GeneralizedTime::new(2024, 1, 15, 10, 30, 45, Some(123)).unwrap();
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&time).unwrap();
    let encoded = encoder.finish().unwrap();

    // Verify tag and length
    assert_eq!(encoded[0], 0x18); // GENERALIZED_TIME tag
    assert_eq!(encoded[1], 19); // Length

    // Verify content
    let content = &encoded[2..];
    assert_eq!(content, b"20240115103045.123Z");

    // Test decoding
    let mut decoder = Decoder::new(&encoded, Encoding::Der);
    let decoded: GeneralizedTime = decoder.decode().unwrap();
    assert_eq!(decoded, time);
}