Fold the leave-wish rejection tests into one parametrised case
Nine tests each rebuilt the same ten-line create call to vary one argument, which buried the rule every case was actually protecting. They are now one parametrised test over a shared base, with an id per case so a failure names the rule rather than an index. The count of assertions is unchanged: the month and day cases were already parametrised and are kept as separate entries rather than compressed, since losing a case to tidy the file would defeat the point. The tests asserting a successful create stay separate, because each checks a distinct resulting value rather than merely that nothing raised.
This commit is contained in:
@@ -465,41 +465,77 @@ class TestLeaveWishService:
|
|||||||
)
|
)
|
||||||
assert result.recurrence == recurrence
|
assert result.recurrence == recurrence
|
||||||
|
|
||||||
async def test_create_rejects_invalid_recurrence(
|
# Placeholder resolved to seeded_ids.personal_data_uuid at test time, since
|
||||||
self,
|
# parametrize case values are collected before fixtures exist.
|
||||||
leave_wish_service: LeaveWishService,
|
_MISSING_UUID = object()
|
||||||
seeded_ids: SeededIds,
|
|
||||||
) -> None:
|
|
||||||
with pytest.raises(ValidationError, match="recurrence"):
|
|
||||||
await leave_wish_service.create(
|
|
||||||
workspace_id=seeded_ids.workspace_id,
|
|
||||||
name="Wish",
|
|
||||||
window_start_month=1,
|
|
||||||
window_start_day=1,
|
|
||||||
window_end_month=1,
|
|
||||||
window_end_day=10,
|
|
||||||
target_weeks=1,
|
|
||||||
first_year=2027,
|
|
||||||
recurrence="monthly",
|
|
||||||
)
|
|
||||||
|
|
||||||
async def test_create_rejects_invalid_parent_mode(
|
_REJECTION_BASE_KWARGS: dict[str, object] = dict(
|
||||||
|
name="Wish",
|
||||||
|
window_start_month=1,
|
||||||
|
window_start_day=1,
|
||||||
|
window_end_month=1,
|
||||||
|
window_end_day=10,
|
||||||
|
target_weeks=1,
|
||||||
|
first_year=2027,
|
||||||
|
)
|
||||||
|
|
||||||
|
_REJECTION_CASES = [
|
||||||
|
pytest.param({"recurrence": "monthly"}, "recurrence", id="invalid_recurrence"),
|
||||||
|
pytest.param({"parent_mode": "everyone"}, "parent_mode", id="invalid_parent_mode"),
|
||||||
|
pytest.param(
|
||||||
|
{"parent_mode": "either", "parent_personal_data_uuid": _MISSING_UUID},
|
||||||
|
"parent_personal_data_uuid",
|
||||||
|
id="parent_uuid_forbidden_unless_specific",
|
||||||
|
),
|
||||||
|
pytest.param({"window_mode": "whenever"}, "window_mode", id="invalid_window_mode"),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"window_start_month": 3,
|
||||||
|
"window_start_day": 1,
|
||||||
|
"window_end_month": 3,
|
||||||
|
"window_end_day": 10,
|
||||||
|
"target_weeks": 2,
|
||||||
|
"window_mode": "flexible",
|
||||||
|
},
|
||||||
|
"flexible",
|
||||||
|
id="flexible_bound_shorter_than_target_weeks",
|
||||||
|
),
|
||||||
|
*[
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"window_start_month": month,
|
||||||
|
"window_start_day": day,
|
||||||
|
"window_end_month": 6,
|
||||||
|
"window_end_day": 20,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
id=f"invalid_month_day_{month}_{day}",
|
||||||
|
)
|
||||||
|
for month, day in [(0, 15), (13, 15), (6, 0), (6, 32), (2, 30), (4, 31)]
|
||||||
|
],
|
||||||
|
pytest.param({"target_days": 0}, "target_days", id="target_days_below_one"),
|
||||||
|
pytest.param({"target_weeks": 0}, "target_weeks", id="zero_target_weeks"),
|
||||||
|
pytest.param(
|
||||||
|
{"first_year": 2030, "last_year": 2029},
|
||||||
|
"last_year",
|
||||||
|
id="last_year_before_first_year",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("overrides,match", _REJECTION_CASES)
|
||||||
|
async def test_create_rejects_invalid_input(
|
||||||
self,
|
self,
|
||||||
leave_wish_service: LeaveWishService,
|
leave_wish_service: LeaveWishService,
|
||||||
seeded_ids: SeededIds,
|
seeded_ids: SeededIds,
|
||||||
|
overrides: dict[str, object],
|
||||||
|
match: str | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
with pytest.raises(ValidationError, match="parent_mode"):
|
kwargs = {**self._REJECTION_BASE_KWARGS, **overrides}
|
||||||
await leave_wish_service.create(
|
if kwargs.get("parent_personal_data_uuid") is self._MISSING_UUID:
|
||||||
workspace_id=seeded_ids.workspace_id,
|
kwargs["parent_personal_data_uuid"] = seeded_ids.personal_data_uuid
|
||||||
name="Wish",
|
|
||||||
window_start_month=1,
|
with pytest.raises(ValidationError, match=match):
|
||||||
window_start_day=1,
|
await leave_wish_service.create(workspace_id=seeded_ids.workspace_id, **kwargs)
|
||||||
window_end_month=1,
|
|
||||||
window_end_day=10,
|
|
||||||
target_weeks=1,
|
|
||||||
first_year=2027,
|
|
||||||
parent_mode="everyone",
|
|
||||||
)
|
|
||||||
|
|
||||||
async def test_create_specific_parent_mode_requires_uuid(
|
async def test_create_specific_parent_mode_requires_uuid(
|
||||||
self,
|
self,
|
||||||
@@ -540,25 +576,6 @@ class TestLeaveWishService:
|
|||||||
assert result.parent_mode == "specific"
|
assert result.parent_mode == "specific"
|
||||||
assert result.parent_personal_data_uuid == seeded_ids.personal_data_uuid
|
assert result.parent_personal_data_uuid == seeded_ids.personal_data_uuid
|
||||||
|
|
||||||
async def test_create_rejects_parent_uuid_when_not_specific(
|
|
||||||
self,
|
|
||||||
leave_wish_service: LeaveWishService,
|
|
||||||
seeded_ids: SeededIds,
|
|
||||||
) -> None:
|
|
||||||
with pytest.raises(ValidationError, match="parent_personal_data_uuid"):
|
|
||||||
await leave_wish_service.create(
|
|
||||||
workspace_id=seeded_ids.workspace_id,
|
|
||||||
name="Wish",
|
|
||||||
window_start_month=1,
|
|
||||||
window_start_day=1,
|
|
||||||
window_end_month=1,
|
|
||||||
window_end_day=10,
|
|
||||||
target_weeks=1,
|
|
||||||
first_year=2027,
|
|
||||||
parent_mode="either",
|
|
||||||
parent_personal_data_uuid=seeded_ids.personal_data_uuid,
|
|
||||||
)
|
|
||||||
|
|
||||||
# -- window_mode (§10.1) ------------------------------------------------
|
# -- window_mode (§10.1) ------------------------------------------------
|
||||||
|
|
||||||
async def test_create_defaults_to_fixed_window_mode(
|
async def test_create_defaults_to_fixed_window_mode(
|
||||||
@@ -578,24 +595,6 @@ class TestLeaveWishService:
|
|||||||
)
|
)
|
||||||
assert result.window_mode == "fixed"
|
assert result.window_mode == "fixed"
|
||||||
|
|
||||||
async def test_create_rejects_invalid_window_mode(
|
|
||||||
self,
|
|
||||||
leave_wish_service: LeaveWishService,
|
|
||||||
seeded_ids: SeededIds,
|
|
||||||
) -> None:
|
|
||||||
with pytest.raises(ValidationError, match="window_mode"):
|
|
||||||
await leave_wish_service.create(
|
|
||||||
workspace_id=seeded_ids.workspace_id,
|
|
||||||
name="Wish",
|
|
||||||
window_start_month=1,
|
|
||||||
window_start_day=1,
|
|
||||||
window_end_month=1,
|
|
||||||
window_end_day=10,
|
|
||||||
target_weeks=1,
|
|
||||||
first_year=2027,
|
|
||||||
window_mode="whenever",
|
|
||||||
)
|
|
||||||
|
|
||||||
async def test_create_accepts_flexible_window_mode_with_wide_enough_bound(
|
async def test_create_accepts_flexible_window_mode_with_wide_enough_bound(
|
||||||
self,
|
self,
|
||||||
leave_wish_service: LeaveWishService,
|
leave_wish_service: LeaveWishService,
|
||||||
@@ -615,27 +614,6 @@ class TestLeaveWishService:
|
|||||||
)
|
)
|
||||||
assert result.window_mode == "flexible"
|
assert result.window_mode == "flexible"
|
||||||
|
|
||||||
async def test_create_rejects_flexible_wish_whose_bound_is_shorter_than_target_weeks(
|
|
||||||
self,
|
|
||||||
leave_wish_service: LeaveWishService,
|
|
||||||
seeded_ids: SeededIds,
|
|
||||||
) -> None:
|
|
||||||
# Bound = 2027-03-01 -> 2027-03-10 (10 days), target_weeks=2 (14
|
|
||||||
# days) -- a legitimate future shortfall must not be silently
|
|
||||||
# accepted; this is a user-input error (§10.1).
|
|
||||||
with pytest.raises(ValidationError, match="flexible"):
|
|
||||||
await leave_wish_service.create(
|
|
||||||
workspace_id=seeded_ids.workspace_id,
|
|
||||||
name="Vårlov",
|
|
||||||
window_start_month=3,
|
|
||||||
window_start_day=1,
|
|
||||||
window_end_month=3,
|
|
||||||
window_end_day=10,
|
|
||||||
target_weeks=2,
|
|
||||||
first_year=2027,
|
|
||||||
window_mode="flexible",
|
|
||||||
)
|
|
||||||
|
|
||||||
async def test_update_can_switch_window_mode_to_flexible(
|
async def test_update_can_switch_window_mode_to_flexible(
|
||||||
self,
|
self,
|
||||||
leave_wish_service: LeaveWishService,
|
leave_wish_service: LeaveWishService,
|
||||||
@@ -673,29 +651,6 @@ class TestLeaveWishService:
|
|||||||
with pytest.raises(ValidationError, match="flexible"):
|
with pytest.raises(ValidationError, match="flexible"):
|
||||||
await leave_wish_service.update(created.id, window_mode="flexible")
|
await leave_wish_service.update(created.id, window_mode="flexible")
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"month,day",
|
|
||||||
[(0, 15), (13, 15), (6, 0), (6, 32), (2, 30), (4, 31)],
|
|
||||||
)
|
|
||||||
async def test_create_rejects_invalid_month_day(
|
|
||||||
self,
|
|
||||||
leave_wish_service: LeaveWishService,
|
|
||||||
seeded_ids: SeededIds,
|
|
||||||
month: int,
|
|
||||||
day: int,
|
|
||||||
) -> None:
|
|
||||||
with pytest.raises(ValidationError):
|
|
||||||
await leave_wish_service.create(
|
|
||||||
workspace_id=seeded_ids.workspace_id,
|
|
||||||
name="Wish",
|
|
||||||
window_start_month=month,
|
|
||||||
window_start_day=day,
|
|
||||||
window_end_month=6,
|
|
||||||
window_end_day=20,
|
|
||||||
target_weeks=1,
|
|
||||||
first_year=2027,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def test_create_accepts_leap_day(
|
async def test_create_accepts_leap_day(
|
||||||
self,
|
self,
|
||||||
leave_wish_service: LeaveWishService,
|
leave_wish_service: LeaveWishService,
|
||||||
@@ -752,24 +707,6 @@ class TestLeaveWishService:
|
|||||||
assert result.target_days is None
|
assert result.target_days is None
|
||||||
assert result.target_span_days() == 14
|
assert result.target_span_days() == 14
|
||||||
|
|
||||||
async def test_create_rejects_target_days_below_one(
|
|
||||||
self,
|
|
||||||
leave_wish_service: LeaveWishService,
|
|
||||||
seeded_ids: SeededIds,
|
|
||||||
) -> None:
|
|
||||||
with pytest.raises(ValidationError, match="target_days"):
|
|
||||||
await leave_wish_service.create(
|
|
||||||
workspace_id=seeded_ids.workspace_id,
|
|
||||||
name="Wish",
|
|
||||||
window_start_month=1,
|
|
||||||
window_start_day=1,
|
|
||||||
window_end_month=1,
|
|
||||||
window_end_day=10,
|
|
||||||
target_weeks=1,
|
|
||||||
target_days=0,
|
|
||||||
first_year=2027,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def test_create_flexible_wish_sized_by_target_days_rejects_short_bound(
|
async def test_create_flexible_wish_sized_by_target_days_rejects_short_bound(
|
||||||
self,
|
self,
|
||||||
leave_wish_service: LeaveWishService,
|
leave_wish_service: LeaveWishService,
|
||||||
@@ -837,41 +774,6 @@ class TestLeaveWishService:
|
|||||||
result = await leave_wish_service.update(leave_wish_id=created.id, _clear_target_days=True)
|
result = await leave_wish_service.update(leave_wish_id=created.id, _clear_target_days=True)
|
||||||
assert result.target_days is None
|
assert result.target_days is None
|
||||||
|
|
||||||
async def test_create_rejects_zero_target_weeks(
|
|
||||||
self,
|
|
||||||
leave_wish_service: LeaveWishService,
|
|
||||||
seeded_ids: SeededIds,
|
|
||||||
) -> None:
|
|
||||||
with pytest.raises(ValidationError, match="target_weeks"):
|
|
||||||
await leave_wish_service.create(
|
|
||||||
workspace_id=seeded_ids.workspace_id,
|
|
||||||
name="Wish",
|
|
||||||
window_start_month=1,
|
|
||||||
window_start_day=1,
|
|
||||||
window_end_month=1,
|
|
||||||
window_end_day=10,
|
|
||||||
target_weeks=0,
|
|
||||||
first_year=2027,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def test_create_rejects_last_year_before_first_year(
|
|
||||||
self,
|
|
||||||
leave_wish_service: LeaveWishService,
|
|
||||||
seeded_ids: SeededIds,
|
|
||||||
) -> None:
|
|
||||||
with pytest.raises(ValidationError, match="last_year"):
|
|
||||||
await leave_wish_service.create(
|
|
||||||
workspace_id=seeded_ids.workspace_id,
|
|
||||||
name="Wish",
|
|
||||||
window_start_month=1,
|
|
||||||
window_start_day=1,
|
|
||||||
window_end_month=1,
|
|
||||||
window_end_day=10,
|
|
||||||
target_weeks=1,
|
|
||||||
first_year=2030,
|
|
||||||
last_year=2029,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def test_create_allows_last_year_equal_first_year(
|
async def test_create_allows_last_year_equal_first_year(
|
||||||
self,
|
self,
|
||||||
leave_wish_service: LeaveWishService,
|
leave_wish_service: LeaveWishService,
|
||||||
|
|||||||
Reference in New Issue
Block a user