source: Klonkt/test/help-c2s.test.js@ a9ede28

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

Open hulpvragen worden nooit afgekapt (shaer-6wt)

Ik vond dit zelf en zette het op P3: "vergt tientallen hulpvragen bij een
guardian". Bart: "precies de jeugdzorgmedewerker."

DAT IS GEEN RANDGEVAL MAAR EEN CASELOAD. Een professionele voogd heeft geen
handvol wards; voor hem zijn tientallen open hulpvragen een gewone dinsdag. De
gebruiker die deze machinerie het hardst nodig heeft was precies degene voor wie
hij brak, en ik had hem als uitzondering weggeschreven.

Wat er misging: de queue kapte op 50. Een oudere vraag zat er niet in, de app
vond geen staat, en toonde hem -- terecht, want bij twijfel OPEN -- alsof er nog
iemand op moest. Een allang afgehandelde hulpvraag die weer om aandacht vraagt.

De regel bij-twijfel-open blijft; die is goed. Wat verandert is dat de twijfel
verdwijnt: OPEN vragen worden nooit afgekapt, dus mag een app concluderen dat wat
er niet in staat ook niet open is. De geschiedenis mag wel afgekapt -- die vraagt
niets, en staat nog gewoon op de server.

shaer:openComplete op de collectie zegt dat die gevolgtrekking is toegestaan.
Ontbreekt de vlag (een oudere server), dan valt de app terug op bij-twijfel-open,
en dat is de veilige kant.

Toets met 120 open vragen. Suite 720/720; met de afkap terug valt er een om.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1// Een hulpvraag oppikken en afsluiten vanuit de app (shaer-lgo, Barts melding 8-8).
2//
3// De apps lazen hulpvragen uit de FEED en kregen de staat niet mee. Ze wisten dus
4// niet of er al iemand op af was, en een afgehandeld verzoek bleef gewoon staan.
5//
6// Wat hier bewaakt wordt: de app loopt door dezelfde markering en dezelfde staat
7// als het paneel. Twee berekeningen zouden twee guardians een ander beeld geven
8// van hetzelfde kind -- en bij een reddingsboei is dat het gevaarlijkste dat er
9// mis kan gaan.
10//
11// In-memory SQLite. Run: npm test
12import { test } from 'node:test';
13import assert from 'node:assert/strict';
14
15process.env.DATABASE_PATH = ':memory:';
16process.env.PUBLIC_BASE_URL = 'https://oma.test';
17
18const dbMod = await import('../src/config/database.js');
19const db = dbMod.default;
20dbMod.initializeDatabase();
21const AP = await import('../src/services/ActivityPubService.js');
22const queues = await import('../src/services/guardianship/queues.js');
23const rel = await import('../src/services/guardianship/relations.js');
24
25db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
26 .run('u1', 'u1', 'u1@t', 'x', 'god');
27db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)').run('s1', 'oma', 'Oma', 'u1');
28const site = () => db.prepare('SELECT * FROM sites WHERE id = ?').get('s1');
29const user = { id: 'u1', username: 'u1' };
30const KIND = 'https://elders.test/ap/users/kind';
31const BOEI = 'https://elders.test/ap/notes/boei-1';
32rel.commitWardForGuardian('oma', KIND, { handle: '@kind' });
33db.prepare(`INSERT INTO ap_mentions (slug, object_uri, actor_uri, actor_handle, content, help_request)
34 VALUES (?,?,?,?,?,1)`).run('oma', BOEI, KIND, '@kind', '<p>help</p>');
35
36const marker = (kind) => ({
37 type: 'Create',
38 object: {
39 type: 'Note',
40 content: '<p>.</p>',
41 to: [KIND],
42 [kind === 'handled' ? 'shaer:helpHandled' : 'shaer:helpPickup']: BOEI,
43 },
44});
45
46test('een verse hulpvraag staat OPEN', () => {
47 const h = queues.helpItemsFor('oma').find((x) => x.object_uri === BOEI);
48 assert.equal(h.state.open, true);
49 assert.equal(h.state.handled, null);
50});
51
52test('oppikken vanuit de app landt in dezelfde staat als het paneel', async () => {
53 await AP.ingestOutboxActivity(site(), user, marker('pickup'));
54 const h = queues.helpItemsFor('oma').find((x) => x.object_uri === BOEI);
55 assert.equal(h.state.pickedUpBy.length, 1);
56 // Nog steeds open: oppikken is geen afhandelen. De faalstand hier is
57 // "iedereen denkt dat het geregeld is", en die is gevaarlijker dan geen
58 // markering.
59 assert.equal(h.state.open, true);
60});
61
62test('afsluiten vanuit de app sluit hem ook echt', async () => {
63 await AP.ingestOutboxActivity(site(), user, marker('handled'));
64 const h = queues.helpItemsFor('oma').find((x) => x.object_uri === BOEI);
65 assert.equal(h.state.open, false);
66 assert.ok(h.state.handled, 'met wie het deed erbij');
67});
68
69test('de collectie voor de apps draagt de staat plat mee', () => {
70 // Een app hoeft hem niet af te leiden, en kan hem dus ook niet anders
71 // afleiden dan het paneel.
72 const coll = queues.helpCollection('https://x/queues/help', 'oma');
73 const item = coll.orderedItems.find((i) => i.id === BOEI);
74 assert.equal(item['shaer:open'], false);
75 assert.ok(item['shaer:handledBy']);
76 assert.equal(item['shaer:helpRequest'], true);
77});
78
79test('een note zonder markering blijft een gewoon bericht', async () => {
80 const uit = await AP.ingestOutboxActivity(site(), user, {
81 type: 'Create', object: { type: 'Note', content: '<p>hoi</p>', to: [KIND] },
82 });
83 assert.notEqual(uit.status, 400);
84});
85
86test('OPEN vragen worden nooit afgekapt, hoeveel het er ook zijn', () => {
87 // Barts punt (8-8): ik noemde tientallen hulpvragen bij een guardian een
88 // randgeval, maar voor een jeugdzorgmedewerker is dat een caseload en dus een
89 // gewone dinsdag. De gebruiker die dit het hardst nodig heeft was precies
90 // degene voor wie het brak.
91 //
92 // Zonder deze regel viel een oudere vraag buiten de queue, vond de app geen
93 // staat, en toonde hem -- terecht, want bij twijfel OPEN -- alsof er nog
94 // iemand op moest.
95 for (let i = 0; i < 120; i++) {
96 db.prepare(`INSERT INTO ap_mentions (slug, object_uri, actor_uri, actor_handle, content, help_request)
97 VALUES (?,?,?,?,?,1)`).run('oma', `https://elders.test/ap/notes/veel-${i}`, KIND, '@kind', '<p>help</p>');
98 }
99 const open = queues.helpItemsFor('oma').filter((h) => h.state.open);
100 assert.equal(open.length, 120, 'alle 120 open vragen komen mee');
101});
102
103test('de collectie zegt dat je uit afwezigheid mag concluderen', () => {
104 // Zonder die vlag mag een app niets afleiden uit een ontbrekende staat, en
105 // valt hij terug op bij-twijfel-open. Dat is de veilige kant, maar dan komt
106 // een afgehandelde vraag terug in het zicht.
107 const coll = queues.helpCollection('https://x/queues/help', 'oma');
108 assert.equal(coll['shaer:openComplete'], true);
109});
Note: See TracBrowser for help on using the repository browser.