"""Tests for calendar invite compression.""" import pytest from pathlib import Path from src.mail.invite_compressor import InviteCompressor, compress_invite from src.mail.utils.calendar_parser import ( parse_calendar_from_raw_message, is_cancelled_event, is_event_request, ) from src.mail.notification_detector import is_calendar_email class TestInviteDetection: """Test detection of calendar invite emails.""" def test_detect_large_group_invite(self): """Test detection of large group meeting invite.""" fixture_path = Path( "tests/fixtures/test_mailbox/INBOX/cur/17051227-large-group-invite.test:2,S" ) assert fixture_path.exists(), f"Fixture not found: {fixture_path}" with open(fixture_path, "r") as f: raw_message = f.read() # Create envelope from message envelope = { "from": {"addr": "product.dev@example.com", "name": "Product Development"}, "subject": "Project Kickoff Meeting", "date": "2025-12-19T21:42:58+00:00", } # Should be detected as calendar email assert is_calendar_email(envelope) is True # Parse the ICS event = parse_calendar_from_raw_message(raw_message) assert event is not None assert event.method == "REQUEST" assert is_event_request(event) is True assert event.summary == "Project Kickoff Meeting" assert len(event.attendees) >= 20 # Large group def test_detect_cancellation(self): """Test detection of meeting cancellation.""" fixture_path = Path( "tests/fixtures/test_mailbox/INBOX/cur/17051228-cancellation.test:2,S" ) assert fixture_path.exists(), f"Fixture not found: {fixture_path}" with open(fixture_path, "r") as f: raw_message = f.read() envelope = { "from": {"addr": "cody.marshall@example.com", "name": "Marshall, Cody"}, "subject": "Canceled: Technical Refinement", "date": "2025-12-19T19:12:46+00:00", } # Should be detected as calendar email assert is_calendar_email(envelope) is True # Parse the ICS event = parse_calendar_from_raw_message(raw_message) assert event is not None assert event.method == "CANCEL" assert is_cancelled_event(event) is True assert event.status == "CANCELLED" class TestInviteCompression: """Test compression of calendar invite content.""" def test_compress_large_group_invite(self): """Test compression of large group meeting invite.""" fixture_path = Path( "tests/fixtures/test_mailbox/INBOX/cur/17051227-large-group-invite.test:2,S" ) with open(fixture_path, "r") as f: raw_message = f.read() envelope = { "from": {"addr": "product.dev@example.com", "name": "Product Development"}, "subject": "Project Kickoff Meeting", "date": "2025-12-19T21:42:58+00:00", } compressor = InviteCompressor(mode="summary") compressed, event = compressor.compress(raw_message, envelope) assert event is not None assert "MEETING INVITE" in compressed assert "Project Kickoff Meeting" in compressed # Should show compressed attendee list assert "more)" in compressed # Truncated attendee list # Should show action hints for REQUEST assert "Accept" in compressed def test_compress_cancellation(self): """Test compression of meeting cancellation.""" fixture_path = Path( "tests/fixtures/test_mailbox/INBOX/cur/17051228-cancellation.test:2,S" ) with open(fixture_path, "r") as f: raw_message = f.read() envelope = { "from": {"addr": "cody.marshall@example.com", "name": "Marshall, Cody"}, "subject": "Canceled: Technical Refinement", "date": "2025-12-19T19:12:46+00:00", } compressor = InviteCompressor(mode="summary") compressed, event = compressor.compress(raw_message, envelope) assert event is not None assert "CANCELLED" in compressed # Title should be strikethrough (without the Canceled: prefix) assert "~~Technical Refinement~~" in compressed # Should NOT show action hints for cancelled meetings assert "Accept" not in compressed def test_attendee_compression(self): """Test attendee list compression.""" compressor = InviteCompressor() # Test with few attendees attendees = ["Alice ", "Bob "] result = compressor._compress_attendees(attendees) assert result == "Alice, Bob" # Test with many attendees many_attendees = [ "Alice ", "Bob ", "Carol ", "Dave ", "Eve ", ] result = compressor._compress_attendees(many_attendees, max_shown=3) assert "Alice" in result assert "Bob" in result assert "Carol" in result assert "(+2 more)" in result def test_compress_off_mode(self): """Test that compression can be disabled.""" fixture_path = Path( "tests/fixtures/test_mailbox/INBOX/cur/17051227-large-group-invite.test:2,S" ) with open(fixture_path, "r") as f: raw_message = f.read() envelope = { "from": {"addr": "product.dev@example.com"}, "subject": "Project Kickoff Meeting", } compressor = InviteCompressor(mode="off") assert compressor.should_compress(envelope) is False compressed, event = compressor.compress(raw_message, envelope) assert compressed == "" assert event is None def test_convenience_function(self): """Test the compress_invite convenience function.""" fixture_path = Path( "tests/fixtures/test_mailbox/INBOX/cur/17051227-large-group-invite.test:2,S" ) with open(fixture_path, "r") as f: raw_message = f.read() envelope = { "from": {"addr": "product.dev@example.com"}, "subject": "Project Kickoff Meeting", } compressed, event = compress_invite(raw_message, envelope) assert event is not None assert "Project Kickoff Meeting" in compressed