import pytest import fooder.view.user as user_view from fooder.exc import CaptchaFailed @pytest.fixture(autouse=True) def bypass_captcha(monkeypatch): async def _noop(token: str, ip=None) -> None: pass monkeypatch.setattr(user_view, "verify_turnstile", _noop) @pytest.fixture def new_user_payload(): return { "username": "newuser", "password": "securepassword1", "captcha_token": "test-token", } async def test_create_user_returns_201(client, new_user_payload): response = await client.post("/api/user", json=new_user_payload) assert response.status_code == 201 async def test_create_user_returns_tokens(client, new_user_payload): response = await client.post("/api/user", json=new_user_payload) body = response.json() assert "access_token" in body assert "refresh_token" in body assert body["token_type"] == "bearer" async def test_create_user_can_login(client, new_user_payload): await client.post("/api/user", json=new_user_payload) response = await client.post( "/api/token", data={ "username": new_user_payload["username"], "password": new_user_payload["password"], }, ) assert response.status_code == 200 async def test_create_user_duplicate_username_returns_409(client, new_user_payload): await client.post("/api/user", json=new_user_payload) response = await client.post("/api/user", json=new_user_payload) assert response.status_code == 409 async def test_create_user_password_too_short_returns_422(client, new_user_payload): new_user_payload["password"] = "short" response = await client.post("/api/user", json=new_user_payload) assert response.status_code == 422 async def test_create_user_captcha_failure_returns_403(client, monkeypatch, new_user_payload): async def _fail(token: str, ip=None) -> None: raise CaptchaFailed() monkeypatch.setattr(user_view, "verify_turnstile", _fail) response = await client.post("/api/user", json=new_user_payload) assert response.status_code == 403 async def test_change_password_returns_204(auth_client, user_password): response = await auth_client.patch( "/api/user/password", json={"current_password": user_password, "new_password": "newpassword1"}, ) assert response.status_code == 204 async def test_change_password_can_login_with_new_password(auth_client, user, user_password): new_password = "newpassword1" await auth_client.patch( "/api/user/password", json={"current_password": user_password, "new_password": new_password}, ) response = await auth_client.post( "/api/token", data={"username": user.username, "password": new_password}, ) assert response.status_code == 200 async def test_change_password_wrong_current_returns_401(auth_client): response = await auth_client.patch( "/api/user/password", json={"current_password": "wrongpassword", "new_password": "newpassword1"}, ) assert response.status_code == 401 async def test_change_password_new_too_short_returns_422(auth_client, user_password): response = await auth_client.patch( "/api/user/password", json={"current_password": user_password, "new_password": "short"}, ) assert response.status_code == 422 async def test_change_password_unauthenticated_returns_401(client): response = await client.patch( "/api/user/password", json={"current_password": "any", "new_password": "newpassword1"}, ) assert response.status_code == 401