source: Klonkt/test/queue-keys-contract.test.js

main
Last change on this file was 2165b6d, checked in by Robin <roboburr@…>, 4 days ago

Wachtrij-contract: wat de actor adverteert ligt vast en moet bestaan (shaer-x3kj)

De daemon en Klonkt delen dit contract (shaer-6d9), en zo ontstond die
bead: Klonkt kreeg er outgoingFollows en help bij, de daemon bleef op
vier staan, en een client die tegen allebei praat vindt twee sleutels
maar op een van de twee.

Deze toets bewaakt de kant die HIER te bewaken is. De zes sleutels
liggen vast, dus een zevende is een bewuste daad met een rode toets
ernaast in plaats van stille drift. En elke geadverteerde sleutel moet
naar een bestaande route wijzen: adverteren wat er niet is, is erger dan
niet adverteren -- dan haalt een client het en krijgt 404 op iets wat het
actor-document beloofde. Zonder token is 403 het goede antwoord; alleen
404 is fout.

Tegenbewijs: een zevende sleutel toevoegen EN een bestaande naar een
onbestaande route laten wijzen laat allebei de toetsen vallen.

De daemon-helft zelf zit hier niet in: die vraagt Rust, en er is op geen
van de bereikbare machines een toolchain om te bouwen of te toetsen. Zie
de bead voor wat daar nog moet en waarom het meer is dan twee routes.

Volle suite 1262 groen.

  • Property mode set to 100644
File size: 3.3 KB
RevLine 
[2165b6d]1// Wat de actor als wachtrij ADVERTEERT, moet er ook zijn -- en de lijst mag
2// niet stilletjes groeien (shaer-x3kj, contract uit shaer-6d9).
3//
4// De daemon en Klonkt delen dit contract: een client die tegen allebei praat
5// mag geen sleutel op de een vinden en op de ander niet. Zo ontstond deze bead:
6// Klonkt kreeg er outgoingFollows en help bij, de daemon bleef op vier staan,
7// en de UI die je tegen de daemon test zegt dan niets over Klonkt.
8//
9// Deze toets bewaakt de kant die HIER te bewaken is:
10// 1. de sleutelverzameling ligt vast, dus een zevende sleutel is een bewuste
11// daad met een rode toets ernaast in plaats van stille drift;
12// 2. elke geadverteerde sleutel wijst naar een route die BESTAAT. Adverteren
13// wat er niet is, is erger dan niet adverteren -- dan gaat een client hem
14// halen en krijgt 404 op iets wat het actor-document beloofde.
15//
16// De spiegelkant (draait de daemon dezelfde zes?) hoort in de daemon zelf; die
17// heeft geen toegang tot deze suite en andersom.
18import { test } from 'node:test';
19import assert from 'node:assert/strict';
20
21process.env.DATABASE_PATH = ':memory:';
22process.env.PUBLIC_BASE_URL = 'https://test.example';
23
24const dbMod = await import('../src/config/database.js');
25const db = dbMod.default;
26{ const stil = console.log; console.log = () => {}; try { dbMod.initializeDatabase(); } finally { console.log = stil; } }
27const express = (await import('express')).default;
28const routes = (await import('../src/routes/activitypub.js')).default;
29
30db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)').run('u1', 'u1', 'u1@t', 'x', 'god');
31db.prepare('INSERT INTO sites (id, slug, title, owner_id, is_public, is_primary) VALUES (?,?,?,?,1,1)').run('s1', 'kid', 'Kid', 'u1');
32
33const app = express(); app.use(routes);
34const server = app.listen(0);
35await new Promise((r) => server.once('listening', r));
36const base = `http://127.0.0.1:${server.address().port}`;
37test.after(() => server.close());
38
39// De zes die Klonkt vandaag adverteert. Komt er een bij, dan hoort hij hier
40// EN in de daemon -- dat is het hele punt van shaer-6d9.
41const VERWACHT = ['follows', 'guardians', 'help', 'offers', 'outgoingFollows', 'wards'];
42
43async function queues() {
44 const r = await fetch(`${base}/ap/users/kid`, { headers: { Accept: 'application/activity+json' } });
45 assert.equal(r.status, 200, 'het actor-document hoort er te zijn');
46 return (await r.json())['shaer:queues'] || {};
47}
48
49test('de actor adverteert precies de afgesproken wachtrijen', async () => {
50 assert.deepEqual(Object.keys(await queues()).sort(), [...VERWACHT].sort(),
51 'wijkt dit af, dan loopt Klonkt uit de pas met de daemon (shaer-x3kj)');
52});
53
54test('elke geadverteerde wachtrij bestaat als route', async () => {
55 const q = await queues();
56 const missend = [];
57 for (const [sleutel, url] of Object.entries(q)) {
58 // Zonder token geeft een bestaande wachtrij 403 (alleen de eigenaar mag
59 // erin). 404 betekent dat de route niet bestaat -- dan belooft het
60 // actor-document iets wat er niet is.
61 const r = await fetch(base + new URL(url).pathname, { headers: { Accept: 'application/activity+json' } });
62 if (r.status === 404) missend.push(`${sleutel} -> ${new URL(url).pathname}`);
63 }
64 assert.deepEqual(missend, [], 'geadverteerd maar niet bereikbaar');
65});
Note: See TracBrowser for help on using the repository browser.