| 1 | // Een kind dat zelf om een poort vraagt (shaer-8ru, Barts opdracht 8-8).
|
|---|
| 2 | //
|
|---|
| 3 | // Tot nu toe liep alles over de guardians: zij zien de catalogus, zij stellen
|
|---|
| 4 | // voor, zij tellen. Het kind liep tegen een dichte deur en had geen woorden.
|
|---|
| 5 | //
|
|---|
| 6 | // De twee dingen die hier stil kunnen breken zijn allebei erg:
|
|---|
| 7 | // - een VRAAG die als STEM telt: dan opent een kind zijn eigen poort door
|
|---|
| 8 | // hard genoeg te vragen;
|
|---|
| 9 | // - een vraag die door de reddingsboei loopt: dan devalueert de boei tot
|
|---|
| 10 | // "het kind wil iets", en kijkt er op een dag niemand meer op als hij afgaat.
|
|---|
| 11 | //
|
|---|
| 12 | // In-memory SQLite. Run: npm test
|
|---|
| 13 | import { test } from 'node:test';
|
|---|
| 14 | import assert from 'node:assert/strict';
|
|---|
| 15 |
|
|---|
| 16 | process.env.DATABASE_PATH = ':memory:';
|
|---|
| 17 | process.env.PUBLIC_BASE_URL = 'https://oma.test';
|
|---|
| 18 |
|
|---|
| 19 | const dbMod = await import('../src/config/database.js');
|
|---|
| 20 | const db = dbMod.default;
|
|---|
| 21 | dbMod.initializeDatabase();
|
|---|
| 22 | const Guardianship = await import('../src/services/guardianship/index.js');
|
|---|
| 23 | const gatereq = await import('../src/services/guardianship/gatereq.js');
|
|---|
| 24 | const rel = await import('../src/services/guardianship/relations.js');
|
|---|
| 25 | const queues = await import('../src/services/guardianship/queues.js');
|
|---|
| 26 |
|
|---|
| 27 | db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
|
|---|
| 28 | .run('u1', 'u1', 'u1@t', 'x', 'god');
|
|---|
| 29 | db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)').run('s1', 'oma', 'Oma', 'u1');
|
|---|
| 30 | const KIND = 'https://elders.test/ap/users/kind';
|
|---|
| 31 | rel.commitWardForGuardian('oma', KIND, { handle: '@kind' });
|
|---|
| 32 |
|
|---|
| 33 | test('een verzoek van een eigen ward wordt bewaard', () => {
|
|---|
| 34 | gatereq.record('oma', KIND, 'shaer:images', 'https://elders.test/ap/notes/1');
|
|---|
| 35 | const open = gatereq.listOpen('oma');
|
|---|
| 36 | assert.equal(open.length, 1);
|
|---|
| 37 | assert.equal(open[0].feature, 'shaer:images');
|
|---|
| 38 | });
|
|---|
| 39 |
|
|---|
| 40 | test('een VRAAG is geen STEM', () => {
|
|---|
| 41 | // De grens van dit hele bead. Een verzoek mag nergens als voorstel of als
|
|---|
| 42 | // stem opduiken: anders opent een kind zijn eigen poort door te vragen.
|
|---|
| 43 | assert.equal(Guardianship.gated.listSent('oma', KIND).length, 0);
|
|---|
| 44 | const rij = queues.wardGates('oma', KIND).find((g) => g.feature === 'shaer:images');
|
|---|
| 45 | assert.equal(rij.proposal, undefined, 'geen voorstel');
|
|---|
| 46 | assert.notEqual(rij.value, true, 'en zeker geen open poort');
|
|---|
| 47 | });
|
|---|
| 48 |
|
|---|
| 49 | test('de vraag staat BIJ de poort waar hij over gaat', () => {
|
|---|
| 50 | // Niet in een aparte lijst die je apart moet openen, en dus vergeet.
|
|---|
| 51 | const rij = queues.wardGates('oma', KIND).find((g) => g.feature === 'shaer:images');
|
|---|
| 52 | assert.equal(rij.requested, 1);
|
|---|
| 53 | });
|
|---|
| 54 |
|
|---|
| 55 | test('en NIET op een hoop met de wachtrij', () => {
|
|---|
| 56 | // Drie onbekenden die je kind willen volgen is iets heel anders dan je kind
|
|---|
| 57 | // dat een keer vraagt of muziek aan mag. Een gedeeld getal maakt daar
|
|---|
| 58 | // hetzelfde van, en dan leest de ene urgentie als de andere.
|
|---|
| 59 | const rij = queues.wardGates('oma', KIND).find((g) => g.feature === 'shaer:images');
|
|---|
| 60 | assert.equal(rij.waiting, undefined);
|
|---|
| 61 | });
|
|---|
| 62 |
|
|---|
| 63 | test('afgehandeld verdwijnt uit het zicht maar niet uit de geschiedenis', () => {
|
|---|
| 64 | // Er wordt niets herschreven, er wordt toegevoegd -- zelfde regel als bij de
|
|---|
| 65 | // hulpvraag: wat een kind gevraagd heeft hoort terug te vinden te zijn, ook
|
|---|
| 66 | // als het antwoord nee was.
|
|---|
| 67 | gatereq.markHandled('oma', KIND, 'shaer:images');
|
|---|
| 68 | assert.equal(gatereq.listOpen('oma').length, 0);
|
|---|
| 69 | const alles = db.prepare('SELECT * FROM ap_gate_requests WHERE ward_uri = ?').all(KIND);
|
|---|
| 70 | assert.equal(alles.length, 1);
|
|---|
| 71 | assert.ok(alles[0].handled_at, 'met een stempel erop');
|
|---|
| 72 | });
|
|---|
| 73 |
|
|---|
| 74 | test('een verzoek zonder feature is geen verzoek', () => {
|
|---|
| 75 | assert.equal(gatereq.parseRequest({ content: 'hoi' }), null);
|
|---|
| 76 | assert.equal(gatereq.parseRequest({ 'shaer:gateRequest': '' }), null);
|
|---|
| 77 | assert.deepEqual(gatereq.parseRequest({ 'shaer:gateRequest': 'shaer:music' }), { feature: 'shaer:music' });
|
|---|
| 78 | });
|
|---|
| 79 |
|
|---|
| 80 | test('het verzoek draagt GEEN vrije tekst van het kind', () => {
|
|---|
| 81 | // Dat is niet gierig maar precies de reden dat hij langs de messages-poort
|
|---|
| 82 | // mag: anders is dit een kanaal om omheen die poort te praten.
|
|---|
| 83 | const note = gatereq.requestNote({ id: 'x', me: 'https://k/u/kind', feature: 'shaer:music', to: ['https://oma.test/ap/users/oma'] });
|
|---|
| 84 | assert.equal(note['shaer:gateRequest'], 'shaer:music');
|
|---|
| 85 | assert.equal(note.content, '<p>Mag dit aan?</p>');
|
|---|
| 86 | });
|
|---|
| 87 |
|
|---|
| 88 | test('een verzoek is NIET de reddingsboei', () => {
|
|---|
| 89 | // Ze door elkaar laten lopen devalueert de boei. Een verzoek draagt geen
|
|---|
| 90 | // helpRequest-vlag, en een hulpvraag geen feature.
|
|---|
| 91 | const note = gatereq.requestNote({ id: 'x', me: 'https://k/u/kind', feature: 'shaer:music', to: [] });
|
|---|
| 92 | assert.equal(note['shaer:helpRequest'], undefined);
|
|---|
| 93 | assert.equal(gatereq.parseRequest({ 'shaer:helpRequest': true }), null);
|
|---|
| 94 | });
|
|---|