Skip to content

test(user): look up bans by user_id filter to avoid pagination flake#259

Open
nijeesh-stream wants to merge 1 commit into
mainfrom
nijeeshjoshy/cha-3267-stabilize-usertest-pagination
Open

test(user): look up bans by user_id filter to avoid pagination flake#259
nijeesh-stream wants to merge 1 commit into
mainfrom
nijeeshjoshy/cha-3267-stabilize-usertest-pagination

Conversation

@nijeesh-stream
Copy link
Copy Markdown
Contributor

Summary

  • Adds a findBanFor(userId) test helper that calls query_banned_users with filter_conditions={"user_id": {"$eq": userId}}, so the moderation tests stop depending on which slice of the global ban list happens to come back on the first page of the shared CI app.
  • Adds a bestEffortUnban(userId) helper used from finally blocks so each test cleans up after itself (regular + shadow), preventing the shared app from accumulating zombie bans.
  • Refactors the five UserTest methods that were failing on every recent CI run (including the scheduled jobs on main, e.g. run 26395993503) to use the helpers: whenBanUser_thenIsBanned, whenBanUserWithDeleteReactions_thenIsBanned, whenShadowBanUser_thenIsShadowBanned, whenListingBannedUsers_thenContainsBanned, whenUnbanUser_thenIsNotBannedAnymore.
  • Tightens the @BeforeAll cleanupLeftoverBans sweep so it actually drains shadow and channel-scoped bans. The previous version always called User.unban(id).request() with no qualifiers, so any first page dominated by shadow / channel zombies caused it to bail with unbannedThisRound == 0 and leave the queue stuck.

Root cause

User.queryBanned().request() returns a paginated slice (limit defaults to ~50, max 300). The shared test app accumulates zombie bans whenever a prior PR's job dies before its inline teardown fires. Once enough pile up, bans.stream().anyMatch(ban -> ban.getUser().getId().equals(userId)) fails because the just-banned user is past page 1, and findFirst().get() in the shadow-ban test throws NoSuchElementException. Filtering query_banned_users by user_id makes the lookup deterministic regardless of zombie count.

Test plan

  • ./gradlew compileTestJava (JDK 11 toolchain)
  • ./gradlew spotlessCheck
  • CI Test & lint job passes the five previously failing UserTest cases
  • Confirm the cleanupLeftoverBans sweep keeps draining the CI app over subsequent runs (visible in successive @BeforeAll timings / scheduled main runs)

Made with Cursor

UserTest's ban / shadow-ban / unban tests query the global ban list with
no filter and assert the just-banned user appears in the response. The
shared CI app accumulates zombie bans whenever a prior job dies before
its inline teardown fires, so the just-created ban routinely ends up
past the first page of query_banned_users and the assertTrue(anyMatch)
checks fail (and the shadow-ban findFirst().get() throws
NoSuchElementException).

Add two test helpers:
  - findBanFor(userId): runs query_banned_users with
    filter_conditions={"user_id": {"$eq": userId}} so the lookup is
    independent of pagination.
  - bestEffortUnban(userId): clears regular + shadow bans in a finally
    block so the test app stops accumulating zombies even when an
    assertion fails.

Refactor the five failing UserTest methods (whenBanUser_thenIsBanned,
whenBanUserWithDeleteReactions_thenIsBanned,
whenShadowBanUser_thenIsShadowBanned,
whenListingBannedUsers_thenContainsBanned,
whenUnbanUser_thenIsNotBannedAnymore) to use the helpers and tidy up
after themselves.

Also tighten the @BeforeAll cleanupLeftoverBans sweep so it actually
drains shadow and channel-scoped bans (which the previous version
silently skipped because it always called unban() with no qualifiers
and bailed as soon as those bans were the only ones left on the first
page).

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants