- item/supplier/quotation/quotation_setting CRUD·service·router 추가 - item protocol delivery_type str→int (ERD/스키마 SMALLINT 일치) - DeliveryType enum + 한글 라벨, 공용 GET /v1/enums (도메인 코드 메타데이터) - CompanyBrief → CompanyData 로 *Data 네이밍 통일 - CORS: WebServerConfig.client_url(단일) 도입 (config_models/router) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
79 lines
2.8 KiB
Python
79 lines
2.8 KiB
Python
"""auth 도메인 e2e 테스트 (negodata: users/companies 기반).
|
|
|
|
실행 전제: PostgreSQL(negodata_db)이 떠 있어야 한다.
|
|
docker compose up -d # 또는 로컬 postgres
|
|
cd negodata/backend && python -m pytest
|
|
계정 생성은 company_id 를 요구하므로 company_id 픽스처(conftest)가 소속사를 시드한다.
|
|
"""
|
|
|
|
|
|
async def test_create_and_login_flow(client, company_id):
|
|
# 1) 계정 생성 (회사 하위로)
|
|
r = await client.post(
|
|
"/v1/auth/create",
|
|
json={"id": "user1", "password": "pw1234", "company_id": company_id, "name": "홍길동"},
|
|
)
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["result"]["success"] is True
|
|
assert body["user_id"]
|
|
|
|
# 2) 로그인 -> 토큰 발급
|
|
r = await client.post("/v1/auth/login", json={"id": "user1", "password": "pw1234"})
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["result"]["success"] is True
|
|
assert body["access_token"]
|
|
assert body["refresh_token"]
|
|
access_token = body["access_token"]
|
|
|
|
# 3) 보호된 엔드포인트(/me) — 토큰의 유저 + 소속사 반환
|
|
r = await client.get("/v1/auth/me", headers={"Authorization": f"Bearer {access_token}"})
|
|
assert r.status_code == 200
|
|
me = r.json()
|
|
assert me["id"] == "user1"
|
|
assert me["name"] == "홍길동"
|
|
assert me["company"]["company_id"] == company_id
|
|
|
|
|
|
async def test_login_with_wrong_password(client, company_id):
|
|
await client.post(
|
|
"/v1/auth/create",
|
|
json={"id": "user2", "password": "correct", "company_id": company_id, "name": "n"},
|
|
)
|
|
|
|
r = await client.post("/v1/auth/login", json={"id": "user2", "password": "wrong"})
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["result"]["success"] is False
|
|
# 자격증명 오류는 ACCOUNT_INVALID_INFO(1200)
|
|
assert body["result"]["code"] == 1200
|
|
assert body.get("access_token", "") == "" # 실패 시 토큰은 빈 문자열
|
|
|
|
|
|
async def test_login_nonexistent_account(client):
|
|
r = await client.post("/v1/auth/login", json={"id": "ghost", "password": "whatever"})
|
|
assert r.json()["result"]["success"] is False
|
|
|
|
|
|
async def test_duplicate_account_create(client, company_id):
|
|
r1 = await client.post(
|
|
"/v1/auth/create",
|
|
json={"id": "dup", "password": "pw1234", "company_id": company_id, "name": "n"},
|
|
)
|
|
assert r1.json()["result"]["success"] is True
|
|
|
|
r2 = await client.post(
|
|
"/v1/auth/create",
|
|
json={"id": "dup", "password": "pw5678", "company_id": company_id, "name": "n2"},
|
|
)
|
|
body = r2.json()
|
|
assert body["result"]["success"] is False
|
|
# ACCOUNT_ALREADY_EXIST(1201)
|
|
assert body["result"]["code"] == 1201
|
|
|
|
|
|
async def test_me_without_token_is_rejected(client):
|
|
r = await client.get("/v1/auth/me")
|
|
assert r.status_code in (401, 403) # HTTPBearer 가 자격증명 없음을 거부
|