tests/brand.rs 5.7 KiB 170 lines Raw
1 //! f0rge #70: gl0w branding + gl0w.world attribution on every page,2 //! theme-aware logo, and an og:image social card.3 4 use std::path::{Path, PathBuf};5 use std::process::Command;6 7 fn fresh(prefix: &str) -> PathBuf {8     let dir = std::env::temp_dir().join(format!(9         "hu13-brand-{prefix}-{}-{}",10         std::process::id(),11         std::time::SystemTime::now()12             .duration_since(std::time::UNIX_EPOCH)13             .map(|d| d.as_nanos())14             .unwrap_or(0)15     ));16     std::fs::create_dir_all(&dir).unwrap();17     dir18 }19 20 fn git(repo: &Path, args: &[&str]) {21     let st = Command::new("git")22         .arg("-C")23         .arg(repo)24         .args(args)25         .status()26         .expect("spawn git");27     assert!(st.success(), "git {args:?}");28 }29 30 fn build() -> PathBuf {31     let repo = fresh("repo");32     let out = fresh("out");33     git(&repo, &["init", "-b", "main"]);34     git(&repo, &["config", "user.name", "hu13-test"]);35     git(&repo, &["config", "user.email", "[email protected]"]);36     git(&repo, &["config", "commit.gpgsign", "false"]);37     std::fs::write(repo.join("README.md"), "# brand\n").unwrap();38     git(&repo, &["add", "-A"]);39     git(&repo, &["commit", "-m", "brand"]);40     let produced = Command::new(env!("CARGO_BIN_EXE_hu13"))41         .arg("build")42         .arg(&repo)43         .arg("-o")44         .arg(&out)45         .output()46         .unwrap();47     assert!(48         produced.status.success(),49         "{}",50         String::from_utf8_lossy(&produced.stderr)51     );52     out53 }54 55 #[test]56 fn header_and_footer_carry_gl0w_branding() {57     let out = build();58     for page in ["index.html", "agents.html", "issues/index.html"] {59         let html = std::fs::read_to_string(out.join(page)).expect(page);60         assert!(61             html.contains("<span class=\"gl0w-mark\" aria-hidden=\"true\"><svg"),62             "{page}: gl0w logo mark in header"63         );64         assert!(65             html.contains("viewBox=\"0 0 357 306\"") && html.contains("M2,2 L355,2"),66             "{page}: gf1 gl0w mark geometry"67         );68         assert!(69             !html.contains("<span class=\"gl0w-mark\" aria-hidden=\"true\">gl0w</span>"),70             "{page}: text placeholder replaced by logo"71         );72         assert!(73             html.contains("<a class=\"gl0w-mark\" href=\"https://gl0w.world\" rel=\"noopener\" aria-label=\"gl0w\">"),74             "{page}: footer logo links gl0w.world"75         );76         assert!(77             html.contains("hu13 — a gl0w project"),78             "{page}: brand tagline"79         );80         assert!(81             html.contains("href=\"https://gl0w.world\""),82             "{page}: links to gl0w.world"83         );84         assert!(85             html.contains("footer-provenance"),86             "{page}: provenance kept"87         );88         // Header lockup keeps the hu13 mark and is linked home.89         assert!(90             html.contains("<img class=\"site-logo\" src=\"/logo.svg\" alt=\"hu13 logo\""),91             "{page}: hu13 logo"92         );93         assert!(94             html.contains("href=\"/\" aria-label=\"hu13 by gl0w"),95             "{page}: lockup links home"96         );97     }98 }99 100 #[test]101 fn social_card_and_meta_present() {102     let out = build();103     let html = std::fs::read_to_string(out.join("index.html")).unwrap();104     for needle in [105         "<meta property=\"og:image\" content=\"/og.png\">",106         "<meta property=\"og:image:width\" content=\"1200\">",107         "<meta property=\"og:image:height\" content=\"630\">",108         "<meta name=\"twitter:card\" content=\"summary_large_image\">",109         "<meta property=\"og:site_name\" content=\"hu13 by gl0w\">",110     ] {111         assert!(html.contains(needle), "index.html has {needle}");112     }113     let png = std::fs::read(out.join("og.png")).expect("og.png emitted");114     assert!(png.starts_with(b"\x89PNG\r\n\x1a\n"), "real PNG");115     assert!(png.len() > 1000, "not a stub");116 }117 118 #[test]119 fn logo_has_no_baked_background() {120     let out = build();121     let logo =122         std::fs::read_to_string(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("static/logo.svg"))123             .unwrap();124     let gl0w =125         std::fs::read_to_string(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("static/gl0w.svg"))126             .unwrap();127     assert!(128         gl0w.contains("viewBox=\"0 0 357 306\"") && gl0w.contains("fill=\"currentColor\""),129         "vendored gf1 gl0w mark"130     );131     let built = std::fs::read_to_string(out.join("gl0w.svg")).unwrap();132     assert_eq!(built, gl0w, "build emits the same gl0w logo");133     assert!(!logo.contains("fill=\"#1a1b26\""), "no dark slab");134     assert!(135         logo.contains("@media (prefers-color-scheme:light)"),136         "ink flips for light theme"137     );138     let css =139         std::fs::read_to_string(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("static/style.css"))140             .unwrap();141     assert!(142         css.contains(".site-logo{display:block;width:auto;height:1.75rem"),143         "logo keeps its 3:1 aspect (was squeezed into 48x48)"144     );145 }146 147 #[test]148 fn repository_readme_has_no_ascii_logo_or_clone_duplicate() {149     let readme = std::fs::read_to_string(150         PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".forge/wiki/README"),151     )152     .unwrap();153     assert!(154         !readme.contains("███") && !readme.contains("▓▓"),155         "README carries no ASCII-art logo"156     );157     assert!(158         !readme.contains("## Clone it"),159         "clone/download lives in the code header, not a duplicate section"160     );161     assert!(162         !readme.starts_with("# "),163         "README does not repeat the repo title; the page header already carries it"164     );165     assert!(166         readme.starts_with("*hu13 (pronounced"),167         "README opens with its intro"168     );169     assert!(readme.contains("## Built with"), "README keeps its ending");170 }