Further centralize state, return result from serial methods
This commit is contained in:
parent
93c62229ad
commit
c23d35217d
15 changed files with 471 additions and 244 deletions
|
|
@ -1,18 +1,23 @@
|
|||
use axum::{
|
||||
body::Body,
|
||||
extract::State,
|
||||
http::{Response, StatusCode, header},
|
||||
};
|
||||
|
||||
use crate::{graph::Graph, router::handlers};
|
||||
use crate::{
|
||||
graph::Graph,
|
||||
router::{GlobalState, handlers},
|
||||
};
|
||||
|
||||
pub(in crate::router::handlers) fn by_code(
|
||||
code: Option<u16>,
|
||||
message: Option<&str>,
|
||||
graph: &Graph,
|
||||
) -> Response<Body> {
|
||||
let out_code = code.unwrap_or(500);
|
||||
let out_message = &message.unwrap_or("Unknown error");
|
||||
|
||||
let body = make_body(Some(out_code), Some(out_message));
|
||||
let body = make_body(Some(out_code), Some(out_message), graph);
|
||||
|
||||
handlers::raw::make_response(
|
||||
&body,
|
||||
|
|
@ -21,10 +26,13 @@ pub(in crate::router::handlers) fn by_code(
|
|||
)
|
||||
}
|
||||
|
||||
fn make_body(code: Option<u16>, message: Option<&str>) -> String {
|
||||
fn make_body(
|
||||
code: Option<u16>,
|
||||
message: Option<&str>,
|
||||
graph: &Graph,
|
||||
) -> String {
|
||||
let mut context = tera::Context::default();
|
||||
|
||||
let graph = Graph::load();
|
||||
let out_code = code.unwrap_or(500);
|
||||
let out_message = &message.unwrap_or("Unknown error");
|
||||
|
||||
|
|
@ -35,12 +43,12 @@ fn make_body(code: Option<u16>, message: Option<&str>) -> String {
|
|||
.to_string(),
|
||||
);
|
||||
|
||||
context.insert("graph", &graph);
|
||||
context.insert("graph", graph);
|
||||
context.insert("message", out_message);
|
||||
context.insert("status_code", &out_code.to_string());
|
||||
|
||||
handlers::template::render(
|
||||
"error.html",
|
||||
"error",
|
||||
&context,
|
||||
Some(&format!(
|
||||
"Failed to render template for Error {out_code}: {out_message}"
|
||||
|
|
@ -50,10 +58,11 @@ fn make_body(code: Option<u16>, message: Option<&str>) -> String {
|
|||
.0
|
||||
}
|
||||
|
||||
pub async fn not_found() -> Response<Body> {
|
||||
pub async fn not_found(State(state): State<GlobalState>) -> Response<Body> {
|
||||
by_code(
|
||||
Some(404),
|
||||
Some("The page you tried to access could not be found."),
|
||||
&state.graph,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -61,27 +70,32 @@ pub async fn not_found() -> Response<Body> {
|
|||
mod tests {
|
||||
use axum::{
|
||||
http::{StatusCode},
|
||||
extract::State,
|
||||
};
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn not_found() {
|
||||
let response = super::not_found().await;
|
||||
let state = State(GlobalState {
|
||||
graph: Graph::load(),
|
||||
});
|
||||
let response = super::not_found(state).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);
|
||||
let graph = Graph::load();
|
||||
assert!(by_code(Some(201), None, &graph).status() == 201);
|
||||
assert!(by_code(Some(304), None, &graph).status() == 304);
|
||||
assert!(by_code(Some(418), None, &graph).status() == 418);
|
||||
assert!(by_code(Some(505), None, &graph).status() == 505);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_message() {
|
||||
let pattern = "sibPtt0mvHPWS9HQ0YBQfGu8cUs954LZ";
|
||||
let body = make_body(Some(501), Some(pattern));
|
||||
let body = make_body(Some(501), Some(pattern), &Graph::load());
|
||||
assert!(body.contains(pattern));
|
||||
assert!(!body.contains(&pattern.chars().rev().collect::<String>()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
use axum::{
|
||||
body::Body,
|
||||
http::{Response, StatusCode, header, HeaderValue},
|
||||
extract::{Path, State},
|
||||
http::{HeaderValue, Response, StatusCode, header},
|
||||
};
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::{
|
||||
router::handlers,
|
||||
graph::{Graph, Format},
|
||||
graph::{Format, Graph, SerialErrorCause},
|
||||
router::{GlobalState, handlers},
|
||||
};
|
||||
|
||||
/// # Panics
|
||||
|
|
@ -41,22 +42,68 @@ pub async fn file(file_path: &str, content_type: &str) -> Response<Body> {
|
|||
response
|
||||
}
|
||||
|
||||
#[expect(clippy::unused_async)]
|
||||
pub async fn serial(format: &Format) -> Response<Body> {
|
||||
let graph = Graph::load();
|
||||
let body = Graph::to_serial(&graph, format);
|
||||
pub async fn serial(
|
||||
Path(format): Path<String>,
|
||||
State(state): State<GlobalState>,
|
||||
) -> Response<Body> {
|
||||
let config = &state.graph.meta.config;
|
||||
|
||||
match *format {
|
||||
Format::TOML => handlers::raw::make_response(
|
||||
&body,
|
||||
200,
|
||||
&[(header::CONTENT_TYPE, "text/plain")],
|
||||
),
|
||||
Format::JSON => handlers::raw::make_response(
|
||||
&body,
|
||||
200,
|
||||
&[(header::CONTENT_TYPE, "application/json")],
|
||||
),
|
||||
let make_error = |code: u16, message: &str| -> Response<Body> {
|
||||
handlers::error::by_code(
|
||||
Some(code),
|
||||
Some(
|
||||
format!(
|
||||
"<p>{message}</p>\n\
|
||||
<p>Check the <a href=/data>data</a> \n\
|
||||
page for the available formats.</p>"
|
||||
)
|
||||
.as_str(),
|
||||
),
|
||||
&state.graph,
|
||||
)
|
||||
};
|
||||
|
||||
let forbidden_response =
|
||||
make_error(403, "This graph format is not available.");
|
||||
let unsupported_response =
|
||||
make_error(400, "This graph format is not supported.");
|
||||
let parse_failure = make_error(505, "The graph has failed to parse.");
|
||||
|
||||
let body =
|
||||
match Graph::to_serial(&state.graph, &Format::from(format.as_str())) {
|
||||
Ok(serial) => serial,
|
||||
Err(error) => match error.cause {
|
||||
SerialErrorCause::MalformedInput => return parse_failure,
|
||||
SerialErrorCause::UnsupportedFormat => {
|
||||
return unsupported_response;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
match Format::from(format.as_str()) {
|
||||
Format::TOML => {
|
||||
if config.raw && config.raw_toml {
|
||||
handlers::raw::make_response(
|
||||
&body,
|
||||
200,
|
||||
&[(header::CONTENT_TYPE, "text/plain")],
|
||||
)
|
||||
} else {
|
||||
forbidden_response
|
||||
}
|
||||
},
|
||||
Format::JSON => {
|
||||
if config.raw && config.raw_json {
|
||||
handlers::raw::make_response(
|
||||
&body,
|
||||
200,
|
||||
&[(header::CONTENT_TYPE, "application/json")],
|
||||
)
|
||||
} else {
|
||||
forbidden_response
|
||||
}
|
||||
},
|
||||
Format::Unsupported => unsupported_response,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,15 +111,28 @@ pub async fn serial(format: &Format) -> Response<Body> {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
async fn wrap_serial(format: &str) -> Response<Body> {
|
||||
let state = GlobalState {
|
||||
graph: Graph::load(),
|
||||
};
|
||||
serial(Path(format.to_string()), State(state)).await
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn serial_toml() {
|
||||
let response = serial(&Format::TOML).await;
|
||||
let response = wrap_serial("toml").await;
|
||||
assert!(response.status() == 200);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn serial_json() {
|
||||
let response = wrap_serial("json").await;
|
||||
assert!(response.status() == 200);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn serial_toml_content_type() {
|
||||
let response = serial(&Format::TOML).await;
|
||||
let response = wrap_serial("TOML").await;
|
||||
assert!(
|
||||
response.headers().get(header::CONTENT_TYPE).unwrap()
|
||||
== "text/plain"
|
||||
|
|
@ -81,7 +141,7 @@ mod tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn serial_json_content_type() {
|
||||
let response = serial(&Format::JSON).await;
|
||||
let response = wrap_serial("json").await;
|
||||
assert!(
|
||||
response.headers().get(header::CONTENT_TYPE).unwrap()
|
||||
== "application/json"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
use axum::response::IntoResponse as _;
|
||||
use axum::{body::Body, extract::Path, http::Response, response::Redirect};
|
||||
use axum::{
|
||||
extract::State,
|
||||
response::IntoResponse as _,
|
||||
{body::Body, extract::Path, http::Response, response::Redirect},
|
||||
};
|
||||
|
||||
use crate::{prelude::*, graph::Graph, router::handlers, graph::Node};
|
||||
use crate::{
|
||||
graph::Node,
|
||||
prelude::*,
|
||||
router::{GlobalState, handlers},
|
||||
};
|
||||
|
||||
pub async fn node(Path(id): Path<String>) -> Response<Body> {
|
||||
pub async fn node(
|
||||
Path(id): Path<String>,
|
||||
State(state): State<GlobalState>,
|
||||
) -> Response<Body> {
|
||||
let instant = now();
|
||||
let graph = Graph::load();
|
||||
let result = graph.find_node(&id);
|
||||
let result = state.graph.find_node(&id);
|
||||
let found = result.node.is_some();
|
||||
let node = result
|
||||
.node
|
||||
|
|
@ -25,20 +34,19 @@ pub async fn node(Path(id): Path<String>) -> Response<Body> {
|
|||
}
|
||||
|
||||
let mut context = tera::Context::default();
|
||||
context.insert("graph", &graph);
|
||||
context.insert("graph", &state.graph);
|
||||
context.insert("node", &node);
|
||||
context.insert("incoming", &graph.incoming.get(&id));
|
||||
context.insert("incoming", &state.graph.incoming.get(&id));
|
||||
|
||||
tlog!(&instant, "Assembled response for node {}", node.id);
|
||||
handlers::template::by_filename(
|
||||
"node.html",
|
||||
handlers::template::with_context(
|
||||
"node",
|
||||
&context,
|
||||
if found { 500 } else { 404 },
|
||||
Some(
|
||||
format!(
|
||||
"Failed to generate page for node {} (ID {}).\n\
|
||||
Node struct: <pre>{:#?}</pre>",
|
||||
node.title, id, node
|
||||
"Failed to generate page for node {} (ID {}).",
|
||||
node.title, id
|
||||
)
|
||||
.to_owned(),
|
||||
),
|
||||
|
|
@ -52,17 +60,26 @@ mod tests {
|
|||
http::{HeaderName, StatusCode},
|
||||
};
|
||||
|
||||
use crate::graph::Graph;
|
||||
|
||||
use super::*;
|
||||
|
||||
async fn wrap_node(query: &str) -> Response<Body> {
|
||||
let state = GlobalState {
|
||||
graph: Graph::load(),
|
||||
};
|
||||
node(Path(query.to_string()), axum::extract::State(state)).await
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn syntax() {
|
||||
let response = node(Path("Syntax".to_string())).await;
|
||||
let response = wrap_node("Syntax").await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn syntax_content_type() {
|
||||
let response = node(Path("Syntax".to_string())).await;
|
||||
let response = wrap_node("Syntax").await;
|
||||
assert!(
|
||||
response
|
||||
.headers()
|
||||
|
|
@ -76,19 +93,19 @@ mod tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn not_found() {
|
||||
let response = node(Path("InexistentNode".to_string())).await;
|
||||
let response = wrap_node("InexistentNode").await;
|
||||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn redirect() {
|
||||
let response = node(Path("syntax".to_string())).await;
|
||||
let response = wrap_node("syntax").await;
|
||||
assert_eq!(response.status(), StatusCode::PERMANENT_REDIRECT);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn docs_redirect() {
|
||||
let response = node(Path("docs".to_string())).await;
|
||||
let response = wrap_node("docs").await;
|
||||
assert_eq!(response.status(), StatusCode::PERMANENT_REDIRECT);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,67 +1,45 @@
|
|||
use axum::{
|
||||
body::Body,
|
||||
http::{Response},
|
||||
response::Redirect,
|
||||
Form,
|
||||
};
|
||||
use axum::{Form, body::Body, extract::State, http::Response, response::Redirect};
|
||||
|
||||
use crate::{
|
||||
prelude::*,
|
||||
graph::{Graph, Node},
|
||||
router::handlers,
|
||||
router::{GlobalState, handlers},
|
||||
};
|
||||
|
||||
#[expect(clippy::unused_async)]
|
||||
pub async fn page(template: &str) -> Response<Body> {
|
||||
let instant = now();
|
||||
let mut context = tera::Context::default();
|
||||
let graph = Graph::load();
|
||||
|
||||
context.insert("graph", &graph);
|
||||
|
||||
tlog!(&instant, "Assembled response for template {template}");
|
||||
handlers::template::by_filename(template, &context, 500, None, false)
|
||||
pub async fn index(State(state): State<GlobalState>) -> Response<Body> {
|
||||
handlers::template::with_graph("index", state).await
|
||||
}
|
||||
|
||||
pub async fn tree() -> Response<Body> {
|
||||
let instant = now();
|
||||
let mut context = tera::Context::default();
|
||||
let mut graph = Graph::load();
|
||||
pub async fn about(State(state): State<GlobalState>) -> Response<Body> {
|
||||
handlers::template::with_graph("about", state).await
|
||||
}
|
||||
|
||||
context.insert("graph", &graph);
|
||||
if let Some(root_node) = graph.get_root() {
|
||||
graph.nodes.remove(&root_node.id);
|
||||
pub async fn tree(State(state): State<GlobalState>) -> Response<Body> {
|
||||
let instant = now();
|
||||
|
||||
let mut context = tera::Context::default();
|
||||
context.insert("graph", &state.graph);
|
||||
if let Some(root_node) = state.graph.get_root() {
|
||||
context.insert("root_node", &root_node);
|
||||
context.insert(
|
||||
"nodes",
|
||||
&graph.nodes.values().cloned().collect::<Vec<Node>>(),
|
||||
);
|
||||
} else {
|
||||
context.insert(
|
||||
"nodes",
|
||||
&graph.nodes.values().cloned().collect::<Vec<Node>>(),
|
||||
);
|
||||
}
|
||||
|
||||
tlog!(&instant, "Assembled response for tree endpoint");
|
||||
handlers::template::by_filename("tree.html", &context, 500, None, false)
|
||||
handlers::template::with_context("tree", &context, 500, None, false)
|
||||
}
|
||||
|
||||
pub async fn data() -> Response<Body> {
|
||||
pub async fn data(State(state): State<GlobalState>) -> Response<Body> {
|
||||
let instant = now();
|
||||
let mut context = tera::Context::default();
|
||||
let graph = Graph::load();
|
||||
|
||||
let mut detached_pairs: Vec<(String, u32)> =
|
||||
graph.stats.detached.clone().into_iter().collect();
|
||||
state.graph.stats.detached.clone().into_iter().collect();
|
||||
detached_pairs.sort_by(|a, b| b.1.cmp(&a.1));
|
||||
|
||||
context.insert("graph", &graph);
|
||||
context.insert("detached_count", &graph.stats.detached.len());
|
||||
let mut context = tera::Context::default();
|
||||
context.insert("graph", &state.graph);
|
||||
context.insert("detached_count", &state.graph.stats.detached.len());
|
||||
context.insert("detached_pairs", &detached_pairs);
|
||||
|
||||
tlog!(&instant, "Assembled response for data endpoint");
|
||||
handlers::template::by_filename("data.html", &context, 500, None, false)
|
||||
handlers::template::with_context("data", &context, 500, None, false)
|
||||
}
|
||||
|
||||
pub async fn search(Form(query): Form<Query>) -> Redirect {
|
||||
|
|
@ -79,11 +57,18 @@ pub struct Query {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use axum::{
|
||||
http::{StatusCode},
|
||||
};
|
||||
use axum::http::StatusCode;
|
||||
use crate::graph::Graph;
|
||||
|
||||
use super::*;
|
||||
|
||||
async fn wrap_page(path: &str) -> Response<Body> {
|
||||
let state = GlobalState {
|
||||
graph: Graph::load(),
|
||||
};
|
||||
handlers::template::with_graph(path, state).await
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn search_redirect() {
|
||||
let query = Form(Query {
|
||||
|
|
@ -95,19 +80,19 @@ mod tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn about_page_ok() {
|
||||
let response = page("about.html").await;
|
||||
let response = wrap_page("about").await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn tree_page_ok() {
|
||||
let response = page("tree.html").await;
|
||||
let response = wrap_page("tree").await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn inexistent_page_error() {
|
||||
let response = page("HBvcwqT8wLk6hxk1GdvNcEzJ6IiZ2Fod").await;
|
||||
let response = wrap_page("HBvcwqT8wLk6hxk1GdvNcEzJ6IiZ2Fod").await;
|
||||
assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,28 @@ use axum::{
|
|||
http::{header, Response, StatusCode},
|
||||
};
|
||||
|
||||
use crate::{prelude::*, router::handlers::raw::make_response};
|
||||
use crate::{
|
||||
prelude::*,
|
||||
router::{GlobalState, handlers::raw::make_response},
|
||||
};
|
||||
|
||||
pub(in crate::router::handlers) fn by_filename(
|
||||
/// Assembles a response containing the graph as its only context
|
||||
///
|
||||
/// The template name **must not** contain the extension.
|
||||
#[expect(clippy::unused_async)]
|
||||
pub async fn with_graph(template: &str, state: GlobalState) -> Response<Body> {
|
||||
let instant = now();
|
||||
let mut context = tera::Context::default();
|
||||
context.insert("graph", &state.graph);
|
||||
|
||||
tlog!(&instant, "Assembled response for template {template}");
|
||||
with_context(template, &context, 500, None, false)
|
||||
}
|
||||
|
||||
/// Assembles a response with a custom context.
|
||||
///
|
||||
/// The template name **must not** contain the extension.
|
||||
pub(in crate::router::handlers) fn with_context(
|
||||
name: &str,
|
||||
context: &tera::Context,
|
||||
error_code: u16,
|
||||
|
|
@ -19,8 +38,11 @@ pub(in crate::router::handlers) fn by_filename(
|
|||
make_response(&body, status_code, &[(header::CONTENT_TYPE, "text/html")])
|
||||
}
|
||||
|
||||
/// Renderes a template into a String and error code
|
||||
///
|
||||
/// The template name **must not** contain the extension (e.g. `.html`).
|
||||
pub(in crate::router::handlers) fn render(
|
||||
name: &str,
|
||||
template: &str,
|
||||
// TODO take Option, skip context if None,
|
||||
// then template_handler can replace static_template_handler
|
||||
context: &tera::Context,
|
||||
|
|
@ -35,29 +57,35 @@ pub(in crate::router::handlers) fn render(
|
|||
},
|
||||
};
|
||||
|
||||
match tera.render(name, context) {
|
||||
match tera.render(format!("{template}.html").as_str(), context) {
|
||||
Ok(t) => {
|
||||
tlog!(&instant, "Rendered template {name}");
|
||||
tlog!(&instant, "Rendered template {template}");
|
||||
(t, 200)
|
||||
},
|
||||
Err(e) => {
|
||||
let mut error_context = tera::Context::default();
|
||||
|
||||
let out_error_message = match error_message {
|
||||
Some(s) => &format!(
|
||||
let mut out_error_message = match error_message {
|
||||
Some(s) => format!(
|
||||
"Template render failed.\n\
|
||||
User message: {s},
|
||||
Engine message:\n<pre>{e:#?}</pre>\n\
|
||||
Context:\n<pre>{context:#?}</pre>"
|
||||
Engine message:\n<pre>{e:#?}</pre>"
|
||||
),
|
||||
None => &format!(
|
||||
None => format!(
|
||||
"Template render failed.\n\
|
||||
Engine message:\n<pre>{e:#?}</pre>\n\
|
||||
Context:\n<pre>{context:#?}</pre>"
|
||||
Engine message:\n<pre>{e:#?}</pre>"
|
||||
),
|
||||
};
|
||||
|
||||
error_context.insert("message", out_error_message);
|
||||
if log::env_level() >= VERBOSE {
|
||||
out_error_message = format!(
|
||||
"{out_error_message}\n\
|
||||
Context:\n<pre>{context:#?}</pre>"
|
||||
);
|
||||
}
|
||||
|
||||
log!(ERROR, "{out_error_message}");
|
||||
error_context.insert("message", &out_error_message);
|
||||
error_context.insert(
|
||||
"title",
|
||||
&StatusCode::INTERNAL_SERVER_ERROR.to_string(),
|
||||
|
|
@ -113,31 +141,21 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn by_filename_forced_error() {
|
||||
let response = by_filename(
|
||||
"index.html",
|
||||
&tera::Context::default(),
|
||||
418,
|
||||
None,
|
||||
true,
|
||||
);
|
||||
let response =
|
||||
with_context("index", &tera::Context::default(), 418, None, true);
|
||||
assert_eq!(response.status(), 418);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn by_filename_index() {
|
||||
let response = by_filename(
|
||||
"index.html",
|
||||
&tera::Context::default(),
|
||||
418,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let response =
|
||||
with_context("index", &tera::Context::default(), 418, None, false);
|
||||
assert_eq!(response.status(), 200);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn by_filename_file_not_found() {
|
||||
let response = by_filename(
|
||||
let response = with_context(
|
||||
"bwbl3BnWsluIgbO2NV9t3vtihwcjuF6t",
|
||||
&tera::Context::default(),
|
||||
418,
|
||||
|
|
@ -150,7 +168,7 @@ mod tests {
|
|||
#[test]
|
||||
fn by_filename_empty() {
|
||||
let response =
|
||||
by_filename("", &tera::Context::default(), 418, None, false);
|
||||
with_context("", &tera::Context::default(), 418, None, false);
|
||||
assert_eq!(response.status(), 500);
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +181,7 @@ mod tests {
|
|||
context.insert("node", &node);
|
||||
context.insert("graph", &graph);
|
||||
context.insert("incoming", &graph.incoming.get(&node.id));
|
||||
let (body, status) = render("node.html", &context, None);
|
||||
let (body, status) = render("node", &context, None);
|
||||
assert_eq!(status, 200);
|
||||
assert!(body.matches(payload).count() == 1);
|
||||
}
|
||||
|
|
@ -203,8 +221,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn render_bad_context() {
|
||||
let (body, status) =
|
||||
render("node.html", &tera::Context::default(), None);
|
||||
let (body, status) = render("node", &tera::Context::default(), None);
|
||||
assert!(body.matches("Template render failed.").count() > 0);
|
||||
assert_eq!(status, 500);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue