| 1 | // Binnen een gesprek leest Berichten van NIEUW naar OUD (Robins besluit,
|
|---|
| 2 | // 25-8), en een ontvangen zwaai staat in de KOP van de draad -- want ingeklapt
|
|---|
| 3 | // zijn de bubbels weg, en juist een zwaai vraagt om een antwoord.
|
|---|
| 4 | //
|
|---|
| 5 | // Dit rendert de echte partial. EJS-fouten bestaan alleen tijdens het renderen:
|
|---|
| 6 | // een verkeerde variabelenaam of een scheve `<% %>` valt hier om en nergens
|
|---|
| 7 | // anders in de suite.
|
|---|
| 8 | import { test } from 'node:test';
|
|---|
| 9 | import assert from 'node:assert/strict';
|
|---|
| 10 | import ejs from 'ejs';
|
|---|
| 11 | import path from 'node:path';
|
|---|
| 12 | import { fileURLToPath } from 'node:url';
|
|---|
| 13 |
|
|---|
| 14 | const partial = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'src', 'views', 'partials', 'msg-item.ejs');
|
|---|
| 15 |
|
|---|
| 16 | // De helpers die de pagina normaal meegeeft. Ze geven hun invoer terug, zodat
|
|---|
| 17 | // wat er in het antwoord staat uit de PARTIAL komt en niet uit een stub.
|
|---|
| 18 | const helpers = { t: (k) => k, avatar: (u) => u, emojiName: (n) => n, formatDateTime: (d) => String(d), canMutate: false, seen: 0 };
|
|---|
| 19 |
|
|---|
| 20 | // De naam is het herkenningspunt: de inhoud loopt via note-body, dat eigen
|
|---|
| 21 | // velden leest. De kop draagt alleen `people`, dus deze drie namen kunnen
|
|---|
| 22 | // alleen uit de bubbels zelf komen.
|
|---|
| 23 | function draad(extra = {}) {
|
|---|
| 24 | return {
|
|---|
| 25 | type: 'thread', key: 'k1', post: null, count: 3, people: [{ name: 'Bart' }],
|
|---|
| 26 | created_at: '2026-08-25T10:00:00Z',
|
|---|
| 27 | messages: [
|
|---|
| 28 | { type: 'mention', name: 'OUDSTE', handle: '@a', created_at: '2026-08-25T09:00:00Z' },
|
|---|
| 29 | { type: 'mention', name: 'MIDDELSTE', handle: '@b', created_at: '2026-08-25T09:30:00Z' },
|
|---|
| 30 | { type: 'mention', name: 'NIEUWSTE', handle: '@c', wave: true, created_at: '2026-08-25T10:00:00Z' },
|
|---|
| 31 | ],
|
|---|
| 32 | ...extra,
|
|---|
| 33 | };
|
|---|
| 34 | }
|
|---|
| 35 |
|
|---|
| 36 | const render = (n) => ejs.renderFile(partial, { ...helpers, n });
|
|---|
| 37 |
|
|---|
| 38 | test('binnen een gesprek staat het nieuwste bovenaan', async () => {
|
|---|
| 39 | const html = await render(draad());
|
|---|
| 40 | const nieuw = html.indexOf('NIEUWSTE'), midden = html.indexOf('MIDDELSTE'), oud = html.indexOf('OUDSTE');
|
|---|
| 41 | assert.ok(nieuw > -1 && midden > -1 && oud > -1, 'alle drie de berichten staan er');
|
|---|
| 42 | assert.ok(nieuw < midden && midden < oud, `nieuwste bovenaan, kreeg N=${nieuw} M=${midden} O=${oud}`);
|
|---|
| 43 | });
|
|---|
| 44 |
|
|---|
| 45 | test('de draad-array zelf blijft oplopend', async () => {
|
|---|
| 46 | // groupConversations sorteert oplopend en de rest van de pagina rekent
|
|---|
| 47 | // daarop: `_tnew` en `_tto` lezen dezelfde array. Draaide de partial het
|
|---|
| 48 | // origineel om, dan werkt dat door naar alles wat er daarna naar kijkt.
|
|---|
| 49 | const d = draad();
|
|---|
| 50 | await render(d);
|
|---|
| 51 | assert.deepEqual(d.messages.map((m) => m.name), ['OUDSTE', 'MIDDELSTE', 'NIEUWSTE']);
|
|---|
| 52 | });
|
|---|
| 53 |
|
|---|
| 54 | test('een ontvangen zwaai staat in de kop, voor de bubbels', async () => {
|
|---|
| 55 | const html = await render(draad());
|
|---|
| 56 | const kop = html.indexOf('msg-thread-wave');
|
|---|
| 57 | assert.ok(kop > -1, 'de kop draagt een zwaai-teken');
|
|---|
| 58 | assert.ok(kop < html.indexOf('msg-thread-msgs'), 'en staat in de kop, niet tussen de bubbels');
|
|---|
| 59 | });
|
|---|
| 60 |
|
|---|
| 61 | test('geen zwaai, geen teken', async () => {
|
|---|
| 62 | const stil = draad();
|
|---|
| 63 | stil.messages = stil.messages.map((m) => ({ ...m, wave: false }));
|
|---|
| 64 | assert.equal((await render(stil)).includes('msg-thread-wave'), false);
|
|---|
| 65 | });
|
|---|
| 66 |
|
|---|
| 67 | test('een zwaai die JIJ stuurde is geen uitnodiging aan jezelf', async () => {
|
|---|
| 68 | const eigen = draad({ messages: [{ type: 'sent', to_handle: '@bart@pruts.nl', wave: true, created_at: '2026-08-25T10:00:00Z' }] });
|
|---|
| 69 | assert.equal((await render(eigen)).includes('msg-thread-wave'), false);
|
|---|
| 70 | });
|
|---|
| 71 |
|
|---|
| 72 | test('antwoorden en zwaaien staan BOVEN de berichten', async () => {
|
|---|
| 73 | // Sinds het nieuwste bovenaan staat hoort de knop daar ook: onderaan zou hij
|
|---|
| 74 | // bij het OUDSTE bericht komen te staan, en daar antwoord je niet op.
|
|---|
| 75 | const html = await ejs.renderFile(partial, {
|
|---|
| 76 | ...helpers, canMutate: true,
|
|---|
| 77 | n: draad({ replyTo: { actorUri: 'https://pruts.nl/ap/users/bart' } }),
|
|---|
| 78 | });
|
|---|
| 79 | const acties = html.indexOf('msg-thread-actions');
|
|---|
| 80 | const bubbels = html.indexOf('msg-thread-msgs');
|
|---|
| 81 | assert.ok(acties > -1, 'de antwoordrij staat er');
|
|---|
| 82 | assert.ok(bubbels > -1, 'en de berichten ook');
|
|---|
| 83 | assert.ok(acties < bubbels, `antwoordrij boven de berichten, kreeg acties=${acties} bubbels=${bubbels}`);
|
|---|
| 84 | // De zwaai-hand hoort in diezelfde rij, dus ook boven de berichten.
|
|---|
| 85 | const zwaai = html.indexOf('class="msg-wave"');
|
|---|
| 86 | assert.ok(zwaai > -1 && zwaai < bubbels, 'de zwaai-hand staat in de rij erboven');
|
|---|
| 87 | });
|
|---|