Skip to content

Commit 2383a69

Browse files
committed
[ADD] Hr Leave test coverage
1 parent 2834fab commit 2383a69

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed

project_forecast_line/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
from . import test_project_task
33
from . import test_forecast_line_mixin
44
from . import test_sale_order
5+
from . import test_hr_leave

project_forecast_line/tests/test_forecast_line.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,52 @@ def test_forecast_with_calendar(self):
344344
)
345345
self.assertFalse(to_remove_lines.exists())
346346

347+
@freeze_time("2022-01-01 12:00:00")
348+
def test_calendar_leave_write_updates_forecast_lines(self):
349+
calendar = self.employee_dev.resource_calendar_id
350+
351+
def _april_hours():
352+
line = self.ForecastLine.search(
353+
[
354+
("employee_id", "=", self.employee_dev.id),
355+
("forecast_role_id", "=", self.role_developer.id),
356+
("res_model", "=", self.role_model),
357+
("date_from", "=", "2022-04-01"),
358+
]
359+
)
360+
return line.forecast_hours if line else None
361+
362+
# Baseline: April = 21 working days × 8 h
363+
april_baseline = 21.0 * 8
364+
self.assertEqual(_april_hours(), april_baseline)
365+
366+
# Create a 1-day leave on April 18 → April shrinks by 8 h
367+
leave = self.env["resource.calendar.leaves"].create(
368+
{
369+
"name": "Easter Monday",
370+
"calendar_id": calendar.id,
371+
"date_from": "2022-04-18 00:00:00",
372+
"date_to": "2022-04-19 00:00:00",
373+
"time_type": "leave",
374+
}
375+
)
376+
self.env.flush_all()
377+
self.assertEqual(
378+
_april_hours(),
379+
(21.0 - 1) * 8,
380+
"Creating the leave must reduce April by 8 h",
381+
)
382+
383+
# Write: extend the leave to 2 days (April 18–20) → April shrinks by another 8 h
384+
leave.write({"date_to": "2022-04-20 00:00:00"})
385+
self.env.flush_all()
386+
387+
self.assertEqual(
388+
_april_hours(),
389+
(21.0 - 2) * 8,
390+
"After extending the leave via write(), April must lose another 8 h",
391+
)
392+
347393
@freeze_time("2022-01-01 12:00:00")
348394
def test_calendar_leave_unlink_updates_forecast_lines(self):
349395
"""Unlinking a resource.calendar.leaves record must trigger
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Copyright 2022 Camptocamp SA
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from freezegun import freeze_time
4+
5+
from .test_forecast_line import BaseForecastRoleTest
6+
7+
8+
class TestHrLeave(BaseForecastRoleTest):
9+
10+
@freeze_time("2022-01-01 12:00:00")
11+
def test_update_forecast_lines_skips_employee_without_main_role(self):
12+
"""When an employee has no main_role_id, _update_forecast_lines
13+
must skip the leave (continue) and NOT create any forecast lines
14+
for it.
15+
"""
16+
# Create an employee with NO forecast role assignments
17+
employee_no_role = self.HrEmployee.create({"name": "No Role Employee"})
18+
user_no_role = self.ResUsers.create(
19+
{"name": "No Role User", "login": "norole@example.com"}
20+
)
21+
employee_no_role.user_id = user_no_role.id
22+
self.env.flush_all()
23+
24+
# Confirm the employee has no main_role_id
25+
self.assertFalse(
26+
employee_no_role.main_role_id,
27+
"Employee must have no main_role_id for this test",
28+
)
29+
30+
# Create an HR leave for this employee
31+
leave_type = self.env["hr.leave.type"].create(
32+
{
33+
"name": "Test Leave Type",
34+
"requires_allocation": "no",
35+
}
36+
)
37+
leave = (
38+
self.env["hr.leave"]
39+
.with_user(user_no_role)
40+
.create(
41+
{
42+
"name": "Sick Day",
43+
"holiday_status_id": leave_type.id,
44+
"date_from": "2022-03-14 08:00:00",
45+
"date_to": "2022-03-15 17:00:00",
46+
"employee_id": employee_no_role.id,
47+
}
48+
)
49+
)
50+
self.env.flush_all()
51+
52+
# No forecast lines should be created for this leave
53+
forecast_lines = self.ForecastLine.search(
54+
[
55+
("res_model", "=", "hr.leave"),
56+
("res_id", "=", leave.id),
57+
]
58+
)
59+
self.assertFalse(
60+
forecast_lines,
61+
"No forecast lines must be created when the employee "
62+
"has no main_role_id",
63+
)
64+
65+
@freeze_time("2022-01-01 12:00:00")
66+
def test_update_forecast_lines_creates_lines_for_employee_with_role(self):
67+
"""When an employee has a main_role_id and the leave state is not
68+
'validate' or 'refuse', _update_forecast_lines must create
69+
forecast lines for the leave.
70+
"""
71+
# employee_consultant has a role via consult_employee_forecast_role
72+
self.assertTrue(
73+
self.employee_consultant.main_role_id,
74+
"Employee must have a main_role_id for this test",
75+
)
76+
77+
leave_type = self.env["hr.leave.type"].create(
78+
{
79+
"name": "Test Leave Type 2",
80+
"requires_allocation": "no",
81+
}
82+
)
83+
leave = (
84+
self.env["hr.leave"]
85+
.with_user(self.user_consultant)
86+
.create(
87+
{
88+
"name": "Vacation",
89+
"holiday_status_id": leave_type.id,
90+
"date_from": "2022-03-14 08:00:00",
91+
"date_to": "2022-03-15 17:00:00",
92+
"employee_id": self.employee_consultant.id,
93+
}
94+
)
95+
)
96+
self.env.flush_all()
97+
98+
# Forecast lines SHOULD be created for this leave
99+
forecast_lines = self.ForecastLine.search(
100+
[
101+
("res_model", "=", "hr.leave"),
102+
("res_id", "=", leave.id),
103+
]
104+
)
105+
self.assertTrue(
106+
forecast_lines,
107+
"Forecast lines must be created when the employee has a "
108+
"main_role_id and leave is not validated/refused",
109+
)
110+
self.assertEqual(
111+
forecast_lines.forecast_role_id,
112+
self.role_consultant,
113+
"Forecast line must use the employee's main_role_id",
114+
)

0 commit comments

Comments
 (0)