"""POST /auth/login and require_user_auth: success, wrong token, unknown user, whitespace.""" from __future__ import annotations import shutil import sys from pathlib import Path import pytest from fastapi.testclient import TestClient _SEED = Path(__file__).resolve().parent.parent / "deploy/hf/seed/hf_bundled_store.db" @pytest.fixture() def api_client(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): assert _SEED.is_file(), f"Missing seed DB: {_SEED}" dest = tmp_path / "auth_login_store.db" shutil.copyfile(_SEED, dest) monkeypatch.setenv("KINK_STORE_PATH", str(dest)) monkeypatch.setenv("KINK_SKIP_HEAVY_WARM", "1") monkeypatch.setenv("KINK_HF_REQUIRE_FULL_CATALOG", "0") sys.modules.pop("api", None) import api as api_mod api_mod._backend_impl = None api_mod._get_backend() return api_mod def test_login_success(api_client) -> None: client = TestClient(api_client.app) u = client.post("/users", json={}).json() r = client.post( "/auth/login", json={"user_id": u["id"], "private_token": u["private_token"]}, ) assert r.status_code == 200 body = r.json() assert body["user"]["id"] == u["id"] assert body["private_token"] == u["private_token"] def test_login_wrong_token_still_401(api_client) -> None: client = TestClient(api_client.app) u = client.post("/users", json={}).json() r = client.post( "/auth/login", json={"user_id": u["id"], "private_token": "not-the-real-token"}, ) assert r.status_code == 401 assert r.json().get("detail") == "Invalid credentials" def test_login_unknown_user_404_not_wrong_password(api_client) -> None: """Unknown id must not read as 'wrong password' (HF ephemeral DB wipe UX).""" client = TestClient(api_client.app) r = client.post( "/auth/login", json={"user_id": "no-such-profile-00", "private_token": "any-token"}, ) assert r.status_code == 404 detail = r.json().get("detail", "") assert "Unknown profile" in detail assert "ephemeral" in detail.lower() def test_new_user_has_recommendations_on_hf_seed(api_client) -> None: """Playwright e2e depends on a non-empty starter deck from ``/recommendations``.""" client = TestClient(api_client.app) u = client.post("/users", json={}).json() r = client.get( f"/users/{u['id']}/recommendations?limit=8", headers={"x-private-token": u["private_token"]}, ) assert r.status_code == 200 assert len(r.json().get("items", [])) >= 1 def test_create_profile_then_get_user_immediately(api_client) -> None: """UI: POST /users then GET /users/:id with token — must not 404/401 (HF create-profile flow).""" client = TestClient(api_client.app) u = client.post("/users", json={}).json() uid = u["id"] tok = u["private_token"] r = client.get(f"/users/{uid}", headers={"x-private-token": tok}) assert r.status_code == 200 body = r.json() assert body["id"] == uid def test_login_strips_whitespace_on_body_fields(api_client) -> None: client = TestClient(api_client.app) u = client.post("/users", json={}).json() r = client.post( "/auth/login", json={ "user_id": f" {u['id']} \n", "private_token": f" {u['private_token']} ", }, ) assert r.status_code == 200