odoo-timesheets/tests/test_utils.py

100 lines
2.9 KiB
Python

from datetime import date
import pytest
from timesheets.utils import (
decimal_to_hhmm,
duration_from_start_end,
format_date,
parse_duration,
strip_markdown_link,
)
class TestParseDuration:
def test_basic(self):
assert parse_duration("01:30") == 1.5
def test_zero(self):
assert parse_duration("00:00") == 0.0
def test_minutes_only(self):
assert parse_duration("00:15") == 0.25
def test_multidigit_hours(self):
assert parse_duration("10:00") == 10.0
def test_strips_whitespace(self):
assert parse_duration(" 01:00 ") == 1.0
@pytest.mark.parametrize("bad", ["1:5", "abc", "1:00:00", ""])
def test_invalid_raises(self, bad):
with pytest.raises(ValueError):
parse_duration(bad)
class TestDurationFromStartEnd:
def test_basic(self):
assert duration_from_start_end("08:00", "09:00") == 1.0
def test_partial_hour(self):
assert duration_from_start_end("08:15", "08:30") == 0.25
def test_midnight_rollover(self):
assert duration_from_start_end("23:45", "00:15") == 0.5
def test_same_time(self):
assert duration_from_start_end("09:00", "09:00") == 0.0
@pytest.mark.parametrize("bad_start,bad_end", [("9:0", "10:00"), ("08:00", "10:0")])
def test_invalid_raises(self, bad_start, bad_end):
with pytest.raises(ValueError):
duration_from_start_end(bad_start, bad_end)
class TestDecimalToHhmm:
@pytest.mark.parametrize(
"hours,expected",
[
(1.0, "01:00"),
(1.5, "01:30"),
(0.25, "00:15"),
(0.0, "00:00"),
(10.0, "10:00"),
# rounding: 0.1666... hours = 10 minutes
(1 / 6, "00:10"),
],
)
def test_conversion(self, hours, expected):
assert decimal_to_hhmm(hours) == expected
class TestStripMarkdownLink:
def test_strips_link(self):
assert strip_markdown_link("[foo bar](http://example.com)") == "foo bar"
def test_strips_joplin_style_link(self):
text = "[29497: collector auto update](:/0ce89020cd874f0281a71f62b9d7b75f)"
assert strip_markdown_link(text) == "29497: collector auto update"
def test_plain_text_unchanged(self):
assert strip_markdown_link("just plain text") == "just plain text"
def test_empty_string(self):
assert strip_markdown_link("") == ""
def test_multiple_links(self):
text = "[a](url1) and [b](url2)"
assert strip_markdown_link(text) == "a and b"
def test_partial_link_unchanged(self):
# Missing closing paren — not a valid link, should be left alone
assert strip_markdown_link("[foo](bar") == "[foo](bar"
class TestFormatDate:
def test_format(self):
assert format_date(date(2026, 3, 22)) == "22/03/26"
def test_single_digit_day_month(self):
assert format_date(date(2026, 1, 5)) == "05/01/26"