Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger-ui

crates/holger-ui-server/tests/buyer_words.rs

//! ★ **Lane BUYFLOW-4: Holger's buy pages say buyer words only** (owner: customer-never-sees-caps,
//! one-monetize-only). The text a buyer sees on the sign-up, welcome and paid pages names none
//! of the operator's machinery. The list is
//! monetize-site-buy's `rules::OPERATOR_WORDS` (this crate builds from a lone clone and links
//! no sibling); the shared scripts' own sentences (buy.js, welcome.js, paid.js) are checked there. The footer's company
//! name is the seller's.

const OPERATOR_WORDS: &[&str] = &["lay", "lays", "laid", "laying", "estate", "estates", "guest", "guests", "operator", "operators", "cap", "caps", "monetize", "tenant", "tenants", "appliance", "vendor", "vendors", "ignalina"];

fn operator_words_in(words: &str) -> bool {
    let w = words.to_lowercase();
    w.contains("one box") || w.split(|c: char| !c.is_alphanumeric()).any(|t| OPERATOR_WORDS.contains(&t))
}

/// What of an HTML page a buyer reads: its text and its labels.
fn visible(html: &str) -> Vec<String> {
    let mut s = html.to_owned();
    for (open, close) in [("<!--", "-->"), ("<style", "</style>"), ("<script", "</script>")] {
        while let Some(a) = s.find(open) {
            let b = s[a..].find(close).map(|b| a + b + close.len()).unwrap_or(s.len());
            s.replace_range(a..b, "\n");
        }
    }
    let mut out = Vec::new();
    for attr in ["aria-label=\"", "title=\"", "placeholder=\"", "alt=\""] {
        for part in s.split(attr).skip(1) {
            out.push(part.split('"').next().unwrap_or_default().to_owned());
        }
    }
    let mut text = String::new();
    let mut in_tag = false;
    for c in s.chars() {
        match c {
            '<' => in_tag = true,
            '>' => {
                in_tag = false;
                text.push('\n');
            }
            c if !in_tag => text.push(c),
            _ => {}
        }
    }
    out.extend(text.lines().map(str::trim).filter(|l| !l.is_empty()).map(str::to_owned));
    out
}

/// The string literals of a script that read as a sentence (a space in them), comment lines
/// left out.
fn sentences(js: &str) -> Vec<String> {
    let mut out = Vec::new();
    for line in js.lines().filter(|l| !l.trim_start().starts_with("//") && !l.trim_start().starts_with('*')) {
        let mut open: Option<char> = None;
        let mut cur = String::new();
        let mut prev = ' ';
        let mut chars = line.chars().peekable();
        while let Some(c) = chars.next() {
            match open {
                None if (c == '\'' || c == '"' || c == '`') && !(c == '\'' && prev.is_alphanumeric()) => {
                    open = Some(c);
                    cur.clear();
                }
                None if c == '/' && chars.peek() == Some(&'/') => break,
                Some(_) if c == '\\' => {
                    chars.next();
                }
                Some(q) if c == q => {
                    if cur.contains(' ') {
                        out.push(cur.clone());
                    }
                    open = None;
                }
                Some(_) => cur.push(c),
                None => {}
            }
            prev = c;
        }
    }
    out
}

#[test]
fn holgers_buy_pages_name_no_operator_machinery() {
    let mut bad = Vec::new();
    for (name, page) in [("signup.html", include_str!("../../../assets/signup.html")), ("welcome.html", include_str!("../../../assets/welcome.html")), ("paid.html", include_str!("../../../assets/paid.html"))] {
        for line in visible(page) {
            if operator_words_in(&line.replace("Ignalina ApS", "")) {
                bad.push(format!("{name}: {line}"));
            }
        }
    }
    assert!(bad.is_empty(), "a buyer reads the operator's words:\n{}", bad.join("\n"));
}

#[test]
fn the_readers_read_what_a_buyer_sees() {
    assert_eq!(visible("<!-- the estate --><style>.estate{}</style><p title=\"An operator's cap\">Your instance</p><script>x('laid')</script>"), vec!["An operator's cap".to_owned(), "Your instance".to_owned()]);
    assert_eq!(sentences("show('Your estate is laid', 'err'); // a lay"), vec!["Your estate is laid".to_owned()]);
    assert!(operator_words_in("The operator's cap") && !operator_words_in("a capacity, capped"));
}