forked from yvv/decision
v3 : interface des objections, des coquilles validées et de la messagerie ; contrôles C28–C31
Une version retenue par une objection le dit sous l'article, à chacun selon son rôle : la personne qui vote voit qu'elle ne se vote plus (les votes faits restent) ; l'auteur, quoi faire (« Modifier l'article visé » pour une redite, « Reformuler » pour une contradiction) ; la personne qui objecte, lever ou réitérer avant l'échéance. Le panier la montre sans choix et ne l'envoie jamais. « Détails » : faire une objection (redit / contredit), les objections et où elles en sont, les coquilles proposées par d'autres avec leur diff resserré, valider / refuser / revenir, l'historique dit qui a validé. Une coquille se propose sur toute version ouverte ou en vigueur. Boîte « Messages » dans le menu, avec le nombre de non-lus (pastille sur le bouton du menu en mobile) : objet, texte, gestes, échéance ; un message traité n'a plus de geste. Répondre à une objection lit son message. Trilingue (fr, en, es). C6 suit la règle : la coquille d'un administrateur sur un texte du seed passe tout de suite ; C28–C31 couvrent le reste. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { clearScope, counts, fill, lines, sections, waiting } from '../../src/lib/basket';
|
||||
import { clearScope, counts, fill, lines, sections, votableIds, waiting } from '../../src/lib/basket';
|
||||
import type { Proposal, Unit } from '../../src/lib/types';
|
||||
|
||||
function prop(id: string, unitId: string, over: Partial<Proposal> = {}): Proposal {
|
||||
@@ -7,7 +7,7 @@ function prop(id: string, unitId: string, over: Partial<Proposal> = {}): Proposa
|
||||
id, unitId, kind: 'text', inertiaTarget: null, title: unitId, body: `texte ${id}`, status: 'open', origin: 'seed',
|
||||
label: null, author: null, mine: false, revision: 1, createdAt: '', updatedAt: '', submittedAt: null, enteredAt: null,
|
||||
confirmedAt: null, seedMinimal: false, tally: { for: 0, against: 0 }, evaluation: null, votedAtInertia: 3,
|
||||
blocked: false, signals: 0, myVote: null, myVoteStale: false, myVoteChain: false, myBallot: null, translations: {},
|
||||
blocked: false, votable: true, objections: 0, myVote: null, myVoteStale: false, myVoteChain: false, myBallot: null, translations: {},
|
||||
...over,
|
||||
};
|
||||
}
|
||||
@@ -72,4 +72,26 @@ describe('the basket of a vote', () => {
|
||||
]);
|
||||
expect(counts({ i1: 'for', e2: 'none', e4: 'against', e5: 'for' })).toEqual({ for: 2, against: 1, none: 1, total: 4 });
|
||||
});
|
||||
|
||||
it('a version held back by an objection is shown apart: no grouped gesture fills it, nothing is sent for it', () => {
|
||||
// E5 has the text in force and a rival held back; E6 is a new article, held back.
|
||||
const e5 = unit('E5', 'technique', prop('e5', 'E5', { status: 'in_force' }), [
|
||||
prop('e5r', 'E5', { blocked: true, votable: false }),
|
||||
]);
|
||||
const e6 = unit('E6', 'technique', null, [prop('e6', 'E6', { blocked: true, votable: false })]);
|
||||
const s = sections([e5, e6]);
|
||||
const [slotE5, slotE6] = s[0]?.slots ?? [];
|
||||
expect(slotE5?.versions.map((p) => p.id)).toEqual(['e5']);
|
||||
expect(slotE5?.held.map((p) => p.id)).toEqual(['e5r']);
|
||||
// A held article stays in sight, with nothing to choose.
|
||||
expect(slotE6?.versions).toEqual([]);
|
||||
expect(slotE6?.held.map((p) => p.id)).toEqual(['e6']);
|
||||
const all = s.flatMap((x) => x.slots);
|
||||
// The held rival does not compete now: the text in force is the only choice.
|
||||
expect(fill(all, 'for', {})).toEqual({ e5: 'for' });
|
||||
expect(waiting(all, {})).toEqual([]);
|
||||
// A choice kept from before the objection is not sent.
|
||||
expect(lines({ e5: 'for', e5r: 'for' }, votableIds(s))).toEqual([{ proposalId: 'e5', choice: 'for' }]);
|
||||
expect(clearScope(all, { e5: 'for', e5r: 'against', i1: 'for' })).toEqual({ i1: 'for' });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user