Files
CODE_ASSISTANT/5_django_backend/tests/test_auth.py
T
leehc991028andClaude Fable 5.1 2869985139 feat(backend): Django + OpenCode 백엔드 추가 — 5_django_backend/
앱이 기대하는 base-backend 계약(envelope·JWT·/chat/stream SSE)을 그대로 구현.
Django 는 로그인·세션 미러(SQLite/PG)·OpenCode 이벤트 번역만 맡고, 답변은 전용
OpenCode 인스턴스(opencode/ workspace, codeassist 에이전트)가 만듦.
- accounts: 이메일 로그인, access 60분 / refresh 14일, entra/config 는 501
- chat: 세션 목록·검색·메시지·취소 + POST /chat/stream 어댑터(part.delta→token,
  idle→usage/done, 클라 끊겨도 턴 감시 태스크가 DB 마무리, 첫 이벤트 60초 타임아웃)
- OpenCode 1.18 멀티 프로젝트라 모든 요청에 ?directory= 부착
- docs-lib 에 OpenCode SDK 1.18.6 타입 원본, pytest 32

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 21:28:31 +09:00

88 lines
2.9 KiB
Python

"""인증 API — 프론트 auth.api.ts / types/api.ts 계약."""
TOKEN_KEYS = {
"token",
"tokenExpirationTime",
"refreshToken",
"refreshTokenExpirationTime",
"tokenType",
"user",
}
USER_KEYS = {"id", "email", "userName", "role", "employeeId", "department", "authProvider"}
def test_login_returns_token_response(api, user):
res = api.post("/api/v1/auth/login", {"email": "U@X.com", "password": "pw1234"}, format="json")
assert res.status_code == 200
data = res.json()["data"]
assert set(data) == TOKEN_KEYS
assert data["tokenType"] == "bearer"
assert set(data["user"]) == USER_KEYS
assert data["user"]["email"] == "u@x.com"
assert data["user"]["role"] == "USER"
assert data["user"]["authProvider"] == "local"
assert data["tokenExpirationTime"] < data["refreshTokenExpirationTime"]
def test_login_wrong_password_401_with_code(api, user):
res = api.post("/api/v1/auth/login", {"email": "u@x.com", "password": "nope"}, format="json")
assert res.status_code == 401
assert res.json()["code"] == "INVALID_CREDENTIALS"
def test_me_with_bearer(auth_api):
res = auth_api.get("/api/v1/users/me")
assert res.status_code == 200
data = res.json()["data"]
assert data["email"] == "u@x.com"
assert data["isActive"] is True
assert "createdAt" in data
def test_me_with_query_token(api, auth_api):
# EventSource 등 헤더 못 붙이는 곳용
plain = api.__class__()
res = plain.get(f"/api/v1/users/me?token={auth_api.tokens['token']}")
assert res.status_code == 200
def test_refresh_issues_new_access(auth_api):
old = auth_api.tokens
res = auth_api.post("/api/v1/auth/refresh", {"refreshToken": old["refreshToken"]}, format="json")
assert res.status_code == 200
data = res.json()["data"]
assert set(data) == TOKEN_KEYS
assert data["refreshToken"] == old["refreshToken"] # 회전 안 함
assert data["user"]["email"] == "u@x.com"
def test_refresh_missing_token(api, db):
res = api.post("/api/v1/auth/refresh", {}, format="json")
assert res.status_code == 401
assert res.json()["code"] == "REFRESH_TOKEN_MISSING"
def test_refresh_bad_token(api, db):
res = api.post("/api/v1/auth/refresh", {"refreshToken": "garbage"}, format="json")
assert res.status_code == 401
assert res.json()["code"] == "REFRESH_TOKEN_INVALID"
def test_logout_is_public_and_null(api, db):
res = api.post("/api/v1/auth/logout", format="json")
assert res.status_code == 200
assert res.json()["data"] is None
def test_entra_config_is_501(api, db):
res = api.get("/api/v1/auth/entra/config")
assert res.status_code == 501
assert res.json()["code"] == "NOT_IMPLEMENTED"
def test_seed_users_exist_after_migrate(db):
from apps.accounts.models import User
assert User.objects.filter(email="admin@codeassist.local", is_superuser=True).exists()
assert User.objects.filter(email="guest@codeassist.local").exists()