use keyhog_core::encoding::{decode_standard_base64, MAX_STANDARD_BASE64_INPUT_BYTES};
#[test]
fn decode_empty_string_returns_empty_vec() {
let result = decode_standard_base64("").expect("empty string is valid");
assert!(result.is_empty());
}
#[test]
fn decode_single_byte_padded() {
let result = decode_standard_base64("QQ==").expect("single byte");
assert_eq!(result, b"A");
}
#[test]
fn decode_two_bytes_padded() {
let result = decode_standard_base64("QUI=").expect("two bytes");
assert_eq!(result, b"AB");
}
#[test]
fn decode_three_bytes_no_padding() {
let result = decode_standard_base64("QUJD").expect("three bytes");
assert_eq!(result, b"ABC");
}
#[test]
fn decode_hello_world() {
let result = decode_standard_base64("SGVsbG8gV29ybGQ=").expect("hello world");
assert_eq!(result, b"Hello World");
}
#[test]
fn decode_all_zeros() {
let result = decode_standard_base64("AAAA").expect("all zeros");
assert_eq!(result, &[0u8, 0, 0]);
}
#[test]
fn decode_binary_round_trip() {
let original: &[u8] = &[0x00, 0x7F, 0x80, 0xFF, 0xAB, 0xCD];
let encoded = "AH+A/6vN";
let result = decode_standard_base64(encoded).expect("binary round-trip");
assert_eq!(result, original);
}
#[test]
fn decode_extra_padding_stripped_gracefully() {
let no_pad = decode_standard_base64("QUJD").expect("no pad");
let with_pad = decode_standard_base64("QUJD==").expect("with pad");
assert_eq!(no_pad, with_pad);
}
#[test]
fn decode_invalid_char_returns_error() {
let result = decode_standard_base64("QUJ@");
assert!(result.is_err(), "invalid char must return Err");
}
#[test]
fn decode_null_byte_in_middle_returns_error() {
let result = decode_standard_base64("QU\0=");
assert!(result.is_err(), "null byte must return Err");
}
#[test]
fn decode_space_returns_error() {
let result = decode_standard_base64("QU J=");
assert!(result.is_err(), "space is not valid base64");
}
#[test]
fn decode_truncated_chunk_returns_error() {
let result = decode_standard_base64("Q");
assert!(result.is_err(), "single char (truncated) should be Err");
}
#[test]
fn decode_at_exact_cap_succeeds() {
let at_cap: String = "A".repeat(MAX_STANDARD_BASE64_INPUT_BYTES);
let result = decode_standard_base64(&at_cap);
match result {
Err(e) if e.contains("exceeds") => {
panic!("at-cap input should not trigger the size error: {e}");
}
_ => {} }
}
#[test]
fn decode_one_over_cap_is_rejected() {
let over_cap: String = "A".repeat(MAX_STANDARD_BASE64_INPUT_BYTES + 1);
let result = decode_standard_base64(&over_cap);
assert!(result.is_err());
assert!(
result.unwrap_err().contains("exceeds"),
"over-cap must return the size-limit error"
);
}
#[test]
fn decode_plus_slash_chars_are_valid_alphabet() {
let result = decode_standard_base64("+/==");
if let Err(ref e) = result {
assert!(
!e.contains("invalid base64 char"),
"'+' and '/' are valid b64 chars"
);
}
}
#[test]
fn decode_url_safe_chars_rejected() {
let result = decode_standard_base64("QU-_");
assert!(result.is_err(), "url-safe chars must be rejected by standard b64 decoder");
}