Changeset f704237 in Klonkt for test/fep1580-migration.test.js


Ignore:
Timestamp:
08/14/2026 02:35:06 AM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
47f1183
Parents:
fc664ce
Message:

Een track zonder bestand is niet hetzelfde als een kapotte track

Robin, over het ene nummer dat niet meekwam: "ah, dat was een no audio 'audio'
voor alleen spotify en youtube links". Dat is een bestaand Klonkt-type, geen
ongelukje: geen gehost bestand, wel externe links, en buildNote maakt er een
embed-kaart van (trackEmbedLinks). Mijn regel "geen bestand, geen track" was te
grof en gooide hem weg.

"Geen bestand" en "niets om te tonen" zijn niet hetzelfde. De regel blijft
staan waar hij hoort: een track zonder bestand EN zonder links wordt nog steeds
geweigerd, want die kan niets.

Het archiefformaat heeft nu drie staten in plaats van twee: included, missing,
en linkOnly. Een link-only track telt dus ook niet meer als "ontbrekend", want
er ontbreekt niets.

EN EEN TWEEDE FOUT DIE HIERONDER LAG. De pull viste de audio-URL uit de
url-lijst met element NUL. buildTrackAudio zet daar een text/html-link naar de
post voor het bestand: wie blind de eerste pakt downloadt een HTML-pagina en
schrijft die weg als mp3. Nu wordt de link met mediaType audio/* gezocht, met
/audio/stream/ als terugval. Dat het bij Robin niet misging is geluk: zijn
tracks hadden geen host-post in die lijst.

Changed files:
src/services/ArchiveExportService.js

  • shaer:availability kent linkOnly; die telt niet als audioMissing

src/services/ArchiveImportService.js

  • link-only tracks komen mee, met media_id NULL zoals op de bron
  • de schrijftak kan een track zonder bestand aan

src/services/MigrationService.js

  • de pull vist de audio-link uit de lijst in plaats van element nul
  • een track met alleen externe links wordt gewoon aangemaakt

test/archive-audio.test.js

  • link-only reist mee; zonder bestand en zonder links blijft geweigerd

test/fep1580-migration.test.js

  • hetzelfde voor de ophaalknop, plus: de audio-link wordt gevist

remarks: Robins Youngstown-nummer komt hiermee alsnog over. Suite 1009 groen;
tegenproef op beide, en de eerste poging daarvan kwam niet aan (te slordige
sabotage), dus opnieuw gedaan met twee rode tests als bewijs.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/fep1580-migration.test.js

    rfc664ce rf704237  
    369369});
    370370
     371test('een link-only nummer komt ook via de ophaalknop mee', async () => {
     372  // Dezelfde regel als bij de zip. Over AP heeft zo'n track geen audio-link in
     373  // zijn url-lijst, alleen de externe. De vorige versie viste blind de eerste
     374  // url en strandde daarop.
     375  const s = site({ aliases: [BRON] });
     376  const kaart = new Map([
     377    [BRON, { id: BRON, type: 'Person', movedTo: IK, outbox: `${BRON}/outbox`, streams: [`${BRON}/tracks`] }],
     378    [`${BRON}/outbox`, { type: 'OrderedCollection', totalItems: 0, first: `${BRON}/outbox?page=1` }],
     379    [`${BRON}/outbox?page=1`, { type: 'OrderedCollectionPage', orderedItems: [] }],
     380    [`${BRON}/tracks`, { type: 'OrderedCollection', orderedItems: [{
     381      id: `${BRON}/tracks/lo`, type: 'Audio', name: 'Alleen links', summary: 'Youngstown',
     382      url: [
     383        { type: 'Link', href: 'https://oud.example/eenpost', mediaType: 'text/html' },
     384        { type: 'Link', href: 'https://open.spotify.com/track/abc' },
     385        { type: 'Link', href: 'https://www.youtube.com/watch?v=xyz' },
     386      ],
     387    }] }],
     388  ]);
     389  const gehaald = [];
     390  const r = await stil(() => Mig.ingestFromSource(s, { deps: {
     391    getJson: async (_s, url) => kaart.get(url) || null,
     392    noteId: (b, id) => `${b}/ap/notes/${id}`,
     393    noteVisibility: AP.noteVisibility,
     394    audioRoot: '/nep/audio', mediaRoot: '/nep/media',
     395    signHeaders: () => ({ Signature: 'nep' }),
     396    safeFetch: async (u) => { gehaald.push(u); return { ok: true, arrayBuffer: async () => Buffer.from('x'), headers: { get: () => 'audio/mpeg' } }; },
     397    fs: { mkdirSync() {}, writeFileSync() {}, statSync() { throw new Error('ENOENT'); } },
     398    path,
     399  } }));
     400  assert.equal(r.tracksBinnen, 1);
     401  assert.equal(r.tracksMislukt, 0);
     402  assert.equal(r.tracksLinks, 1);
     403  assert.deepEqual(gehaald, [], 'er valt niets te downloaden, en dat hoort ook niet geprobeerd');
     404  const t = db.prepare("SELECT title, artist, media_id, link_spotify, link_youtube FROM audio_tracks WHERE id = 'lo'").get();
     405  assert.ok(t, 'de track staat er');
     406  assert.equal(t.media_id, null);
     407  assert.equal(t.artist, 'Youngstown', 'de artiest komt uit summary');
     408  assert.equal(t.link_spotify, 'https://open.spotify.com/track/abc');
     409  assert.equal(t.link_youtube, 'https://www.youtube.com/watch?v=xyz');
     410});
     411
     412test('de audio-link wordt uit de lijst GEVIST, niet blind de eerste gepakt', async () => {
     413  // buildTrackAudio zet een text/html-link naar de post VOOR het bestand. Wie
     414  // element nul pakt downloadt een HTML-pagina en noemt dat een mp3.
     415  const s = site({ aliases: [BRON] });
     416  const MP3 = 'https://oud.example/audio/stream/x.mp3';
     417  const kaart = new Map([
     418    [BRON, { id: BRON, type: 'Person', movedTo: IK, outbox: `${BRON}/outbox`, streams: [`${BRON}/tracks`] }],
     419    [`${BRON}/outbox`, { type: 'OrderedCollection', totalItems: 0, first: `${BRON}/outbox?page=1` }],
     420    [`${BRON}/outbox?page=1`, { type: 'OrderedCollectionPage', orderedItems: [] }],
     421    [`${BRON}/tracks`, { type: 'OrderedCollection', orderedItems: [{
     422      id: `${BRON}/tracks/m1`, type: 'Audio', name: 'Met bestand',
     423      url: [
     424        { type: 'Link', href: 'https://oud.example/depost', mediaType: 'text/html' },
     425        { type: 'Link', href: MP3, mediaType: 'audio/mpeg' },
     426      ],
     427    }] }],
     428  ]);
     429  const gehaald = [];
     430  await stil(() => Mig.ingestFromSource(s, { deps: {
     431    getJson: async (_s, url) => kaart.get(url) || null,
     432    noteId: (b, id) => `${b}/ap/notes/${id}`,
     433    noteVisibility: AP.noteVisibility,
     434    audioRoot: '/nep/audio', mediaRoot: '/nep/media',
     435    signHeaders: () => ({ Signature: 'nep' }),
     436    safeFetch: async (u) => { gehaald.push(u); return { ok: true, arrayBuffer: async () => Buffer.from('x'), headers: { get: () => 'audio/mpeg' } }; },
     437    fs: { mkdirSync() {}, writeFileSync() {}, statSync() { throw new Error('ENOENT'); } },
     438    path,
     439  } }));
     440  assert.deepEqual(gehaald, [MP3], 'het bestand, niet de postpagina');
     441});
     442
    371443test('een nummer waarvan de bytes niet komen levert GEEN track op', async () => {
    372444  // Dezelfde regel als bij de zip. Een nummer dat in de lijst staat en 404't is
Note: See TracChangeset for help on using the changeset viewer.