Lot T4 : les tests d'avant suivent le seed de T4 sans rien perdre de ce qu'ils prouvent

Les tests qui lisaient F, N ou O rejouent leurs transitions sur le seed de M8
(tests/fixtures/seed-m8) : seed_quorum_texts, seed_rules, seed_proposals, api,
quorum ; ils disent en plus que ces amendements sont dépassés par le retrait
(superseded_by). Les comptes suivent le document de T4 : 27 articles, quatre
Propositions seed (I1, E1, E12, E2), 33 modules à voter (27 articles, le titre,
l'ordre de 5 sections). modules.rs : l'ordre sous vote se rejoue sur
« conclusion » (K1, K2) ; « un ordre d'un seul article n'a rien à décider » sur
une base née du seed de M8 (O1). seed_amend : tests unitaires de
Version::SeedProposal et de la ligne seed_proposal (put_forward). order.rs ne lit
que les colonnes d'avant 0012 : sections_now ne sert qu'à la naissance des
modules, et article_amend n'en garde que les articles vivants.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-11-03 21:21:44 +01:00
co-authored by Claude Opus 5.5
parent dda1ca85dd
commit 093d1ca471
14 changed files with 384 additions and 189 deletions
+38 -10
View File
@@ -442,7 +442,8 @@ async fn previews_and_assistant() {
a.login("Yvv", false).await;
let id = doc_id(&mut a, "monnaie-libre").await;
let (_, v) = a.call("GET", &format!("/api/docs/{id}/preview?mode=all"), None).await;
assert_eq!(v["units"].as_array().expect("u").len(), 33);
// 27 articles since lot T4 (the articles of operation out of the document, ADR 0014; E12 in).
assert_eq!(v["units"].as_array().expect("u").len(), 27);
let (_, v) = a.call("GET", &format!("/api/docs/{id}/preview?mode=wellrated"), None).await;
assert_eq!(v["units"].as_array().expect("u").len(), 0, "nothing in force, nothing well rated at zero votes");
let (_, v) = a
@@ -951,11 +952,21 @@ const PREAMBULE: [(&str, &str, &str); 3] = [
const RAISON_D_ETRE: &str = "*«\u{a0}Derrière une clé il n'y a qu'un seul être humain vivant\u{a0}; derrière un être humain, il n'y a qu'une seule clé certifiante.\u{a0}»*\n\nC'est le seul et unique propos de la certification";
/// The Raison d'être since lot T4 (Yvv, 03/11): its beginning.
const RAISON_D_ETRE_T4: &str = "*«\u{a0}Derrière une clé il y a un et un seul être humain vivant\u{a0}; derrière un être humain, il y a une et une seule clé certifiante.\u{a0}»*\n\nC'est l'unique enjeu de la certification";
fn today_seed() -> Value {
let path = Config::for_tests().seed_dir.join("acte-engagement-certification.json");
serde_json::from_str(&std::fs::read_to_string(path).expect("seed")).expect("json")
}
/// The seed of M8 (de1b7eb): the last that gave I1 the Raison d'être of 30/10.
fn m8_seed() -> Value {
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/seed-m8/acte-engagement-certification.json");
serde_json::from_str(&std::fs::read_to_string(path).expect("seed")).expect("json")
}
/// The seed production runs, I1 in force: the amendment of 30/10 is replayed on it.
fn production_seed() -> Value {
let path = production_seed_dir().join("acte-engagement-certification.json");
@@ -1026,15 +1037,24 @@ async fn a_new_base_starts_with_the_raison_d_etre() {
for group in ["monnaie-libre", "essai"] {
let i1 = i1_of(&mut c, group).await;
assert_eq!(i1["title"], "Raison d'être");
assert!(i1["body"].as_str().expect("body").starts_with(RAISON_D_ETRE), "{i1}");
assert!(i1["body"].as_str().expect("body").starts_with(RAISON_D_ETRE_T4), "{i1}");
assert_eq!((i1["revision"].as_i64(), i1["seedProposal"].as_bool()), (Some(1), Some(true)));
for (lang, title) in [("en", "Purpose"), ("es", "Razón de ser")] {
let tr = &i1["translations"][lang];
assert_eq!((tr["title"].as_str(), tr["stale"].as_bool()), (Some(title), Some(false)), "{lang}");
}
}
// Born with the text, put forward: nothing to replace, and it is said once.
assert_eq!(outcomes(&decisions(&state).await), [("essai", "present", None), ("monnaie-libre", "present", None)]);
// Born with the text of lot T4, put forward: nothing to replace, and it is said once; the
// amendment of 30/10, superseded, decides nothing on a new base.
assert!(decisions(&state).await.is_empty());
let t4: Vec<(String, String)> = sqlx::query_as(
"SELECT d.group_slug, s.outcome FROM seed_amendments s JOIN documents d ON d.id = s.doc_id
WHERE s.amendment_id = '2026-11-03-i1-amorce' ORDER BY d.group_slug",
)
.fetch_all(&state.db)
.await
.expect("decisions");
assert_eq!(t4, [("essai".to_owned(), "present".to_owned()), ("monnaie-libre".to_owned(), "present".to_owned())]);
}
#[tokio::test]
@@ -1043,13 +1063,21 @@ async fn the_shipped_amendment_goes_from_the_preambule_to_the_seed_text() {
assert_eq!(a.doc, "acte-engagement-certification");
let (_, title, body) = PREAMBULE[0];
assert_eq!(ld_server::seed_amend::fingerprint(title, body), a.from, "the Préambule bases hold");
let seed = today_seed();
let i1 = seed["units"].as_array().expect("units").iter().find(|u| u["code"] == "I1").expect("I1");
let v = &i1["versions"][0];
// Today the starting text is a seed proposal (ADR 0011); the text is the same.
let i1_of = |seed: &Value| -> (String, String, Value) {
let i1 = seed["units"].as_array().expect("units").iter().find(|u| u["code"] == "I1").expect("I1");
let v = &i1["versions"][0];
let (title, body) = (v["title"]["fr"].as_str().expect("title"), v["body"]["fr"].as_str().expect("body"));
(title.to_owned(), body.to_owned(), v.clone())
};
// Until M8 the starting text is a seed proposal (ADR 0011); the text is the same.
let (title, body, v) = i1_of(&m8_seed());
assert_eq!((v["status"].as_str(), v["seedProposal"].as_bool()), (Some("open"), Some(true)));
let (title, body) = (v["title"]["fr"].as_str().expect("title"), v["body"]["fr"].as_str().expect("body"));
assert_eq!(ld_server::seed_amend::fingerprint(title, body), a.to, "the text of the seed today");
assert_eq!(ld_server::seed_amend::fingerprint(&title, &body), a.to, "the text of the seed of M8");
// Lot T4 replaces it, after it only (Yvv's text of 03/11): this one decides nothing more.
let t4 = ld_server::seed_amend::AMENDMENTS.iter().find(|x| x.id == "2026-11-03-i1-amorce").expect("lot T4");
assert_eq!((t4.from, t4.follows, a.superseded_by), (a.to, Some(a.id), Some(t4.id)));
let (title, body, _) = i1_of(&today_seed());
assert_eq!(ld_server::seed_amend::fingerprint(&title, &body), t4.to, "the text of the seed today");
}
#[tokio::test]