Skip to content

test(e2e): cover the user delete check end to end - #2028

Open
AmanGIT07 wants to merge 2 commits into
feat/user-delete-checkfrom
test/user-delete-check
Open

AmanGIT07 wants to merge 2 commits into
feat/user-delete-checkfrom
test/user-delete-check

Conversation

@AmanGIT07

@AmanGIT07 AmanGIT07 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #2027. Merge #2027 first.

Summary

End-to-end tests for the user delete check in #2027. The admin user delete is refused while anything blocks it, and nothing changes. It deletes the orgs where the user is the only member. After a failed step, the next try continues from where the last one stopped.

Changes

  • test/e2e/regression/api_test.go: TestUserDeleteWithOrgs, six cases:
    • The user is the only owner of an org with another member, and alone in an org whose offline billing account is at -30 tokens. The delete is refused with two violations, SOLE_OWNER_WITH_MEMBERS and NEGATIVE_TOKEN_BALANCE. The user, the orgs, the balance and the user's membership stay as they were. Once that org has a second owner and the usage is refunded, the delete goes through: the orgs where the user was alone are deleted, and the shared org stays without the user.
    • A disabled member still counts, so the only owner of that org is refused.
    • Orgs where the user is the only member are deleted with the user: an enabled one, a disabled one, and one whose only other member is a service user.
    • A member of a disabled org leaves it. The org stays, and the user has no live policy on it.
    • A disk in an org where the user is the only member refuses the delete with RESOURCES_EXIST, and the message names the org: user cannot be deleted yet: organization[user-delete-check-disk]: RESOURCES_EXIST. The user's other, empty org is not deleted. Once the disk is gone, the delete goes through.
    • A trigger fails one write at a time: the project delete inside an org that goes with the user, the user's removal from another org, and the user row. Each try returns an error and stops at that step. The next try continues from there, and the last one deletes the user.
  • test/e2e/regression/billing_test.go: TestUserDeleteRefusedWhileAnOrgHasAPaidSubscription. A paid subscription in an org where the user is the only member refuses the delete with ACTIVE_SUBSCRIPTION. The user, the org and the subscription stay.
  • signUpUser and requireDeleteRefused are shared by both suites.

Technical Details

  • The users sign up and create their own orgs, so they are the only members. The disabled org case uses an org the admin created, so the admin stays its owner and the user only leaves it.
  • orgHasUser looks at both lists of ListOrganizationUsers. users hides deleted users, while role_pairs comes from the org's live policies, so only role_pairs would still show a policy left behind after the delete.
  • ListOrganizationUsers refuses a disabled org, so the disabled org case counts the user's live policies on it in the database.
  • A plain member leaving an enabled org is covered by TestUserDeleteLeavesNoAccessAndNoLivePolicy, from fix(deleter): user delete removes every policy the user holds #2022.
  • The billing suite runs stripe-mock, which answers every invoice list with the same draft invoice. The delete reads invoices from the provider, so it also reports that invoice as UNPAID_INVOICE. The test only checks that ACTIVE_SUBSCRIPTION is among the violations. An unpaid invoice cannot be set up locally for the delete.
  • The triggers work like the one in TestConsentInsertFailureRollsBackTheUser: fixed names and emails in the function bodies, no SQL built from strings, and a deferred cleanup that drops them even when the test fails. The trigger on users matches both a delete and a soft delete, so it keeps working after feat(store): user delete keeps the row #2023.
  • The server replaces the text of every internal error with a generic message, so the test cannot match the injected failure text. Each stop is pinned by what the steps before it leave behind instead:
    • after the project failure, the project has no live policy but its row is live, because the project delete removes its policies before its row;
    • after the removal failure, the org that goes with the user is gone, and the user is still in the other org and still signed in;
    • after the user row failure, the user's session no longer works but the row is live, because the sessions end just before the row.
  • project.Service.DeleteModel removes a project's relations before its row. After the injected failure on the row, the API answers permission denied for that project, even to an admin, until a retry finishes the delete. The test checks the project row in the database instead.

Test Plan

  • Each case fails when the rule it covers is broken: the delete ignoring blockers, skipping the blockers of orgs that go with the user, a negative balance or a paid subscription not blocking, a disabled member not counting, a service user counting, a disabled org skipped, the orgs where the user is alone kept, and the delete carrying on after a failed org delete or a failed removal from an org.
  • The newer checks fail too when broken: a policy left on the shared org after the delete (found through role_pairs; the users list alone misses it), the removal from a disabled org failing, and an injected failure moved one step earlier (the project's policies, or the sessions).
  • go test ./test/e2e/... passes.
  • make lint reports no issues.

@vercel

vercel Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
frontier Ready Ready Preview Oct 28, 2026 2:54pm UTC

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@coveralls

coveralls commented Oct 26, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 40710379612

Coverage remained the same at 55.922%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 42082
Covered Lines: 23533
Line Coverage: 55.92%
Coverage Strength: 19.66 hits per line

💛 - Coveralls

Comment thread test/e2e/regression/billing_test.go Outdated
Comment thread test/e2e/regression/api_test.go
Comment thread test/e2e/regression/api_test.go
Comment thread test/e2e/regression/api_test.go Outdated
Comment thread test/e2e/regression/api_test.go
The admin user delete is refused with one violation per blocker across the user's orgs, including a negative token balance and a paid subscription, and nothing changes until the blockers are cleared. Orgs where the user is the only member are deleted with the user, including a disabled org and one whose only other member is a service user. A failure injected at the org delete, the removal from another org and the user row stops the delete, and each retry continues from where the last one stopped.

This branch was successfully deployed

1 active deployment
Preview — 16df0ba5 Deployed Oct 28, 2026 by vercel[bot]
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.

3 participants