diff --git a/web/e2e/ordre-quorum.spec.ts b/web/e2e/ordre-quorum.spec.ts index f30c60b..94bf058 100644 --- a/web/e2e/ordre-quorum.spec.ts +++ b/web/e2e/ordre-quorum.spec.ts @@ -230,7 +230,8 @@ test('C37 — le quorum d’un article : son auteur le fixe avant le premier vot expect(r.ok()).toBe(true); await field.fill('2'); await quorum.getByRole('button', { name: 'Fixer ce quorum' }).click(); - await expect(quorum.getByRole('alert')).toHaveText("Quelqu'un a déjà voté sur cet article : son quorum ne change plus."); + // « ne change pas », not « plus »: a vote withdrawn here leaves no trace (lot T2). + await expect(quorum.getByRole('alert')).toHaveText("Quelqu'un a déjà voté sur cet article : son quorum ne change pas."); await page.reload(); await expect(fold).toBeVisible(); await expect(fold.getByRole('region', { name: /^Quorum/ })).toHaveCount(0); diff --git a/web/src/lib/i18n/en.ts b/web/src/lib/i18n/en.ts index be653d4..57b6641 100644 --- a/web/src/lib/i18n/en.ts +++ b/web/src/lib/i18n/en.ts @@ -304,7 +304,7 @@ export const en: Messages = { 'quorum.reset.done.one': 'Quorum back to the default: {n} voter.', 'quorum.reset.done.other': 'Quorum back to the default: {n} voters.', 'quorum.error.quorum': 'This quorum is out of bounds: at least 2 voters (1 in the test group), at most {w}, the electorate.', - 'quorum.error.voted': 'Someone has already voted on this article: its quorum no longer changes.', + 'quorum.error.voted': 'Someone has already voted on this article: its quorum does not change.', 'quorum.error.forbidden': 'Only the person who wrote the article sets its quorum, before the first vote.', 'ballot.reason.not_member': 'the wallet that signed is not that of a member of the Ğ1 web of trust.', 'ballot.reason.no_identity': 'the wallet that signed is linked to no Ğ1 identity.', @@ -400,7 +400,7 @@ export const en: Messages = { 'ballots.verify.unreadable': 'This is not a readable vote receipt.', 'inertia.title': 'Inertia', - 'inertia.explain': 'The higher the inertia, the more votes it takes to change this text when few people vote.', + 'inertia.explain': 'The higher the inertia, the more votes it takes to change this text. Below the quorum, the missing voters count as “no”; beyond it, the share of “yes” asked for falls as turnout rises.', 'inertia.change': 'Propose an inertia change', 'inertia.change.to': 'New inertia', 'inertia.change.note': "A change of inertia is itself voted at the article's inertia: {level}.", @@ -421,7 +421,7 @@ export const en: Messages = { 'formula.B': 'B — base: {n}', 'formula.Q': 'Q — quorum: {n}', 'formula.R': 'R — current threshold: {n} votes in favor', - 'formula.reading': 'At low turnout, near-unanimity is needed; when everyone votes, majority M is enough. Below the quorum Q, the missing voters count as against.', + 'formula.reading': 'Below the quorum Q, the missing voters count as against. Beyond it, the share of votes in favour asked for, highest at the quorum, falls as turnout rises; when everyone votes, majority M is enough.', 'common.pct': '{n}%', 'settings.title': 'Formula settings', 'settings.intro': 'To change a text, the group asks for a number of votes in favour that depends on its electorate, its usual turnout and the inertia of the article.', diff --git a/web/src/lib/i18n/es.ts b/web/src/lib/i18n/es.ts index b4e148c..e81ad42 100644 --- a/web/src/lib/i18n/es.ts +++ b/web/src/lib/i18n/es.ts @@ -304,7 +304,7 @@ export const es: Messages = { 'quorum.reset.done.one': 'Quórum de vuelta al valor por defecto: {n} votante.', 'quorum.reset.done.other': 'Quórum de vuelta al valor por defecto: {n} votantes.', 'quorum.error.quorum': 'Este quórum se sale de los límites: al menos 2 votantes (1 en el grupo de prueba), como mucho {w}, el electorado.', - 'quorum.error.voted': 'Alguien ya ha votado sobre este artículo: su quórum ya no cambia.', + 'quorum.error.voted': 'Alguien ya ha votado sobre este artículo: su quórum no cambia.', 'quorum.error.forbidden': 'Solo la persona que escribió el artículo fija su quórum, antes del primer voto.', 'ballot.reason.not_member': 'el monedero que firmó no es el de un miembro de la red de confianza Ğ1.', 'ballot.reason.no_identity': 'el monedero que firmó no está vinculado a ninguna identidad Ğ1.', @@ -400,7 +400,7 @@ export const es: Messages = { 'ballots.verify.unreadable': 'No es un recibo de voto legible.', 'inertia.title': 'Inercia', - 'inertia.explain': 'Cuanto más alta es la inercia, más votos hacen falta para cambiar este texto cuando vota poca gente.', + 'inertia.explain': 'Cuanto más alta es la inercia, más votos hacen falta para cambiar este texto. Por debajo del quórum, los votantes que faltan cuentan como «no»; más allá, la proporción de «sí» pedida baja cuando sube la participación.', 'inertia.change': 'Proponer un cambio de inercia', 'inertia.change.to': 'Nueva inercia', 'inertia.change.note': 'Un cambio de inercia se vota a su vez con la inercia del artículo: {level}.', @@ -421,7 +421,7 @@ export const es: Messages = { 'formula.B': 'B — base: {n}', 'formula.Q': 'Q — quórum: {n}', 'formula.R': 'R — umbral actual: {n} votos a favor', - 'formula.reading': 'Con poca participación, hace falta casi la unanimidad; cuando vota todo el mundo, basta la mayoría M. Por debajo del quórum Q, los votantes que faltan cuentan como «no».', + 'formula.reading': 'Por debajo del quórum Q, los votantes que faltan cuentan como «no». Más allá, la proporción de votos a favor pedida, la más alta en el quórum, baja cuando sube la participación; cuando vota todo el mundo, basta la mayoría M.', 'common.pct': '{n} %', 'settings.title': 'Ajustes de la fórmula', 'settings.intro': 'Para cambiar un texto, el grupo pide un número de votos a favor que depende de su electorado, de su participación habitual y de la inercia del artículo.', diff --git a/web/src/lib/i18n/fr.ts b/web/src/lib/i18n/fr.ts index c77ee41..b7beb00 100644 --- a/web/src/lib/i18n/fr.ts +++ b/web/src/lib/i18n/fr.ts @@ -308,7 +308,7 @@ export const fr = { 'quorum.reset.done.one': 'Quorum revenu au défaut : {n} votant.', 'quorum.reset.done.other': 'Quorum revenu au défaut : {n} votants.', 'quorum.error.quorum': "Ce quorum sort des bornes : au moins 2 votants (1 dans le groupe d'essai), au plus {w}, l'électorat.", - 'quorum.error.voted': "Quelqu'un a déjà voté sur cet article : son quorum ne change plus.", + 'quorum.error.voted': "Quelqu'un a déjà voté sur cet article : son quorum ne change pas.", 'quorum.error.forbidden': "Seule la personne qui a écrit l'article fixe son quorum, avant le premier vote.", 'ballot.reason.not_member': "le portefeuille qui a signé n'est pas celui d'un membre de la toile de confiance Ğ1.", 'ballot.reason.no_identity': "le portefeuille qui a signé n'est rattaché à aucune identité Ğ1.", @@ -404,7 +404,7 @@ export const fr = { 'ballots.verify.unreadable': "Ce n'est pas un reçu de vote lisible.", 'inertia.title': 'Inertie', - 'inertia.explain': "Plus l'inertie est haute, plus il faut de voix pour changer ce texte quand peu de gens votent.", + 'inertia.explain': "Plus l'inertie est haute, plus il faut de voix pour changer ce texte. Sous le quorum, les votants qui manquent comptent comme « non » ; au-delà, la part de « pour » demandée baisse quand la participation monte.", 'inertia.change': "Proposer un changement d'inertie", 'inertia.change.to': 'Nouvelle inertie', 'inertia.change.note': "Un changement d'inertie se vote lui-même à l'inertie de l'article : {level}.", @@ -425,7 +425,7 @@ export const fr = { 'formula.B': 'B — base : {n}', 'formula.Q': 'Q — quorum : {n}', 'formula.R': 'R — seuil actuel : {n} voix pour', - 'formula.reading': "À faible participation, il faut presque l'unanimité ; quand tout le monde vote, la majorité M suffit. Sous le quorum Q, les votants qui manquent comptent comme « non ».", + 'formula.reading': "Sous le quorum Q, les votants qui manquent comptent comme « non ». Au-delà, la part de « pour » demandée, la plus haute au quorum, baisse quand la participation monte ; quand tout le monde vote, la majorité M suffit.", 'common.pct': '{n} %', 'settings.title': 'Réglages de la formule', 'settings.intro': "Pour changer un texte, le groupe demande un nombre de voix pour qui dépend de son électorat, de sa participation habituelle et de l'inertie de l'article.", diff --git a/web/tests/unit/inertia.test.ts b/web/tests/unit/inertia.test.ts index 2830c34..ccd4efd 100644 --- a/web/tests/unit/inertia.test.ts +++ b/web/tests/unit/inertia.test.ts @@ -28,6 +28,21 @@ describe('five levels of inertia', () => { expect(fr['formula.reading']).toContain('les votants qui manquent comptent comme « non »'); expect(fr['settings.quorum.note']).toContain('avant le premier vote'); }); + it('the share asked is highest at the quorum, never near-unanimity because few vote (review of M6b, lot T2)', () => { + const lowTurnout = /unanimi|peu de gens votent|faible participation|few people vote|low turnout|vota poca gente|poca participación/; + for (const cat of [fr, en, es]) { + for (const k of ['inertia.explain', 'formula.reading'] as const) expect(cat[k], k).not.toMatch(lowTurnout); + // After the act « supprime », or a direct vote withdrawn, the quorum changes again. + expect(cat['quorum.error.voted']).not.toMatch(/ne change plus|no longer changes|ya no cambia/); + } + expect(fr['inertia.explain']).toBe( + "Plus l'inertie est haute, plus il faut de voix pour changer ce texte. Sous le quorum, les votants qui manquent comptent comme « non » ; au-delà, la part de « pour » demandée baisse quand la participation monte.", + ); + expect(fr['formula.reading']).toBe( + "Sous le quorum Q, les votants qui manquent comptent comme « non ». Au-delà, la part de « pour » demandée, la plus haute au quorum, baisse quand la participation monte ; quand tout le monde vote, la majorité M suffit.", + ); + expect(fr['quorum.error.voted']).toBe("Quelqu'un a déjà voté sur cet article : son quorum ne change pas."); + }); it('a change of inertia is said to be voted at the level of the article, no longer one above', () => { for (const cat of [fr, en, es]) expect(cat['inertia.change.note']).toContain('{level}'); expect(fr['inertia.change.note']).toContain("à l'inertie de l'article");