source: Klonkt/test/boost-media.test.js

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

Fix: boosted video-only posts keep their media in the Circle (Loops)

Boosting a video-only post lost its media twice over: resolveRemoteNote only
surfaced image/* attachments (images list), so upsertBoostedNote stored
media_json=[] for a Loops video; and its refresh-UPDATE clobbered an existing
good media_json (cached via following) with that empty set. resolveRemoteNote
now also returns full typed media via mediaFromNote (images stays image-only
for the interact preview); upsertBoostedNote prefers the typed media and its
refresh keeps cached media when the resolve yielded none. Verified live: the
reported Loops file is 2.9MB with moov in reach, and a seeded boosted video row
now renders a grid tile with a real generated poster (200 image/webp, 13KB).
Covered by test/boost-media.test.js (63 tests green). Reported by Robin.

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

  • Property mode set to 100644
File size: 2.7 KB
Line 
1// Cirkel/boost-media: een geboostte video-only post (Loops) verloor zijn media —
2// upsertBoostedNote keek alleen naar note.images (afbeeldingen) en de refresh
3// overschreef bestaande media_json met []. Dekt de typed-media opslag, de
4// niet-clobberen-refresh en de images-fallback af.
5//
6// Run: npm test (= node --test)
7
8import { test } from 'node:test';
9import assert from 'node:assert/strict';
10
11process.env.DATABASE_PATH = ':memory:';
12process.env.PUBLIC_BASE_URL = 'https://klonkt.test';
13
14const dbMod = await import('../src/config/database.js');
15const db = dbMod.default;
16const AP = await import('../src/services/ActivityPubService.js');
17
18dbMod.initializeDatabase();
19
20const VIDEO_MEDIA = JSON.stringify([{ url: 'https://cdn.test/clip.720p.mp4', type: 'video/mp4' }]);
21
22function mediaOf(id) {
23 const r = db.prepare('SELECT media_json FROM ap_timeline WHERE slug = ? AND id = ?').get('me', id);
24 return r ? r.media_json : null;
25}
26
27test('boost van een video-only post bewaart de video in media_json', () => {
28 AP.upsertBoostedNote('me', {
29 object_uri: 'https://loops.test/n/1', actor_uri: 'https://loops.test/u/a',
30 actor_name: 'A', content: '<p>x</p>', media: VIDEO_MEDIA, images: [],
31 });
32 const m = JSON.parse(mediaOf('https://loops.test/n/1'));
33 assert.equal(m.length, 1);
34 assert.equal(m[0].type, 'video/mp4');
35});
36
37test('refresh met lege media clobbert een bestaande media_json NIET', () => {
38 // rij bestaat al (met video); een re-upsert die niks resolvede mag hem niet wissen
39 AP.upsertBoostedNote('me', {
40 object_uri: 'https://loops.test/n/1', actor_uri: 'https://loops.test/u/a',
41 actor_name: 'A', content: '<p>x2</p>', media: '[]', images: [],
42 });
43 const m = JSON.parse(mediaOf('https://loops.test/n/1'));
44 assert.equal(m.length, 1, 'media_json is gewist door een lege refresh');
45 assert.equal(m[0].type, 'video/mp4');
46});
47
48test('refresh met nieuwe media werkt de rij wel bij', () => {
49 const newer = JSON.stringify([{ url: 'https://cdn.test/clip2.mp4', type: 'video/mp4' }]);
50 AP.upsertBoostedNote('me', {
51 object_uri: 'https://loops.test/n/1', actor_uri: 'https://loops.test/u/a',
52 actor_name: 'A', content: '<p>x3</p>', media: newer, images: [],
53 });
54 assert.equal(JSON.parse(mediaOf('https://loops.test/n/1'))[0].url, 'https://cdn.test/clip2.mp4');
55});
56
57test('images-fallback (oude callers zonder note.media) blijft werken', () => {
58 AP.upsertBoostedNote('me', {
59 object_uri: 'https://old.test/n/2', actor_uri: 'https://old.test/u/b',
60 actor_name: 'B', content: '<p>y</p>', images: ['https://old.test/img.jpg'],
61 });
62 const m = JSON.parse(mediaOf('https://old.test/n/2'));
63 assert.equal(m[0].url, 'https://old.test/img.jpg');
64 assert.equal(m[0].type, 'image/jpeg');
65});
Note: See TracBrowser for help on using the repository browser.