Files
crr-shifts/tests/test_cli.py
T

77 lines
3.8 KiB
Python

from datetime import date, timedelta
import pytest
from sqlalchemy import create_engine, select
from sqlalchemy.orm import sessionmaker
from app import cli, database
from app.models import Assignment, MonthlyPattern, RotationMember, Schedule, User
from app.security import verify_password
@pytest.fixture()
def sessions(tmp_path, monkeypatch):
url = f"sqlite:///{tmp_path / 'demo.db'}"
engine = create_engine(url)
factory = sessionmaker(bind=engine, expire_on_commit=False)
monkeypatch.setattr(database.settings, "database_url", url)
monkeypatch.setattr(database, "engine", engine)
monkeypatch.setattr(cli, "SessionLocal", factory)
yield factory
engine.dispose()
def test_demo_seeds_repeating_schedules_and_is_repeatable(sessions):
cli.seed_demo()
today = date.today()
next_month = (today.replace(day=28) + timedelta(days=4)).replace(day=1)
with sessions() as db:
people = db.scalars(select(User).where(User.username.in_(["alice", "bruno", "carla", "diogo"]))).all()
assert len(people) == 4
assert all(verify_password("demo-password", person.password_hash) for person in people)
assert len(db.scalars(select(MonthlyPattern)).all()) == 31
assert len(db.scalars(select(RotationMember)).all()) == 8
assignments = db.scalars(select(Assignment)).all()
assert all(row.user_id is not None for row in assignments)
assert {row.date.replace(day=1) for row in assignments} == {today.replace(day=1), next_month}
original = [(row.id, row.date, row.user_id, row.source) for row in assignments]
cli.seed_demo()
with sessions() as db:
assert len(db.scalars(select(User)).all()) == 5
assert len(db.scalars(select(MonthlyPattern)).all()) == 31
assert len(db.scalars(select(RotationMember)).all()) == 8
assert [(row.id, row.date, row.user_id, row.source) for row in db.scalars(select(Assignment)).all()] == original
def test_demo_preserves_existing_people_configuration_and_assignments(sessions):
cli.init_db()
today = date.today()
assigned_day = today.replace(day=1) if today.day != 1 else today + timedelta(days=1)
with sessions() as db:
night = db.scalar(select(Schedule).where(Schedule.slug == "night"))
saturday = db.scalar(select(Schedule).where(Schedule.slug == "saturday-lunch"))
alice = User(name="My Alice", username="alice", password_hash="keep-this-password", is_active=True)
db.add(alice)
db.flush()
db.add_all([
MonthlyPattern(schedule_id=night.id, day_of_month=1, user_id=alice.id),
RotationMember(schedule_id=saturday.id, position=10, user_id=alice.id),
Assignment(schedule_id=night.id, date=today, user_id=None, source="manual", note="Keep unassigned"),
Assignment(schedule_id=night.id, date=assigned_day, user_id=alice.id, source="swap"),
])
db.commit()
original = [(row.id, row.user_id, row.source, row.note) for row in db.scalars(select(Assignment)).all()]
cli.seed_demo()
with sessions() as db:
alice = db.scalar(select(User).where(User.username == "alice"))
assert (alice.name, alice.password_hash) == ("My Alice", "keep-this-password")
pattern = db.scalars(select(MonthlyPattern).where(MonthlyPattern.schedule_id == night.id)).all()
assert [(row.day_of_month, row.user_id) for row in pattern] == [(1, alice.id)]
rotation = db.scalars(select(RotationMember).where(RotationMember.schedule_id == saturday.id)).all()
assert [(row.position, row.user_id) for row in rotation] == [(10, alice.id)]
for assignment_id, user_id, source, note in original:
row = db.get(Assignment, assignment_id)
assert (row.user_id, row.source, row.note) == (user_id, source, note)