""" E2E tests for portfolio management flow. """ import pytest from fastapi.testclient import TestClient def test_portfolio_crud_flow(client: TestClient, auth_headers): """Test complete portfolio CRUD flow.""" # Create portfolio response = client.post( "/api/portfolios", json={ "name": "Test Portfolio", "portfolio_type": "pension", }, headers=auth_headers, ) assert response.status_code == 201 portfolio = response.json() portfolio_id = portfolio["id"] assert portfolio["name"] == "Test Portfolio" assert portfolio["portfolio_type"] == "pension" # Get portfolio list response = client.get("/api/portfolios", headers=auth_headers) assert response.status_code == 200 portfolios = response.json() assert len(portfolios) == 1 assert portfolios[0]["id"] == portfolio_id # Get single portfolio response = client.get(f"/api/portfolios/{portfolio_id}", headers=auth_headers) assert response.status_code == 200 assert response.json()["id"] == portfolio_id # Update portfolio response = client.put( f"/api/portfolios/{portfolio_id}", json={"name": "Updated Portfolio"}, headers=auth_headers, ) assert response.status_code == 200 assert response.json()["name"] == "Updated Portfolio" # Delete portfolio response = client.delete(f"/api/portfolios/{portfolio_id}", headers=auth_headers) assert response.status_code == 204 # Verify deleted response = client.get(f"/api/portfolios/{portfolio_id}", headers=auth_headers) assert response.status_code == 404 def test_targets_flow(client: TestClient, auth_headers): """Test portfolio target allocation flow.""" # Create portfolio response = client.post( "/api/portfolios", json={"name": "Target Test Portfolio", "portfolio_type": "general"}, headers=auth_headers, ) portfolio_id = response.json()["id"] # Set targets targets = [ {"ticker": "005930", "target_ratio": 40}, {"ticker": "000660", "target_ratio": 30}, {"ticker": "035420", "target_ratio": 30}, ] response = client.put( f"/api/portfolios/{portfolio_id}/targets", json=targets, headers=auth_headers, ) assert response.status_code == 200 result = response.json() assert len(result) == 3 assert sum(t["target_ratio"] for t in result) == 100 # Get targets response = client.get( f"/api/portfolios/{portfolio_id}/targets", headers=auth_headers, ) assert response.status_code == 200 assert len(response.json()) == 3 # Test invalid targets (not 100%) invalid_targets = [ {"ticker": "005930", "target_ratio": 50}, {"ticker": "000660", "target_ratio": 30}, ] response = client.put( f"/api/portfolios/{portfolio_id}/targets", json=invalid_targets, headers=auth_headers, ) assert response.status_code == 400 def test_holdings_flow(client: TestClient, auth_headers): """Test portfolio holdings flow.""" # Create portfolio response = client.post( "/api/portfolios", json={"name": "Holdings Test Portfolio", "portfolio_type": "general"}, headers=auth_headers, ) portfolio_id = response.json()["id"] # Set holdings holdings = [ {"ticker": "005930", "quantity": 10, "avg_price": 70000}, {"ticker": "000660", "quantity": 5, "avg_price": 120000}, ] response = client.put( f"/api/portfolios/{portfolio_id}/holdings", json=holdings, headers=auth_headers, ) assert response.status_code == 200 result = response.json() assert len(result) == 2 # Get holdings response = client.get( f"/api/portfolios/{portfolio_id}/holdings", headers=auth_headers, ) assert response.status_code == 200 assert len(response.json()) == 2 def test_transaction_flow(client: TestClient, auth_headers): """Test transaction recording flow.""" # Create portfolio with initial holdings response = client.post( "/api/portfolios", json={"name": "Transaction Test Portfolio", "portfolio_type": "general"}, headers=auth_headers, ) portfolio_id = response.json()["id"] # Buy transaction response = client.post( f"/api/portfolios/{portfolio_id}/transactions", json={ "ticker": "005930", "tx_type": "buy", "quantity": 10, "price": 70000, "executed_at": "2024-01-15T10:00:00", "memo": "Initial purchase", }, headers=auth_headers, ) assert response.status_code == 201 tx = response.json() assert tx["ticker"] == "005930" assert tx["tx_type"] == "buy" # Verify holdings updated response = client.get( f"/api/portfolios/{portfolio_id}/holdings", headers=auth_headers, ) holdings = response.json() assert len(holdings) == 1 assert holdings[0]["ticker"] == "005930" assert holdings[0]["quantity"] == 10 # Sell transaction response = client.post( f"/api/portfolios/{portfolio_id}/transactions", json={ "ticker": "005930", "tx_type": "sell", "quantity": 5, "price": 75000, "executed_at": "2024-01-16T10:00:00", }, headers=auth_headers, ) assert response.status_code == 201 # Verify holdings updated response = client.get( f"/api/portfolios/{portfolio_id}/holdings", headers=auth_headers, ) holdings = response.json() assert holdings[0]["quantity"] == 5 # Get transactions response = client.get( f"/api/portfolios/{portfolio_id}/transactions", headers=auth_headers, ) assert response.status_code == 200 txs = response.json() assert len(txs) == 2 def test_unauthorized_access(client: TestClient, auth_headers): """Test that users can't access other users' portfolios.""" # Create portfolio with test user response = client.post( "/api/portfolios", json={"name": "Private Portfolio", "portfolio_type": "general"}, headers=auth_headers, ) portfolio_id = response.json()["id"] # Try to access without auth response = client.get(f"/api/portfolios/{portfolio_id}") assert response.status_code == 401