Files
F-r-ldraledigplannerare/backend/tests/unit/test_vacation_days_repository.py
T
2026-06-01 16:48:21 +02:00

161 lines
5.9 KiB
Python

"""Tests for the reference repository + service.
Demonstrates the testing pattern: arrange an entity, exercise the repo/service,
assert on the result. Aim for >=90% coverage on new code (ARCHITECTURE.md §10).
"""
from datetime import datetime
from uuid import uuid4
import pytest
from app.entities.personal_data import PersonalData
from app.entities.vacation_days import VacationDays
from app.entities.workspace import Workspace
from app.repositories_impl.sqlite.personal_data_repository import SQLitePersonalDataRepository
from app.repositories_impl.sqlite.vacation_days_repository import (
SQLiteVacationDaysRepository,
)
from app.repositories_impl.sqlite.workspace_repository import SQLiteWorkspaceRepository
from app.services.vacation_days_service import VacationDaysService
from app.utils.errors import NotFoundError, ValidationError
from tests.conftest import SeededIds
def _make(workspace_id=None, personal_data_uuid=None, **overrides) -> VacationDays:
base = dict(
id=uuid4(),
personal_data_uuid=personal_data_uuid or uuid4(),
workspace_id=workspace_id or uuid4(),
year=2026,
total_days=25,
saved_days_in=0,
created_at=datetime.now(),
updated_at=datetime.now(),
)
base.update(overrides)
return VacationDays(**base)
class TestSQLiteVacationDaysRepository:
async def test_create_and_get_by_id(
self,
vacation_repo: SQLiteVacationDaysRepository,
seeded_ids: SeededIds,
) -> None:
entity = _make(
workspace_id=seeded_ids.workspace_id, personal_data_uuid=seeded_ids.personal_data_uuid
)
await vacation_repo.create(entity)
fetched = await vacation_repo.get_by_id(entity.id)
assert fetched is not None
assert fetched.id == entity.id
assert fetched.total_days == 25
async def test_get_by_parent_year(
self,
vacation_repo: SQLiteVacationDaysRepository,
seeded_ids: SeededIds,
) -> None:
entity = _make(
workspace_id=seeded_ids.workspace_id, personal_data_uuid=seeded_ids.personal_data_uuid
)
await vacation_repo.create(entity)
found = await vacation_repo.get_by_parent_year(entity.personal_data_uuid, 2026)
assert found is not None
assert found.id == entity.id
missing = await vacation_repo.get_by_parent_year(uuid4(), 2026)
assert missing is None
async def test_update(
self,
vacation_repo: SQLiteVacationDaysRepository,
seeded_ids: SeededIds,
) -> None:
entity = _make(
total_days=20,
workspace_id=seeded_ids.workspace_id,
personal_data_uuid=seeded_ids.personal_data_uuid,
)
await vacation_repo.create(entity)
entity.total_days = 30
updated = await vacation_repo.update(entity.id, entity)
assert updated.total_days == 30
async def test_update_missing_raises(self, vacation_repo: SQLiteVacationDaysRepository) -> None:
with pytest.raises(NotFoundError):
await vacation_repo.update(uuid4(), _make())
async def test_delete(
self,
vacation_repo: SQLiteVacationDaysRepository,
seeded_ids: SeededIds,
) -> None:
entity = _make(
workspace_id=seeded_ids.workspace_id, personal_data_uuid=seeded_ids.personal_data_uuid
)
await vacation_repo.create(entity)
await vacation_repo.delete(entity.id)
assert await vacation_repo.get_by_id(entity.id) is None
async def test_delete_missing_raises(self, vacation_repo: SQLiteVacationDaysRepository) -> None:
with pytest.raises(NotFoundError):
await vacation_repo.delete(uuid4())
async def test_list_filters_by_workspace(
self,
vacation_repo: SQLiteVacationDaysRepository,
seeded_ids: SeededIds,
workspace_repo: SQLiteWorkspaceRepository,
personal_data_repo: SQLitePersonalDataRepository,
) -> None:
ws = seeded_ids.workspace_id
pd_uuid = seeded_ids.personal_data_uuid
# Create a second workspace + personal_data for the "different workspace" row
ws2 = await workspace_repo.create(
Workspace(id=uuid4(), name="WS2", created_at=datetime.now())
)
pd2 = await personal_data_repo.create(
PersonalData(
uuid=uuid4(), workspace_id=ws2.id, name="Parent2", created_at=datetime.now()
)
)
await vacation_repo.create(_make(workspace_id=ws, personal_data_uuid=pd_uuid, year=2025))
await vacation_repo.create(_make(workspace_id=ws, personal_data_uuid=pd_uuid, year=2026))
await vacation_repo.create(_make(workspace_id=ws2.id, personal_data_uuid=pd2.uuid))
rows = await vacation_repo.list(workspace_id=ws)
assert len(rows) == 2
assert [r.year for r in rows] == [2026, 2025] # ordered year DESC
class TestVacationDaysService:
async def test_upsert_creates_then_updates(
self,
vacation_service: VacationDaysService,
seeded_ids: SeededIds,
) -> None:
parent = seeded_ids.personal_data_uuid
ws = seeded_ids.workspace_id
created = await vacation_service.upsert(parent, ws, 2026, 25)
assert created.total_days == 25
updated = await vacation_service.upsert(parent, ws, 2026, 30, saved_days_in=5)
assert updated.id == created.id # same (parent, year) row
assert updated.total_days == 30
assert updated.saved_days_in == 5
async def test_upsert_rejects_negative(self, vacation_service: VacationDaysService) -> None:
with pytest.raises(ValidationError):
await vacation_service.upsert(uuid4(), uuid4(), 2026, -1)
async def test_get_missing_raises(self, vacation_service: VacationDaysService) -> None:
with pytest.raises(NotFoundError):
await vacation_service.get(uuid4())