//! Smoke test: every page template loads from the embedded environment and
//! renders with a plausible context. Templates are data, not code, so a typo
//! in one is invisible to `cargo check` — this is what catches it.
use bismuth::build_environment;
use bismuth::handlers::cards::options;
use bismuth::render::{palette, render_svg, CardSpec, Output};
use minijinja::context;
fn user() -> minijinja::Value {
context! {
username => "alice",
email => "alice@example.com",
is_active => true,
created_at => "2026-08-03T00:00:00Z",
last_login_at => "2026-08-03T12:00:00Z",
}
}
fn snippet() -> minijinja::Value {
context! {
slug => "abcde23456",
title => "main.rs — Konsole",
language => "Rust",
chrome => "keramik",
palette => "auto",
}
}
fn svg() -> String {
render_svg(&CardSpec::default(), Output::Inline)
}
/// Every full page renders and carries the app name from `APP_NAME`.
#[test]
fn renders_every_page() {
let env = build_environment();
let spec = CardSpec::default();
let editor = |user: Option<minijinja::Value>, slug: Option<&str>| {
context! {
title => "New card", user => user, spec => &spec, slug => slug,
options => options(), max_padding => 160, card_svg => svg(),
}
};
let show = |is_owner: bool| {
context! {
title => "main.rs", user => user(), snippet => snippet(), is_owner => is_owner,
base => "https://bismuth.example", palette => "keramik", card_svg => svg(),
}
};
let cases: Vec<(&str, minijinja::Value)> = vec![
("editor.html", editor(None, None)),
("editor.html", editor(Some(user()), None)),
("editor.html", editor(Some(user()), Some("abcde23456"))),
("snippets/show.html", show(true)),
("snippets/show.html", show(false)),
("snippets/list.html", context! { title => "Snippets", user => user(), snippets => vec![snippet()] }),
("auth/login.html", context! { title => "Login" }),
(
"auth/register.html",
context! { title => "Register", invite_token => "tok-123", registration_open => false },
),
("auth/profile.html", context! { title => "Profile", user => user() }),
(
"auth/invites.html",
context! {
title => "Invites",
user => user(),
now => "2026-08-03T00:00:00Z",
invites => vec![context! {
token => "tok-123",
email => "friend@example.com",
expires_at => "2026-09-03T00:00:00Z",
is_used => false,
}],
},
),
];
for (name, ctx) in cases {
let tmpl = env.get_template(name).unwrap_or_else(|e| panic!("load {name}: {e}"));
let html = tmpl.render(ctx).unwrap_or_else(|e| panic!("render {name}: {e}"));
assert!(html.contains(bismuth::APP_NAME), "{name} did not render the app name");
}
}
/// The empty-collection branches of the list pages.
#[test]
fn renders_empty_lists() {
let env = build_environment();
let pages = [("auth/invites.html", "invites"), ("snippets/list.html", "snippets")];
for (name, key) in pages {
let ctx = context! { user => user(), now => "2026-08-03T00:00:00Z", ..
minijinja::Value::from_iter([(key, Vec::<minijinja::Value>::new())]) };
let tmpl = env.get_template(name).unwrap();
tmpl.render(ctx).unwrap_or_else(|e| panic!("render empty {name}: {e}"));
}
}
/// The editor's selects carry every decoration, palette and highlight theme,
/// and mark the spec's own choice selected.
#[test]
fn editor_lists_every_option() {
let env = build_environment();
let spec = CardSpec { palette: "blueprint".into(), ..CardSpec::default() };
let html = env
.get_template("editor.html")
.unwrap()
.render(context! {
spec => &spec, slug => None::<&str>, options => options(),
max_padding => 160, card_svg => svg(),
})
.unwrap();
for p in palette::PALETTES.iter() {
assert!(html.contains(&format!(r#"value="{}""#, p.id)), "palette {} missing", p.id);
}
assert!(html.contains(r#"value="blueprint" selected"#));
assert!(html.contains(r#"value="solarized" selected"#), "solarized should be the default");
}
/// The embed speaks the theme handshake and lists the palettes it accepts,
/// including every scheme name presentato can send.
#[test]
fn embed_speaks_the_handshake() {
let env = build_environment();
let html = env
.get_template("embed.html")
.unwrap()
.render(context! {
snippet => snippet(), palette => "keramik",
themes => palette::ids().join(" "), src => "/s/abcde23456/card.svg", card_svg => svg(),
})
.unwrap();
assert!(html.contains("bismuth:set-theme"));
assert!(html.contains("bismuth:ready"));
for presentato in ["blueprint", "her", "afterdark", "forest", "sky", "clays", "stones", "light", "dark"] {
assert!(palette::get(presentato).is_some(), "presentato scheme {presentato} has no palette");
}
}
neiam
/bismuth
MOTHER-FUCKING-BISMUTH
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
5.1 KiB · text
History
d76cd01