#[cfg(test)]
mod tests {
use crate::constants::{MAGIC_BYTES, VERSION};
use crate::crypto::DEFAULT_CHUNK_SIZE;
use crate::headers::Headers;
use crate::huffman::{decoder::decode, encoder::encode};
use std::io::{Cursor, Seek, SeekFrom};
#[test]
fn test_basic_unencrypted_decoding() {
let original_content = b"Hello, this is a test string for basic decoding.";
let mut input_reader = Cursor::new(original_content.to_vec());
let mut encoded_output_buffer = Cursor::new(Vec::new());
let _encode_info = encode(
&mut input_reader,
"test_file.txt",
None,
&mut encoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Encoding failed");
encoded_output_buffer
.seek(SeekFrom::Start(0))
.expect("Failed to rewind");
let header =
Headers::from_reader(&mut encoded_output_buffer).expect("Failed to read header");
let mut decoded_output_buffer = Cursor::new(Vec::new());
let decode_info = decode(
header,
&mut encoded_output_buffer,
None,
&mut decoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Decoding failed");
assert_eq!(decode_info.original_size, original_content.len() as u64);
assert_eq!(decode_info.original_file_name, "test_file.txt");
assert_eq!(
decoded_output_buffer.into_inner(),
original_content.to_vec()
);
}
#[test]
fn test_encrypted_decoding() {
let original_content =
b"This is a secret message that should be encrypted and then decrypted.";
let mut input_reader = Cursor::new(original_content.to_vec());
let mut encoded_output_buffer = Cursor::new(Vec::new());
let password = "test_password_123";
let _encode_info = encode(
&mut input_reader,
"secret_file.txt",
Some(password),
&mut encoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Encoding failed");
encoded_output_buffer
.seek(SeekFrom::Start(0))
.expect("Failed to rewind");
let header =
Headers::from_reader(&mut encoded_output_buffer).expect("Failed to read header");
let mut decoded_output_buffer = Cursor::new(Vec::new());
let decode_info = decode(
header,
&mut encoded_output_buffer,
Some(password),
&mut decoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Decoding failed");
assert_eq!(decode_info.original_size, original_content.len() as u64);
assert_eq!(decode_info.original_file_name, "secret_file.txt");
assert_eq!(
decoded_output_buffer.into_inner(),
original_content.to_vec()
);
}
#[test]
fn test_encrypted_decoding_wrong_password() {
let original_content = b"This is a secret message.";
let mut input_reader = Cursor::new(original_content.to_vec());
let mut encoded_output_buffer = Cursor::new(Vec::new());
let correct_password = "correct_password";
let wrong_password = "wrong_password";
encode(
&mut input_reader,
"secret_file.txt",
Some(correct_password),
&mut encoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Encoding failed");
encoded_output_buffer
.seek(SeekFrom::Start(0))
.expect("Failed to rewind");
let header =
Headers::from_reader(&mut encoded_output_buffer).expect("Failed to read header");
let mut decoded_output_buffer = Cursor::new(Vec::new());
let result = decode(
header,
&mut encoded_output_buffer,
Some(wrong_password),
&mut decoded_output_buffer,
DEFAULT_CHUNK_SIZE,
);
assert!(result.is_err());
}
#[test]
fn test_raw_store_decoding() {
let original_content = b"\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF";
let mut input_reader = Cursor::new(original_content.to_vec());
let mut encoded_output_buffer = Cursor::new(Vec::new());
let _encode_info = encode(
&mut input_reader,
"binary_file.bin",
None,
&mut encoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Encoding failed");
encoded_output_buffer
.seek(SeekFrom::Start(0))
.expect("Failed to rewind");
let header =
Headers::from_reader(&mut encoded_output_buffer).expect("Failed to read header");
let mut decoded_output_buffer = Cursor::new(Vec::new());
let decode_info = decode(
header,
&mut encoded_output_buffer,
None,
&mut decoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Decoding failed");
assert_eq!(decode_info.original_size, original_content.len() as u64);
assert_eq!(
decoded_output_buffer.into_inner(),
original_content.to_vec()
);
}
#[test]
fn test_empty_file_decoding() {
let original_content = b"";
let mut input_reader = Cursor::new(original_content.to_vec());
let mut encoded_output_buffer = Cursor::new(Vec::new());
let _encode_info = encode(
&mut input_reader,
"empty_file.txt",
None,
&mut encoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Encoding failed");
encoded_output_buffer
.seek(SeekFrom::Start(0))
.expect("Failed to rewind");
let header =
Headers::from_reader(&mut encoded_output_buffer).expect("Failed to read header");
let mut decoded_output_buffer = Cursor::new(Vec::new());
let decode_info = decode(
header,
&mut encoded_output_buffer,
None,
&mut decoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Decoding failed");
assert_eq!(decode_info.original_size, 0);
assert_eq!(decode_info.original_file_name, "empty_file.txt");
assert_eq!(decoded_output_buffer.into_inner(), Vec::<u8>::new());
}
#[test]
fn test_invalid_magic_bytes() {
let mut invalid_header = Headers::default();
invalid_header.magic_bytes = [0x00, 0x00, 0x00, 0x00]; invalid_header.version = VERSION;
let mut fake_payload = Cursor::new(b"fake payload");
let mut output_buffer = Cursor::new(Vec::new());
let result = decode(
invalid_header,
&mut fake_payload,
None,
&mut output_buffer,
DEFAULT_CHUNK_SIZE,
);
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Not a valid .small file"));
}
#[test]
fn test_invalid_version() {
let mut invalid_header = Headers::default();
invalid_header.magic_bytes = MAGIC_BYTES;
invalid_header.version = 0xFF;
let mut fake_payload = Cursor::new(b"fake payload");
let mut output_buffer = Cursor::new(Vec::new());
let result = decode(
invalid_header,
&mut fake_payload,
None,
&mut output_buffer,
DEFAULT_CHUNK_SIZE,
);
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("Incorrect version"));
}
#[test]
fn test_missing_password_for_encrypted_file() {
let original_content = b"Encrypted content";
let mut input_reader = Cursor::new(original_content.to_vec());
let mut encoded_output_buffer = Cursor::new(Vec::new());
encode(
&mut input_reader,
"encrypted_file.txt",
Some("password"),
&mut encoded_output_buffer,
DEFAULT_CHUNK_SIZE,
)
.expect("Encoding failed");
encoded_output_buffer
.seek(SeekFrom::Start(0))
.expect("Failed to rewind");
let header =
Headers::from_reader(&mut encoded_output_buffer).expect("Failed to read header");
let mut decoded_output_buffer = Cursor::new(Vec::new());
let result = decode(
header,
&mut encoded_output_buffer,
None, &mut decoded_output_buffer,
DEFAULT_CHUNK_SIZE,
);
assert!(result.is_err());
assert!(result
.unwrap_err()
.to_string()
.contains("password required"));
}
#[test]
fn test_decoding_with_different_chunk_sizes() {
let original_content = b"Test content for different chunk sizes during decoding.";
let chunk_sizes = [1024, 4096, 16384, 65536];
for chunk_size in chunk_sizes.iter() {
let mut input_reader = Cursor::new(original_content.to_vec());
let mut encoded_output_buffer = Cursor::new(Vec::new());
let encode_info = encode(
&mut input_reader,
"chunk_test.txt",
None,
&mut encoded_output_buffer,
*chunk_size,
)
.expect("Encoding failed");
encoded_output_buffer
.seek(SeekFrom::Start(0))
.expect("Failed to rewind");
let header =
Headers::from_reader(&mut encoded_output_buffer).expect("Failed to read header");
let mut decoded_output_buffer = Cursor::new(Vec::new());
let decode_info = decode(
header,
&mut encoded_output_buffer,
None,
&mut decoded_output_buffer,
*chunk_size,
)
.expect("Decoding failed");
assert_eq!(encode_info.original_size, decode_info.original_size);
assert_eq!(
decoded_output_buffer.into_inner(),
original_content.to_vec()
);
}
}
}