source: Klonkt/test/guardian-gate-panel.test.js@ 3b43e4c

main
Last change on this file since 3b43e4c was b2646cc, checked in by roboburr <roboburr@…>, 5 weeks ago

Waarschuwen voor wat er blijft hangen (shaer-nf9)

Barts opdracht: waarschuw bij het openen en het accepteren van een gate-voorstel.
Zijn zin was "Een geopende poort gaat niet meer dicht!"

DIE ZIN STAAT ER NIET, EN DAT IS MET OPZET. Als uitspraak over de INSTELLING is
hij onwaar: shaer-ahy eist het tegendeel en de code doet het -- een voorstel
draagt true of false. Een waarschuwing die aantoonbaar niet klopt neemt de rest
van het scherm mee in zijn val zodra iemand het merkt.

Wat wel onomkeerbaar is, is het GEVOLG, en die versie is zwaarder:

Wat hier doorheen komt, komt niet meer terug. Je kunt deze instelling later
weer dichtzetten -- wat je kind gezien heeft niet.

Independence krijgt zijn eigen tekst, want dat draagt gezag over en is wel echt
onomkeerbaar (shaer-90v). Welke tekst je krijgt volgt uit de catalogus, dus een
nieuwe gate hoeft niets te bedenken.

ONBEKEND KRIJGT DE ZWAARSTE. Een guardian elders kan iets voorstellen dat onze
catalogus niet kent. Bij twijfel waarschuwen we zwaarder, niet lichter -- de
faalstand die pijn doet is een guardian die iets doorlaat omdat het scherm er
licht over deed.

ALLEEN BIJ OPENZETTEN. Dichtzetten laat niets nieuws door, en een waarschuwing
die overal staat wordt nergens gelezen.

BIJ ACCEPTEREN KON HET GEVRAAGDE NIET. De bead stelde voor te tonen of jouw
antwoord de drempel haalt, want gatedProgress bestaat al. Maar die werkt op een
LOKALE slug, en er zijn geen lokale wards -- voor deze kaart komt hij altijd op
null uit. Een verzonnen "1 van 2" zou hier het gevaarlijkste getal op het scherm
zijn: het leest als "er kan nog iemand na mij". Er staat nu wat waar is: wij zien
de telling niet, die loopt op de server van het kind, en jouw ja kan de doorslag
geven -- want de tally settelt op het moment dat de drempel gehaald is.

