Add paginated responses (items/total/skip/limit) to:
- GET /api/data/stocks/{ticker}/prices (default limit=365)
- GET /api/data/etfs/{ticker}/prices (default limit=365)
- GET /api/portfolios/{id}/snapshots (default limit=100)
- GET /api/portfolios/{id}/transactions (default limit=50)
Frontend: update snapshot/transaction consumers to handle new response
shape, add "Load more" button to transaction table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
125 lines
3.7 KiB
Python
125 lines
3.7 KiB
Python
"""
|
|
E2E tests for snapshot and returns flow.
|
|
"""
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
def test_snapshot_requires_holdings(client: TestClient, auth_headers):
|
|
"""Test that snapshot creation requires holdings."""
|
|
# Create portfolio without holdings
|
|
response = client.post(
|
|
"/api/portfolios",
|
|
json={"name": "Empty Portfolio", "portfolio_type": "general"},
|
|
headers=auth_headers,
|
|
)
|
|
portfolio_id = response.json()["id"]
|
|
|
|
# Try to create snapshot
|
|
response = client.post(
|
|
f"/api/portfolios/{portfolio_id}/snapshots",
|
|
headers=auth_headers,
|
|
)
|
|
assert response.status_code == 400
|
|
assert "empty" in response.json()["detail"].lower()
|
|
|
|
|
|
def test_snapshot_list_empty(client: TestClient, auth_headers):
|
|
"""Test listing snapshots for portfolio with no snapshots."""
|
|
# Create portfolio
|
|
response = client.post(
|
|
"/api/portfolios",
|
|
json={"name": "Snapshot Test Portfolio", "portfolio_type": "general"},
|
|
headers=auth_headers,
|
|
)
|
|
portfolio_id = response.json()["id"]
|
|
|
|
# List snapshots
|
|
response = client.get(
|
|
f"/api/portfolios/{portfolio_id}/snapshots",
|
|
headers=auth_headers,
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["items"] == []
|
|
assert data["total"] == 0
|
|
|
|
|
|
def test_returns_empty(client: TestClient, auth_headers):
|
|
"""Test returns for portfolio with no snapshots."""
|
|
# Create portfolio
|
|
response = client.post(
|
|
"/api/portfolios",
|
|
json={"name": "Returns Test Portfolio", "portfolio_type": "general"},
|
|
headers=auth_headers,
|
|
)
|
|
portfolio_id = response.json()["id"]
|
|
|
|
# Get returns
|
|
response = client.get(
|
|
f"/api/portfolios/{portfolio_id}/returns",
|
|
headers=auth_headers,
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["portfolio_id"] == portfolio_id
|
|
assert data["total_return"] is None
|
|
assert data["data"] == []
|
|
|
|
|
|
def test_snapshot_not_found(client: TestClient, auth_headers):
|
|
"""Test getting non-existent snapshot."""
|
|
# Create portfolio
|
|
response = client.post(
|
|
"/api/portfolios",
|
|
json={"name": "Not Found Test Portfolio", "portfolio_type": "general"},
|
|
headers=auth_headers,
|
|
)
|
|
portfolio_id = response.json()["id"]
|
|
|
|
# Get non-existent snapshot
|
|
response = client.get(
|
|
f"/api/portfolios/{portfolio_id}/snapshots/99999",
|
|
headers=auth_headers,
|
|
)
|
|
assert response.status_code == 404
|
|
|
|
|
|
def test_snapshot_delete_not_found(client: TestClient, auth_headers):
|
|
"""Test deleting non-existent snapshot."""
|
|
# Create portfolio
|
|
response = client.post(
|
|
"/api/portfolios",
|
|
json={"name": "Delete Test Portfolio", "portfolio_type": "general"},
|
|
headers=auth_headers,
|
|
)
|
|
portfolio_id = response.json()["id"]
|
|
|
|
# Delete non-existent snapshot
|
|
response = client.delete(
|
|
f"/api/portfolios/{portfolio_id}/snapshots/99999",
|
|
headers=auth_headers,
|
|
)
|
|
assert response.status_code == 404
|
|
|
|
|
|
def test_snapshot_requires_auth(client: TestClient, auth_headers):
|
|
"""Test that snapshot endpoints require authentication."""
|
|
# Create portfolio
|
|
response = client.post(
|
|
"/api/portfolios",
|
|
json={"name": "Auth Test Portfolio", "portfolio_type": "general"},
|
|
headers=auth_headers,
|
|
)
|
|
portfolio_id = response.json()["id"]
|
|
|
|
# Try without auth
|
|
response = client.get(f"/api/portfolios/{portfolio_id}/snapshots")
|
|
assert response.status_code == 401
|
|
|
|
response = client.post(f"/api/portfolios/{portfolio_id}/snapshots")
|
|
assert response.status_code == 401
|
|
|
|
response = client.get(f"/api/portfolios/{portfolio_id}/returns")
|
|
assert response.status_code == 401
|