87 lines
2.7 KiB
Python
87 lines
2.7 KiB
Python
from __future__ import annotations
|
||
|
||
import json
|
||
import sys
|
||
from datetime import date
|
||
from pathlib import Path
|
||
|
||
import pytest
|
||
|
||
ROOT = Path(__file__).resolve().parents[1]
|
||
if str(ROOT) not in sys.path:
|
||
sys.path.insert(0, str(ROOT))
|
||
|
||
FIXTURES = ROOT / "tests" / "fixtures"
|
||
FIXTURE_ISIN = "RU000A106169"
|
||
FIXTURE_DATE = date(2026, 10, 8)
|
||
|
||
|
||
@pytest.fixture
|
||
def fixtures_dir() -> Path:
|
||
"""Сохранённые реальные ответы MOEX ISS / ЦБ (байт в байт, см. .gitattributes)."""
|
||
return FIXTURES
|
||
|
||
|
||
@pytest.fixture
|
||
def session_local(tmp_path: Path, monkeypatch):
|
||
"""Временный SQLite со схемой из миграций (с сидами) вместо SessionLocal
|
||
во всех модулях сервисов. Postgres не нужен."""
|
||
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
|
||
from sqlalchemy.pool import NullPool
|
||
|
||
from alembic import command
|
||
from alembic.config import Config
|
||
from app.core.config import settings
|
||
from app.services import (
|
||
fx_rates,
|
||
manual_operations,
|
||
market_data,
|
||
quik_import,
|
||
request_log,
|
||
securities,
|
||
)
|
||
|
||
db_url = f"sqlite+aiosqlite:///{(tmp_path / 'drrk.db').as_posix()}"
|
||
monkeypatch.setattr(settings, "DATABASE_URL", db_url)
|
||
monkeypatch.setattr(settings, "DATABASE_SCHEMA", "")
|
||
cfg = Config()
|
||
cfg.set_main_option("script_location", str(ROOT / "alembic"))
|
||
command.upgrade(cfg, "head")
|
||
|
||
factory = async_sessionmaker(
|
||
bind=create_async_engine(db_url, poolclass=NullPool),
|
||
autoflush=False,
|
||
expire_on_commit=False,
|
||
)
|
||
for module in (
|
||
securities,
|
||
market_data,
|
||
fx_rates,
|
||
request_log,
|
||
quik_import,
|
||
manual_operations,
|
||
):
|
||
monkeypatch.setattr(module, "SessionLocal", factory)
|
||
return factory
|
||
|
||
|
||
@pytest.fixture
|
||
def fixture_moex(fixtures_dir: Path):
|
||
"""Фейковый MOEX, отвечающий реальными фикстурами РЭО-02 за 08.10.2026."""
|
||
from app.integrations.moex import parse_history, parse_security
|
||
from tests.unit.fakes import FakeMoex, search_hit
|
||
|
||
security_payload = json.loads(
|
||
(fixtures_dir / "moex_security_RU000A106169.json").read_text("utf-8")
|
||
)
|
||
history_payload = json.loads(
|
||
(fixtures_dir / "moex_history_RU000A106169_2026-10-08.json").read_text("utf-8")
|
||
)
|
||
return FakeMoex(
|
||
search={FIXTURE_ISIN: search_hit(FIXTURE_ISIN, FIXTURE_ISIN)},
|
||
securities={FIXTURE_ISIN: parse_security(security_payload)},
|
||
history={
|
||
FIXTURE_ISIN: parse_history(history_payload, FIXTURE_DATE, ["TQCB", "TQOB"])
|
||
},
|
||
)
|