""" Portfolio API integration tests """ import pytest from fastapi.testclient import TestClient from sqlalchemy.orm import Session @pytest.mark.integration class TestPortfolioAPI: """Portfolio API endpoint tests""" def test_create_portfolio_success( self, client: TestClient, sample_assets ): """Test successful portfolio creation""" portfolio_data = { "name": "테스트 포트폴리오", "description": "API 테스트용", "assets": [ {"ticker": "005930", "target_ratio": 50.0}, {"ticker": "000660", "target_ratio": 30.0}, {"ticker": "035420", "target_ratio": 20.0}, ] } response = client.post("/api/v1/portfolios/", json=portfolio_data) assert response.status_code == 200 data = response.json() assert "id" in data assert data["name"] == portfolio_data["name"] assert len(data["assets"]) == 3 def test_create_portfolio_invalid_ratio_sum( self, client: TestClient, sample_assets ): """Test portfolio creation with invalid ratio sum""" portfolio_data = { "name": "Invalid Ratio Portfolio", "description": "목표 비율 합이 100이 아님", "assets": [ {"ticker": "005930", "target_ratio": 50.0}, {"ticker": "000660", "target_ratio": 30.0}, # Sum = 80, not 100 ] } response = client.post("/api/v1/portfolios/", json=portfolio_data) # Should fail validation assert response.status_code in [400, 422] def test_create_portfolio_invalid_ticker(self, client: TestClient): """Test portfolio creation with non-existent ticker""" portfolio_data = { "name": "Invalid Ticker Portfolio", "description": "존재하지 않는 종목코드", "assets": [ {"ticker": "999999", "target_ratio": 100.0}, ] } response = client.post("/api/v1/portfolios/", json=portfolio_data) # Should fail validation assert response.status_code in [400, 404] def test_get_portfolio( self, client: TestClient, sample_portfolio ): """Test getting portfolio by ID""" response = client.get(f"/api/v1/portfolios/{sample_portfolio.id}") assert response.status_code == 200 data = response.json() assert data["id"] == str(sample_portfolio.id) assert data["name"] == sample_portfolio.name assert len(data["assets"]) == 3 def test_get_portfolio_not_found(self, client: TestClient): """Test getting non-existent portfolio""" import uuid fake_id = str(uuid.uuid4()) response = client.get(f"/api/v1/portfolios/{fake_id}") assert response.status_code == 404 def test_list_portfolios( self, client: TestClient, sample_portfolio ): """Test listing portfolios""" response = client.get("/api/v1/portfolios/?skip=0&limit=10") assert response.status_code == 200 data = response.json() assert isinstance(data, list) assert len(data) > 0 def test_update_portfolio( self, client: TestClient, sample_portfolio, sample_assets ): """Test updating portfolio""" update_data = { "name": "Updated Portfolio Name", "description": "Updated description", "assets": [ {"ticker": "005930", "target_ratio": 60.0}, {"ticker": "000660", "target_ratio": 40.0}, ] } response = client.put( f"/api/v1/portfolios/{sample_portfolio.id}", json=update_data ) assert response.status_code == 200 data = response.json() assert data["name"] == update_data["name"] assert len(data["assets"]) == 2 def test_delete_portfolio( self, client: TestClient, sample_portfolio ): """Test deleting portfolio""" response = client.delete(f"/api/v1/portfolios/{sample_portfolio.id}") assert response.status_code == 200 # Verify deletion get_response = client.get(f"/api/v1/portfolios/{sample_portfolio.id}") assert get_response.status_code == 404