4.2 KiB
4.2 KiB
QA: Paginated media listing (API)
HTTP-level (Go, test/, task test)
Build media.NewHandler(...) over the real ListMediaUseCase and in-memory fakes of image.Repository, article.Repository, user.Repository and image.VariantFileRepository (extend the existing media fakes, keeping type names unique across files). Mount on a fresh chi.NewRouter() mirroring the media router in api/router.go (GET / inside jwtauth.Verifier + jwtauth.Authenticator, test jwtauth.New("HS256", ...), valid jwt cookie with a user_id claim of a verified user). Call validator.InitValidator(). No live server, no SQLite file.
Helper: decode into {items []map, total, page, size int, counts {all, unused, duplicates}}; also assert the raw JSON contains "items":[ (never null) and does not contain next_cursor.
- Bare request: 30 images -> object, page 1, size 25, total 30, 25 items, no
next_cursor. - Defaults table: page=2, page=3, size=5, size=50, size=100 on 60 images.
- Partition: 12 images, pages 1-3 of size 5 -> 5, 5, 2; 12 distinct ids.
- Order: equal-timestamp case -> ids 3,2,1. Sort table (newest, oldest, name, largest, total_size): 12 images, three pages, concatenation equals the full ordered list, no repeat. Ties break on id.
- Filter/variants/q: unused -> total 6, counts unchanged; variants=with -> total 3; q=wall&size=5&page=2 -> total 7, 2 items, counts.all 27.
- Hash: hash=H&page=1&size=100 -> 3 copies; hash=H alone -> page 1, size 25, 3 items.
- Out of range: page=99&size=5 -> 200, raw
"items":[], total 12. - Empty library -> items [], total 0, counts 0/0/0.
- counts library-wide: q=zzzz&page=3&size=5 -> items [], total 0, counts.all 30.
- cursor/limit ignored: rows
cursor=abc,limit=5,limit=0,limit=abc, a valid-looking old cursor -> 200, page 1, size 25, 25 items. - Invalid table (all rows): each -> 400, body exactly "The media query is invalid.", repository call counters stay 0.
- Repository failure -> 500 "Internal server error".
- Missing or invalid jwt cookie -> the auth group's 401, use case counter 0.
- Use-case tests:
ListMediaUseCase.Listreturns items, total, page, size and counts; slices after sorting; propagates a repository error (errors.Ison a sentinel);Describeis unchanged;ListQuery.Validaterejects page < 1 and sizes outside 5/25/50/100 withErrInvalidQuery.image.ListQuery.Cursorand.Limit,MediaPage.NextCursor,encodeCursoranddecodeCursorno longer exist. - Existing tests that read
next_cursor, sendlimitorcursor, or callNewListQuery(media tests intest/,features/media_library.qa.md,features/media_browse.qa.md) are amended to the envelope; list them in the diff.
Docs (verified by reading the diff)
docs/api.mdlines 99-103: replacecursorandlimitwithpage(default 1) andsize(5, 25, 50, 100; default 25); state the envelope (items,total,page,size,counts), thatcountsstays library-wide, that invalid values answer 400 "The media query is invalid.", and a "Breaking change" note:next_cursoris gone,cursorandlimitare ignored.docs/api/*.md: grep for/v1/media/andcursor; update the media listing section if one exists.web/src/data/apiCatalogue.tsmed-list: addpage,size,q,filter,sort,variants,hashquery entries, the 400 error, and a paged example (total,page,size, nonext_cursor). Remove thenext_cursorrule (line ~129, with its French entry inweb/src/i18n/messages.tsline ~1606) if it is only used by media. Integration specs asserting the catalogue are amended.- Flag for the user (read-only to agents):
docs/design/screens/integration.mdanddocs/design/source/IntegrationPage.dc.html(med-list with no params),docs/design/screens/media.md,routes.md,change-list.mditem 13b,README.mdline 92 andscreens/media-picker.md: all still say "array body" and "X-Total-Count". - A release note under
docs/releases/is the maintainer's call: flag it.
Manual verification
- Real SQLite file via
task dev: seed 60 images, check page=2&size=25, ordering by each sort and counts; the same on MySQL/PostgreSQL if available (no live DB in tests). - An authenticated curl returns the envelope with no
next_cursor.