Increases overall test coverage from 53% to 56% by adding tests for: - accommodation.py (60% → 100%) - birthday.py (24% → 100%) - calendar.py (19% → 100%) - carnival.py (33% → 100%) - domains.py (75% → 100%) - events_yaml.py (50% → 96%) - fx.py (14% → 21% for tested functions) - sun.py (55% → 100%) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
270 lines
9.7 KiB
Python
270 lines
9.7 KiB
Python
"""Tests for calendar functionality."""
|
|
|
|
from datetime import date, datetime, timedelta
|
|
from typing import Any
|
|
|
|
from agenda.calendar import build_events, colors, event_type_color_map
|
|
from agenda.event import Event
|
|
|
|
|
|
class TestEventTypeColorMap:
|
|
"""Test the event type color mapping."""
|
|
|
|
def test_event_type_color_map_contains_expected_types(self) -> None:
|
|
"""Test that color map contains expected event types."""
|
|
expected_types = {
|
|
"bank_holiday", "conference", "us_holiday",
|
|
"birthday", "waste_schedule"
|
|
}
|
|
assert set(event_type_color_map.keys()) == expected_types
|
|
|
|
def test_event_type_color_map_values_are_valid(self) -> None:
|
|
"""Test that all color values are valid color names."""
|
|
expected_colors = {
|
|
"success-subtle", "primary-subtle", "secondary-subtle",
|
|
"info-subtle", "danger-subtle"
|
|
}
|
|
assert set(event_type_color_map.values()).issubset(expected_colors)
|
|
|
|
|
|
class TestColorsDict:
|
|
"""Test the colors dictionary."""
|
|
|
|
def test_colors_contains_expected_keys(self) -> None:
|
|
"""Test that colors dict contains expected color keys."""
|
|
expected_keys = {
|
|
"primary-subtle", "secondary-subtle", "success-subtle",
|
|
"info-subtle", "warning-subtle", "danger-subtle"
|
|
}
|
|
assert set(colors.keys()) == expected_keys
|
|
|
|
def test_colors_values_are_hex_codes(self) -> None:
|
|
"""Test that all color values are valid hex codes."""
|
|
for color_value in colors.values():
|
|
assert color_value.startswith("#")
|
|
assert len(color_value) == 7
|
|
# Check that remaining characters are valid hex
|
|
hex_part = color_value[1:]
|
|
int(hex_part, 16) # This will raise ValueError if not valid hex
|
|
|
|
|
|
class TestBuildEvents:
|
|
"""Test the build_events function."""
|
|
|
|
def test_build_events_empty_list(self) -> None:
|
|
"""Test building events with empty list."""
|
|
result = build_events([])
|
|
assert result == []
|
|
|
|
def test_build_events_today_event_filtered(self) -> None:
|
|
"""Test that 'today' events are filtered out."""
|
|
events = [
|
|
Event(date=date(2024, 1, 1), name="today", title="Today"),
|
|
Event(date=date(2024, 1, 2), name="birthday", title="Birthday"),
|
|
]
|
|
result = build_events(events)
|
|
|
|
assert len(result) == 1
|
|
assert result[0]["title"] == "🎈 Birthday"
|
|
|
|
def test_build_events_simple_event(self) -> None:
|
|
"""Test building a simple event without time."""
|
|
events = [
|
|
Event(
|
|
date=date(2024, 1, 15),
|
|
name="birthday",
|
|
title="John's Birthday"
|
|
)
|
|
]
|
|
result = build_events(events)
|
|
|
|
assert len(result) == 1
|
|
item = result[0]
|
|
assert item["allDay"] is True
|
|
assert item["title"] == "🎈 John's Birthday"
|
|
assert item["start"] == "2024-01-15"
|
|
assert item["end"] == "2024-01-16" # Next day
|
|
assert item["color"] == colors["info-subtle"]
|
|
assert item["textColor"] == "black"
|
|
|
|
def test_build_events_with_time(self) -> None:
|
|
"""Test building an event with time."""
|
|
event_datetime = datetime(2024, 1, 15, 14, 30)
|
|
events = [
|
|
Event(
|
|
date=event_datetime,
|
|
name="meeting",
|
|
title="Team Meeting"
|
|
)
|
|
]
|
|
result = build_events(events)
|
|
|
|
assert len(result) == 1
|
|
item = result[0]
|
|
assert item["allDay"] is False
|
|
assert item["title"] == "Team Meeting"
|
|
assert item["start"] == "2024-01-15T14:30:00"
|
|
assert item["end"] == "2024-01-15T15:00:00" # 30 minutes later
|
|
|
|
def test_build_events_with_end_date(self) -> None:
|
|
"""Test building an event with end date."""
|
|
events = [
|
|
Event(
|
|
date=date(2024, 1, 15),
|
|
name="conference",
|
|
title="Tech Conference",
|
|
end_date=date(2024, 1, 17)
|
|
)
|
|
]
|
|
result = build_events(events)
|
|
|
|
assert len(result) == 1
|
|
item = result[0]
|
|
assert item["allDay"] is True
|
|
assert item["start"] == "2024-01-15"
|
|
assert item["end"] == "2024-01-18" # End date + 1 day
|
|
|
|
def test_build_events_with_time_and_end_date(self) -> None:
|
|
"""Test building an event with time and end date."""
|
|
start_datetime = datetime(2024, 1, 15, 9, 0)
|
|
end_datetime = datetime(2024, 1, 15, 17, 0)
|
|
events = [
|
|
Event(
|
|
date=start_datetime,
|
|
name="workshop",
|
|
title="Python Workshop",
|
|
end_date=end_datetime
|
|
)
|
|
]
|
|
result = build_events(events)
|
|
|
|
assert len(result) == 1
|
|
item = result[0]
|
|
assert item["allDay"] is False
|
|
assert item["start"] == "2024-01-15T09:00:00"
|
|
assert item["end"] == "2024-01-15T17:00:00"
|
|
|
|
def test_build_events_with_url(self) -> None:
|
|
"""Test building an event with URL."""
|
|
events = [
|
|
Event(
|
|
date=date(2024, 1, 15),
|
|
name="conference",
|
|
title="Tech Conference",
|
|
url="https://example.com"
|
|
)
|
|
]
|
|
result = build_events(events)
|
|
|
|
assert len(result) == 1
|
|
item = result[0]
|
|
assert item["url"] == "https://example.com"
|
|
|
|
def test_build_events_accommodation(self) -> None:
|
|
"""Test building accommodation events."""
|
|
events = [
|
|
Event(
|
|
date=datetime(2024, 1, 15, 15, 0), # Check-in time
|
|
name="accommodation",
|
|
title="Hotel Stay",
|
|
end_date=datetime(2024, 1, 17, 11, 0), # Check-out time
|
|
url="https://hotel.com"
|
|
)
|
|
]
|
|
result = build_events(events)
|
|
|
|
# Should create 3 events: main accommodation + check-in + check-out
|
|
assert len(result) == 3
|
|
|
|
# Main accommodation event
|
|
main_event = result[0]
|
|
assert main_event["allDay"] is True
|
|
assert main_event["title"] == "🏨 Hotel Stay"
|
|
assert main_event["start"] == "2024-01-15"
|
|
assert main_event["end"] == "2024-01-18" # End date + 1 day
|
|
assert main_event["url"] == "https://hotel.com"
|
|
|
|
# Check-in event
|
|
checkin_event = result[1]
|
|
assert checkin_event["allDay"] is False
|
|
assert checkin_event["title"] == "check-in: Hotel Stay"
|
|
assert checkin_event["start"] == "2024-01-15T15:00:00"
|
|
assert checkin_event["url"] == "https://hotel.com"
|
|
|
|
# Check-out event
|
|
checkout_event = result[2]
|
|
assert checkout_event["allDay"] is False
|
|
assert checkout_event["title"] == "checkout: Hotel Stay"
|
|
assert checkout_event["start"] == "2024-01-17T11:00:00"
|
|
assert checkout_event["url"] == "https://hotel.com"
|
|
|
|
def test_build_events_no_color_for_unknown_type(self) -> None:
|
|
"""Test that events with unknown types don't get color."""
|
|
events = [
|
|
Event(
|
|
date=date(2024, 1, 15),
|
|
name="unknown_type",
|
|
title="Unknown Event"
|
|
)
|
|
]
|
|
result = build_events(events)
|
|
|
|
assert len(result) == 1
|
|
item = result[0]
|
|
assert "color" not in item
|
|
assert "textColor" not in item
|
|
|
|
def test_build_events_multiple_event_types(self) -> None:
|
|
"""Test building events with different types and colors."""
|
|
events = [
|
|
Event(date=date(2024, 1, 15), name="bank_holiday", title="New Year"),
|
|
Event(date=date(2024, 1, 16), name="conference", title="PyCon"),
|
|
Event(date=date(2024, 1, 17), name="birthday", title="Birthday"),
|
|
Event(date=date(2024, 1, 18), name="waste_schedule", title="Recycling"),
|
|
Event(date=date(2024, 1, 19), name="us_holiday", title="MLK Day"),
|
|
]
|
|
result = build_events(events)
|
|
|
|
assert len(result) == 5
|
|
|
|
# Check colors are assigned correctly
|
|
assert result[0]["color"] == colors["success-subtle"] # bank_holiday
|
|
assert result[1]["color"] == colors["primary-subtle"] # conference
|
|
assert result[2]["color"] == colors["info-subtle"] # birthday
|
|
assert result[3]["color"] == colors["danger-subtle"] # waste_schedule
|
|
assert result[4]["color"] == colors["secondary-subtle"] # us_holiday
|
|
|
|
# All should have black text
|
|
for item in result:
|
|
assert item["textColor"] == "black"
|
|
|
|
def test_build_events_mixed_scenarios(self) -> None:
|
|
"""Test building events with mixed scenarios."""
|
|
events = [
|
|
# Today event (should be filtered)
|
|
Event(date=date(2024, 1, 1), name="today", title="Today"),
|
|
# Simple event
|
|
Event(date=date(2024, 1, 15), name="birthday", title="Birthday"),
|
|
# Event with time
|
|
Event(date=datetime(2024, 1, 16, 10, 0), name="meeting", title="Meeting"),
|
|
# Accommodation
|
|
Event(
|
|
date=datetime(2024, 1, 20, 15, 0),
|
|
name="accommodation",
|
|
title="Hotel",
|
|
end_date=datetime(2024, 1, 22, 11, 0),
|
|
url="https://hotel.com"
|
|
),
|
|
]
|
|
result = build_events(events)
|
|
|
|
# Should have 5 events total (today filtered, accommodation creates 3)
|
|
assert len(result) == 5
|
|
|
|
# Verify titles
|
|
titles = [item["title"] for item in result]
|
|
assert "🎈 Birthday" in titles
|
|
assert "Meeting" in titles
|
|
assert "🏨 Hotel" in titles
|
|
assert "check-in: Hotel" in titles
|
|
assert "checkout: Hotel" in titles |