Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions Ical.Net.Tests/CalendarPropertiesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,68 @@ public void AddPropertyShouldNotIncludePropertyNameInValue()
}

[Test]
[Ignore("Calendar properties aren't being properly serialized")]
public void PropertySerialization_Tests()
public void PropertySerialization()
{
const string formatted =
@"FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 3.2//EN"">\n<HTML>\n<HEAD>\n<META NAME=""Generator"" CONTENT=""MS Exchange Server version rmj.rmm.rup.rpr"">\n<TITLE></TITLE>\n</HEAD>\n<BODY>\n<!-- Converted from text/rtf format -->\n\n<P DIR=LTR><SPAN LANG=""en-us""><FONT FACE=""Calibri"">This is some</FONT></SPAN><SPAN LANG=""en-us""><B> <FONT FACE=""Calibri"">HTML</FONT></B></SPAN><SPAN LANG=""en-us""><FONT FACE=""Calibri""></FONT></SPAN><SPAN LANG=""en-us""><U> <FONT FACE=""Calibri"">formatted</FONT></U></SPAN><SPAN LANG=""en-us""><FONT FACE=""Calibri""></FONT></SPAN><SPAN LANG=""en-us""><I> <FONT FACE=""Calibri"">text</FONT></I></SPAN><SPAN LANG=""en-us""><FONT FACE=""Calibri"">.</FONT></SPAN><SPAN LANG=""en-us""></SPAN></P>\n\n</BODY>\n</HTML>";

var start = DateTime.Now;
const string propValue =
"""<html><body>BodyText</body></html>""";
var start = DateTime.UtcNow;
var end = start.AddHours(1);
var @event = new CalendarEvent
{
Start = new CalDateTime(start),
End = new CalDateTime(end),
Description = "This is a description",
};
var property = new CalendarProperty("X-ALT-DESC", formatted);
var property = new CalendarProperty("X-ALT-DESC", propValue);
// Parameters most not be part of the value
property.Parameters.Add("FMTTYPE", "text/html");
var property2 = new CalendarProperty("ATTENDEE", "mailto:[email protected]");
property2.Parameters.Add("MEMBER", "mailto:[email protected],mailto:[email protected]");
@event.Properties.Add(property2);
@event.AddProperty(property);
var calendar = new Calendar();
calendar.Events.Add(@event);

var serialized = new CalendarSerializer().SerializeToString(calendar);
Assert.That(serialized, Does.Contain("X-ALT-DESC;"));
Assert.That(serialized, Does.Contain($"X-ALT-DESC;FMTTYPE=text/html:{propValue}"),
"Parameter and value should get serialized standard compliant");
}

[Test]
public void PropertyDeserialization()
{
var ics = """
BEGIN:VCALENDAR
PRODID:-//github.com/ical-org/ical.net//NONSGML ical.net 5.0.0.0//EN
VERSION:2.0
BEGIN:VEVENT
DESCRIPTION:This is a description
DTEND:20250518T145922Z
DTSTAMP:20250518T135922Z
DTSTART:20250518T135922Z
SEQUENCE:0
UID:8f7aa9fc-e9d7-4276-8bf6-915dfe168f0d
X-ALT-DESC;FMTTYPE=text/html:<html><body>BodyText</body></html>
X-PROJECTS;PROP=name;PRIO=high:ProjectA,ProjectB
END:VEVENT
END:VCALENDAR
""";
var calendar = Calendar.Load(ics)!;
var calEvent = calendar.Events.First();
var propDescription = calEvent.Properties.FirstOrDefault(x => x.Name == "X-ALT-DESC")!;
var propProjects = calEvent.Properties.FirstOrDefault(x => x.Name == "X-PROJECTS")!;

Assert.Multiple(() =>
{
Assert.That(propDescription.Parameters, Has.Count.EqualTo(1));
Assert.That(propDescription.Value, Is.EqualTo("<html><body>BodyText</body></html>"));
Assert.That(propDescription.Parameters.FirstOrDefault(p => p.Name == "FMTTYPE")!.Value, Is.EqualTo("text/html"));

Assert.That(propProjects.Parameters, Has.Count.EqualTo(2), "Parameter list should have 2 elements");
Assert.That(propProjects.Value, Is.EqualTo("ProjectA,ProjectB"));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should propProject.Values be a list containing ProjectA and ProjectB as elements?

Assert.That(propProjects.Parameters.FirstOrDefault(p => p.Name == "PROP")!.Value!.ToString(), Is.EqualTo("name"));
Assert.That(propProjects.Parameters.FirstOrDefault(p => p.Name == "PRIO")!.Value!.ToString(), Is.EqualTo("high"));
});
}

[Test]
Expand Down
42 changes: 22 additions & 20 deletions Ical.Net.Tests/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public void SerializeDeserialize()
cal1.Events.Add(evt);

