Changeset 8b65e67 in Klonkt for test


Ignore:
Timestamp:
08/18/2026 06:47:58 PM (3 weeks ago)
Author:
Bart <bart@…>
Branches:
main
Children:
f5cf299
Parents:
b1b7652
git-author:
Bart <bart@…> (08/17/2026 07:37:17 PM)
git-committer:
Bart <bart@…> (08/18/2026 06:47:58 PM)
Message:

Een gesloten bericht houdt zijn plek, en zijn tekst blijft thuis

Tweede stap voor de tijdlijn (Barts idee, naar bartoverkamp.nl): hele berichten
in de stroom in plaats van kaartjes. Een poort kan dan geen pagina meer zijn --
een betaald of fan-bericht moet ter plekke zeggen wat er is, met behoud van zijn
plek. Weglaten zou erger zijn: dan zien een supporter en een vreemde een andere
tijdlijn met andere buren, en klopt "vorige/volgende" voor niemand.

postEntry() is met opzet een functie en geen sjabloonconditie. Het lijf wordt
alleen GERENDERD als het ook getoond mag worden, dus bij een dichte poort reist
de tekst niet mee. Een <% if %> in een sjabloon krijgt hem wel in het model,
en dan staat er één vergeten conditie -- of één partial die net iets anders
samenstelt -- tussen de betaalmuur en de tekst erachter.

partials/post-body.ejs kiest alleen de vorm en gebruikt de woorden van de
bestaande poorten (pgate./fgate.), zodat ze niet uiteen gaan lopen na de eerste
tekstwijziging. Het ontgrendelen zelf blijft op de eigen pagina, want daar zit
de passkey-code; één knop ernaartoe is eerlijker dan een halve poort.

Vijf toetsen erbij, waaronder dat er bij een dichte poort niets van de tweede
alinea in het model zit.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/post-access.test.js

    rb1b7652 r8b65e67  
    9696  assert.equal(paidTeaser(post({ excerpt: 'zelf geschreven' })), 'zelf geschreven');
    9797});
     98
     99// ── Wat de tijdlijn krijgt ────────────────────────────────────────────────
     100// De tijdlijn toont hele berichten, dus een gesloten bericht moet zijn plek
     101// houden ZONDER dat de tekst meereist. Dat is geen sjabloonkwestie: wat niet
     102// gerenderd wordt, kan ook niet per ongeluk getoond worden.
     103
     104const { postEntry } = await import('../src/services/PostAccessService.js');
     105const renderBody = (p) => `<div>GEHEIM: ${p.content}</div>`;
     106
     107test('een open bericht krijgt zijn lijf', () => {
     108  const e = postEntry(post(), { user: VREEMDE, site: SITE }, { renderBody });
     109  assert.equal(e.access, 'full');
     110  assert.match(e.content_html, /GEHEIM/);
     111  assert.equal(e.teaser, null, 'geen teaser NAAST het lijf');
     112});
     113
     114test('een betaald bericht reist zonder tekst', () => {
     115  const e = postEntry(post({ paid: 1 }), { user: VREEMDE, site: SITE }, { renderBody });
     116  assert.equal(e.access, 'paid');
     117  assert.equal(e.content_html, null, 'het lijf wordt niet eens gerenderd');
     118  assert.match(e.teaser, /eerste alinea/);
     119  assert.ok(!JSON.stringify(e).includes('tweede alinea'), 'en niets erachter lekt mee');
     120});
     121
     122test('een fan-bericht ook niet', () => {
     123  const e = postEntry(post({ fan_only: 1 }), { user: VREEMDE, site: SITE }, { renderBody });
     124  assert.equal(e.access, 'fan');
     125  assert.equal(e.content_html, null);
     126});
     127
     128test('een concept levert helemaal niets op', () => {
     129  const e = postEntry(post({ status: 'draft' }), { user: VREEMDE, site: SITE }, { renderBody });
     130  assert.equal(e.access, 'forbidden');
     131  assert.equal(e.content_html, null);
     132  assert.equal(e.teaser, null, 'ook geen teaser: over een concept valt niets te zeggen');
     133});
     134
     135test('zonder renderer nog steeds geen lijf, en geen fout', () => {
     136  const e = postEntry(post(), { user: VREEMDE, site: SITE });
     137  assert.equal(e.access, 'full');
     138  assert.equal(e.content_html, null);
     139});
Note: See TracChangeset for help on using the changeset viewer.