forked from yvv/decision
Fusion de chantier/acte-certification (lots H et S) dans le lot V : le tampon et ses états, avec le quorum et les Propositions seed
- conflits résolus des deux côtés : kept_params garde le quorum (S) et la part simulée, la version déplacée, le cran d'avant (V) ; proposals.rs garde seedMinimal / seedProposal (S) et tallyPending / tallySimulated / myVoteState (V) ; - simulation::reexamine juge sur le quorum gardé par l'adoption (params.quorum, à défaut celui de l'article) ; - l'acte répété n'examine plus une adoption qui tient (params.reexamined) ; - tests V repris sans texte en vigueur au départ (I1, E1 : la Proposition seed) et sur un quorum 2 (small_web) ; le test overview d'une personne invitée dans Monnaie libre suit la simulation (elle vote, chaîne fermée). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,10 +14,14 @@ struct Client {
|
||||
|
||||
impl Client {
|
||||
async fn new() -> Self {
|
||||
Self::with_state().await.0
|
||||
}
|
||||
|
||||
async fn with_state() -> (Self, AppState) {
|
||||
let db = open_db("sqlite::memory:").await.expect("db");
|
||||
let state = AppState::new(Config::for_tests(), db).await.expect("state");
|
||||
seed::ensure(&state).await.expect("seed");
|
||||
Self { router: app(state), cookie: None }
|
||||
(Self { router: app(state.clone()), cookie: None }, state)
|
||||
}
|
||||
|
||||
fn other(&self) -> Self {
|
||||
@@ -91,6 +95,21 @@ fn version(doc: &Value, code: &str, which: &str) -> String {
|
||||
v["id"].as_str().expect("id").to_owned()
|
||||
}
|
||||
|
||||
/// The quorum of an article of the test group set to 2, as its author — an administrator,
|
||||
/// for a text of the seed — sets it before the first vote (ADR 0013): where the quorum of
|
||||
/// every level is 1 and one voice passes, one voice of two then no longer does.
|
||||
async fn two_voices(state: &AppState, code: &str) {
|
||||
let n = sqlx::query(
|
||||
"UPDATE units SET quorum = 2 WHERE code = ? AND doc_id IN (SELECT id FROM documents WHERE group_slug = 'essai')",
|
||||
)
|
||||
.bind(code)
|
||||
.execute(&state.db)
|
||||
.await
|
||||
.expect("quorum")
|
||||
.rows_affected();
|
||||
assert_eq!(n, 1, "{code}");
|
||||
}
|
||||
|
||||
async fn decisions(c: &mut Client, group: &str) -> Value {
|
||||
c.get(&format!("/api/groups/{group}/decisions")).await
|
||||
}
|
||||
@@ -139,28 +158,33 @@ async fn a_group_one_does_not_open_shows_nothing_of_what_is_coming() {
|
||||
async fn decisions_one_line_per_doc_with_the_modules_left_to_vote() {
|
||||
// In the test group, which votes on the server (Monnaie libre votes on the chain:
|
||||
// tests/ballots.rs counts « sans ton vote » there).
|
||||
let mut c = Client::new().await;
|
||||
let (mut c, state) = Client::with_state().await;
|
||||
c.login("Chiara", false).await;
|
||||
// Someone else, who will not vote: W(essai) = 2.
|
||||
let mut yvv = c.other();
|
||||
yvv.login("Yvv", false).await;
|
||||
let d = decisions(&mut c, "essai").await;
|
||||
assert_eq!(d["canVote"], true);
|
||||
let docs = d["docs"].as_array().expect("docs");
|
||||
assert_eq!(docs.len(), 1);
|
||||
assert_eq!(docs[0]["slug"], "acte-engagement-certification");
|
||||
assert_eq!(docs[0]["title"]["fr"], "Acte d'engagement Certification");
|
||||
// 3 seeds a minima + 30 open articles, the two variants counting once; the title of the
|
||||
// document and the order of 7 sections (« ordonnancement » holds one article: nothing to decide).
|
||||
// 3 seed proposals (ADR 0011) + 30 open articles, the two variants counting once; the title
|
||||
// of the document and the order of 7 sections (« ordonnancement » holds one article: nothing
|
||||
// to decide).
|
||||
assert_eq!(docs[0]["toVote"], 41);
|
||||
assert_eq!(docs[0]["withoutMyVote"], 41);
|
||||
|
||||
let doc = the_doc(&mut c, "essai").await;
|
||||
// Votes that adopt nothing: the quorum 2 (ADR 0013), one voice of two.
|
||||
two_voices(&state, "E3").await;
|
||||
two_voices(&state, "I1").await;
|
||||
c.vote(&version(&doc, "E3", "0"), "for").await;
|
||||
c.vote(&version(&doc, "E3", "1"), "against").await;
|
||||
c.vote(&version(&doc, "I1", "inForce"), "for").await;
|
||||
c.vote(&version(&doc, "I1", "0"), "for").await;
|
||||
let d = decisions(&mut c, "essai").await;
|
||||
assert_eq!((d["docs"][0]["toVote"].as_u64(), d["docs"][0]["withoutMyVote"].as_u64()), (Some(41), Some(39)));
|
||||
// Someone else has not voted yet.
|
||||
let mut yvv = c.other();
|
||||
yvv.login("Yvv", false).await;
|
||||
assert_eq!(decisions(&mut yvv, "essai").await["docs"][0]["withoutMyVote"], 41);
|
||||
}
|
||||
|
||||
@@ -170,11 +194,11 @@ async fn an_adopted_module_leaves_the_count_and_a_vote_to_reconfirm_does_not_cou
|
||||
yvv.login("Yvv", false).await;
|
||||
let mut chiara = yvv.other();
|
||||
chiara.login("Chiara", false).await;
|
||||
// Dev identities are members of every group: W(essai) = 2, C = 1; two « for » adopt.
|
||||
// Dev identities are members of every group: W(essai) = 2, the quorum 1 at every level
|
||||
// (ADR 0013): one « for » adopts.
|
||||
let doc = the_doc(&mut yvv, "essai").await;
|
||||
let e3 = version(&doc, "E3", "0");
|
||||
yvv.vote(&e3, "for").await;
|
||||
let v = chiara.vote(&e3, "for").await;
|
||||
let v = yvv.vote(&e3, "for").await;
|
||||
assert_eq!(v["entered"][0]["code"], "E3");
|
||||
let d = decisions(&mut yvv, "essai").await;
|
||||
assert_eq!((d["docs"][0]["toVote"].as_u64(), d["docs"][0]["withoutMyVote"].as_u64()), (Some(40), Some(40)));
|
||||
@@ -239,15 +263,16 @@ async fn a_version_held_by_an_objection_is_not_to_vote_while_it_is_held() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn where_one_does_not_vote_there_is_no_count_of_ones_own() {
|
||||
async fn while_the_chain_is_closed_a_guest_votes_in_simulation_and_has_a_count_of_ones_own() {
|
||||
let mut admin = Client::new().await;
|
||||
admin.login("Yvv", true).await;
|
||||
let mut guest = admin.other();
|
||||
guest.invited(&mut admin, &["monnaie-libre", "essai"]).await;
|
||||
// No vote account: Monnaie libre votes in simulation, for whoever opens it (ADR 0012).
|
||||
let d = decisions(&mut guest, "monnaie-libre").await;
|
||||
assert_eq!(d["canVote"], false);
|
||||
assert_eq!(d["canVote"], true);
|
||||
assert_eq!(d["docs"][0]["toVote"], 41);
|
||||
assert!(d["docs"][0]["withoutMyVote"].is_null());
|
||||
assert_eq!(d["docs"][0]["withoutMyVote"], 41);
|
||||
// In the test group, the same person votes.
|
||||
let d = decisions(&mut guest, "essai").await;
|
||||
assert_eq!(d["canVote"], true);
|
||||
|
||||
Reference in New Issue
Block a user