77 lines
3.8 KiB
Python
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)
|