test(managementapi): filtered listing behavior suite part 3/4 (S09 Enforcement plan: 19/20)

Part 3 of 4 of the S09 enforcement plan — Step 19: Permission-filtered repository listing.

The step is split into 4 stacked MRs to keep each within the review size limit (≈800 ideal). Each part targets the previous one; the stack sits on step 18 part 4 (!2146 (merged)). Review and merge bottom-up.

Stacked MRs (review/merge bottom-up)

This part (~1,070 reviewable LoC, test-only)

The remaining HTTP-level behavior suite for the filtered branch — no production change. What it pins, by group:

  • Pagination: the next-page token anchors on the last returned survivor (never the last enumerated candidate — a regression there silently skips visible rows), filter-before-paginate hasMore semantics (survivor count only, never the store's raw signal), the early exit at limit+1 survivors, backward pages (order flip + reverse, both links when survivors exceed the limit) and the backward resume when a page's rows all vanish.
  • Chunking: chunk boundaries advance on the raw last key even through fully-denied chunks, a filtered-empty chunk with more candidates is not termination, cross-chunk survivor dedupe does not shorten a page, and a full 9,998-key chunk's ReadRelationships request stays at or under the 10,000-object IAM cap.
  • BatchCheck consumption: a malformed response (duplicate, unrequested, out-of-range, missing, or object-echo-violating verdict) answers 503, never an implicit deny or a dropped row; verdict order never affects page order; the relationship cap splits one chunk into multiple conforming requests carrying the shared ancestor tuples.
  • Scoping and failure: tenant scoping on every store call under hostile query parameters, the format/kind/sort/order parameter matrix on the filtered branch, any chunk failure is 503-never-partial, the vanished-row race, the FindByIDs 100-id cap boundary, and the 503 log carrying the namespace id.

Size

Over the 500 LoC guideline because fetchAuthorizedListPage is a single unexported entry point: the external test package reaches every behavior above only through ServeHTTP, so the suite is one feature's coverage and splitting it further would separate tests from the behavior boundary they share.

References

No e2e scenario is added or affected: no catalog covers the management API, and the listing filter's behavior is pinned by this suite (plan Testing Strategy).

Related to #861 (closed)

Edited by David Fernandez

Merge request reports

Loading
Loading