"""Integration tests for duty-schedule import (parser + repo, no bot).""" from datetime import date import pytest from db import init_db from db.models import Base from db.repository import get_duties from db.session import get_session from importers.duty_schedule import DutyScheduleResult, parse_duty_schedule from handlers.import_duty_schedule import _run_import @pytest.fixture def db_url(): return "sqlite:///:memory:" @pytest.fixture(autouse=True) def _reset_db_session(db_url): """Ensure each test uses a fresh engine for :memory: (clear global cache for test URL).""" import db.session as session_module session_module._engine = None session_module._SessionLocal = None init_db(db_url) yield session_module._engine = None session_module._SessionLocal = None def test_import_creates_users_and_duties(db_url): """Import creates users by full_name and correct duty records.""" result = DutyScheduleResult( start_date=date(2026, 2, 16), end_date=date(2026, 2, 18), entries=[ ("Ivanov I.I.", [date(2026, 2, 16), date(2026, 2, 18)]), ("Petrov P.P.", [date(2026, 2, 17)]), ], ) num_users, num_duties = _run_import(db_url, result, 6, 0) assert num_users == 2 assert num_duties == 3 session = get_session(db_url) try: # to_date inclusive: duty on 18th has start_at 2026-02-18T06:00:00Z, so use 2026-02-19 duties = get_duties(session, "2026-02-16", "2026-02-19") finally: session.close() assert len(duties) == 3 starts = {d[0].start_at for d in duties} assert "2026-02-16T06:00:00Z" in starts assert "2026-02-17T06:00:00Z" in starts assert "2026-02-18T06:00:00Z" in starts def test_import_replaces_duties_in_range(db_url): """Re-importing same range replaces old duties.""" result1 = DutyScheduleResult( start_date=date(2026, 2, 16), end_date=date(2026, 2, 17), entries=[("Sidorov", [date(2026, 2, 16), date(2026, 2, 17)])], ) _run_import(db_url, result1, 9, 0) session = get_session(db_url) try: duties_first = get_duties(session, "2026-02-16", "2026-02-18") finally: session.close() assert len(duties_first) == 2 result2 = DutyScheduleResult( start_date=date(2026, 2, 16), end_date=date(2026, 2, 17), entries=[("Sidorov", [date(2026, 2, 17)])], ) _run_import(db_url, result2, 9, 0) session = get_session(db_url) try: duties_second = get_duties(session, "2026-02-16", "2026-02-18") finally: session.close() assert len(duties_second) == 1 assert duties_second[0][0].start_at == "2026-02-17T09:00:00Z" def test_import_full_flow_parse_then_import(db_url): """Parse real-looking JSON then run import.""" raw = ( '{"meta": {"start_date": "2026-02-16"}, ' '"schedule": [{"name": "Alexey A.", "duty": "\u0431; ; \u0432"}]}' ).encode("utf-8") parsed = parse_duty_schedule(raw) num_users, num_duties = _run_import(db_url, parsed, 6, 0) assert num_users == 1 assert num_duties == 2 session = get_session(db_url) try: duties = get_duties(session, "2026-02-16", "2026-02-19") finally: session.close() assert len(duties) == 2 assert duties[0][1] == "Alexey A."