o2o-site-AEO/solution/backend/tests/test_config.py
Mina Choi 48109fdc99 [feat] solution/backend,frontend: id/pw 가입 · 구글 로그인 — 계정을 만들 길이 없던 걸 연다
계정 생성 API 가 아예 없었다(그동안 users 를 손으로 INSERT 했다). 로그인 화면은 있는데
그 뒤에 설 계정을 만들 방법이 제품에 없는 상태였다.

- auth_service.signup: 가입 = **새 회사(테넌트) 1개 + 첫 계정 1개**. users.company_id 가
  NOT NULL 이고 모든 도메인이 company 로 스코프돼서, 회사 없는 계정은 아무것도 못 만든다
- services/external/google_identity: 구글 ID 토큰의 서명·iss·만료에 더해 **aud(우리 client_id)와
  email_verified 를 본다.** aud 검사가 빠지면 남의 앱에 발급된 '진짜' 구글 토큰으로 우리 계정에
  들어온다 — 서명도 발급자도 전부 맞으므로 다른 검사로는 안 걸린다
- users.provider/provider_uid 추가, password NULL 허용, id 20→64자(google_<sub> 가 20자를 넘는다).
  provider 에 server_default 를 같이 준 이유: ORM default 는 raw INSERT(테스트 시드)에 안 먹어서
  NOT NULL 컬럼이면 그 경로가 통째로 깨진다
- attempt_login: 소셜 계정을 먼저 끊는다. 안 끊으면 bcrypt 가 None 해시를 만나 500 이다
- 같은 이메일이라도 id/pw 계정과 구글 계정을 **잇지 않는다.** 이으면 계정 선점이다 —
  남의 이메일로 먼저 만들어 둔 계정에 그 사람의 구글 로그인이 들어간다 → DECISIONS 1-5
- LoginPage 는 admin 과 공유라 selfServe 로 갈랐다. admin 은 가입 링크도 구글 버튼도 안 뜬다
  (admin 라우터에 /signup 이 없어 404 가 난다)
- GOOGLE_CLIENT_ID 는 루트 .env 한 곳. compose 가 VITE_GOOGLE_CLIENT_ID 로 흘려보낸다 —
  두 곳에 적으면 백엔드 aud 대조와 화면 버튼이 조용히 갈라진다

★ 이미 도는 DB 는 init.sql 을 다시 적용해야 한다(말미 ALTER 섹션).

pytest: auth 13건 + 구글 토큰 검증 8건(진짜 RSA 서명으로 aud·iss·만료·email_verified·변조
거절 확인) 통과. 전체 527 passed / 8 failed(전부 기존 실패, 인증과 무관).
tsc·eslint·vite build 통과.
2026-09-02 09:33:59 +09:00

25 lines
1.7 KiB
Python

"""설정 로딩 — 우선순위와 테스트 격리.
우선순위: 실제 환경변수 > 레포 최상위 .env > config.{APP_ENV}.toml
.env 에 APP_ENV=local 이 들어 있어도 테스트는 반드시 test DB 를 봐야 한다 —
그 규칙이 깨지면 db_engine 픽스처의 TRUNCATE 가 dev DB 를 지운다.
"""
from config.server_configs import APP_ENV, external_api_config, google_oauth_config, main_db_config
def test_tests_run_against_test_db():
"""검증: 테스트 실행 시 바라보는 DB.
기대결과: APP_ENV=test, DB 이름에 'test' 포함 — .env 의 APP_ENV=local 에 끌려가지 않는다."""
assert APP_ENV == "test", f"테스트가 APP_ENV={APP_ENV} 로 돈다 — .env 나 실행 환경을 확인할 것"
assert "test" in main_db_config.name, f"테스트가 비-test DB('{main_db_config.name}')를 가리킨다"
def test_external_api_keys_are_absent_in_tests():
"""검증: 테스트 환경의 외부 API 키.
기대결과: 전부 빈 값 — 테스트가 실제 외부 API 를 때리지 않는다(수집 경로는 MockAdapter 로 검증)."""
for name in ("perplexity_api_key", "kakao_rest_api_key", "gemini_api_key", "tour_api_key"):
# 값 자체는 출력하지 않는다(실키가 로그·CI 에 남지 않게).
assert not getattr(external_api_config, name), f"{name} 이 테스트 환경에 설정돼 있다 — .env 가 새어 들어왔다"
# 구글 client_id 도 같은 규칙이다. 이게 새어 들어오면 구글 로그인 테스트가 진짜 JWKS 를 받으러 나간다.
assert not google_oauth_config.client_id, "GOOGLE_CLIENT_ID 가 테스트 환경에 설정돼 있다 — .env 가 새어 들어왔다"