crates/gunnar-ui-web/src/identities.rs
//! **Administration → Identities: the words in its empty fields, and when Purge may be
//! pressed** — on the host side of the wasm boundary, where `cargo test` reaches it.
//!
//! Owner 2026-10-14: the fields showed the example name "alice", and beside "Purge
//! account — deletes everything, no undelete" that read like a real account filled in.
//! They are empty, with plain hints, and a hint is never a value.
/// The hint in Add principal's Name.
pub const HINT_NEW_PRINCIPAL: &str = "New principal's name";
/// The hint in Lockouts' Account.
pub const HINT_LOCK_OUT: &str = "Account to lock out";
/// The hint in Purge an account's Account.
pub const HINT_PURGE: &str = "Account to purge";
/// The hint, and the label, of the purge's confirmation.
pub const HINT_PURGE_CONFIRM: &str = "Type the account name to confirm";
/// **May Purge be pressed?** Only with an account TYPED and the very same name typed
/// again. A hint is never a value, so no hint can satisfy it — the two fields are what
/// a person typed, and nothing else.
pub fn may_purge(account: &str, confirm: &str) -> bool {
let account = account.trim();
!account.is_empty() && confirm.trim() == account
}
/// **The Principals table's columns, in order** — the admin's user list
/// (owner, 2026-10-21: when someone last signed in, and last did something).
pub const PRINCIPAL_COLUMNS: [&str; 6] = ["Name", "Kind", "Id", "Created", "Last sign-in", "Last operation"];
/// **A last-seen cell**: what it reads — "5 min ago", "3 h ago", "2 d ago", or
/// "never" — and what its hover says: the exact UTC time (empty for never).
pub fn seen_cell(unix_ms: Option<i64>, now: i64) -> (String, String) {
match unix_ms {
Some(at) => (crate::fmt::since(at, now), crate::fmt::utc(at)),
None => ("never".to_owned(), String::new()),
}
}
#[cfg(test)]
mod tests {
use super::*;
/// The admin's user list shows both columns (owner, 2026-10-21).
#[test]
fn the_principals_table_has_last_sign_in_and_last_operation() {
assert!(PRINCIPAL_COLUMNS.contains(&"Last sign-in"), "{PRINCIPAL_COLUMNS:?}");
assert!(PRINCIPAL_COLUMNS.contains(&"Last operation"), "{PRINCIPAL_COLUMNS:?}");
// …and the page draws its header and its two cells from here.
let page = crate::code::of(include_str!("pages/access.rs"));
assert!(page.contains("crate::identities::PRINCIPAL_COLUMNS"), "the Principals header is not drawn from PRINCIPAL_COLUMNS");
assert!(page.contains("seen_td(p.last_sign_in_unix_ms, now)") && page.contains("seen_td(p.last_operation_unix_ms, now)"), "the Principals rows do not draw both cells");
}
/// "x min/h/d ago", the exact UTC time on hover, and "never" for never.
#[test]
fn a_seen_cell_reads_ago_hovers_utc_and_says_never() {
let now = 1_792_540_800_000; // 2026-10-21 00:00:00 UTC
assert_eq!(seen_cell(Some(now - 300_000), now), ("5 min ago".to_owned(), "2026-10-20 23:55 UTC".to_owned()));
assert_eq!(seen_cell(Some(now - 3 * 3_600_000), now).0, "3 h ago");
assert_eq!(seen_cell(Some(now - 2 * 86_400_000), now).0, "2 d ago");
assert_eq!(seen_cell(None, now), ("never".to_owned(), String::new()));
}
/// ★ The purge is armed only by the account typed twice; empty fields — whatever
/// their hints say — never arm it, and a hint typed in is just a name that differs.
#[test]
fn purge_is_armed_only_by_the_account_typed_again() {
assert!(may_purge("kim", " kim "));
assert!(!may_purge("", ""), "two empty fields arm a purge");
assert!(!may_purge("kim", ""));
assert!(!may_purge("kim", "ki"));
assert!(!may_purge("kim", HINT_PURGE_CONFIRM), "the confirm's hint is not the name");
assert!(!may_purge("", HINT_PURGE), "the account's hint is not an account");
assert_eq!([HINT_NEW_PRINCIPAL, HINT_LOCK_OUT, HINT_PURGE, HINT_PURGE_CONFIRM], ["New principal's name", "Account to lock out", "Account to purge", "Type the account name to confirm"]);
}
/// No example name is left in the page's fields.
#[test]
fn no_field_on_the_page_shows_an_example_name() {
let page = include_str!("pages/access.rs");
assert!(!page.contains("placeholder=\"alice\""), "a field still shows \"alice\"");
for hint in ["identities::HINT_NEW_PRINCIPAL", "identities::HINT_LOCK_OUT", "identities::HINT_PURGE", "identities::HINT_PURGE_CONFIRM", "identities::may_purge("] {
assert!(page.contains(hint), "the page does not use {hint}");
}
}
}