| 1 | // Onze Audio inhoudelijk gelijk aan die van Funkwhale (shaer-0nh).
|
|---|
| 2 | //
|
|---|
| 3 | // Vergelijking van dezelfde track aan beide kanten leerde: op elk veld waar AS2
|
|---|
| 4 | // iets zegt zijn WIJ conform en zij niet -- en dat is precies een veld,
|
|---|
| 5 | // duration. Al hun extra velden bestaan gewoon in schema.org, dat Klonkt al in
|
|---|
| 6 | // zijn context had. Dus we konden ze alle vier overnemen zonder concessie: de
|
|---|
| 7 | // SLEUTELS zijn die van Funkwhale, de BETEKENIS komt van schema.org.
|
|---|
| 8 | import { test } from 'node:test';
|
|---|
| 9 | import assert from 'node:assert/strict';
|
|---|
| 10 |
|
|---|
| 11 | process.env.DATABASE_PATH = ':memory:';
|
|---|
| 12 | process.env.PUBLIC_BASE_URL = 'https://test.example';
|
|---|
| 13 |
|
|---|
| 14 | const dbMod = await import('../src/config/database.js');
|
|---|
| 15 | const db = dbMod.default;
|
|---|
| 16 | dbMod.initializeDatabase();
|
|---|
| 17 | const AP = (await import('../src/services/ActivityPubService.js')).default;
|
|---|
| 18 |
|
|---|
| 19 | const BASE = 'https://test.example';
|
|---|
| 20 | db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
|
|---|
| 21 | .run('u1', 'u1', 'u1@t', 'x', 'god');
|
|---|
| 22 | db.prepare('INSERT INTO sites (id, slug, title, owner_id, is_public, is_primary) VALUES (?,?,?,?,1,1)')
|
|---|
| 23 | .run('s1', 'band', 'De Band', 'u1');
|
|---|
| 24 |
|
|---|
| 25 | db.prepare('INSERT INTO media (id, site_id, filename, storage_path, mime_type, size) VALUES (?,?,?,?,?,?)')
|
|---|
| 26 | .run('m1', 's1', 'nummer.mp3', 'audio/nummer.mp3', 'audio/mpeg', 1653698);
|
|---|
| 27 | db.prepare(`INSERT INTO audio_tracks (id, site_id, title, artist, duration, media_id, cover_url, position, license, fedi_open, created_at)
|
|---|
| 28 | VALUES (?,?,?,?,?,?,?,?,?,1,?)`)
|
|---|
| 29 | .run('t1', 's1', '0METAL MARIO', 'De Band', 103, 'm1', '/media/hoes.jpg', 1, 'CC BY 4.0', '2026-08-08 04:38:34');
|
|---|
| 30 |
|
|---|
| 31 | const track = () => AP.siteOpenTracks('s1')[0];
|
|---|
| 32 | const audio = () => AP.buildTrackAudio(BASE, { slug: 'band' }, track());
|
|---|
| 33 |
|
|---|
| 34 | test('de bestandsgegevens zitten op de LINK, niet op het object', () => {
|
|---|
| 35 | const a = audio();
|
|---|
| 36 | assert.equal(a.url.length, 1);
|
|---|
| 37 | assert.equal(a.url[0].size, 1653698, 'bytes horen bij deze representatie');
|
|---|
| 38 | assert.equal(a.url[0].bitrate, Math.round((1653698 * 8) / 103), 'afgeleid uit bytes en seconden, niet gegokt');
|
|---|
| 39 | assert.equal(a.size, undefined, 'het NUMMER is geen bestand');
|
|---|
| 40 | assert.equal(a.bitrate, undefined);
|
|---|
| 41 | });
|
|---|
| 42 |
|
|---|
| 43 | test('to staat op het object zelf, niet alleen op de Create', () => {
|
|---|
| 44 | assert.deepEqual(audio().to, ['https://www.w3.org/ns/activitystreams#Public'],
|
|---|
| 45 | 'een los opgehaalde track moet zelf kunnen zeggen dat hij openbaar is');
|
|---|
| 46 | });
|
|---|
| 47 |
|
|---|
| 48 | test('position en license komen mee', () => {
|
|---|
| 49 | const a = audio();
|
|---|
| 50 | assert.equal(a.position, 1);
|
|---|
| 51 | assert.equal(a.license, 'http://creativecommons.org/licenses/by/4.0/', 'de tekst uit onze keuzelijst wordt de canonieke URI');
|
|---|
| 52 | });
|
|---|
| 53 |
|
|---|
| 54 | test('de hoes staat onder icon EN image -- allebei AS2-kern', () => {
|
|---|
| 55 | const a = audio();
|
|---|
| 56 | assert.equal(a.icon.url, 'https://test.example/media/hoes.jpg');
|
|---|
| 57 | assert.deepEqual(a.image, a.icon, 'dezelfde hoes, twee namen; wij lazen icon, Funkwhale leest image');
|
|---|
| 58 | });
|
|---|
| 59 |
|
|---|
| 60 | test('duration blijft de spec volgen -- daar wijken we bewust af van Funkwhale', () => {
|
|---|
| 61 | // AS2 zegt MUST xsd:duration, schema.org zegt ISO 8601. Funkwhale stuurt een
|
|---|
| 62 | // getal. Op dit ene veld hebben wij gelijk, dus hier bewegen we niet.
|
|---|
| 63 | assert.equal(audio().duration, 'PT103S');
|
|---|
| 64 | });
|
|---|
| 65 |
|
|---|
| 66 | test('een licentie die we niet kennen levert GEEN veld op', () => {
|
|---|
| 67 | db.prepare("UPDATE audio_tracks SET license = 'Alle rechten voorbehouden' WHERE id = 't1'").run();
|
|---|
| 68 | assert.equal(audio().license, undefined, 'een zelfbedachte licentie-URI is erger dan geen: een lezer gelooft hem');
|
|---|
| 69 | db.prepare("UPDATE audio_tracks SET license = 'https://voorbeeld.example/licentie' WHERE id = 't1'").run();
|
|---|
| 70 | assert.equal(audio().license, 'https://voorbeeld.example/licentie', 'een ingevulde URI gaat wel door');
|
|---|
| 71 | db.prepare("UPDATE audio_tracks SET license = 'CC BY 4.0' WHERE id = 't1'").run();
|
|---|
| 72 | });
|
|---|
| 73 |
|
|---|
| 74 | test('zonder duur of grootte geen verzonnen bitrate', () => {
|
|---|
| 75 | // media.size is NOT NULL, dus 0 als "onbekend" -- dat is ook wat de kolom in
|
|---|
| 76 | // de praktijk krijgt als de grootte niet bepaald kon worden.
|
|---|
| 77 | db.prepare("UPDATE media SET size = 0 WHERE id = 'm1'").run();
|
|---|
| 78 | const a = audio();
|
|---|
| 79 | assert.equal(a.url[0].bitrate, undefined);
|
|---|
| 80 | assert.equal(a.url[0].size, undefined);
|
|---|
| 81 | assert.equal(a.duration, 'PT103S', 'de duur staat er nog wel');
|
|---|
| 82 | db.prepare('UPDATE media SET size = 1653698 WHERE id = ?').run('m1');
|
|---|
| 83 | });
|
|---|