agenda/tests/test_conference.py
Edward Betts 88ccd79cb2 Add comprehensive tests for conference module.
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-20 01:14:24 +02:00

371 lines
12 KiB
Python

"""Tests for agenda.conference module."""
import decimal
import tempfile
from datetime import date, datetime
from typing import Any
import pytest
import yaml
from agenda.conference import Conference, get_list
from agenda.event import Event
class TestConference:
"""Tests for Conference dataclass."""
def test_conference_creation_minimal(self) -> None:
"""Test creating conference with minimal required fields."""
conf = Conference(
name="PyCon",
topic="Python",
location="Portland",
start=date(2024, 5, 15),
end=date(2024, 5, 17),
)
assert conf.name == "PyCon"
assert conf.topic == "Python"
assert conf.location == "Portland"
assert conf.start == date(2024, 5, 15)
assert conf.end == date(2024, 5, 17)
assert conf.trip is None
assert conf.going is False
assert conf.online is False
def test_conference_creation_full(self) -> None:
"""Test creating conference with all fields."""
conf = Conference(
name="PyCon US",
topic="Python",
location="Portland",
start=date(2024, 5, 15),
end=date(2024, 5, 17),
trip=date(2024, 5, 14),
country="USA",
venue="Convention Center",
address="123 Main St",
url="https://pycon.org",
accommodation_booked=True,
transport_booked=True,
going=True,
registered=True,
speaking=True,
online=False,
price=decimal.Decimal("500.00"),
currency="USD",
latitude=45.5152,
longitude=-122.6784,
cfp_end=date(2024, 2, 1),
cfp_url="https://pycon.org/cfp",
free=False,
hackathon=True,
ticket_type="early_bird",
attendees=3000,
hashtag="#pycon2024",
)
assert conf.name == "PyCon US"
assert conf.going is True
assert conf.price == decimal.Decimal("500.00")
assert conf.currency == "USD"
assert conf.latitude == 45.5152
assert conf.longitude == -122.6784
assert conf.cfp_end == date(2024, 2, 1)
assert conf.hashtag == "#pycon2024"
def test_display_name_location_in_name(self) -> None:
"""Test display_name when location is already in conference name."""
conf = Conference(
name="PyCon Portland",
topic="Python",
location="Portland",
start=date(2024, 5, 15),
end=date(2024, 5, 17),
)
assert conf.display_name == "PyCon Portland"
def test_display_name_location_not_in_name(self) -> None:
"""Test display_name when location is not in conference name."""
conf = Conference(
name="PyCon",
topic="Python",
location="Portland",
start=date(2024, 5, 15),
end=date(2024, 5, 17),
)
assert conf.display_name == "PyCon (Portland)"
def test_display_name_partial_location_match(self) -> None:
"""Test display_name when location is partially in name."""
conf = Conference(
name="PyConf",
topic="Python",
location="Conference Center",
start=date(2024, 5, 15),
end=date(2024, 5, 17),
)
assert conf.display_name == "PyConf (Conference Center)"
def test_conference_with_datetime(self) -> None:
"""Test conference with datetime objects."""
start_dt = datetime(2024, 5, 15, 9, 0)
end_dt = datetime(2024, 5, 17, 17, 0)
conf = Conference(
name="PyCon",
topic="Python",
location="Portland",
start=start_dt,
end=end_dt,
)
assert conf.start == start_dt
assert conf.end == end_dt
class TestGetList:
"""Tests for get_list function."""
def test_get_list_single_conference(self) -> None:
"""Test reading single conference from YAML."""
yaml_data = [
{
"name": "PyCon",
"topic": "Python",
"location": "Portland",
"start": date(2024, 5, 15),
"end": date(2024, 5, 17),
"url": "https://pycon.org",
"going": True,
}
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
events = get_list(f.name)
assert len(events) == 1
event = events[0]
assert isinstance(event, Event)
assert event.name == "conference"
assert event.date == date(2024, 5, 15)
assert event.end_date == date(2024, 5, 17)
assert event.title == "PyCon (Portland)"
assert event.url == "https://pycon.org"
assert event.going is True
def test_get_list_conference_with_cfp(self) -> None:
"""Test reading conference with CFP end date."""
yaml_data = [
{
"name": "PyCon",
"topic": "Python",
"location": "Portland",
"start": date(2024, 5, 15),
"end": date(2024, 5, 17),
"url": "https://pycon.org",
"cfp_end": date(2024, 2, 1),
"cfp_url": "https://pycon.org/cfp",
}
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
events = get_list(f.name)
assert len(events) == 2
# Conference event
conf_event = events[0]
assert conf_event.name == "conference"
assert conf_event.title == "PyCon (Portland)"
assert conf_event.url == "https://pycon.org"
# CFP end event
cfp_event = events[1]
assert cfp_event.name == "cfp_end"
assert cfp_event.date == date(2024, 2, 1)
assert cfp_event.title == "CFP end: PyCon (Portland)"
assert cfp_event.url == "https://pycon.org/cfp"
def test_get_list_conference_cfp_no_url(self) -> None:
"""Test reading conference with CFP end date but no CFP URL."""
yaml_data = [
{
"name": "PyCon",
"topic": "Python",
"location": "Portland",
"start": date(2024, 5, 15),
"end": date(2024, 5, 17),
"url": "https://pycon.org",
"cfp_end": date(2024, 2, 1),
}
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
events = get_list(f.name)
assert len(events) == 2
cfp_event = events[1]
assert cfp_event.url == "https://pycon.org" # Falls back to conference URL
def test_get_list_multiple_conferences(self) -> None:
"""Test reading multiple conferences from YAML."""
yaml_data = [
{
"name": "PyCon",
"topic": "Python",
"location": "Portland",
"start": date(2024, 5, 15),
"end": date(2024, 5, 17),
},
{
"name": "EuroPython",
"topic": "Python",
"location": "Prague",
"start": date(2024, 7, 8),
"end": date(2024, 7, 14),
"cfp_end": date(2024, 3, 15),
},
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
events = get_list(f.name)
assert len(events) == 3 # 2 conferences + 1 CFP end
# First conference
assert events[0].title == "PyCon (Portland)"
assert events[0].date == date(2024, 5, 15)
# Second conference
assert events[1].title == "EuroPython (Prague)"
assert events[1].date == date(2024, 7, 8)
# CFP end event for second conference
assert events[2].name == "cfp_end"
assert events[2].title == "CFP end: EuroPython (Prague)"
def test_get_list_location_in_name(self) -> None:
"""Test conference where location is already in name."""
yaml_data = [
{
"name": "PyCon Portland",
"topic": "Python",
"location": "Portland",
"start": date(2024, 5, 15),
"end": date(2024, 5, 17),
}
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
events = get_list(f.name)
assert len(events) == 1
assert events[0].title == "PyCon Portland" # No location appended
def test_get_list_datetime_objects(self) -> None:
"""Test reading conferences with datetime objects."""
yaml_data = [
{
"name": "PyCon",
"topic": "Python",
"location": "Portland",
"start": datetime(2024, 5, 15, 9, 0),
"end": datetime(2024, 5, 17, 17, 0),
}
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
events = get_list(f.name)
assert len(events) == 1
event = events[0]
assert event.date == datetime(2024, 5, 15, 9, 0)
assert event.end_date == datetime(2024, 5, 17, 17, 0)
def test_get_list_invalid_date_order(self) -> None:
"""Test that conferences with end before start raise assertion error."""
yaml_data = [
{
"name": "Invalid Conference",
"topic": "Testing",
"location": "Nowhere",
"start": date(2024, 5, 17),
"end": date(2024, 5, 15), # End before start
}
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
with pytest.raises(AssertionError):
get_list(f.name)
def test_get_list_too_long_conference(self) -> None:
"""Test that conferences longer than MAX_CONF_DAYS raise assertion error."""
yaml_data = [
{
"name": "Too Long Conference",
"topic": "Testing",
"location": "Nowhere",
"start": date(2024, 5, 1),
"end": date(2024, 6, 1), # More than 20 days
}
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
with pytest.raises(AssertionError):
get_list(f.name)
def test_get_list_empty_file(self) -> None:
"""Test reading empty YAML file."""
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump([], f)
f.flush()
events = get_list(f.name)
assert events == []
def test_get_list_same_day_conference(self) -> None:
"""Test conference that starts and ends on same day."""
yaml_data = [
{
"name": "One Day Conference",
"topic": "Testing",
"location": "Test City",
"start": date(2024, 5, 15),
"end": date(2024, 5, 15),
}
]
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
yaml.dump(yaml_data, f)
f.flush()
events = get_list(f.name)
assert len(events) == 1
event = events[0]
assert event.date == date(2024, 5, 15)
assert event.end_date == date(2024, 5, 15)