148 lines
4.0 KiB
Python
148 lines
4.0 KiB
Python
"""oa_overtime_hours unit tests"""
|
|
from app.services.oa_overtime_hours import (
|
|
MANUAL_PREFIX,
|
|
DEFAULT_OVERTIME_WINDOWS,
|
|
apply_overtime_kit_hours,
|
|
calc_overtime_hours,
|
|
validate_overtime_kit_form_values,
|
|
)
|
|
|
|
REST = {
|
|
"2026-08-07": False,
|
|
"2026-08-08": True,
|
|
"2026-08-09": True,
|
|
}
|
|
|
|
|
|
def is_rest(ymd: str) -> bool:
|
|
if ymd in REST:
|
|
return REST[ymd]
|
|
from datetime import datetime
|
|
|
|
return datetime.strptime(ymd, "%Y-%m-%d").weekday() >= 5
|
|
|
|
|
|
def test_weekday_evening():
|
|
assert (
|
|
calc_overtime_hours("2026-08-07 18:00", "2026-08-07 20:00", DEFAULT_OVERTIME_WINDOWS, is_rest)
|
|
== 2.0
|
|
)
|
|
|
|
|
|
def test_weekday_partial_window():
|
|
assert (
|
|
calc_overtime_hours("2026-08-07 14:00", "2026-08-07 18:00", DEFAULT_OVERTIME_WINDOWS, is_rest)
|
|
== 0.5
|
|
)
|
|
|
|
|
|
def test_full_weekday_window():
|
|
assert (
|
|
calc_overtime_hours("2026-08-07 17:30", "2026-08-08 08:30", DEFAULT_OVERTIME_WINDOWS, is_rest)
|
|
== 15.0
|
|
)
|
|
|
|
|
|
def test_saturday_with_break():
|
|
assert (
|
|
calc_overtime_hours("2026-08-08 09:00", "2026-08-08 15:00", DEFAULT_OVERTIME_WINDOWS, is_rest)
|
|
== 4.0
|
|
)
|
|
|
|
|
|
def test_fri_to_sat():
|
|
assert (
|
|
calc_overtime_hours("2026-08-07 18:00", "2026-08-08 12:00", DEFAULT_OVERTIME_WINDOWS, is_rest)
|
|
== 17.5
|
|
)
|
|
|
|
|
|
def test_invalid():
|
|
assert (
|
|
calc_overtime_hours("2026-08-07 20:00", "2026-08-07 18:00", DEFAULT_OVERTIME_WINDOWS, is_rest)
|
|
is None
|
|
)
|
|
|
|
|
|
def test_apply_overwrites_when_not_manual():
|
|
schema = {
|
|
"rule": [
|
|
{
|
|
"type": "overtimeKit",
|
|
"props": {
|
|
"startField": "overtimeStart",
|
|
"endField": "overtimeEnd",
|
|
"durationField": "overtimeDuration",
|
|
},
|
|
"children": [
|
|
{"type": "person", "field": "overtimePerson"},
|
|
{
|
|
"type": "datePicker",
|
|
"field": "overtimeStart",
|
|
"props": {"_fc_kit_field": "overtimeStart"},
|
|
},
|
|
{
|
|
"type": "datePicker",
|
|
"field": "overtimeEnd",
|
|
"props": {"_fc_kit_field": "overtimeEnd"},
|
|
},
|
|
{
|
|
"type": "inputNumber",
|
|
"field": "overtimeDuration",
|
|
"props": {"_fc_kit_field": "overtimeDuration"},
|
|
},
|
|
],
|
|
}
|
|
]
|
|
}
|
|
data = {
|
|
"overtimeStart": "2026-08-07 18:00",
|
|
"overtimeEnd": "2026-08-07 20:00",
|
|
"overtimeDuration": 1,
|
|
}
|
|
out = apply_overtime_kit_hours(schema, data, is_rest)
|
|
assert out["overtimeDuration"] == 2.0
|
|
|
|
|
|
def test_apply_respects_manual():
|
|
schema = {
|
|
"rule": [
|
|
{
|
|
"type": "overtimeKit",
|
|
"props": {},
|
|
"children": [
|
|
{"type": "datePicker", "field": "overtimeStart"},
|
|
{"type": "datePicker", "field": "overtimeEnd"},
|
|
{"type": "inputNumber", "field": "overtimeDuration"},
|
|
],
|
|
}
|
|
]
|
|
}
|
|
data = {
|
|
"overtimeStart": "2026-08-07 18:00",
|
|
"overtimeEnd": "2026-08-07 20:00",
|
|
"overtimeDuration": 8,
|
|
f"{MANUAL_PREFIX}overtimeDuration": True,
|
|
}
|
|
out = apply_overtime_kit_hours(schema, data, is_rest)
|
|
assert out["overtimeDuration"] == 8.0
|
|
|
|
|
|
def test_validate_end_before_start():
|
|
schema = {
|
|
"rule": [
|
|
{
|
|
"type": "overtimeKit",
|
|
"children": [
|
|
{"type": "datePicker", "field": "s"},
|
|
{"type": "datePicker", "field": "e"},
|
|
{"type": "inputNumber", "field": "d"},
|
|
],
|
|
}
|
|
]
|
|
}
|
|
errs = validate_overtime_kit_form_values(
|
|
schema, {"s": "2026-08-07 20:00", "e": "2026-08-07 18:00", "d": 1}
|
|
)
|
|
assert any("结束" in e for e in errs)
|