diff --git a/src/mail.rs b/src/mail.rs index 7505dc4..3ed0cf8 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -18,7 +18,9 @@ //! - **warn** a dialogue that does not close: the person is mailed on //! the way in and not told how their case ended; //! - **warn** a mail that tells a person their case is where they may -//! now act on it, and gives them no link to do so. +//! now act on it, and gives them no link to do so; +//! - **warn** a long answer (a `textarea` field) put in a subject line, +//! which becomes the whole brief in someone's inbox list. use std::collections::{BTreeMap, BTreeSet, HashMap}; @@ -161,6 +163,12 @@ pub fn check(questions: &HashMap, aggregates: &HashMap>().join(", "))); } } + for key in placeholders(&mail.subject) { + let long = questions.values().flat_map(|q| &q.alternatives).filter(|a| a.record_as.as_deref() == Some(bucket.as_str())).flat_map(|a| a.features.iter().flat_map(|f| &f.requirements)).any(|r| r.name == key && r.kind == "textarea"); + if long { + warns.push(format!("{at}: the subject carries {{{key}}}, a long answer (textarea) - the whole of it lands in the subject line")); + } + } for path in site_links(&mail.body).into_iter().chain(site_links(&mail.subject)) { if path.contains('{') { continue; // filled per record; the page is checked where the pattern is declared @@ -281,6 +289,15 @@ mod tests { assert!(f.iter().any(|x| x.text.contains("no {link}"))); } + #[test] + fn a_long_answer_in_a_subject_line_is_found() { + let agg = AGG.replace("Got it, {name}", "About {brief}"); + let form = FORM.replace(" - { name: email, type: email }\n", " - { name: email, type: email }\n - { name: brief, type: textarea }\n"); + let (q, a) = repo(&agg, &[("/", &form), ("/decide/trial", DECIDE)]); + let f = check(&q, &a, &site("mail: { from: x@y.no }\n")); + assert!(f.iter().any(|x| x.level == Level::Warn && x.text.contains("{brief}") && x.text.contains("subject")), "{f:?}"); + } + #[test] fn a_mail_about_a_case_the_person_may_act_on_links_to_it() { let agg = AGG.replace("Withdraw at {site}/decide/trial?chain={chain}", "We have it");