source: Klonkt/test/music-type.test.js@ c832064

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

De soort van een playlist wordt opgezocht, niet afgeleid (shaer-cyg)

Robins afbakening maakt twee dingen tegelijk simpeler. Album of playlist wordt
gekozen wanneer de PLAYLIST wordt gemaakt -- die keuze staat al in
playlists.kind -- en de post neemt bij een enkele insluiting die soort over. Een
post om een album is dus een album, ook al heet de shortcode [[playlist:...]].

En de afleiding is er voor BESTAANDE posts; nieuwe krijgen hun type uit de
keuze. Daarmee is "wie wint, de keuze of de afleiding?" geen vraag meer: ze
komen elkaar niet tegen. De afleiding draait eenmalig, de keuze daarna.

Onbekende situatie -> gewone post met insluitingen die de post als context
hebben. Een onvindbare playlist, of een van een andere site, verzint dus geen
type meer.

De patronen zijn nu die van AudioEmbedService: wat daar niet insluit, telt hier
niet mee. Mijn playlist-patroon accepteerde underscores die de renderer weigert,
en zo'n shortcode had wel het type van de post kunnen bepalen.

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

  • Property mode set to 100644
File size: 5.6 KB
Line 
1// Welk soort uitgave is een BESTAANDE post? (shaer-cyg)
2//
3// Nieuwe posts krijgen hun type uit de keuze -- album of playlist wordt gekozen
4// als de playlist wordt gemaakt. Deze afleiding is er voor wat er al staat: de
5// type=audio posts van voor die keuze. De regel gaat over IDENTITEIT en niet
6// over tellen: een post neemt het type van zijn muziek over als hij precies EEN
7// muzikale eenheid bevat. Zijn het er meer, dan is de post een post die naar
8// muziek verwijst en houden de collecties hun eigen identiteit -- en vervalt de
9// reden om de posttitel en -cover te lenen.
10import { test } from 'node:test';
11import assert from 'node:assert/strict';
12
13process.env.DATABASE_PATH = ':memory:';
14process.env.PUBLIC_BASE_URL = 'https://test.example';
15
16const dbMod = await import('../src/config/database.js');
17dbMod.initializeDatabase();
18const db = dbMod.default;
19const { postMusicType } = await import('../src/services/music/index.js');
20
21const SITE = 'site-muziek';
22const ANDERE = 'site-anders';
23db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
24 .run('u1', 'robin', 'r@test', 'x', 'god');
25db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)').run(SITE, 'muziek', 'Muziek', 'u1');
26db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)').run(ANDERE, 'anders', 'Anders', 'u1');
27
28const maakPlaylist = (id, kind, siteId = SITE) =>
29 db.prepare('INSERT INTO playlists (id, site_id, title, kind) VALUES (?, ?, ?, ?)')
30 .run(id, siteId, id, kind);
31
32maakPlaylist('nachtlicht', 'playlist');
33maakPlaylist('de-plaat', 'album');
34maakPlaylist('tweede', 'playlist');
35maakPlaylist('elders', 'playlist', ANDERE);
36
37const type = (c) => postMusicType(c, SITE);
38
39test('geen muziek: geen type', () => {
40 assert.equal(type('<p>gewoon een bericht</p>'), null);
41 assert.equal(type(''), null);
42 assert.equal(type(null), null);
43});
44
45test('losse tracks worden een playlist, en lenen de metadata van de post', () => {
46 const r = type('Twee nieuwe: [[track:a]] en [[track:b]]');
47 assert.equal(r.type, 'playlist');
48 assert.deepEqual(r.tracks, ['a', 'b']);
49 assert.equal(r.leentMetadata, true);
50});
51
52test('ook EEN losse track wordt een playlist', () => {
53 // Naar buiten toe is er dan altijd een collectie om naar te wijzen. Dat
54 // "Playlist" boven een enkel nummer gek leest is een weergavekwestie.
55 assert.equal(type('[[track:a]]').type, 'playlist');
56});
57
58test('de post neemt de GEKOZEN soort van de playlist over', () => {
59 // De kern van Robins besluit: album of playlist is bij het maken van de
60 // playlist al gekozen. Hier wordt hij opgezocht, niet afgeleid.
61 assert.equal(type('Nieuw: [[playlist:nachtlicht]]').type, 'playlist');
62 assert.equal(type('Nieuw: [[playlist:de-plaat]]').type, 'album',
63 'een post om een album is een album, ook al heet de shortcode playlist');
64});
65
66test('de collectie draagt haar eigen soort mee', () => {
67 const r = type('Nieuw: [[playlist:nachtlicht]]');
68 assert.deepEqual(r.collectie, { soort: 'playlist', id: 'nachtlicht' });
69 assert.equal(r.leentMetadata, true);
70});
71
72test('een album-insluiting is ook een collectie, en telt als album', () => {
73 // [[album:naam]] groepeert tracks op hun albumveld -- geen playlist-rij, dus
74 // geen gekozen soort. Hem als losse tracks tellen zou een albumpost tot
75 // playlist maken.
76 const r = type('Luister [[album:De Plaat]]');
77 assert.equal(r.type, 'album');
78 assert.deepEqual(r.collectie, { soort: 'album', naam: 'De Plaat' });
79});
80
81test('een collectie MET losse tracks is een album, en die losse zijn bonus', () => {
82 const r = type('[[playlist:nachtlicht]] plus [[track:x]] en [[track:y]]');
83 assert.equal(r.type, 'album', 'ook al is de playlist zelf een playlist');
84 assert.equal(r.collectie.id, 'nachtlicht');
85 assert.deepEqual(r.bonus, ['x', 'y'], 'geen rommelrestje maar bonus-tracks');
86 assert.deepEqual(r.tracks, [], 'de losse zitten in bonus, niet twee keer');
87 assert.equal(r.leentMetadata, true);
88});
89
90test('TWEE collecties: de post blijft een post en leent niets', () => {
91 const r = type('[[playlist:nachtlicht]] en ook [[playlist:tweede]]');
92 assert.equal(r.type, 'post');
93 assert.equal(r.collecties.length, 2);
94 assert.equal(r.leentMetadata, false,
95 'bij twee is de post niet meer de drager van EEN identiteit');
96});
97
98test('twee collecties van verschillende soort tellen ook als twee', () => {
99 const r = type('[[playlist:nachtlicht]] naast [[album:De Plaat]]');
100 assert.equal(r.type, 'post');
101 assert.equal(r.collecties.length, 2);
102});
103
104test('dezelfde insluiting twee keer is EEN collectie', () => {
105 // Anders maakt een herhaalde shortcode van een albumpost stilletjes een
106 // gewone post.
107 const r = type('[[playlist:nachtlicht]] ... en nog eens [[playlist:nachtlicht]]');
108 assert.equal(r.type, 'playlist');
109 assert.equal(r.collectie.id, 'nachtlicht');
110});
111
112test('dezelfde track twee keer telt ook maar een keer', () => {
113 assert.deepEqual(type('[[track:a]] [[track:a]] [[track:b]]').tracks, ['a', 'b']);
114});
115
116test('onbekende playlist: gewone post, niets verzonnen', () => {
117 // Robins laatste optie voor een onbekende situatie. De insluiting blijft
118 // staan en houdt de post als context; alleen het label wordt niet geraden.
119 const r = type('[[playlist:bestaat-niet]]');
120 assert.equal(r.type, 'post');
121 assert.deepEqual(r.onbekend, ['bestaat-niet']);
122 assert.equal(r.leentMetadata, false);
123});
124
125test('een playlist van een ANDERE site telt niet als de onze', () => {
126 const r = type('[[playlist:elders]]');
127 assert.equal(r.type, 'post');
128 assert.deepEqual(r.onbekend, ['elders']);
129});
130
131test('zonder site is er niets op te zoeken, dus geen type verzinnen', () => {
132 assert.equal(postMusicType('[[playlist:nachtlicht]]').type, 'post');
133});
Note: See TracBrowser for help on using the repository browser.