Geen window.confirm, zoals bij het loslaten van een ward: de uitleg staat er, en
dan pas de knop. Drie talen. Vier toetsen, twee vallen om bij mutatie. 619/619.

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[792af53]1// Het gate-paneel per ward (shaer-ahy.1).
2//
3// Wat gated wordt is een ontwerpkeuze van de implementatie -- de FEP levert het
4// mechanisme en een paar voorbeelden, niet de lijst. GATE_CATALOGUE is die lijst
5// op een plek, en gateRows maakt er de rijen van die het paneel toont.
6//
7// De regels die hier bewaakt worden zijn geen opmaak maar betekenis: een gate
8// die je niet kunt verzetten hoort tOch zichtbaar te zijn, onbekend is niet uit,
9// en er wordt geen drempel verzonnen die we niet kennen.
10//
11// Run: npm test
12
13import { test } from 'node:test';
14import assert from 'node:assert/strict';
15
16process.env.DATABASE_PATH = ':memory:';
17const gated = await import('../src/services/guardianship/gated.js');
18
19const rij = (rows, f) => rows.find((r) => r.feature === f);
20
21test('elke gate uit de catalogus krijgt een rij, ook de vaste', () => {
22 // Een paneel dat alleen verstelbare dingen toont verzwijgt de helft van wat er
23 // voor dit kind geldt.
24 const rows = gated.gateRows({});
25 assert.equal(rows.length, gated.GATE_CATALOGUE.length);
26 assert.ok(rij(rows, 'shaer:follows'), 'volgverzoeken zijn altijd gated en horen er tOch te staan');
27 assert.equal(rij(rows, 'shaer:follows').adjustable, false, 'maar niet te verzetten');
28});
29
30test('het soort staat erbij, want ze werken niet hetzelfde', () => {
31 const rows = gated.gateRows({});
32 assert.equal(rij(rows, 'shaer:externalEmbeds').kind, 'setting');
33 assert.equal(rij(rows, 'shaer:follows').kind, 'perRequest');
34});
35
36test('de drempel volgt het aantal guardians', () => {
37 const drie = gated.gateRows({ guardianCount: 3 });
38 assert.deepEqual(rij(drie, 'shaer:externalEmbeds').threshold, { need: 2, of: 3 });
39 const een = gated.gateRows({ guardianCount: 1 });
40 assert.deepEqual(rij(een, 'shaer:externalEmbeds').threshold, { need: 1, of: 1 });
41});
42
43test('een ONBEKEND aantal guardians levert GEEN drempel op', () => {
44 // Bij een ward elders wordt die set op diens eigen server bijgehouden. Een
45 // verzonnen getal leest als een feit, en dit is precies waar een guardian op
46 // afgaat voordat hij iets voorstelt.
47 const rows = gated.gateRows({ guardianCount: null });
48 assert.equal(rij(rows, 'shaer:externalEmbeds').threshold, null);
49});
50
51test('afspelen is dicht zolang zien UIT staat', () => {
52 const rows = gated.gateRows({ settings: { 'shaer:externalEmbeds': false } });
53 const p = rij(rows, 'shaer:externalPlayback');
54 assert.equal(p.adjustable, false);
55 assert.equal(p.blockedBy, 'shaer:externalEmbeds');
56});
57
58test('maar ONBEKEND is niet hetzelfde als uit', () => {
59 // Verbergen bij onbekend betekende ooit dat een guardian elders afspelen nooit
60 // kon voorstellen -- daar ging een hele voorstelronde de verkeerde gate in.
61 const rows = gated.gateRows({ settings: { 'shaer:externalEmbeds': null } });
62 const p = rij(rows, 'shaer:externalPlayback');
63 assert.equal(p.adjustable, true);
64 assert.equal(p.blockedBy, undefined);
65});
66
67test('een lopend voorstel hangt aan zijn eigen gate', () => {
68 const rows = gated.gateRows({
69 proposals: [{ feature: 'shaer:externalPlayback', value: true, status: 'open' }],
70 });
71 assert.equal(rij(rows, 'shaer:externalPlayback').proposal.status, 'open');
72 assert.equal(rij(rows, 'shaer:externalEmbeds').proposal, undefined);
73});
74
75test('wat er wacht staat bij de gate waar het op wacht', () => {
76 const rows = gated.gateRows({ waiting: { 'shaer:follows': 2 } });
77 assert.equal(rij(rows, 'shaer:follows').waiting, 2);
78});
79
[72d8eff]80test('de stand komt uit de BESLUITEN, en zegt of er wel besloten is', () => {
81 // Er zijn geen lokale accounts: elke ward woont elders, dus de kolom op onze
82 // eigen sites-tabel is voor iedere ward leeg. Wat een guardian wel heeft is de
83 // uitslag van wat hij voorstelde.
84 const aan = gated.gateRows({ settings: { 'shaer:externalEmbeds': { value: true, decided: true } } });
85 assert.equal(rij(aan, 'shaer:externalEmbeds').value, true);
86 assert.equal(rij(aan, 'shaer:externalEmbeds').decided, true);
87});
88
89test('nooit besloten is iets anders dan besloten-uit', () => {
90 // "Uit" en "voor zover wij weten uit" zijn niet hetzelfde. Dat tweede als een
91 // besluit tonen suggereert dat iemand het genomen heeft.
92 const r = rij(gated.gateRows({ settings: { 'shaer:externalEmbeds': { value: false, decided: false } } }), 'shaer:externalEmbeds');
93 assert.equal(r.value, false);
94 assert.equal(r.decided, false);
95});
96
97test('de trap blokkeert alleen op een BESLOTEN dicht', () => {
98 // Blokkeren op de standaard zou betekenen dat afspelen nooit als eerste
99 // voorgesteld kan worden -- en zo ging er ooit een hele voorstelronde de
100 // verkeerde gate in.
101 const standaard = gated.gateRows({ settings: { 'shaer:externalEmbeds': { value: false, decided: false } } });
102 assert.equal(rij(standaard, 'shaer:externalPlayback').adjustable, true);
103 const beslist = gated.gateRows({ settings: { 'shaer:externalEmbeds': { value: false, decided: true } } });
104 assert.equal(rij(beslist, 'shaer:externalPlayback').adjustable, false);
105});
106
107test('de oude vorm (kale boolean) blijft werken', () => {
108 // Backwards: een aanroeper die nog true/false doorgeeft hoort niet om te vallen.
109 const r = rij(gated.gateRows({ settings: { 'shaer:externalEmbeds': true } }), 'shaer:externalEmbeds');
110 assert.equal(r.value, true);
111 assert.equal(r.decided, true);
112});
113
[792af53]114test('omkeerbaarheid staat per gate genoteerd', () => {
115 // Nu is alles omkeerbaar. Zodra independence erbij komt (shaer-90v) is dat het
116 // niet, en dan moet het paneel dat kunnen zeggen zonder verbouwing.
117 for (const r of gated.gateRows({})) assert.equal(typeof r.reversible, 'boolean');
118});
[b2646cc]119
120// ── De waarschuwing bij een voorstel (shaer-nf9) ────────────────────────
121
122test('een gewone gate waarschuwt omkeerbaar, niet onomkeerbaar', () => {
123 // Barts zin "een geopende poort gaat niet meer dicht" klopt niet over de
124 // INSTELLING -- die gaat wel weer dicht. Zo'n aantoonbaar onware waarschuwing
125 // neemt de rest van het scherm mee in zijn val zodra iemand het merkt.
126 assert.equal(gated.gateConsequence('shaer:externalEmbeds'), 'reversible');
127});
128
129test('independence waarschuwt WEL onomkeerbaar', () => {
130 // De enige die gezag overdraagt (shaer-90v). Daar is Barts zin wel waar.
131 assert.equal(gated.gateConsequence('shaer:independence'), 'irreversible');
132});
133
134test('een gate die we NIET kennen krijgt de zwaarste tekst', () => {
135 // Een mede-guardian elders kan iets voorstellen dat onze catalogus niet kent.
136 // Bij twijfel waarschuwen we zwaarder, niet lichter: de faalstand die hier pijn
137 // doet is een guardian die iets doorlaat omdat het scherm er licht over deed.
138 assert.equal(gated.gateConsequence('shaer:ietsNieuws'), 'unknown');
139});
140
141test('elke gate uit de catalogus levert een gevolg op', () => {
142 // Anders valt er stilletjes een rij zonder waarschuwing door.
143 for (const g of gated.GATE_CATALOGUE) {
144 assert.ok(['reversible', 'irreversible'].includes(gated.gateConsequence(g.feature)), g.feature);
145 }
146});
Note: See TracBrowser for help on using the repository browser.