Files
openbb-invest-api/tests/test_routes_technical.py
Yaojia Wang ad45cb429c feat: OpenBB Investment Analysis API
REST API wrapping OpenBB SDK for stock data, sentiment analysis,
technical indicators, macro data, and rule-based portfolio analysis.

- Stock data via yfinance (quote, profile, metrics, financials, historical, news)
- News sentiment via Alpha Vantage (per-article, per-ticker scores)
- Analyst data via Finnhub (recommendations, insider trades, upgrades)
- Macro data via FRED (Fed rate, CPI, GDP, unemployment, treasury yields)
- Technical indicators via openbb-technical (RSI, MACD, SMA, EMA, Bollinger)
- Rule-based portfolio analysis engine (BUY_MORE/HOLD/SELL)
- Stock discovery (gainers, losers, active, undervalued, growth)
- 102 tests, all passing
2026-03-09 00:20:10 +01:00

43 lines
1.3 KiB
Python

from unittest.mock import patch, AsyncMock
import pytest
from httpx import AsyncClient, ASGITransport
from main import app
@pytest.fixture
async def client():
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as c:
yield c
@pytest.mark.asyncio
@patch("routes_technical.technical_service.get_technical_indicators", new_callable=AsyncMock)
async def test_stock_technical(mock_tech, client):
mock_tech.return_value = {
"symbol": "AAPL",
"rsi_14": 55.3,
"macd": {"macd": 1.5, "signal": 1.2, "histogram": 0.3},
"sma_20": 180.0,
"sma_50": 175.0,
"sma_200": 170.0,
"ema_12": 179.0,
"ema_26": 176.0,
"bollinger_bands": {"upper": 190.0, "middle": 180.0, "lower": 170.0},
"signals": ["RSI 55.3: Neutral", "MACD histogram positive (bullish momentum)"],
}
resp = await client.get("/api/v1/stock/AAPL/technical")
assert resp.status_code == 200
data = resp.json()["data"]
assert data["symbol"] == "AAPL"
assert data["rsi_14"] == 55.3
assert len(data["signals"]) == 2
@pytest.mark.asyncio
async def test_invalid_symbol_technical(client):
resp = await client.get("/api/v1/stock/INVALID!!!/technical")
assert resp.status_code == 400