build: the plan's contact may be a group, which then answers for every page
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
894f228b8f
commit
67250af445
@@ -12,7 +12,9 @@
|
||||
# igjen.
|
||||
business: Tomter Vel
|
||||
language: no
|
||||
contact: { name: Styret i Tomter Vel, email: post@tomtervel.no }
|
||||
# Styret svarer for sidene som gruppe: ingen konto for innboksen, og
|
||||
# hvert styremedlem kan foreslå endringer på dem.
|
||||
contact: { name: Styret i Tomter Vel, email: post@tomtervel.no, group: styret }
|
||||
# Avsenderen for all e-post fra siden (gdo på kasse leverer); det
|
||||
# kasses postfix kan sende for i dag.
|
||||
mail: { from: "Tomter Vel <tomtervel@klingenbergbygg.no>", reply_to: post@tomtervel.no }
|
||||
|
||||
+28
-1
@@ -156,6 +156,11 @@ pub struct Door {
|
||||
pub struct Contact {
|
||||
pub name: String,
|
||||
pub email: String,
|
||||
/// The group the contact is: a board's inbox, not a person. Then
|
||||
/// portal makes no account for the address, and every member of
|
||||
/// the group may suggest changes to the pages it answers for.
|
||||
#[serde(default)]
|
||||
pub group: Option<String>,
|
||||
}
|
||||
|
||||
/// Who the site's mail comes from: portal sends nothing without it,
|
||||
@@ -343,6 +348,13 @@ fn is_id(s: &str) -> bool {
|
||||
|
||||
impl Plan {
|
||||
pub fn validate(&self) -> anyhow::Result<()> {
|
||||
// A contact that is a group has to be one with a desk, or
|
||||
// nobody could sign in as it.
|
||||
if let Some(group) = &self.contact.group {
|
||||
if !groups(self).contains(group) {
|
||||
bail!("contact: group {group:?} has no desk: it must handle, watch or move something");
|
||||
}
|
||||
}
|
||||
let mut doors = BTreeSet::new();
|
||||
for door in &self.doors {
|
||||
if !is_id(&door.id) || !doors.insert(&door.id) {
|
||||
@@ -1591,7 +1603,10 @@ fn form_alternative(plan: &Plan, need: &PlanNeed, w: &Value, action: &str) -> Va
|
||||
/// Every file of the content repo, from the plan and a set of words.
|
||||
pub fn render(plan: &Plan, words: &BTreeMap<String, Value>) -> anyhow::Result<BTreeMap<String, String>> {
|
||||
let mut files: BTreeMap<String, Value> = BTreeMap::new();
|
||||
let responsible = json!({ "name": plan.contact.name, "contact": plan.contact.email });
|
||||
let mut responsible = json!({ "name": plan.contact.name, "contact": plan.contact.email });
|
||||
if let Some(group) = &plan.contact.group {
|
||||
responsible["group"] = json!(group);
|
||||
}
|
||||
|
||||
let mut site = json!({ "title": plan.business, "lang": plan.language });
|
||||
if let Some(mail) = &plan.mail {
|
||||
@@ -2909,6 +2924,18 @@ mod invite_tests {
|
||||
|
||||
const BOARD: &str = "business: Vel\ncontact: { name: S, email: s@v.example }\nmail: { from: v@v.example }\nlanguage: no\nneeds:\n - id: notice\n who: en nabo som har noe å låne ut\n wants: et oppslag naboene ser\n lands_in: oppslag\n handled_by: redaktor\n stages: [open, tatt_ned]\n done_when: [tatt_ned]\n moves_by: { tatt_ned: [submitter, redaktor] }\n mails: { open: s@v.example }\n watched_by: [public]\n public_states: [open]\n max_fields: 3\n collects:\n - { name: email, type: email }\n - { name: hva, type: textarea }\n - id: answer\n who: en nabo som kan låne ut det\n wants: at den som la ut oppslaget får vite det\n about: notice\n lands_in: svar\n handled_by: redaktor\n stages: [open, lest]\n done_when: [lest]\n mails: { open: owner }\n max_fields: 1\n collects:\n - { name: email, type: email }\n";
|
||||
|
||||
#[test]
|
||||
fn a_contact_that_is_a_group_answers_for_every_page_as_that_group() {
|
||||
let plan: Plan = serde_yaml::from_str(&BOARD.replace("contact: { name: S, email: s@v.example }", "contact: { name: S, email: s@v.example, group: redaktor }")).unwrap();
|
||||
plan.validate().unwrap();
|
||||
let files = render(&plan, &fallback_words(&plan)).unwrap();
|
||||
let front: Value = serde_yaml::from_str(&files["questions/index.yaml"]).unwrap();
|
||||
assert_eq!(front["responsible"]["group"], "redaktor");
|
||||
assert_eq!(front["responsible"]["contact"], "s@v.example");
|
||||
let nobody: Plan = serde_yaml::from_str(&BOARD.replace("contact: { name: S, email: s@v.example }", "contact: { name: S, email: s@v.example, group: nobody }")).unwrap();
|
||||
assert!(nobody.validate().unwrap_err().to_string().contains("no desk"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_need_about_another_is_answered_from_the_boards_own_rows() {
|
||||
let plan: Plan = serde_yaml::from_str(BOARD).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user