"""Tests for SQLitePersonalDataRepository, focused on the Task 1 addition: `min_vacation_days_per_year` (semesterlagen minimum, PLANNING_ENGINE_SPEC ยง9.2). The rest of the repository (soft-delete, workspace listing, ...) is already exercised indirectly via `seeded_ids` and the allocation-input-loader tests; this file targets the new column's round trip specifically. """ from datetime import datetime from uuid import uuid4 import pytest from app.entities.personal_data import PersonalData from app.entities.workspace import Workspace from app.repositories_impl.sqlite.personal_data_repository import SQLitePersonalDataRepository from app.repositories_impl.sqlite.workspace_repository import SQLiteWorkspaceRepository class TestPersonalDataMinVacationDays: async def test_create_defaults_to_statutory_minimum( self, personal_data_repo: SQLitePersonalDataRepository, workspace_repo: SQLiteWorkspaceRepository, ) -> None: ws = await workspace_repo.create( Workspace(id=uuid4(), name="WS", created_at=datetime.now()) ) created = await personal_data_repo.create( PersonalData(uuid=uuid4(), workspace_id=ws.id, name="Parent", created_at=datetime.now()) ) assert created.min_vacation_days_per_year == 20 fetched = await personal_data_repo.get_by_id(created.uuid) assert fetched is not None assert fetched.min_vacation_days_per_year == 20 async def test_create_with_custom_minimum_round_trips( self, personal_data_repo: SQLitePersonalDataRepository, workspace_repo: SQLiteWorkspaceRepository, ) -> None: ws = await workspace_repo.create( Workspace(id=uuid4(), name="WS", created_at=datetime.now()) ) created = await personal_data_repo.create( PersonalData( uuid=uuid4(), workspace_id=ws.id, name="Parent", min_vacation_days_per_year=30, created_at=datetime.now(), ) ) fetched = await personal_data_repo.get_by_id(created.uuid) assert fetched is not None assert fetched.min_vacation_days_per_year == 30 async def test_update_changes_the_minimum( self, personal_data_repo: SQLitePersonalDataRepository, workspace_repo: SQLiteWorkspaceRepository, ) -> None: ws = await workspace_repo.create( Workspace(id=uuid4(), name="WS", created_at=datetime.now()) ) created = await personal_data_repo.create( PersonalData(uuid=uuid4(), workspace_id=ws.id, name="Parent", created_at=datetime.now()) ) created.min_vacation_days_per_year = 15 updated = await personal_data_repo.update(created.uuid, created) assert updated.min_vacation_days_per_year == 15 fetched = await personal_data_repo.get_by_id(created.uuid) assert fetched is not None assert fetched.min_vacation_days_per_year == 15 async def test_list_rejects_unsupported_filter( self, personal_data_repo: SQLitePersonalDataRepository, ) -> None: """Passing an unsupported filter must raise ValueError.""" with pytest.raises(ValueError, match="invalid_column"): await personal_data_repo.list(invalid_column="value") async def test_list_accepts_include_deleted_filter( self, personal_data_repo: SQLitePersonalDataRepository, workspace_repo: SQLiteWorkspaceRepository, ) -> None: """The SoftDeleteRepository contract requires list() to accept include_deleted=True.""" ws = await workspace_repo.create( Workspace(id=uuid4(), name="WS", created_at=datetime.now()) ) pd = await personal_data_repo.create( PersonalData(uuid=uuid4(), workspace_id=ws.id, name="Parent", created_at=datetime.now()) ) # By default, deleted items should not be listed await personal_data_repo.soft_delete(pd.uuid) rows = await personal_data_repo.list(workspace_id=ws.id) ids = {r.uuid for r in rows} assert pd.uuid not in ids # With include_deleted=True, deleted items should be included rows_with_deleted = await personal_data_repo.list(workspace_id=ws.id, include_deleted=True) ids_with_deleted = {r.uuid for r in rows_with_deleted} assert pd.uuid in ids_with_deleted async def test_list_error_message_lists_supported_filters( self, personal_data_repo: SQLitePersonalDataRepository, ) -> None: """Error message should list supported filters.""" with pytest.raises(ValueError, match="include_deleted.*workspace_id"): await personal_data_repo.list(bad_filter="value")