source: Klonkt/test/mixtape-ui.test.js@ 8e1af9c

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

Mixtape als posttype, kiesbaar in de composer

Het bandje bestond wel als soort playlist, maar je kon er geen post van maken.
Nu wel: een eigen knop met een eigen teken, en het muziekpaneel deelt hij met
album en playlist -- het verschil zit in de playlist die je insluit, niet in
wat je uploadt.

KEUZE_TYPES en MUZIEK_TYPES in config/post-types.js waren de goede plek; dat
bestand bestaat precies omdat die lijst eerder drie keer los rondslingerde.

Nog twee keer dezelfde binaire vorm opgeruimd, en de tweede was een echte:

  • VOLGBAAR kende geen mixtape, dus het type volgde de muziek niet.
  • De editor zocht de soort op met de vorm p.kind === 'playlist' ? 'playlist' : 'album'. Het scherm zag dus album terwijl de server mixtape opsloeg: het type verspringt onder je handen bij het bewaren.
  • De renderer koos teken en woord met dezelfde tweewegkeuze, waardoor een ingesloten mixtape het jasje van een album droeg.

De SPELER is er nog niet -- een mixtape rendert voorlopig als de gewone lijst.
Wat af is, is dat hij overal zichzelf noemt.

Zes tests, waaronder de opslagweg door de echte route: kent de opslag een type
niet, dan wordt de post zonder melding een gewone post, en dat is precies de
fout waar config/post-types.js voor waarschuwt. Een van de tests riep eerst een
methode aan die niet bestaat en sloeg zichzelf over; die gaat nu door
embedPlaylistShortcodes heen en valt om als je de tweewegkeuze terugzet.

MOD_V naar 51.

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

  • Property mode set to 100644
File size: 4.8 KB
Line 
1// De mixtape als POSTTYPE: kiesbaar, opslaanbaar, en zichzelf noemend.
2//
3// De waarschuwing staat al in config/post-types.js en is hier het hele punt:
4// kent de opslag een type niet, dan wordt de post ZONDER MELDING een gewone
5// post. De keuze verdwijnt dan in plaats van geweigerd te worden, en niemand
6// ziet het tot een post van soort blijkt te zijn veranderd.
7import { test } from 'node:test';
8import assert from 'node:assert/strict';
9import fs from 'node:fs';
10
11process.env.DATABASE_PATH = ':memory:';
12process.env.PUBLIC_BASE_URL = 'https://test.example';
13const dbMod = await import('../src/config/database.js');
14const db = dbMod.default;
15dbMod.initializeDatabase();
16
17const { KEUZE_TYPES, POST_TYPES, MUZIEK_TYPES } = await import('../src/config/post-types.js');
18
19test('mixtape is een kiesbaar type, en draagt muziek', () => {
20 assert.ok(KEUZE_TYPES.includes('mixtape'), 'anders staat de knop er niet');
21 assert.ok(POST_TYPES.has('mixtape'), 'anders gooit het opslaan hem stil weg');
22 assert.ok(MUZIEK_TYPES.has('mixtape'), 'anders deelt hij het muziekpaneel niet');
23});
24
25test('de composer toont de knop en deelt het muziekpaneel', () => {
26 const ejsBron = fs.readFileSync('src/views/pages/post-edit.ejs', 'utf8');
27 assert.match(ejsBron, /mixtape: '📼'/, 'een eigen teken, niet dat van een album');
28 assert.match(ejsBron, /data-panel="album playlist mixtape audio"/,
29 'zonder mixtape in deze lijst verdwijnt het uploadpaneel zodra je het type kiest');
30});
31
32test('het type mag meeveranderen met de muziek', () => {
33 const mod = fs.readFileSync('src/assets/js/mod/post-edit.js', 'utf8');
34 assert.match(mod, /VOLGBAAR = new Set\(\[[^\]]*'mixtape'/,
35 'anders blijft het type op post staan als je een mixtape invoegt');
36 // De opzoeker van de editor moet dezelfde soorten kennen als de server, anders
37 // ziet het scherm album terwijl de server mixtape opslaat.
38 assert.doesNotMatch(mod, /kindVan\.set\(p\.id, p\.kind === 'playlist'/,
39 'de binaire vorm hoort weg te zijn');
40});
41
42test('een post van type mixtape houdt zijn type bij het opslaan', async () => {
43 db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
44 .run('u1', 'baas', 'b@t.nl', 'x', 'god');
45 db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)')
46 .run('s1', 'robo', 'Soundfabrics', 'u1');
47
48 const express = (await import('express')).default;
49 const router = (await import('../src/routes/posts.js')).default;
50 const app = express();
51 app.use(express.urlencoded({ extended: true }));
52 app.use((req, res, next) => {
53 req.session = { user: { id: 'u1', role: 'god', username: 'baas' } };
54 res.locals.site = db.prepare('SELECT * FROM sites WHERE slug = ?').get('robo');
55 res.locals.siteUrlBase = '';
56 next();
57 });
58 app.use('/', router);
59 const server = app.listen(0);
60 server.unref();
61
62 const r = await fetch(`http://127.0.0.1:${server.address().port}/posts/create`, {
63 method: 'POST', redirect: 'manual',
64 headers: { 'content-type': 'application/x-www-form-urlencoded' },
65 body: new URLSearchParams({
66 title: 'De Mixtape', content: '<p>kant A</p>', type: 'mixtape', status: 'published',
67 }).toString(),
68 signal: AbortSignal.timeout(5000),
69 }).catch((e) => assert.fail(`de route antwoordde niet (${e.name})`));
70 assert.ok(r.status === 302 || r.status === 200, 'opslaan mag niet stranden, kreeg ' + r.status);
71
72 const post = db.prepare("SELECT type FROM posts WHERE title = ?").get('De Mixtape');
73 assert.ok(post, 'de post hoort te bestaan');
74 assert.equal(post.type, 'mixtape', 'het type mag niet stil terugvallen op post');
75 server.close();
76});
77
78test('een ingesloten mixtape noemt zich mixtape en geen album', async () => {
79 const AudioEmbedService = (await import('../src/services/AudioEmbedService.js')).default;
80 const pl = {
81 id: 'tape', title: 'De Mixtape', artist: 'robo', kind: 'mixtape',
82 tracks: [{ id: 't1', title: 'Kant A', artist: 'robo', url: '/a.mp3', duration: 100, cover: '' }],
83 };
84 // Door de ECHTE weg: de shortcode in de tekst, uitgeklapt zoals bij het tonen
85 // van een post. De vorige versie van deze test riep een methode aan die niet
86 // bestaat en sloeg zichzelf dan over -- groen zonder iets te meten.
87 const html = AudioEmbedService.embedPlaylistShortcodes('<p>[[playlist:tape]]</p>', (id) => (id === 'tape' ? pl : null));
88 assert.match(html, /📼 Mixtape/, 'een mixtape hoort zichzelf zo te noemen');
89 assert.doesNotMatch(html, /💿 Album/, 'en niet het jasje van een album te dragen');
90});
91
92test('de renderer kiest zijn label niet meer met een tweewegkeuze', () => {
93 const bron = fs.readFileSync('src/services/AudioEmbedService.js', 'utf8');
94 assert.doesNotMatch(bron, /kind === 'playlist' \? '📃 Playlist' : '💿 Album'/,
95 'die vorm gaf een mixtape het jasje van een album');
96 assert.match(bron, /mixtape: '📼 Mixtape'/);
97});
Note: See TracBrowser for help on using the repository browser.