133 lines
4.4 KiB
C#
133 lines
4.4 KiB
C#
using Socialize.Api.Modules.CalendarIntegrations.Services;
|
|
|
|
namespace Socialize.Tests.CalendarIntegrations;
|
|
|
|
public class IcsCalendarParserTests
|
|
{
|
|
private readonly IcsCalendarParser _parser = new();
|
|
|
|
[Fact]
|
|
public void Parse_preserves_all_day_calendar_dates()
|
|
{
|
|
string ics = """
|
|
BEGIN:VCALENDAR
|
|
BEGIN:VEVENT
|
|
UID:christmas-eve
|
|
SUMMARY:Christmas Eve
|
|
DTSTART;VALUE=DATE:20261224
|
|
DTEND;VALUE=DATE:20261225
|
|
END:VEVENT
|
|
END:VCALENDAR
|
|
""";
|
|
|
|
ParsedCalendarEvent calendarEvent = Assert.Single(_parser.Parse(
|
|
ics,
|
|
new DateOnly(2026, 12, 1),
|
|
new DateOnly(2026, 12, 31)));
|
|
|
|
Assert.True(calendarEvent.IsAllDay);
|
|
Assert.Equal(new DateOnly(2026, 12, 24), calendarEvent.StartDate);
|
|
Assert.Equal(new DateOnly(2026, 12, 25), calendarEvent.EndDate);
|
|
Assert.Null(calendarEvent.StartUtc);
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_keeps_floating_timed_events_as_local_values_without_utc_conversion()
|
|
{
|
|
string ics = """
|
|
BEGIN:VCALENDAR
|
|
BEGIN:VEVENT
|
|
UID:floating
|
|
SUMMARY:Local planning
|
|
DTSTART:20260510T090000
|
|
DTEND:20260510T100000
|
|
END:VEVENT
|
|
END:VCALENDAR
|
|
""";
|
|
|
|
ParsedCalendarEvent calendarEvent = Assert.Single(_parser.Parse(
|
|
ics,
|
|
new DateOnly(2026, 5, 1),
|
|
new DateOnly(2026, 5, 31)));
|
|
|
|
Assert.False(calendarEvent.IsAllDay);
|
|
Assert.True(calendarEvent.IsFloatingTime);
|
|
Assert.Equal(new DateTime(2026, 5, 10, 9, 0, 0), calendarEvent.StartLocalDateTime);
|
|
Assert.Null(calendarEvent.StartUtc);
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_converts_timezone_bearing_timed_events_when_timezone_is_known()
|
|
{
|
|
string ics = """
|
|
BEGIN:VCALENDAR
|
|
BEGIN:VEVENT
|
|
UID:timed
|
|
SUMMARY:Launch
|
|
DTSTART;TZID=America/Toronto:20260510T090000
|
|
DTEND;TZID=America/Toronto:20260510T100000
|
|
END:VEVENT
|
|
END:VCALENDAR
|
|
""";
|
|
|
|
ParsedCalendarEvent calendarEvent = Assert.Single(_parser.Parse(
|
|
ics,
|
|
new DateOnly(2026, 5, 1),
|
|
new DateOnly(2026, 5, 31)));
|
|
|
|
Assert.False(calendarEvent.IsFloatingTime);
|
|
Assert.Equal("America/Toronto", calendarEvent.TimeZoneId);
|
|
Assert.Equal(TimeSpan.Zero, calendarEvent.StartUtc?.Offset);
|
|
Assert.Equal(13, calendarEvent.StartUtc?.Hour);
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_expands_yearly_recurrence_inside_requested_range()
|
|
{
|
|
string ics = """
|
|
BEGIN:VCALENDAR
|
|
BEGIN:VEVENT
|
|
UID:mothers-day
|
|
SUMMARY:Mother's Day
|
|
DTSTART;VALUE=DATE:20240512
|
|
DTEND;VALUE=DATE:20240513
|
|
RRULE:FREQ=YEARLY;COUNT=5
|
|
END:VEVENT
|
|
END:VCALENDAR
|
|
""";
|
|
|
|
IReadOnlyCollection<ParsedCalendarEvent> events = _parser.Parse(
|
|
ics,
|
|
new DateOnly(2026, 1, 1),
|
|
new DateOnly(2027, 12, 31));
|
|
|
|
Assert.Collection(
|
|
events,
|
|
first => Assert.Equal(new DateOnly(2026, 5, 12), first.StartDate),
|
|
second => Assert.Equal(new DateOnly(2027, 5, 12), second.StartDate));
|
|
Assert.All(events, calendarEvent => Assert.Equal("mothers-day", calendarEvent.RecurrenceId));
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_unfolds_folded_text_lines()
|
|
{
|
|
string ics = """
|
|
BEGIN:VCALENDAR
|
|
BEGIN:VEVENT
|
|
UID:folded
|
|
SUMMARY:Long
|
|
title
|
|
DTSTART;VALUE=DATE:20260510
|
|
END:VEVENT
|
|
END:VCALENDAR
|
|
""";
|
|
|
|
ParsedCalendarEvent calendarEvent = Assert.Single(_parser.Parse(
|
|
ics,
|
|
new DateOnly(2026, 5, 1),
|
|
new DateOnly(2026, 5, 31)));
|
|
|
|
Assert.Equal("Longtitle", calendarEvent.Title);
|
|
}
|
|
}
|