var serializer = new CalendarSerializer();
var serializedCalendar = serializer.SerializeToString(cal1);
var serializedCalendar = serializer.SerializeToString(cal1)!;
var cal2 = Calendar.Load(serializedCalendar);
CompareCalendars(cal1, cal2);
}
Expand All @@ -240,24 +240,23 @@ public void EventPropertiesSerialized()
var evt = new CalendarEvent
{
Class = "PRIVATE",
Created = new CalDateTime(2010, 3, 25, 12, 53, 35),
DtStamp = new CalDateTime(2010, 3, 25, 12, 53, 35),
LastModified = new CalDateTime(2010, 3, 27, 13, 53, 35),
Created = new CalDateTime(2025, 3, 25, 12, 53, 35),
DtStamp = new CalDateTime(2025, 3, 25, 12, 53, 35),
LastModified = new CalDateTime(2025, 3, 27, 13, 53, 35),
Sequence = 0,
Uid = "42f58d4f-847e-46f8-9f4a-ce52697682cf",
Priority = 5,
Location = "here",
Summary = "test",
DtStart = new CalDateTime(2012, 3, 25, 12, 50, 00),
DtEnd = new CalDateTime(2012, 3, 25, 13, 10, 00)
//not yet testing property below as serialized output currently does not comply with RTFC 2445
//Transparency = TransparencyType.Opaque,
//Status = EventStatus.Confirmed
DtStart = new CalDateTime(2025, 3, 25, 12, 50, 00),
DtEnd = new CalDateTime(2025, 3, 25, 13, 10, 00),
Transparency = TransparencyType.Opaque,
Status = EventStatus.Confirmed
};
cal.Events.Add(evt);

var serializer = new CalendarSerializer();
var serializedCalendar = serializer.SerializeToString(cal);
var serializedCalendar = serializer.SerializeToString(cal)!;

Assert.Multiple(() =>
{
Expand All @@ -269,18 +268,21 @@ public void EventPropertiesSerialized()

foreach (var p in expectProperties)
{
Assert.That(serializedCalendar, Does.Contain(SerializationConstants.LineBreak + p + SerializationConstants.LineBreak), "expected '" + p + "' not found");
Assert.That(serializedCalendar,
Does.Contain(SerializationConstants.LineBreak + p + SerializationConstants.LineBreak),
"expected '" + p + "' not found");
}

InspectSerializedSection(serializedCalendar, "VEVENT",
new[]
{
"CLASS:" + evt.Class, "CREATED:" + CalDateString(evt.Created), "DTSTAMP:" + CalDateString(evt.DtStamp),
"LAST-MODIFIED:" + CalDateString(evt.LastModified), "SEQUENCE:" + evt.Sequence, "UID:" + evt.Uid, "PRIORITY:" + evt.Priority,
"LOCATION:" + evt.Location, "SUMMARY:" + evt.Summary, "DTSTART:" + CalDateString(evt.DtStart), "DTEND:" + CalDateString(evt.DtEnd)
//"TRANSPARENCY:" + TransparencyType.Opaque.ToString().ToUpperInvariant(),
//"STATUS:" + EventStatus.Confirmed.ToString().ToUpperInvariant()
});
[
"CLASS:" + evt.Class, "CREATED:" + CalDateString(evt.Created), "DTSTAMP:" + CalDateString(evt.DtStamp),
"LAST-MODIFIED:" + CalDateString(evt.LastModified), "SEQUENCE:" + evt.Sequence, "UID:" + evt.Uid,
"PRIORITY:" + evt.Priority,
"LOCATION:" + evt.Location, "SUMMARY:" + evt.Summary, "DTSTART:" + CalDateString(evt.DtStart),
"DTEND:" + CalDateString(evt.DtEnd),
"TRANSP:" + TransparencyType.Opaque.ToUpperInvariant(),
"STATUS:" + EventStatus.Confirmed.ToUpperInvariant()
]);
}

private static readonly IList<Attendee> _attendees = new List<Attendee>
Expand Down Expand Up @@ -352,7 +354,7 @@ public void AttendeesSerialized()
public void ZeroDuration_Test()
{
var result = new DurationSerializer().SerializeToString(Duration.Zero);
Assert.That("P0D".Equals(result, StringComparison.Ordinal), Is.True);
Assert.That(result, Is.EqualTo("P0D"));
}

[Test]
Expand Down
2 changes: 1 addition & 1 deletion Ical.Net/CalendarComponents/CalendarComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ public virtual void AddProperty(string name, string value)
public virtual void AddProperty(ICalendarProperty p)
{
p.Parent = this;
Properties.Set(p.Name, p.Value);
Properties.Add(p);
}
}
Loading