refactor: implement user deletion functionality and enhance settings management

This commit is contained in:
Abhimanyu Saharan
2026-02-10 00:17:06 +05:30
parent d9f560ee0c
commit 55d4c482bc
11 changed files with 843 additions and 41 deletions

View File

@@ -0,0 +1,98 @@
# ruff: noqa: S101
"""Tests for user self-delete API behavior."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
from uuid import uuid4
import pytest
from fastapi import HTTPException, status
from app.api import users
from app.core.auth import AuthContext
from app.models.users import User
@dataclass
class _FakeSession:
committed: int = 0
async def commit(self) -> None:
self.committed += 1
class _EmptyMembershipQuery:
async def all(self, _session: Any) -> list[Any]:
return []
class _FakeOrganizationMemberModel:
class objects:
@staticmethod
def filter_by(**_kwargs: Any) -> _EmptyMembershipQuery:
return _EmptyMembershipQuery()
@pytest.mark.asyncio
async def test_delete_me_aborts_when_clerk_delete_fails(monkeypatch: pytest.MonkeyPatch) -> None:
"""Local deletion should not run if Clerk account deletion fails."""
session = _FakeSession()
user = User(id=uuid4(), clerk_user_id="user_123")
auth = AuthContext(actor_type="user", user=user)
async def _fail_delete(_clerk_user_id: str) -> None:
raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail="clerk failure")
async def _unexpected_update(*_args: Any, **_kwargs: Any) -> int:
raise AssertionError("crud.update_where should not be called on Clerk failure")
async def _unexpected_delete(*_args: Any, **_kwargs: Any) -> int:
raise AssertionError("crud.delete_where should not be called on Clerk failure")
monkeypatch.setattr(users, "delete_clerk_user", _fail_delete)
monkeypatch.setattr(users.crud, "update_where", _unexpected_update)
monkeypatch.setattr(users.crud, "delete_where", _unexpected_delete)
with pytest.raises(HTTPException) as exc_info:
await users.delete_me(session=session, auth=auth)
assert exc_info.value.status_code == status.HTTP_502_BAD_GATEWAY
assert session.committed == 0
@pytest.mark.asyncio
async def test_delete_me_deletes_local_user_after_clerk_success(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""User delete should invoke Clerk deletion, then remove local account."""
session = _FakeSession()
user = User(id=uuid4(), clerk_user_id="user_456")
auth = AuthContext(actor_type="user", user=user)
calls: dict[str, int] = {"clerk": 0, "update": 0, "delete": 0}
async def _delete_from_clerk(clerk_user_id: str) -> None:
assert clerk_user_id == "user_456"
calls["clerk"] += 1
async def _update_where(*_args: Any, **_kwargs: Any) -> int:
calls["update"] += 1
return 0
async def _delete_where(*_args: Any, **_kwargs: Any) -> int:
calls["delete"] += 1
return 1
monkeypatch.setattr(users, "delete_clerk_user", _delete_from_clerk)
monkeypatch.setattr(users, "OrganizationMember", _FakeOrganizationMemberModel)
monkeypatch.setattr(users.crud, "update_where", _update_where)
monkeypatch.setattr(users.crud, "delete_where", _delete_where)
response = await users.delete_me(session=session, auth=auth)
assert response.ok is True
assert calls["clerk"] == 1
assert calls["update"] == 3
assert calls["delete"] == 1
assert session.committed == 1