Skip to content

Fixed flaky email verification trigger acceptance test#28006

Merged
9larsons merged 1 commit into
mainfrom
fix-flaky-email-verification-trigger-test
May 20, 2026
Merged

Fixed flaky email verification trigger acceptance test#28006
9larsons merged 1 commit into
mainfrom
fix-flaky-email-verification-trigger-test

Conversation

@9larsons
Copy link
Copy Markdown
Contributor

@9larsons 9larsons commented May 20, 2026

What

Makes the acceptance test members.test.js → "Email verification trigger › Can add a member and trigger host email verification limits" deterministic. It has been failing intermittently on the mysql8 acceptance lane.

Why it was flaky

The test asserted that email verification becomes required on the exact member that crosses the admin threshold. That assertion is racy: VerificationTrigger decides whether the threshold is exceeded by counting members_created_events rows, but that table is written by a separate MemberCreatedEvent subscriber (EventStorage). The two handlers run concurrently with no ordering guarantee — when the trigger's count query wins the race it misses the just-created member's row, undercounts by one, and fires one member creation late.

What this PR does

Adds a buffer member past the threshold. By the time its event is handled, the earlier members' rows are guaranteed committed, so verification has deterministically triggered before it is asserted — regardless of how the race lands. The webhook assertion is relaxed accordingly (amountTriggered is now 2 or 3). The buffer member uses a raw POST so the response-body snapshots are untouched.

This is a test-only change. The underlying product off-by-one is low impact — it self-heals on the next member creation and has no user-facing effect — and is tracked separately in BER-3680. The test carries a TODO to restore the precise assertion once that is fixed.

ref https://linear.app/ghost/issue/BER-3680

- the test asserted email verification triggers on the exact member that
  crosses the admin threshold; that assertion is racy because the trigger
  counts members_created_events rows written by a separate MemberCreatedEvent
  subscriber, with no ordering guarantee between the two handlers
- when the trigger's count wins the race it undercounts by one and verification
  fires one member creation late, so the assertion failed intermittently on CI
- added a buffer member past the threshold so verification has deterministically
  triggered by the time it is asserted, regardless of how the race lands
- the underlying product off-by-one is low impact and tracked in BER-3680
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Review Change Stack

Walkthrough

The "Email verification trigger" test in the members.test.js file is modified to address flakiness caused by an off-by-one race condition between independent webhook subscribers. The test now adds a recovery member after the initial threshold-crossing attempt, settles domain events, and then relaxes its webhook assertion from requiring an exact amountTriggered value of 2 to checking for >= 2. Cleanup is updated to delete only the newly added recovery member instead of the earlier test members.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: fixing a flaky email verification trigger acceptance test.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly relates to the changeset, explaining the flakiness issue, root cause, and solution implemented.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-flaky-email-verification-trigger-test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ghost/core/test/e2e-api/admin/members.test.js`:
- Around line 1114-1117: The current assertion uses a too-broad check
(matchingRequest.body.amountTriggered >= 2); narrow it to only allow the two
documented outcomes (2 or 3) by replacing that condition with an explicit check
that matchingRequest.body.amountTriggered is either 2 or 3 (e.g., assert that
matchingRequest.body.amountTriggered equals 2 or equals 3) so overcount
regressions will fail; update the assertion around
matchingRequest.body.amountTriggered accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 44c0dd1d-d228-46e2-8504-2cecedc77743

📥 Commits

Reviewing files that changed from the base of the PR and between b8c6656 and 98897f2.

📒 Files selected for processing (1)
  • ghost/core/test/e2e-api/admin/members.test.js

Comment on lines +1114 to +1117
// amountTriggered is the member count observed when verification fired.
// It is past the threshold (1); the exact value (2 or 3) depends on the
// off-by-one race described above.
assert.ok(matchingRequest.body.amountTriggered >= 2, 'Expected the webhook to report a member count past the threshold');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Tighten the relaxed amountTriggered assertion.

>= 2 is broader than the behavior this test documents, so an overcount regression would still pass. With one buffer member and the known race, the only expected values here should be 2 or 3.

🎯 Narrow the assertion to the two valid outcomes
-            assert.ok(matchingRequest.body.amountTriggered >= 2, 'Expected the webhook to report a member count past the threshold');
+            assert.ok([2, 3].includes(matchingRequest.body.amountTriggered), 'Expected the webhook to report a member count of 2 or 3 when verification fired');
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// amountTriggered is the member count observed when verification fired.
// It is past the threshold (1); the exact value (2 or 3) depends on the
// off-by-one race described above.
assert.ok(matchingRequest.body.amountTriggered >= 2, 'Expected the webhook to report a member count past the threshold');
// amountTriggered is the member count observed when verification fired.
// It is past the threshold (1); the exact value (2 or 3) depends on the
// off-by-one race described above.
assert.ok([2, 3].includes(matchingRequest.body.amountTriggered), 'Expected the webhook to report a member count of 2 or 3 when verification fired');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ghost/core/test/e2e-api/admin/members.test.js` around lines 1114 - 1117, The
current assertion uses a too-broad check (matchingRequest.body.amountTriggered
>= 2); narrow it to only allow the two documented outcomes (2 or 3) by replacing
that condition with an explicit check that matchingRequest.body.amountTriggered
is either 2 or 3 (e.g., assert that matchingRequest.body.amountTriggered equals
2 or equals 3) so overcount regressions will fail; update the assertion around
matchingRequest.body.amountTriggered accordingly.

@9larsons 9larsons enabled auto-merge (squash) May 20, 2026 23:39
@9larsons 9larsons merged commit 0d307bd into main May 20, 2026
43 checks passed
@9larsons 9larsons deleted the fix-flaky-email-verification-trigger-test branch May 20, 2026 23:56
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.

1 participant