crates/holger-ui-server/tests/open_build_speaks_no_money.rs
//! **The open console's server speaks no money** (A28 M13): Gunnar's guard
//! (`gunnar/crates/gunnar-server/tests/open_build_speaks_no_money.rs`) and its console twin
//! (`gunnar-ui/crates/gunnar-ui-server/tests/open_build_speaks_no_money.rs`), ported.
//!
//! * **the ROUTES**, driven: in `src/lib.rs`, `the_open_console_serves_no_money_route` asks a
//! default build's router for every page, file and door of the paid half (404, no
//! document). Here, the same claim from the outside: the public API names no buy route.
//! * **the WORDS the open server can say**: every string literal an open
//! `holger-ui-server` compiles (its `--help`, its refusals, its routes), with comments and
//! the code an open build does not contain (`#[cfg(feature = "metered")]`, tests) left out.
//!
//! The judge and the lexer are Gunnar's, verbatim, with the words Holger adds (holger's
//! `server/lib/tests/money/judge.rs`, the same text), in ONE file both halves read:
//! `tests/money/mod.rs` at the repository root. The console bundle (the wasm console in `src/`
//! and the pages in `assets/`) has its own guard there: `tests/open_bundle_speaks_no_money.rs`.
#[path = "../../../tests/money/mod.rs"]
mod money;
#[cfg_attr(feature = "metered", allow(unused_imports))]
use money::{leaks_in, scan_source, sources};
#[cfg_attr(feature = "metered", allow(unused_imports))]
use std::path::Path;
/// **Deliberate exceptions**, `(file suffix, fragment, reason)`. Each must still match.
#[cfg(not(feature = "metered"))]
const EXCEPTIONS: &[(&str, &str, &str)] = &[
(
"src/lib.rs",
"/paid",
"`OPEN_REFUSES`: the paid half's page and file NAMES the open console answers 404 for, so \
the bundle's copies are never served; a path refused is never shown as words",
),
(
"src/lib.rs",
"/billing/",
"`OPEN_REFUSES`: the pay link's path, refused (404) by the open console, as above",
),
];
#[cfg(not(feature = "metered"))]
#[test]
fn the_open_server_says_no_money() {
let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let mut leaks = Vec::new();
let mut used = vec![false; EXCEPTIONS.len()];
let files = sources(&root.join("src"));
assert!(files.len() >= 2, "only {} files: the layout moved", files.len());
for path in &files {
let rel = path.strip_prefix(root).unwrap_or(path).to_string_lossy().replace('\\', "/");
let text = std::fs::read_to_string(path).unwrap();
for lit in scan_source(&text).literals {
let hits = leaks_in(&lit.text);
if hits.is_empty() {
continue;
}
if let Some(k) = EXCEPTIONS.iter().position(|(f, frag, _)| rel.ends_with(f) && lit.text.contains(frag)) {
used[k] = true;
continue;
}
leaks.push(format!("{rel}:{}: {hits:?} in {:?}", lit.line, lit.text));
}
}
let stale: Vec<_> = EXCEPTIONS.iter().zip(&used).filter(|(_, u)| !**u).map(|(e, _)| e.1).collect();
assert!(stale.is_empty(), "exceptions that no longer match anything: {stale:?}");
assert!(
leaks.is_empty(),
"an OPEN holger-ui-server compiles money vocabulary into what it says ({} literals). \
Reword neutrally, or gate the code under `metered`.\n {}",
leaks.len(),
leaks.join("\n ")
);
}
/// **The open build's public surface names no buy route**: its route table is the login page.
#[cfg(not(feature = "metered"))]
#[test]
fn the_open_route_table_is_the_login_page() {
let paths: Vec<&str> = holger_ui_server::BUY_ROUTES.iter().map(|r| r.path).collect();
assert_eq!(paths, ["/login"]);
for refused in ["/signup", "/paid/{*reference}", "/billing/{*tenant}", "/welcome", "/signup.js"] {
assert!(holger_ui_server::OPEN_REFUSES.contains(&refused), "{refused} is not refused by name");
}
}