| 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 |
|
|---|
| 13 | import { test } from 'node:test';
|
|---|
| 14 | import assert from 'node:assert/strict';
|
|---|
| 15 |
|
|---|
| 16 | process.env.DATABASE_PATH = ':memory:';
|
|---|
| 17 | const gated = await import('../src/services/guardianship/gated.js');
|
|---|
| 18 |
|
|---|
| 19 | const rij = (rows, f) => rows.find((r) => r.feature === f);
|
|---|
| 20 |
|
|---|
| 21 | test('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 |
|
|---|
| 30 | test('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 |
|
|---|
| 36 | test('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 |
|
|---|
| 43 | test('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 |
|
|---|
| 51 | test('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 |
|
|---|
| 58 | test('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 |
|
|---|
| 67 | test('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 |
|
|---|
| 75 | test('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 |
|
|---|
| 80 | test('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 |
|
|---|
| 89 | test('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 |
|
|---|
| 97 | test('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 |
|
|---|
| 107 | test('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 |
|
|---|
| 114 | test('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 | });
|
|---|