source: Klonkt/test/library-luisteraars.test.js@ 732272a

main
Last change on this file since 732272a was 732272a, checked in by Robin <roboburr@…>, 4 weeks ago

Luisteraars: een eigen tab, want het is een eigen soort relatie (shaer-0nh)

Accounts die aan de BIBLIOTHEEK hangen in plaats van aan de actor. Ze krijgen de
muziek en met opzet NIET de gewone posts -- wie zich op een platenkast
abonneert heeft niet om de Krant gevraagd.

EEN EIGEN TABEL EN GEEN VLAG, en dat is de kern. Zolang ze in
ap_library_followers staan kan een postbezorging ze niet per ongeluk meenemen.
Een vlag op ap_followers die iemand vergeet te filteren doet dat wel, en die
fout is aan onze kant onzichtbaar: de posts komen gewoon aan bij mensen die er
niet om vroegen. De vorm moet de fout onmogelijk maken, niet alleen
onwaarschijnlijk. Een test bewaakt dat ap_followers leeg blijft.

WAT ER WERKT

  • Follow op /ap/users/<slug>/library wordt herkend, meteen geaccepteerd en vastgelegd. Meteen, want de bibliotheek is openbaar (alles erin is fedi_open) -- er valt niets goed te keuren, en dan is wachten oneerlijk.
  • Undo(Follow) haalt hem er meteen weer uit.
  • Volgen is idempotent; remote servers sturen een Follow gerust nog eens.
  • inboxen() ontdubbelt op gedeelde inbox: twee luisteraars op dezelfde instance krijgen EEN bezorging.
  • de tab in Mediabeheer, met naam, handle, sinds en laatste bezorging, in drie talen.

DE HERKENNING IS STRENG. libraryOwnerSlug eist dat de uri met ONZE basis begint
en dat de site bestaat -- via localSlugOf, dezelfde zeef als gisteren. Anders
levert andermans /library met dezelfde padstaart hier een luisteraar op onze
naam op.

WAT ER NOG NIET IS, en dat is de volgende stap: de BEZORGING. Er gaat nog geen
Create(Audio) naar deze inboxen. De lijst vult zich dus wel en "laatste
bezorging" blijft leeg -- eerlijk, want er is niets bezorgd.

Co-Authored-By: Claude Opus 5 <noreply@…>

  • Property mode set to 100644
File size: 3.2 KB
Line 
1// Luisteraars: wie de BIBLIOTHEEK volgt (shaer-0nh).
2//
3// Het hele punt is een NEGATIEVE garantie: deze accounts krijgen de muziek en
4// NIET de gewone posts. Wie zich op een platenkast abonneert heeft niet om de
5// Krant gevraagd. Daarom een eigen tabel en geen vlag: zolang ze ergens anders
6// staan kan een postbezorging ze niet per ongeluk meenemen, en dat is een fout
7// die aan onze kant onzichtbaar zou zijn.
8import { test } from 'node:test';
9import assert from 'node:assert/strict';
10
11process.env.DATABASE_PATH = ':memory:';
12process.env.PUBLIC_BASE_URL = 'https://ons.test';
13
14const dbMod = await import('../src/config/database.js');
15const db = dbMod.default;
16dbMod.initializeDatabase();
17const { luisteraars } = await import('../src/services/music/index.js');
18
19db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
20 .run('u1', 'u1', 'u1@t', 'x', 'god');
21db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)').run('s1', 'band', 'De Band', 'u1');
22
23const VER = 'https://open.audio/federation/actors/iemand';
24
25test('een luisteraar erbij, en volgen is idempotent', () => {
26 assert.equal(luisteraars.voegToe('band', { actorUri: VER, inbox: `${VER}/inbox`, name: 'Iemand', handle: '@iemand@open.audio' }), true);
27 assert.equal(luisteraars.telling('band'), 1);
28 // Twee keer volgen is geen twee luisteraars -- remote servers sturen een
29 // Follow gerust nog eens.
30 luisteraars.voegToe('band', { actorUri: VER, inbox: `${VER}/inbox`, name: 'Iemand Anders' });
31 assert.equal(luisteraars.telling('band'), 1);
32 assert.equal(luisteraars.lijst('band')[0].name, 'Iemand Anders', 'en de laatste gegevens winnen');
33});
34
35test('ze staan NIET tussen de gewone volgers -- dat is de hele garantie', () => {
36 const gewoon = db.prepare('SELECT COUNT(*) n FROM ap_followers WHERE slug = ?').get('band').n;
37 assert.equal(gewoon, 0,
38 'een luisteraar in ap_followers zou de Krant bezorgen bij iemand die alleen muziek wilde');
39});
40
41test('weggaan werkt meteen', () => {
42 assert.equal(luisteraars.verwijder('band', VER), true);
43 assert.equal(luisteraars.telling('band'), 0);
44 assert.equal(luisteraars.verwijder('band', VER), false, 'en twee keer weggaan is geen fout');
45});
46
47test('de inboxen worden ontdubbeld op de gedeelde inbox', () => {
48 // Twee luisteraars op dezelfde instance horen EEN bezorging te krijgen.
49 luisteraars.voegToe('band', { actorUri: `${VER}/a`, inbox: `${VER}/a/inbox`, sharedInbox: 'https://open.audio/inbox' });
50 luisteraars.voegToe('band', { actorUri: `${VER}/b`, inbox: `${VER}/b/inbox`, sharedInbox: 'https://open.audio/inbox' });
51 luisteraars.voegToe('band', { actorUri: 'https://elders.test/u/c', inbox: 'https://elders.test/u/c/inbox' });
52 assert.deepEqual(luisteraars.inboxen('band').sort(),
53 ['https://elders.test/u/c/inbox', 'https://open.audio/inbox']);
54});
55
56test('een luisteraar van een ANDERE site telt hier niet mee', () => {
57 db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)').run('s2', 'ander', 'Ander', 'u1');
58 luisteraars.voegToe('ander', { actorUri: VER, inbox: `${VER}/inbox` });
59 assert.equal(luisteraars.telling('ander'), 1);
60 assert.equal(luisteraars.isLuisteraar('band', VER), false);
61});
Note: See TracBrowser for help on using the repository browser.