ptth/crates/ptth_server/src/file_server/tests.rs

232 lines
5.9 KiB
Rust

use std::{
ffi::OsStr,
path::{
Component,
Path,
},
};
use maplit::*;
use tokio::runtime::Runtime;
#[test]
fn icons () {
let video = "🎞️";
let picture = "📷";
let file = "📄";
for (input, expected) in vec! [
("copying_is_not_theft.mp4", video),
("copying_is_not_theft.avi", video),
("copying_is_not_theft.mkv", video),
("copying_is_not_theft.webm", video),
("lolcats.jpg", picture),
("lolcats.jpeg", picture),
("lolcats.png", picture),
("lolcats.bmp", picture),
("ptth.log", file),
("README.md", file),
("todo.txt", file),
].into_iter () {
assert_eq! (super::get_icon (input), expected);
}
}
#[test]
fn parse_range_header () {
for (input, expected) in vec! [
("", (None, None)),
("bytes=0-", (Some (0), None)),
("bytes=0-999", (Some (0), Some (1000))),
("bytes=111-999", (Some (111), Some (1000))),
].into_iter () {
let actual = super::parse_range_header (input);
assert_eq! (actual, expected);
}
use super::ParsedRange::*;
for (header, file_len, expected) in vec! [
(None, 0, Ok (0..0)),
(None, 1024, Ok (0..1024)),
(Some (""), 0, RangeNotSatisfiable (0)),
(Some (""), 1024, PartialContent (0..1024)),
(Some ("bytes=0-"), 1024, PartialContent (0..1024)),
(Some ("bytes=0-999"), 1024, PartialContent (0..1000)),
(Some ("bytes=0-1023"), 1024, PartialContent (0..1024)),
(Some ("bytes=111-999"), 1024, PartialContent (111..1000)),
(Some ("bytes=111-1023"), 1024, PartialContent (111..1024)),
(Some ("bytes=200-100"), 1024, RangeNotSatisfiable (1024)),
(Some ("bytes=0-"), 512, PartialContent (0..512)),
(Some ("bytes=0-1023"), 512, RangeNotSatisfiable (512)),
(Some ("bytes=1000-1023"), 512, RangeNotSatisfiable (512)),
].into_iter () {
let actual = super::check_range (header, file_len);
assert_eq! (actual, expected);
}
}
#[test]
fn pretty_print_bytes () {
for (input_after, expected_before, expected_after) in vec! [
(1, "0 B", "1 B"),
(1024, "1023 B", "1 KiB"),
(1024 + 512, "1 KiB", "2 KiB"),
(1023 * 1024 + 512, "1023 KiB", "1 MiB"),
((1024 + 512) * 1024, "1 MiB", "2 MiB"),
(1023 * 1024 * 1024 + 512 * 1024, "1023 MiB", "1 GiB"),
((1024 + 512) * 1024 * 1024, "1 GiB", "2 GiB"),
].into_iter () {
let actual = super::pretty_print_bytes (input_after - 1);
assert_eq! (&actual, expected_before);
let actual = super::pretty_print_bytes (input_after);
assert_eq! (&actual, expected_after);
}
}
#[test]
fn i_hate_paths () {
let mut components = Path::new ("/home/user").components ();
assert_eq! (components.next (), Some (Component::RootDir));
assert_eq! (components.next (), Some (Component::Normal (OsStr::new ("home"))));
assert_eq! (components.next (), Some (Component::Normal (OsStr::new ("user"))));
assert_eq! (components.next (), None);
let mut components = Path::new ("./home/user").components ();
assert_eq! (components.next (), Some (Component::CurDir));
assert_eq! (components.next (), Some (Component::Normal (OsStr::new ("home"))));
assert_eq! (components.next (), Some (Component::Normal (OsStr::new ("user"))));
assert_eq! (components.next (), None);
let mut components = Path::new (".").components ();
assert_eq! (components.next (), Some (Component::CurDir));
assert_eq! (components.next (), None);
}
#[test]
fn file_server () {
use ptth_core::{
http_serde::Method,
};
use super::*;
tracing_subscriber::fmt ().try_init ().ok ();
let mut rt = Runtime::new ().expect ("Can't create runtime");
rt.block_on (async {
let file_server_root = PathBuf::from ("./");
let headers = Default::default ();
{
use InternalResponse::*;
use crate::file_server::FileServerError;
let bad_passwords_path = "/files/src/bad_passwords.txt";
for (uri_path, expected) in vec! [
("/", Root),
("/files", Redirect ("files/".to_string ())),
("/files/?", InvalidQuery),
("/files/src", Redirect ("src/".to_string ())),
("/files/src/?", InvalidQuery),
(bad_passwords_path, ServeFile (ServeFileParams {
send_body: true,
range: 0..1_048_576,
range_requested: false,
file: AlwaysEqual::testing_blank (),
})),
("/files/test/test.md", ServeFile (ServeFileParams {
send_body: true,
range: 0..144,
range_requested: false,
file: AlwaysEqual::testing_blank (),
})),
] {
let resp = internal_serve_all (
&file_server_root,
Method::Get,
uri_path,
&headers,
None
).await;
assert_eq! (resp.expect ("This block only tests Ok (_) responses"), expected);
}
for (uri_path, checker) in vec! [
("/ ", |e| match e {
FileServerError::InvalidUri (_) => (),
e => panic! ("Expected InvalidUri, got {:?}", e),
}),
] {
let resp = internal_serve_all (
&file_server_root,
Method::Get,
uri_path,
&headers,
None
).await;
checker (resp.unwrap_err ());
}
let resp = internal_serve_all (
&file_server_root,
Method::Get,
bad_passwords_path,
&hashmap! {
"range".into () => b"bytes=0-2000000".to_vec (),
},
None
).await;
assert_eq! (resp.expect ("Should be Ok (_)"), RangeNotSatisfiable (1_048_576));
let resp = internal_serve_all (
&file_server_root,
Method::Head,
bad_passwords_path,
&headers,
None
).await;
assert_eq! (resp.expect ("Should be Ok (_)"), ServeFile (ServeFileParams {
send_body: false,
range: 0..1_048_576,
range_requested: false,
file: AlwaysEqual::testing_blank (),
}));
}
});
}
#[test]
fn parse_uri () {
assert! (http::Uri::from_maybe_shared ("/").is_ok ());
}
#[test]
fn markdown () {
use super::*;
for (input, expected) in vec! [
("", ""),
(
"Hello world, this is a ~~complicated~~ *very simple* example.",
"<p>Hello world, this is a <del>complicated</del> <em>very simple</em> example.</p>\n"
),
].into_iter () {
let mut out = String::default ();
render_markdown (input.as_bytes (), &mut out).expect ("Markdown sample failed");
assert_eq! (expected, &out);
}
}