from __future__ import annotations import json import sys import unittest from pathlib import Path from unittest.mock import patch ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) import tools.validate_kis_api_credentials_v1 as validator class _FakeCreds: def __init__(self, account: str): self.account = account self.domain = "https://openapi.koreainvestment.com:9443" if account == "real" else "https://openapivts.koreainvestment.com:29443" self.app_key = f"{account}-key" self.app_secret = f"{account}-secret" class TestValidateKisApiCredentials(unittest.TestCase): def test_validate_kis_api_credentials_writes_pass_json(self): import tempfile import shutil tmp_dir = tempfile.mkdtemp() try: out = Path(tmp_dir) / "kis_api_credentials_validation_v1.json" with patch.dict("os.environ", {"KIS_APP_Key_TEST": "mock-key", "KIS_APP_Secret_TEST": "mock-secret"}): with patch.object(validator, "KisCredentials") as mock_creds: mock_creds.load.side_effect = lambda account: _FakeCreds(account) with patch.object(validator, "get_current_price") as mock_price: mock_price.side_effect = RuntimeError("network should not be called in dry-run") with patch.object(sys, "argv", ["validate_kis_api_credentials_v1.py", "--account", "mock", "--ticker", "005930", "--dry-run", "--output", str(out)]): rc = validator.main() payload = json.loads(out.read_text(encoding="utf-8")) self.assertEqual(rc, 0) self.assertEqual(payload["gate"], "PASS") self.assertEqual(payload["evidence"]["account"], "mock") self.assertEqual(payload["evidence"]["ticker"], "005930") self.assertTrue(payload["evidence"]["dry_run"]) finally: shutil.rmtree(tmp_dir) def test_validate_kis_api_credentials_fails_when_api_call_errors(self): import tempfile import shutil tmp_dir = tempfile.mkdtemp() try: out = Path(tmp_dir) / "kis_api_credentials_validation_v1.json" with patch.object(validator, "KisCredentials") as mock_creds: mock_creds.load.side_effect = lambda account: _FakeCreds(account) with patch.object(validator, "get_current_price") as mock_price: mock_price.side_effect = RuntimeError("boom") with patch.object(sys, "argv", ["validate_kis_api_credentials_v1.py", "--account", "mock", "--ticker", "005930", "--output", str(out)]): rc = validator.main() payload = json.loads(out.read_text(encoding="utf-8")) self.assertEqual(rc, 1) self.assertEqual(payload["gate"], "FAIL") self.assertTrue(payload["errors"]) finally: shutil.rmtree(tmp_dir) if __name__ == "__main__": unittest.main()