source: Klonkt/test/gate-request.test.js@ 2bfe26c

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

Voorstellen vanuit de app, en een kind dat zelf kan vragen (shaer-8ru)

Barts opdracht: bouw shaer-8ru zodat de apps ook kunnen voorstellen, en maak
daarnaast het pad voor de ward om zelf een voorstel aan te zwengelen als hij
tegen een gated feature aanloopt.

DEEL 1 -- DE APPS KUNNEN VOORSTELLEN. De outbox kent nu een Offer van een
shaer:GatedSetting, precies de vorm die 5.6 al beschrijft en die de inbox al las.
De afweging zelf is verhuisd naar AP.proposeGate, waar de PWA-route nu ook
doorheen loopt. Twee implementaties naast elkaar zou een tweede weg naar
hetzelfde besluit zijn -- exact de fout die we vanmiddag bij de antwoordpoort
rechtzetten, toen de innamepoort alleen in C2S bleek te zitten.

DEEL 2 -- HET KIND KRIJGT WOORDEN. Tot nu toe liep alles over de guardians: zij
zien de catalogus, zij stellen voor, zij tellen. Het kind liep tegen een dichte
deur en kon niets. Nu stuurt het een shaer:gateRequest, en die landt bij zijn
guardians BIJ DE POORT waar hij over gaat -- niet in een aparte lijst die je
apart moet openen en dus vergeet.

EEN VRAAG IS GEEN STEM, en dat is de hele grens. Het verzoek is geen voorstel en
telt nergens mee; pas als een guardian het oppakt wordt het een voorstel dat
langs de gewone tally gaat. Anders opent een kind zijn eigen poort door hard
genoeg te vragen. Er staat een toets op die kijkt of er echt geen voorstel en
geen open poort uit ontstaat.

NIET DE REDDINGSBOEI. Een hulpvraag is een noodgeval en gaat door elke dichte
deur; dit is een wens. Ze door elkaar laten lopen zou de boei devalueren tot "het
kind wil iets", en dan kijkt er op een dag niemand meer op als hij afgaat.

GEEN VRIJE TEKST, en dat is geen gierigheid maar de reden dat het verzoek langs
de messages-poort MAG. Een kind met berichten dicht kan nog steeds om iets
vragen, zonder dat er een kanaal ontstaat om omheen die poort te praten. Wil het
uitleggen waarom, dan is dat een gesprek, en gesprekken hebben hun eigen poort.

Alleen van een eigen ward: een verzoek van een vreemde is geen vraag maar een
onbekende die iets over jouw instellingen wil zeggen.

Twaalf toetsen. Twee mutaties gecontroleerd (1 en 6 rood). Suite 712/712.

  • Property mode set to 100644
File size: 4.2 KB
Line 
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
13import { test } from 'node:test';
14import assert from 'node:assert/strict';
15
16process.env.DATABASE_PATH = ':memory:';
17process.env.PUBLIC_BASE_URL = 'https://oma.test';
18
19const dbMod = await import('../src/config/database.js');
20const db = dbMod.default;
21dbMod.initializeDatabase();
22const Guardianship = await import('../src/services/guardianship/index.js');
23const gatereq = await import('../src/services/guardianship/gatereq.js');
24const rel = await import('../src/services/guardianship/relations.js');
25const queues = await import('../src/services/guardianship/queues.js');
26
27db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
28 .run('u1', 'u1', 'u1@t', 'x', 'god');
29db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)').run('s1', 'oma', 'Oma', 'u1');
30const KIND = 'https://elders.test/ap/users/kind';
31rel.commitWardForGuardian('oma', KIND, { handle: '@kind' });
32
33test('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
40test('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
49test('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.waiting, 1);
53});
54
55test('afgehandeld verdwijnt uit het zicht maar niet uit de geschiedenis', () => {
56 // Er wordt niets herschreven, er wordt toegevoegd -- zelfde regel als bij de
57 // hulpvraag: wat een kind gevraagd heeft hoort terug te vinden te zijn, ook
58 // als het antwoord nee was.
59 gatereq.markHandled('oma', KIND, 'shaer:images');
60 assert.equal(gatereq.listOpen('oma').length, 0);
61 const alles = db.prepare('SELECT * FROM ap_gate_requests WHERE ward_uri = ?').all(KIND);
62 assert.equal(alles.length, 1);
63 assert.ok(alles[0].handled_at, 'met een stempel erop');
64});
65
66test('een verzoek zonder feature is geen verzoek', () => {
67 assert.equal(gatereq.parseRequest({ content: 'hoi' }), null);
68 assert.equal(gatereq.parseRequest({ 'shaer:gateRequest': '' }), null);
69 assert.deepEqual(gatereq.parseRequest({ 'shaer:gateRequest': 'shaer:music' }), { feature: 'shaer:music' });
70});
71
72test('het verzoek draagt GEEN vrije tekst van het kind', () => {
73 // Dat is niet gierig maar precies de reden dat hij langs de messages-poort
74 // mag: anders is dit een kanaal om omheen die poort te praten.
75 const note = gatereq.requestNote({ id: 'x', me: 'https://k/u/kind', feature: 'shaer:music', to: ['https://oma.test/ap/users/oma'] });
76 assert.equal(note['shaer:gateRequest'], 'shaer:music');
77 assert.equal(note.content, '<p>Mag dit aan?</p>');
78});
79
80test('een verzoek is NIET de reddingsboei', () => {
81 // Ze door elkaar laten lopen devalueert de boei. Een verzoek draagt geen
82 // helpRequest-vlag, en een hulpvraag geen feature.
83 const note = gatereq.requestNote({ id: 'x', me: 'https://k/u/kind', feature: 'shaer:music', to: [] });
84 assert.equal(note['shaer:helpRequest'], undefined);
85 assert.equal(gatereq.parseRequest({ 'shaer:helpRequest': true }), null);
86});
Note: See TracBrowser for help on using the repository browser.