source: Klonkt/test/collectie-paginering.test.js

main
Last change on this file was bac4bf3, checked in by Robin <roboburr@…>, 4 weeks ago

Paginering die echt pagineert (shaer-sk4)

Robin zag dat elke ?page= dezelfde inhoud gaf. Dat klopte, en het was geen halve
implementatie maar een omhulsel: pagedCollection veranderde alleen de VORM en
sneed nooit. first en last wezen allebei naar ?page=1, en de routes lazen
!!req.query.page -- of de parameter er STAAT, niet welke. Live gaf ?page=2 en
?page=99 dezelfde acht items, en noemden zichzelf pagina 1.

Nu: echt snijden, met next en prev, en een pagina die zijn eigen nummer
draagt. Een pagina voorbij het einde is LEEG en zegt dat ook -- hem naar de
laatste terugbuigen zou opnieuw een antwoord zijn dat over zichzelf liegt.

DE WORTEL HOUDT ZIJN ITEMS INLINE, en dat is geen slordigheid maar de reden dat
dit veilig is. Shaer leest een document en volgt next niet (KlonktClient.swift
orderedItems). Werd de wortel nu leeg, dan kreeg elke draaiende app nul items en
geen foutmelding -- dezelfde stille val waar ik op 10 augustus bij Funkwhale zelf
in trapte. Eerst de clients leren pagineren, dan pas de wortel afslanken.

WAT WEL EN NIET GEPAGINEERD IS. Volgers en following pagineren nu volledig: die
lijsten zitten al in het geheugen, dus dat kost niets extra. De outbox krijgt de
juiste VORM maar niet meer diepte: de route kapt al op twintig rijen in SQL.
Echt doorbladeren vraagt daar een LIMIT/OFFSET, en dat is lastiger dan bij
volgers omdat posts en tracks op datum door elkaar gevlochten worden en uit twee
tabellen komen -- een UNION met een offset erover, geen tweede slice. Dat staat
als naad in de code en op de bead, niet weggemoffeld.

Zeven tests, waaronder de klacht zelf: pagina 2 geeft ANDERE items dan pagina 1.

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

  • Property mode set to 100644
File size: 3.1 KB
Line 
1// Echte paginering (shaer-sk4).
2//
3// Robin zag dat elke ?page= dezelfde inhoud gaf. Dat klopte: pagedCollection
4// veranderde alleen de VORM en sneed nooit, first en last wezen allebei naar
5// pagina 1, en pagina 99 noemde zichzelf pagina 1.
6//
7// De WORTEL houdt zijn items inline, en dat is de hele reden dat dit veilig is:
8// Shaer leest een document en volgt `next` niet. Werd de wortel nu leeg, dan
9// kreeg elke draaiende app nul items en geen foutmelding.
10import { test } from 'node:test';
11import assert from 'node:assert/strict';
12
13process.env.DATABASE_PATH = ':memory:';
14process.env.PUBLIC_BASE_URL = 'https://ons.test';
15
16const { pagedCollection, PAGINA_GROOTTE } = await import('../src/services/ap-core.js');
17
18const ID = 'https://ons.test/ap/users/dev/followers';
19const vijftig = Array.from({ length: 50 }, (_, i) => `https://elders.test/u/${i}`);
20
21test('de wortel draagt ALLES inline, en wijst naar echte grenzen', () => {
22 const c = pagedCollection(ID, vijftig);
23 assert.equal(c.type, 'OrderedCollection');
24 assert.equal(c.orderedItems.length, 50, 'inline, want de app volgt next niet');
25 assert.equal(c.first, `${ID}?page=1`);
26 assert.equal(c.last, `${ID}?page=3`, '50 items bij 20 per pagina is drie paginas');
27});
28
29test('pagina 1 snijdt echt, en biedt een next', () => {
30 const p = pagedCollection(ID, vijftig, { page: 1 });
31 assert.equal(p.type, 'OrderedCollectionPage');
32 assert.equal(p.id, `${ID}?page=1`);
33 assert.equal(p.partOf, ID);
34 assert.equal(p.orderedItems.length, PAGINA_GROOTTE);
35 assert.equal(p.orderedItems[0], vijftig[0]);
36 assert.equal(p.next, `${ID}?page=2`);
37 assert.equal(p.prev, undefined, 'de eerste heeft geen vorige');
38});
39
40test('pagina 2 geeft ANDERE items dan pagina 1 -- dat was de klacht', () => {
41 const een = pagedCollection(ID, vijftig, { page: 1 }).orderedItems;
42 const twee = pagedCollection(ID, vijftig, { page: 2 }).orderedItems;
43 assert.notDeepEqual(een, twee);
44 assert.equal(twee[0], vijftig[20]);
45 assert.equal(pagedCollection(ID, vijftig, { page: 2 }).prev, `${ID}?page=1`);
46});
47
48test('de laatste pagina heeft de rest en GEEN next', () => {
49 const p = pagedCollection(ID, vijftig, { page: 3 });
50 assert.equal(p.orderedItems.length, 10);
51 assert.equal(p.next, undefined);
52 assert.equal(p.prev, `${ID}?page=2`);
53});
54
55test('een pagina voorbij het einde is leeg en zegt dat ook', () => {
56 // Hem naar de laatste terugbuigen zou opnieuw een antwoord zijn dat over
57 // zichzelf liegt -- precies wat er mis was.
58 const p = pagedCollection(ID, vijftig, { page: 99 });
59 assert.equal(p.id, `${ID}?page=99`, 'en niet ?page=1');
60 assert.equal(p.orderedItems.length, 0);
61 assert.equal(p.next, undefined);
62});
63
64test('een lege collectie heeft een pagina, geen nul', () => {
65 const c = pagedCollection(ID, []);
66 assert.equal(c.first, `${ID}?page=1`);
67 assert.equal(c.last, `${ID}?page=1`);
68});
69
70test('totalItems telt het GEHEEL, ook op een pagina', () => {
71 // De count-only vorm voor het publiek geeft een telling zonder items; die
72 // mag een pagina niet stilletjes tot nul maken.
73 const p = pagedCollection(ID, vijftig, { page: 2, totalItems: 12345 });
74 assert.equal(p.totalItems, 12345);
75});
Note: See TracBrowser for help on using the repository browser.