source: Klonkt/test/ap-library.test.js@ 2091647

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

Een Library-skelet, want zonder bak blijft een track een naam zonder geluid

GEMETEN, en dat gaf dit zijn richting. open.audio heeft onze vier tracks
binnengehaald langs de AP-weg -- met ONZE track-id's als fid, en met een
artist_credit dat Funkwhale zelf uit onze attributedTo afleidde. Precies het
object waarvan ons gevraagd werd het te sturen; dat hoefde dus niet, hij leidt
het af. Maar uploads is leeg en is_playable false.

Het audiobestand is niet het probleem: /audio/stream geeft 200, audio/mpeg,
2722880 bytes, ook anoniem en met een vreemde User-Agent. Ze hebben het niet
opgehaald. Bij Funkwhale hangt een upload aan een LIBRARY, en die hadden we niet.

DE VORM IS DIE UIT HUN DOCS: type Library, id, name, followers, totalItems,
first, last, plus attributedTo en summary. Onze pagedCollection deed het meeste
al; wat erbij komt is de naam, de volgers en het type.

DE ENIGE TERM DIE WE UIT HUN VOCABULAIRE OVERNEMEN, en het verschil met
track/ArtistCredit is de reden dat dit wel mag: die twee vragen ENTITEITEN waar
wij tekst hebben -- een artiest en een album zijn bij ons kolommen, en er een id
voor verzinnen zou beloven wat we niet kunnen waarmaken. Een library is precies
wat er al staat: onze open tracks, met een echte telling en een echt id. Er valt
niets te verzinnen.

SKELET, letterlijk. Er is GEEN volg-afhandeling. Onze bibliotheek is openbaar --
alles erin heeft fedi_open -- dus er valt niets goed te keuren en de
volgerslijst is leeg en eerlijk. Komt er ooit een besloten variant, dan hoort
daar het Follow/Accept-werk bij en dat is een eigen stuk.

Een test bewaakt dat een GESLOTEN track er niet in komt. De bak is openbaar, en
dat kan alleen als er niets in zit dat het niet is -- anders overrulet de
openbaarheid van de bak de poort van de track.

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

  • Property mode set to 100644
File size: 3.8 KB
Line 
1// De site als Funkwhale-Library, skelet (shaer-0nh).
2//
3// AANLEIDING, gemeten op 13-8 tegen open.audio: onze vier tracks waren daar
4// binnengehaald langs de AP-weg -- met ONZE track-id's als fid, en met een
5// artist_credit dat Funkwhale zelf uit onze attributedTo had afgeleid. Maar
6// `uploads` was leeg en `is_playable` false. Bij hen hangt een upload aan een
7// library; zonder die bak blijft een track een naam zonder geluid. Het
8// audiobestand zelf is gewoon anoniem op te halen -- ze hadden het niet
9// geprobeerd.
10import { test } from 'node:test';
11import assert from 'node:assert/strict';
12
13process.env.DATABASE_PATH = ':memory:';
14process.env.PUBLIC_BASE_URL = 'https://ons.test';
15
16const dbMod = await import('../src/config/database.js');
17const db = dbMod.default;
18dbMod.initializeDatabase();
19const AP = await import('../src/services/ActivityPubService.js');
20
21const BASE = 'https://ons.test';
22db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
23 .run('u1', 'u1', 'u1@t', 'x', 'god');
24db.prepare('INSERT INTO sites (id, slug, title, description, owner_id) VALUES (?,?,?,?,?)')
25 .run('s1', 'band', 'De Band', 'Onze plaatjes', 'u1');
26const site = db.prepare("SELECT * FROM sites WHERE id = 's1'").get();
27
28const insM = db.prepare('INSERT INTO media (id, site_id, filename, storage_path, mime_type, size) VALUES (?,?,?,?,?,?)');
29const insT = db.prepare('INSERT INTO audio_tracks (id, site_id, title, duration, media_id, fedi_open) VALUES (?,?,?,?,?,?)');
30insM.run('m1', 's1', 'open.mp3', 'a/open.mp3', 'audio/mpeg', 4210688);
31insM.run('m2', 's1', 'dicht.mp3', 'a/dicht.mp3', 'audio/mpeg', 999);
32insT.run('t1', 's1', 'Het open nummer', 203, 'm1', 1);
33insT.run('t2', 's1', 'Achter de poort', 100, 'm2', 0);
34
35const LIB = `${BASE}/ap/users/band/library`;
36
37test('de bibliotheek heeft de vorm die hun docs voorschrijven', () => {
38 const lib = AP.buildLibrary(BASE, site, AP.siteOpenTracks('s1'));
39 assert.equal(lib.type, 'Library', 'niet OrderedCollection -- daar zoeken ze op');
40 assert.equal(lib.id, LIB);
41 assert.equal(lib.name, 'De Band');
42 assert.equal(lib.attributedTo, `${BASE}/ap/users/band`);
43 assert.equal(lib.followers, `${LIB}/followers`, 'vereist volgens hun docs');
44 assert.equal(lib.first, `${LIB}?page=1`);
45 assert.equal(lib.last, `${LIB}?page=1`);
46 assert.equal(lib.totalItems, 1);
47 assert.equal(lib.summary, 'Onze plaatjes');
48});
49
50test('een gesloten track hoort er NIET in -- dicht is dicht', () => {
51 // De bibliotheek is openbaar; dat kan alleen als er niets in zit dat het
52 // niet is. Zou een gated track hier binnenglippen, dan zou de openbaarheid
53 // van de bak zijn poort overrulen.
54 const lib = AP.buildLibrary(BASE, site, AP.siteOpenTracks('s1'));
55 assert.deepEqual(lib.orderedItems.map((a) => a.name), ['Het open nummer']);
56});
57
58test('elke Audio wijst naar de bibliotheek', () => {
59 // Dit is het veld waar het om begonnen was: het haakje waar een upload aan komt.
60 const lib = AP.buildLibrary(BASE, site, AP.siteOpenTracks('s1'));
61 for (const a of lib.orderedItems) assert.equal(a.library, LIB);
62 // Ook als de track ergens anders vandaan komt -- de losse ophaal, de
63 // trackcollectie, de playlist. Anders hangt het er maar op een plek.
64 const los = AP.buildTrackAudio(BASE, site, AP.openTrack('s1', 't1'), { standalone: true });
65 assert.equal(los.library, LIB);
66});
67
68test('de term is gedeclareerd, anders laat een strikte lezer hem vallen', async () => {
69 const core = await import('../src/services/ap-core.js');
70 const term = core.AP_CONTEXT.find((x) => x && typeof x === 'object' && x.library);
71 assert.ok(term, 'library staat in de context');
72 assert.equal(term.library['@id'], 'fw:library');
73 assert.equal(term.library['@type'], '@id', 'het is een URI, geen tekst');
74 assert.equal(term.Library, 'fw:Library');
75 assert.equal(term.fw, 'https://funkwhale.audio/ns#');
76});
Note: See TracBrowser for help on using the repository browser.