Add tests for all but the content syntax parser module
This commit is contained in:
parent
f48b2070bc
commit
e657eb6513
17 changed files with 1072 additions and 127 deletions
|
|
@ -56,3 +56,33 @@ pub async fn not_found() -> Response<Body> {
|
|||
Some("The page you tried to access could not be found."),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use axum::{
|
||||
http::{StatusCode},
|
||||
};
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn not_found() {
|
||||
let response = super::not_found().await;
|
||||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn internal_error() {
|
||||
assert!(by_code(Some(201), None).status() == 201);
|
||||
assert!(by_code(Some(304), None).status() == 304);
|
||||
assert!(by_code(Some(418), None).status() == 418);
|
||||
assert!(by_code(Some(505), None).status() == 505);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_message() {
|
||||
let pattern = "sibPtt0mvHPWS9HQ0YBQfGu8cUs954LZ";
|
||||
let body = make_body(Some(501), Some(pattern));
|
||||
assert!(body.contains(pattern));
|
||||
assert!(!body.contains(&pattern.chars().rev().collect::<String>()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,7 @@ pub async fn file(file_path: &str, content_type: &str) -> Response<Body> {
|
|||
let header = header::CONTENT_TYPE;
|
||||
|
||||
if let Ok(header_value) = HeaderValue::from_str(content_type) {
|
||||
if let Some(h) = response.headers_mut().insert(header, header_value) {
|
||||
log!(
|
||||
"Overwrote existing header {h:?} because a header for the same key existed"
|
||||
);
|
||||
}
|
||||
response.headers_mut().append(header, header_value);
|
||||
} else {
|
||||
log!("Failed to create content type header value from {content_type}");
|
||||
}
|
||||
|
|
@ -43,15 +39,70 @@ pub async fn serial(format: &Format) -> Response<Body> {
|
|||
let body = serialize_graph(format, &graph);
|
||||
|
||||
match *format {
|
||||
Format::Toml => handlers::raw::make_response(
|
||||
Format::TOML => handlers::raw::make_response(
|
||||
&body,
|
||||
200,
|
||||
&[(header::CONTENT_TYPE, "text/plain")],
|
||||
),
|
||||
Format::Json => handlers::raw::make_response(
|
||||
Format::JSON => handlers::raw::make_response(
|
||||
&body,
|
||||
200,
|
||||
&[(header::CONTENT_TYPE, "application/json")],
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn serial_toml() {
|
||||
let response = serial(&Format::TOML).await;
|
||||
assert!(response.status() == 200);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn serial_toml_content_type() {
|
||||
let response = serial(&Format::TOML).await;
|
||||
assert!(
|
||||
response.headers().get(header::CONTENT_TYPE).unwrap()
|
||||
== "text/plain"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn serial_json_content_type() {
|
||||
let response = serial(&Format::JSON).await;
|
||||
assert!(
|
||||
response.headers().get(header::CONTENT_TYPE).unwrap()
|
||||
== "application/json"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn file_valid_header() {
|
||||
let payload = "y1mgMhjeIMFsRNZ1tskP52DfWuvhvbRP";
|
||||
let response = file("./static/graph.toml", payload).await;
|
||||
assert_eq!(
|
||||
response.headers().get(header::CONTENT_TYPE).unwrap(),
|
||||
payload
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn file_invalid_header() {
|
||||
let response = file("./static/graph.toml", "\n").await;
|
||||
println!("{response:#?}");
|
||||
assert!(response.headers().get(header::CONTENT_TYPE).is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[should_panic(
|
||||
expected = "Failed to read IvnhZhdHb1xDnUw4hYDDNIERoaOojkiu \
|
||||
contents: No such file or directory (os error 2)"
|
||||
)]
|
||||
async fn file_invalid_path() {
|
||||
drop(file("IvnhZhdHb1xDnUw4hYDDNIERoaOojkiu", "text/plain").await);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,3 +40,44 @@ pub async fn node(Path(id): Path<String>) -> Response<Body> {
|
|||
not_found,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use axum::{
|
||||
http::{HeaderName, StatusCode},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn syntax() {
|
||||
let response = node(Path("Syntax".to_string())).await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn syntax_content_type() {
|
||||
let response = node(Path("Syntax".to_string())).await;
|
||||
assert!(
|
||||
response
|
||||
.headers()
|
||||
.get(HeaderName::from_static("content-type"),)
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
== "text/html"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn not_found() {
|
||||
let response = node(Path("InexistentNode".to_string())).await;
|
||||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn redirect() {
|
||||
let response = node(Path("syntax".to_string())).await;
|
||||
assert_eq!(response.status(), StatusCode::PERMANENT_REDIRECT);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,3 +29,38 @@ pub async fn search(Form(query): Form<Query>) -> Redirect {
|
|||
pub struct Query {
|
||||
node: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use axum::{
|
||||
http::{StatusCode},
|
||||
};
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn search_redirect() {
|
||||
let query = Form(Query {
|
||||
node: String::from("duZzBrgCzMhVY15wehxasezsGNatOKIq"),
|
||||
});
|
||||
let response = search(query).await;
|
||||
assert!(response.status_code() == StatusCode::PERMANENT_REDIRECT);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn about_page_ok() {
|
||||
let response = page("about.html").await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn tree_page_ok() {
|
||||
let response = page("tree.html").await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn inexistent_page_error() {
|
||||
let response = page("HBvcwqT8wLk6hxk1GdvNcEzJ6IiZ2Fod").await;
|
||||
assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,39 @@ pub(in crate::router::handlers) fn make_response(
|
|||
);
|
||||
}
|
||||
} else {
|
||||
log!("Failed to wrap header value {}", header.1);
|
||||
log!("Failed to create header value from {}", header.1);
|
||||
}
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn repeated_header() {
|
||||
let headers = [
|
||||
(header::ACCEPT, "Not really"),
|
||||
(header::ACCEPT, "This again?"),
|
||||
];
|
||||
let response = make_response("", 418, &headers);
|
||||
assert!(response.headers().get_all(header::ACCEPT).iter().count() == 1);
|
||||
assert_eq!(
|
||||
response
|
||||
.headers()
|
||||
.get(header::ACCEPT)
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
"This again?",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_header() {
|
||||
let response = make_response("", 418, &[(header::MAX_FORWARDS, "\n")]);
|
||||
assert!(response.headers().get(header::MAX_FORWARDS).is_none());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,9 @@ pub(in crate::router::handlers) fn render(
|
|||
error_message: Option<String>,
|
||||
) -> (String, u16) {
|
||||
// TODO just return an Option/String> here
|
||||
let tera = match tera::Tera::new(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/templates/**/*"
|
||||
)) {
|
||||
let tera = match tera::Tera::new("./templates/**/*") {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
let early_error_message = format!("{e:#?}");
|
||||
log!("{}", early_error_message);
|
||||
return (emergency_wrap(&e), 500);
|
||||
},
|
||||
};
|
||||
|
|
@ -73,7 +68,8 @@ pub(in crate::router::handlers) fn render(
|
|||
}
|
||||
}
|
||||
|
||||
fn emergency_wrap(message: &tera::Error) -> String {
|
||||
fn emergency_wrap(error: &tera::Error) -> String {
|
||||
log!("{error:#?}");
|
||||
format!(
|
||||
r#"<!DOCTYPE html>
|
||||
<html>
|
||||
|
|
@ -93,7 +89,7 @@ fn emergency_wrap(message: &tera::Error) -> String {
|
|||
<h2><strong>Early Pre-Templating Error</strong></h2>
|
||||
<p>This normally indicates a malformed template.</p>
|
||||
<pre>
|
||||
{message}
|
||||
{error:#?}
|
||||
</pre>
|
||||
<p>
|
||||
If you haven't modified templates, plese consider
|
||||
|
|
@ -104,3 +100,104 @@ fn emergency_wrap(message: &tera::Error) -> String {
|
|||
"#
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn by_filename_forced_error() {
|
||||
let response =
|
||||
by_filename("index.html", &tera::Context::new(), 418, None, true);
|
||||
assert_eq!(response.status(), 418);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn by_filename_index() {
|
||||
let response =
|
||||
by_filename("index.html", &tera::Context::new(), 418, None, false);
|
||||
assert_eq!(response.status(), 200);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn by_filename_file_not_found() {
|
||||
let response = by_filename(
|
||||
"bwbl3BnWsluIgbO2NV9t3vtihwcjuF6t",
|
||||
&tera::Context::new(),
|
||||
418,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
assert_eq!(response.status(), 500);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn by_filename_empty() {
|
||||
let response = by_filename("", &tera::Context::new(), 418, None, false);
|
||||
assert_eq!(response.status(), 500);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_with_context() {
|
||||
let payload = "dBgIw8DnNHxJojiXzu445qUC4UpxwZCy";
|
||||
let mut context = tera::Context::new();
|
||||
let node = crate::types::Node::new(Some(payload.to_string()));
|
||||
let graph = crate::syntax::serial::populate_graph();
|
||||
context.insert("node", &node);
|
||||
context.insert("text", &crate::syntax::content::parse(&node.text));
|
||||
context.insert("incoming", &graph.incoming.get(&node.id));
|
||||
context.insert("config", &graph.meta.config.parse_text());
|
||||
let (body, status) = render("node.html", &context, None);
|
||||
assert_eq!(status, 200);
|
||||
assert!(body.matches(payload).count() == 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_custom_error_message() {
|
||||
let payload = "dBgIw8DnNHxJojiXzu445qUC4UpxwZCy";
|
||||
let (body, status) = render(
|
||||
"ObH9jYUl4wMhUNcXnuqwVVzHoqx4ufyN",
|
||||
&tera::Context::new(),
|
||||
Some(payload.to_string()),
|
||||
);
|
||||
assert_eq!(status, 500);
|
||||
assert!(body.matches(payload).count() == 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_empty() {
|
||||
let (body, status) = render(
|
||||
"R8D1pxwHZDxcH5SMjR7rZEnIzmpkiHkH",
|
||||
&tera::Context::new(),
|
||||
None,
|
||||
);
|
||||
assert_eq!(status, 500);
|
||||
assert!(body.matches("Template render failed").count() == 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_not_found() {
|
||||
let payload = "OL6kb9qHe7Iwr7wFIRKUTeFhF34BRsQo";
|
||||
let (body, status) = render(payload, &tera::Context::new(), None);
|
||||
|
||||
assert!(body.matches("TemplateNotFound").count() > 0);
|
||||
assert!(body.matches(payload).count() > 0);
|
||||
assert_eq!(status, 500);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_bad_context() {
|
||||
let (body, status) = render("node.html", &tera::Context::new(), None);
|
||||
assert!(body.matches("Template render failed.").count() > 0);
|
||||
assert_eq!(status, 500);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn emergency_wrap_custom_message() {
|
||||
let payload = "JLaTtsnd2IFukIOvqFNymeuiaS6nMaUc";
|
||||
let error = tera::Error::msg(payload);
|
||||
let html = emergency_wrap(&error);
|
||||
assert!(html.matches(payload).count() == 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue