en/src/router/handlers/graph.rs

91 lines
2.5 KiB
Rust

use crate::prelude::*;
use axum::response::IntoResponse as _;
use axum::{body::Body, extract::Path, http::Response, response::Redirect};
use crate::syntax::content;
use crate::{syntax::serial::populate_graph, router::handlers, types::Node};
pub async fn node(Path(id): Path<String>) -> Response<Body> {
let graph = populate_graph();
let empty_node = Node::new(Some(format!("Could not find node ID {id}.")));
let (node_match, exact) = graph.find_node(&id);
let node = node_match.unwrap_or(empty_node.clone());
if !node.redirect.is_empty() {
return Redirect::permanent(
format!("/node/{}", node.redirect).as_str(),
)
.into_response();
}
if !exact {
log!("Redirecting non-exact match to {}", node.id);
return Redirect::permanent(format!("/node/{}", node.id).as_str())
.into_response();
}
let mut context = tera::Context::default();
context.insert("node", &node);
context.insert("text", &content::parse(&node.text, &graph.meta.config));
context.insert("incoming", &graph.incoming.get(&id));
context.insert("config", &graph.meta.config);
let not_found = node == empty_node;
handlers::template::by_filename(
"node.html",
&context,
if not_found { 404 } else { 500 },
Some(
format!(
"Failed to generate page for node {} (ID {}).\n\
Node struct: <pre>{:#?}</pre>",
node.title, id, node
)
.to_owned(),
),
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);
}
}