박재오 결정 2026-05-19 — V2를 정식 명칭 ai_trade로 graduation, V1은 deprecated 마킹 (legacy 디렉토리 이동은 file lock 풀린 후 후속). 변경 사항: - signal_v2/ → ai_trade/ (git mv, import 일괄 sed: signal_v2.x → ai_trade.x) - root start.bat → legacy/start_v1.bat (V1 자동 시작 차단) - ai_trade/start.bat 내부 uvicorn target signal_v2.main → ai_trade.main - signal_v1/DEPRECATED.md 추가 (사용 금지 명시) - CLAUDE.md 디렉토리 표·서버 시작 방식 갱신 - services/ 디렉토리 미래 예정 (Plan-B-Insta 작업 시 신설) ai_trade tests 59/59 PASS 확인. signal_v1/ 디렉토리 자체 이동(legacy/signal_v1/)은 telegram_bot.log + data/news_snapshots.db file lock으로 보류. lock 해제 후 후속 커밋. 후속 작업: Plan-B-Insta (services/insta-render + NAS insta 분할) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
63 lines
2.6 KiB
Python
63 lines
2.6 KiB
Python
"""Tests for FastAPI main app."""
|
|
import logging
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
def test_health_endpoint_returns_status_online(monkeypatch):
|
|
monkeypatch.setenv("STOCK_API_URL", "https://test.stock.local")
|
|
monkeypatch.setenv("WEBAI_API_KEY", "test-secret")
|
|
# Reload modules so they pick up the new env
|
|
import importlib
|
|
from ai_trade import config as cfg
|
|
importlib.reload(cfg)
|
|
from ai_trade import main as main_mod
|
|
importlib.reload(main_mod)
|
|
with TestClient(main_mod.app) as client:
|
|
r = client.get("/health")
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["status"] == "online"
|
|
assert body["stock_api_url"] == "https://test.stock.local"
|
|
|
|
|
|
def test_startup_warns_if_webai_api_key_missing(monkeypatch, caplog):
|
|
# Use setenv with empty string + no-op load_dotenv to defeat .env re-read on reload
|
|
monkeypatch.setattr("ai_trade.config.load_dotenv", lambda *a, **k: None)
|
|
monkeypatch.setenv("WEBAI_API_KEY", "")
|
|
monkeypatch.setenv("STOCK_API_URL", "https://test.stock.local")
|
|
import importlib
|
|
from ai_trade import config as cfg
|
|
importlib.reload(cfg)
|
|
# After reload, load_dotenv reference is fresh — re-patch
|
|
monkeypatch.setattr("ai_trade.config.load_dotenv", lambda *a, **k: None)
|
|
from ai_trade import main as main_mod
|
|
importlib.reload(main_mod)
|
|
with caplog.at_level(logging.WARNING, logger="ai_trade.main"):
|
|
with TestClient(main_mod.app) as client:
|
|
client.get("/health")
|
|
assert any("WEBAI_API_KEY" in rec.message for rec in caplog.records)
|
|
|
|
|
|
def test_startup_warns_if_kis_app_key_missing(monkeypatch, caplog):
|
|
"""KIS app_key 미설정 시 startup WARNING (KIS 호출 disabled) — V1 패턴."""
|
|
monkeypatch.setattr("ai_trade.config.load_dotenv", lambda *a, **k: None)
|
|
monkeypatch.setenv("STOCK_API_URL", "https://test.stock.local")
|
|
monkeypatch.setenv("WEBAI_API_KEY", "test-secret")
|
|
# V1 pattern: kis_env_type=virtual, both virtual keys empty
|
|
monkeypatch.setenv("KIS_ENV_TYPE", "virtual")
|
|
monkeypatch.setenv("KIS_VIRTUAL_APP_KEY", "")
|
|
monkeypatch.setenv("KIS_REAL_APP_KEY", "")
|
|
|
|
import importlib
|
|
from ai_trade import config as cfg
|
|
importlib.reload(cfg)
|
|
monkeypatch.setattr("ai_trade.config.load_dotenv", lambda *a, **k: None)
|
|
from ai_trade import main as main_mod
|
|
importlib.reload(main_mod)
|
|
with caplog.at_level(logging.WARNING, logger="ai_trade.main"):
|
|
with TestClient(main_mod.app) as client:
|
|
client.get("/health")
|
|
assert any("KIS" in rec.message and "app_key" in rec.message.lower() for rec in caplog.records)
|