Files
duty-teller/tests/test_repository_duty_range.py
Nikolay Tatarinov 28973489a5 Refactor project structure and enhance Docker configuration
- Updated `.dockerignore` to exclude test and development artifacts, optimizing the Docker image size.
- Refactored `main.py` to delegate execution to `duty_teller.run.main()`, simplifying the entry point.
- Introduced a new `duty_teller` package to encapsulate core functionality, improving modularity and organization.
- Enhanced `pyproject.toml` to define a script for running the application, streamlining the execution process.
- Updated README documentation to reflect changes in project structure and usage instructions.
- Improved Alembic environment configuration to utilize the new package structure for database migrations.
2026-02-18 13:03:14 +03:00

110 lines
3.3 KiB
Python

"""Tests for delete_duties_in_range and get_or_create_user_by_full_name."""
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from duty_teller.db.models import Base, User
from duty_teller.db.repository import (
delete_duties_in_range,
get_or_create_user_by_full_name,
get_duties,
insert_duty,
)
@pytest.fixture
def session():
engine = create_engine(
"sqlite:///:memory:", connect_args={"check_same_thread": False}
)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine, autocommit=False, autoflush=False)
s = Session()
try:
yield s
finally:
s.close()
@pytest.fixture
def user_a(session):
u = User(
telegram_user_id=None,
full_name="User A",
username=None,
first_name=None,
last_name=None,
)
session.add(u)
session.commit()
session.refresh(u)
return u
def test_get_or_create_user_by_full_name_creates(session):
u = get_or_create_user_by_full_name(session, "Новый Пользователь")
assert u.id is not None
assert u.full_name == "Новый Пользователь"
assert u.telegram_user_id is None
def test_get_or_create_user_by_full_name_returns_existing(session, user_a):
u = get_or_create_user_by_full_name(session, "User A")
assert u.id == user_a.id
assert u.full_name == "User A"
def test_delete_duties_in_range_removes_only_in_range(session, user_a):
# Duties: 2026-02-01 06:00 - 2026-02-02 06:00; 2026-02-15 - 2026-02-16; 2026-02-28 - 2026-03-01
insert_duty(
session,
user_a.id,
"2026-02-01T06:00:00Z",
"2026-02-02T06:00:00Z",
)
insert_duty(
session,
user_a.id,
"2026-02-15T06:00:00Z",
"2026-02-16T06:00:00Z",
)
insert_duty(
session,
user_a.id,
"2026-02-28T06:00:00Z",
"2026-03-01T06:00:00Z",
)
deleted = delete_duties_in_range(session, user_a.id, "2026-02-10", "2026-02-20")
assert deleted == 1
remaining = get_duties(session, "2026-01-01", "2026-03-31")
assert len(remaining) == 2
starts = [d[0].start_at for d in remaining]
assert "2026-02-01T06:00:00Z" in starts
assert "2026-02-28T06:00:00Z" in starts
assert "2026-02-15T06:00:00Z" not in starts
def test_delete_duties_in_range_other_user_unchanged(session, user_a):
user_b = get_or_create_user_by_full_name(session, "User B")
insert_duty(session, user_a.id, "2026-02-10T06:00:00Z", "2026-02-11T06:00:00Z")
insert_duty(session, user_b.id, "2026-02-10T06:00:00Z", "2026-02-11T06:00:00Z")
delete_duties_in_range(session, user_a.id, "2026-02-01", "2026-02-28")
remaining = get_duties(session, "2026-02-01", "2026-02-28")
assert len(remaining) == 1
assert remaining[0][1] == "User B"
def test_get_duties_includes_duty_starting_on_last_day_of_range(session, user_a):
"""Duty starting on to_date (e.g. 2026-01-31T09:00:00Z) must be included when to_date is 2026-01-31."""
insert_duty(
session,
user_a.id,
"2026-01-31T09:00:00Z",
"2026-02-01T09:00:00Z",
)
rows = get_duties(session, "2026-01-01", "2026-01-31")
assert len(rows) == 1
assert rows[0][0].start_at == "2026-01-31T09:00:00Z"
assert rows[0][1] == "User A"