forked from yvv/decision
v3 : la Raison d'être remplace le Préambule (L7), amendement de seed gardé
- seed : I1 devient « Raison d'être », texte d'Yvv (fr), traduit en « Purpose » et « Razón de ser » ; apostrophes droites comme le reste du seed, insécables avant « ; » et dans les guillemets. - seed_amend.rs : un amendement de seed remplace un texte de départ dans une base existante, décidé une fois par document et seulement si personne n'a touché l'article (seed a minima d'origine, révision 1, aucun vote, aucune correction, aucune traduction de membre, aucun signalement, empreinte attendue). Décision consignée (migration 0004, table seed_amendments), ligne d'historique « texte de départ remplacé » avec son diff, republication mise en file là où le document publie. - Une coquille se mesure désormais aussi contre le texte posé par l'amendement. - Tests : règle pure (3), scénarios d'API (base neuve, amendement appliqué et republié une seule fois, cinq refus), e2e C13 ; C3, C6 et l'API suivent le nouveau texte (C6 : les apostrophes typographiques d'Unicité du compte, « latransmission » ayant disparu). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+26
-8
@@ -22,13 +22,13 @@ test('C2 — les groupes de la même clé ; pas l’Atelier du canal', async ({
|
||||
await expect(page.getByText('Atelier du canal')).toHaveCount(0);
|
||||
});
|
||||
|
||||
test('C3 — le texte en vigueur : préambule et deux engagements, seed a minima', async ({ page }) => {
|
||||
test('C3 — le texte en vigueur : raison d’être et deux engagements, seed a minima', async ({ page }) => {
|
||||
await signIn(page, 'Chiara');
|
||||
await page.goto(DOC);
|
||||
await expect(page.getByRole('heading', { level: 1 })).toHaveText("Acte d'engagement Certification");
|
||||
const units = page.locator('section.text article.unit');
|
||||
await expect(units).toHaveCount(3);
|
||||
await expect(units.nth(0).locator('h2')).toHaveText('Préambule');
|
||||
await expect(units.nth(0).locator('h2')).toHaveText("Raison d'être");
|
||||
await expect(units.nth(1).locator('h2')).toHaveText('Unicité du compte');
|
||||
await expect(units.nth(2).locator('h2')).toHaveText('Réciprocité');
|
||||
await expect(page.getByText('seed a minima · 0 vote')).toHaveCount(3);
|
||||
@@ -70,19 +70,20 @@ test('C5 — une proposition remonte en vigueur quand elle atteint son seuil (gr
|
||||
test('C6 — une coquille se corrige sans vote', async ({ page }) => {
|
||||
await signIn(page, 'Chiara');
|
||||
await page.goto(TEST_DOC);
|
||||
const preamble = page.locator('section.text article.unit').first();
|
||||
await preamble.hover();
|
||||
await preamble.getByRole('button', { name: 'Le vote' }).click();
|
||||
const unicity = page.locator('section.text article.unit', { hasText: 'Unicité du compte' });
|
||||
await unicity.hover();
|
||||
await unicity.getByRole('button', { name: 'Le vote' }).click();
|
||||
const panel = page.locator('aside.panel');
|
||||
await panel.getByText('Corriger une coquille').click();
|
||||
const body = panel.getByLabel('Texte', { exact: true });
|
||||
await body.fill((await body.inputValue()).replace('latransmission', 'la transmission'));
|
||||
// Typographic apostrophes: the letters and the signs stay, only their style changes.
|
||||
await body.fill((await body.inputValue()).replaceAll("'", '’'));
|
||||
await panel.getByRole('button', { name: 'Enregistrer la correction' }).click();
|
||||
await expect(page.getByText('Coquille corrigée, sans toucher aux votes.')).toBeVisible();
|
||||
await expect(preamble).toContainText('la transmission de ce document');
|
||||
await expect(unicity).toContainText('Je m’engage sur l’honneur');
|
||||
// A change of meaning is turned away.
|
||||
await panel.getByText('Corriger une coquille').click();
|
||||
await body.fill('Tout autre chose, qui change le sens du préambule.');
|
||||
await body.fill('Tout autre chose, qui change le sens de cet engagement.');
|
||||
await panel.getByRole('button', { name: 'Enregistrer la correction' }).click();
|
||||
await expect(panel.getByText('Ce changement touche au sens : propose-le comme modification.')).toBeVisible();
|
||||
});
|
||||
@@ -187,3 +188,20 @@ test('C12 — lien d’équipe : chaque personne qui l’ouvre a sa propre ident
|
||||
await expect(team.getByText('2 / 30 personnes', { exact: false })).toBeVisible();
|
||||
await expect(yvv.getByText('venue par « Équipe de test »')).toHaveCount(2);
|
||||
});
|
||||
|
||||
test('C13 — la Raison d’être ouvre le texte en vigueur, en trois langues', async ({ page }) => {
|
||||
await signIn(page, 'Chiara');
|
||||
await page.goto(DOC);
|
||||
const first = page.locator('section.text article.unit').first();
|
||||
await expect(first.locator('h2')).toHaveText("Raison d'être");
|
||||
// The first sentence in italics, then two paragraphs.
|
||||
const paragraphs = first.locator('.prose p');
|
||||
await expect(paragraphs).toHaveCount(3);
|
||||
await expect(paragraphs.nth(0).locator('em')).toContainText("Derrière une clé il n'y a qu'un seul être humain vivant");
|
||||
await expect(paragraphs.nth(1)).toContainText("C'est le seul et unique propos de la certification");
|
||||
await expect(paragraphs.nth(2)).toContainText('la première monnaie libre');
|
||||
await page.getByRole('radiogroup', { name: 'Langue du texte' }).getByRole('radio', { name: 'EN' }).click();
|
||||
await expect(first.locator('h2')).toHaveText('Purpose');
|
||||
await page.getByRole('radiogroup', { name: 'Text language' }).getByRole('radio', { name: 'ES' }).click();
|
||||
await expect(first.locator('h2')).toHaveText('Razón de ser');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user