use std::fs::read;
use rustls_acme::CertCache;
use crate::{
config::Path,
server::{self, PathTree, read_paths},
};
#[test]
fn test_path_tree() {
let _ = pretty_env_logger::try_init();
let mut paths = Vec::new();
paths.push(Path::new("/test/path/one/two", "a location"));
paths.push(Path::new("/test/path/one/one", "a location"));
paths.push(Path::new("/test/path/other", "a location"));
paths.push(Path::new("/different/path/", "a location"));
let read = read_paths(&paths);
println!("res: {:#?}", read);
match &read[0] {
PathTree::Group(paths) => {
assert_eq!(paths.path, "/test/path/");
assert_eq!(paths.children.len(), 2);
match &paths.children[0] {
PathTree::Path(path) => {
assert_eq!(path.path, "other");
}
_ => panic!("wrong conversion"),
}
match &paths.children[1] {
PathTree::Group(up) => {
assert_eq!(up.path, "one/");
assert_eq!(up.children.len(), 2);
}
_ => panic!("wrong conversion"),
}
}
_ => panic!("wrong conversion"),
}
match &read[1] {
PathTree::Path(path) => {
assert_eq!(path.path, "/different/path/");
}
_ => panic!("wrong conversion"),
}
}
#[test]
fn test_path_tree_double_jump() {
let _ = pretty_env_logger::try_init();
let mut paths = Vec::new();
paths.push(Path::new("/test/path/other", "a location"));
paths.push(Path::new("/test/path/one/two", "a location"));
paths.push(Path::new("/test/path/one/one", "a location"));
paths.push(Path::new("/test/one", "a location"));
let read = read_paths(&paths);
println!("res: {:#?}", read);
match &read[0] {
PathTree::Group(paths) => {
assert_eq!(paths.path, "/test/");
assert_eq!(paths.children.len(), 2);
match &paths.children[0] {
PathTree::Group(up) => {
assert_eq!(up.path, "path/");
assert_eq!(up.children.len(), 2);
}
_ => panic!("wrong conversion"),
}
match &paths.children[1] {
PathTree::Path(path) => {
assert_eq!(path.path, "one");
}
_ => panic!("wrong conversion"),
}
}
_ => panic!("wrong conversion"),
}
}
#[test]
fn test_path_tree_simple_one_after_the_other() {
let _ = pretty_env_logger::try_init();
let mut paths = Vec::new();
paths.push(Path::new("/test/one/", "a location"));
paths.push(Path::new("/test", "a location"));
paths.push(Path::new("/other", "a location"));
let read = read_paths(&paths);
println!("res: {:#?}", read);
match &read[0] {
PathTree::Group(paths) => {
assert_eq!(paths.path, "/test");
assert_eq!(paths.children.len(), 2);
match &paths.children[0] {
PathTree::Path(up) => {
assert_eq!(up.path, "/one/");
}
_ => panic!("wrong conversion"),
}
match &paths.children[1] {
PathTree::Path(path) => {
assert_eq!(path.path, "");
}
_ => panic!("wrong conversion"),
}
}
_ => panic!("wrong conversion"),
}
match &read[1] {
PathTree::Path(path) => {
assert_eq!(path.path, "/other");
}
_ => panic!("wrong conversion"),
}
}
#[actix_rt::test]
async fn test_cert_read_write() {
use server::FilesCache;
let cache = FilesCache::new("target/certs").unwrap();
let data = read("./fixtures/all.pem").unwrap();
let domains = ["example.com".to_owned()];
let pem_blocks = pem::parse_many(&data).unwrap();
let mut cert_pems = Vec::new();
let mut key_pem = None;
for pem in &pem_blocks {
match pem.tag() {
"CERTIFICATE" => cert_pems.push(pem.clone()),
"PRIVATE KEY" | "RSA PRIVATE KEY" | "EC PRIVATE KEY" => {
if key_pem.is_none() {
key_pem = Some(pem.clone());
}
}
_ => {} }
}
cache.store_cert(&domains, "example.com", &data).await.unwrap();
let read = cache.load_cert(&domains, "example.com").await.unwrap();
match read {
Some(cert_data) => {
assert_eq!(
String::from_utf8(data),
String::from_utf8(cert_data),
"Read cert data should exactly match stored data"
);
}
None => {
panic!("Failed to read cert after storing");
}
}
}
#[actix_rt::test]
async fn test_domain_links_creation() {
use server::FilesCache;
use std::fs;
use std::path::Path;
let test_dir = "target/certs_test_links";
let cache = FilesCache::new(test_dir).unwrap();
let data = read("./fixtures/all.pem").unwrap();
let domains = vec!["example.com".to_owned(), "www.example.com".to_owned()];
if Path::new(test_dir).exists() {
fs::remove_dir_all(test_dir).unwrap();
}
cache.store_cert(&domains, "example.com", &data).await.unwrap();
for domain in &domains {
let link_path = Path::new(test_dir).join(domain);
assert!(link_path.is_symlink(), "Path should be a symbolic link: {}", domain);
let link_target = fs::read_link(&link_path).unwrap();
let cert_dir = if link_target.is_absolute() {
link_target.clone()
} else {
Path::new(test_dir).join(&link_target)
};
assert!(cert_dir.exists(), "Link target should exist: {}", cert_dir.display());
assert!(
cert_dir.join("fullchain.pem").exists(),
"fullchain.pem should exist in cert directory"
);
assert!(
cert_dir.join("privkey.pem").exists(),
"privkey.pem should exist in cert directory"
);
}
let domains2 = vec!["newdomain.com".to_owned()];
cache.store_cert(&domains2, "newdomain.com", &data).await.unwrap();
let new_link_path = Path::new(test_dir).join("newdomain.com");
assert!(new_link_path.exists(), "New domain link should exist");
assert!(new_link_path.is_symlink(), "New domain path should be a symbolic link");
fs::remove_dir_all(test_dir).unwrap();
}