major update
Some checks failed
Deploy / lint (push) Failing after 8s
Deploy / test (push) Has been skipped
Deploy / deploy (push) Has been skipped

This commit is contained in:
Dennis Thiessen
2026-02-27 16:08:09 +01:00
parent 61ab24490d
commit 181cfe6588
71 changed files with 7647 additions and 281 deletions

View File

@@ -0,0 +1,99 @@
"""Unit tests for fundamental_service — unavailable_fields persistence."""
from __future__ import annotations
import json
import pytest
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from app.database import Base
from app.models.ticker import Ticker
from app.services import fundamental_service
# Use a dedicated engine so commit/refresh work without conflicting
# with the conftest transactional session.
_engine = create_async_engine("sqlite+aiosqlite://", echo=False)
_session_factory = async_sessionmaker(_engine, class_=AsyncSession, expire_on_commit=False)
@pytest.fixture(autouse=True)
async def _setup_tables():
async with _engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
yield
async with _engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
@pytest.fixture
async def session() -> AsyncSession:
async with _session_factory() as s:
yield s
@pytest.fixture
async def ticker(session: AsyncSession) -> Ticker:
"""Create a test ticker."""
t = Ticker(symbol="AAPL")
session.add(t)
await session.commit()
await session.refresh(t)
return t
@pytest.mark.asyncio
async def test_store_fundamental_persists_unavailable_fields(
session: AsyncSession, ticker: Ticker
):
"""unavailable_fields dict is serialized to JSON and stored."""
fields = {"pe_ratio": "requires paid plan", "revenue_growth": "requires paid plan"}
record = await fundamental_service.store_fundamental(
session,
symbol="AAPL",
pe_ratio=None,
revenue_growth=None,
market_cap=1_000_000.0,
unavailable_fields=fields,
)
assert json.loads(record.unavailable_fields_json) == fields
@pytest.mark.asyncio
async def test_store_fundamental_defaults_to_empty_dict(
session: AsyncSession, ticker: Ticker
):
"""When unavailable_fields is not provided, column defaults to '{}'."""
record = await fundamental_service.store_fundamental(
session,
symbol="AAPL",
pe_ratio=25.0,
)
assert json.loads(record.unavailable_fields_json) == {}
@pytest.mark.asyncio
async def test_store_fundamental_updates_unavailable_fields(
session: AsyncSession, ticker: Ticker
):
"""Updating an existing record also updates unavailable_fields_json."""
# First store
await fundamental_service.store_fundamental(
session,
symbol="AAPL",
pe_ratio=None,
unavailable_fields={"pe_ratio": "requires paid plan"},
)
# Second store — fields now available
record = await fundamental_service.store_fundamental(
session,
symbol="AAPL",
pe_ratio=25.0,
unavailable_fields={},
)
assert json.loads(record.unavailable_fields_json) == {}