| 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.
|
|---|
| 18 | import { test } from 'node:test';
|
|---|
| 19 | import assert from 'node:assert/strict';
|
|---|
| 20 |
|
|---|
| 21 | process.env.DATABASE_PATH = ':memory:';
|
|---|
| 22 | process.env.PUBLIC_BASE_URL = 'https://test.example';
|
|---|
| 23 |
|
|---|
| 24 | const dbMod = await import('../src/config/database.js');
|
|---|
| 25 | const db = dbMod.default;
|
|---|
| 26 | { const stil = console.log; console.log = () => {}; try { dbMod.initializeDatabase(); } finally { console.log = stil; } }
|
|---|
| 27 | const express = (await import('express')).default;
|
|---|
| 28 | const routes = (await import('../src/routes/activitypub.js')).default;
|
|---|
| 29 |
|
|---|
| 30 | db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)').run('u1', 'u1', 'u1@t', 'x', 'god');
|
|---|
| 31 | db.prepare('INSERT INTO sites (id, slug, title, owner_id, is_public, is_primary) VALUES (?,?,?,?,1,1)').run('s1', 'kid', 'Kid', 'u1');
|
|---|
| 32 |
|
|---|
| 33 | const app = express(); app.use(routes);
|
|---|
| 34 | const server = app.listen(0);
|
|---|
| 35 | await new Promise((r) => server.once('listening', r));
|
|---|
| 36 | const base = `http://127.0.0.1:${server.address().port}`;
|
|---|
| 37 | test.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.
|
|---|
| 41 | const VERWACHT = ['follows', 'guardians', 'help', 'offers', 'outgoingFollows', 'wards'];
|
|---|
| 42 |
|
|---|
| 43 | async 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 |
|
|---|
| 49 | test('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 |
|
|---|
| 54 | test('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 | });
|
|---|