check: warn on a long answer (textarea) in a mail's subject line
Test / test (pull_request) Successful in 2m6s
Test / test (pull_request) Successful in 2m6s
Found by the trainer's first mail rewording: 'We'll take on {project}'
puts the whole brief in the inbox list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8bee3ed4ec
commit
de622e4164
+18
-1
@@ -18,7 +18,9 @@
|
|||||||
//! - **warn** a dialogue that does not close: the person is mailed on
|
//! - **warn** a dialogue that does not close: the person is mailed on
|
||||||
//! the way in and not told how their case ended;
|
//! the way in and not told how their case ended;
|
||||||
//! - **warn** a mail that tells a person their case is where they may
|
//! - **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};
|
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||||
|
|
||||||
@@ -161,6 +163,12 @@ pub fn check(questions: &HashMap<String, Question>, aggregates: &HashMap<String,
|
|||||||
warns.push(format!("{at}: {{{key}}} is blank for records sent from {}", missing.iter().map(|n| format!("{n:?}")).collect::<Vec<_>>().join(", ")));
|
warns.push(format!("{at}: {{{key}}} is blank for records sent from {}", missing.iter().map(|n| format!("{n:?}")).collect::<Vec<_>>().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)) {
|
for path in site_links(&mail.body).into_iter().chain(site_links(&mail.subject)) {
|
||||||
if path.contains('{') {
|
if path.contains('{') {
|
||||||
continue; // filled per record; the page is checked where the pattern is declared
|
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}")));
|
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]
|
#[test]
|
||||||
fn a_mail_about_a_case_the_person_may_act_on_links_to_it() {
|
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");
|
let agg = AGG.replace("Withdraw at {site}/decide/trial?chain={chain}", "We have it");
|
||||||
|
|||||||
Reference in New Issue
Block a user