diff --git a/CHANGELOG.md b/CHANGELOG.md index 12b6f76..22fb1ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.11.1] - 2025-01-31 +### Added +- Derived type declarations on `SuggestionBase` + ## [2.11.0] - 2025-01-10 ### Added - Context.MessageId on RichMessages supporting WhatsApp for referencing a previous message diff --git a/CM.Text.Tests/SuggestionsTests.cs b/CM.Text.Tests/SuggestionsTests.cs new file mode 100644 index 0000000..a22c3ea --- /dev/null +++ b/CM.Text.Tests/SuggestionsTests.cs @@ -0,0 +1,123 @@ +using System.Text.Json; +using CM.Text.BusinessMessaging.Model.MultiChannel; +using FluentAssertions; + +namespace CM.Text.Tests +{ + [TestClass] + public class SuggestionsTests + { + [TestMethod] + public void SerializationCalendarSuggestionTest() + { + var calenderSuggestion = new CalendarSuggestion() + { + Calendar = new CalendarOptions() + { + Title = "Appointment selection", + Description = "Schedule an appointment with us", + EndTime = DateTime.UtcNow, + StartTime = DateTime.UtcNow, + } + }; + + var serialized= JsonSerializer.Serialize(calenderSuggestion); + + serialized.Should().NotBeNullOrWhiteSpace(); + + var deserialized = JsonSerializer.Deserialize(serialized); + + deserialized.Should().BeOfType(); + var deserializedCalendarSuggestion = deserialized as CalendarSuggestion; + deserializedCalendarSuggestion.Should().BeEquivalentTo(calenderSuggestion); + } + + [TestMethod] + public void SerializationDialSuggestionTest() + { + var dialSuggestion = new DialSuggestion() + { + Dial = new Dial() + { + PhoneNumber = "0031612345678" + } + }; + + var serialized= JsonSerializer.Serialize(dialSuggestion); + + serialized.Should().NotBeNullOrWhiteSpace(); + + var deserialized = JsonSerializer.Deserialize(serialized); + + deserialized.Should().BeOfType(); + var deserializedDialSuggestion = deserialized as DialSuggestion; + deserializedDialSuggestion.Should().BeEquivalentTo(dialSuggestion); + } + + [TestMethod] + public void SerializationOpenUrlSuggestionTest() + { + var openUrlSuggestion = new OpenUrlSuggestion() + { + Url = "https://www.cm.com" + }; + + var serialized= JsonSerializer.Serialize(openUrlSuggestion); + + serialized.Should().NotBeNullOrWhiteSpace(); + + var deserialized = JsonSerializer.Deserialize(serialized); + + deserialized.Should().BeOfType(); + var deserializedOpenUrlSuggestion = deserialized as OpenUrlSuggestion; + deserializedOpenUrlSuggestion.Should().BeEquivalentTo(openUrlSuggestion); + } + + [TestMethod] + public void SerializationViewLocationSuggestionTest() + { + var viewLocationSuggestion = new ViewLocationSuggestion() + { + Location = new ViewLocationOptions() + { + Label = "CM.com headquarters", + Latitude = "51.602885", + Longitude = "4.7683932", + SearchQuery = "CM.com headquarters", + Radius = 5 + } + }; + + var serialized= JsonSerializer.Serialize(viewLocationSuggestion); + + serialized.Should().NotBeNullOrWhiteSpace(); + + var deserialized = JsonSerializer.Deserialize(serialized); + + deserialized.Should().BeOfType(); + var deserializedViewLocationSuggestion = deserialized as ViewLocationSuggestion; + deserializedViewLocationSuggestion.Should().BeEquivalentTo(viewLocationSuggestion); + } + + [TestMethod] + public void SerializationReplySuggestionTest() + { + var replySuggestion = new ReplySuggestion() + { + Label = "Some label", + PostbackData = "LABEL", + Description = "Description of the label", + Media = new MediaContent("Test image", "https://example.com", "image/jpg") + }; + var serialized= JsonSerializer.Serialize(replySuggestion); + + serialized.Should().NotBeNullOrWhiteSpace(); + + var deserialized = JsonSerializer.Deserialize(serialized); + + deserialized.Should().BeOfType(); + var deserializedReplySuggestion = deserialized as ReplySuggestion; + deserializedReplySuggestion.Should().BeEquivalentTo(replySuggestion); + } + } +} diff --git a/CM.Text/BusinessMessaging/Model/MultiChannel/CalendarOptions.cs b/CM.Text/BusinessMessaging/Model/MultiChannel/CalendarOptions.cs index 0e7744f..7122d14 100644 --- a/CM.Text/BusinessMessaging/Model/MultiChannel/CalendarOptions.cs +++ b/CM.Text/BusinessMessaging/Model/MultiChannel/CalendarOptions.cs @@ -13,12 +13,14 @@ public class CalendarOptions /// /// The end of the appointment. /// - [JsonPropertyName("endTime")] public DateTime EndTime; + [JsonPropertyName("endTime")] + public DateTime EndTime { get; set; } /// /// The start of the appointment. /// - [JsonPropertyName("startTime")] public DateTime StartTime; + [JsonPropertyName("startTime")] + public DateTime StartTime { get; set; } /// /// The description which will appear in the calendar app diff --git a/CM.Text/BusinessMessaging/Model/MultiChannel/CalendarSuggestion.cs b/CM.Text/BusinessMessaging/Model/MultiChannel/CalendarSuggestion.cs index c8768b2..2a52e55 100644 --- a/CM.Text/BusinessMessaging/Model/MultiChannel/CalendarSuggestion.cs +++ b/CM.Text/BusinessMessaging/Model/MultiChannel/CalendarSuggestion.cs @@ -11,12 +11,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel [PublicAPI] public class CalendarSuggestion : SuggestionBase { - /// - /// The action of this suggestion - /// - [JsonPropertyName("action")] - public override string Action => "CreateCalendarEvent"; - /// /// The options of the agenda item /// diff --git a/CM.Text/BusinessMessaging/Model/MultiChannel/DialSuggestion.cs b/CM.Text/BusinessMessaging/Model/MultiChannel/DialSuggestion.cs index 2508ae3..13c6894 100644 --- a/CM.Text/BusinessMessaging/Model/MultiChannel/DialSuggestion.cs +++ b/CM.Text/BusinessMessaging/Model/MultiChannel/DialSuggestion.cs @@ -11,12 +11,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel [PublicAPI] public class DialSuggestion : SuggestionBase { - /// - /// The action of this suggestion - /// - [JsonPropertyName("action")] - public override string Action => "Dial"; - /// /// The dial options /// diff --git a/CM.Text/BusinessMessaging/Model/MultiChannel/OpenUrlSuggestion.cs b/CM.Text/BusinessMessaging/Model/MultiChannel/OpenUrlSuggestion.cs index 267dd0a..66faff6 100644 --- a/CM.Text/BusinessMessaging/Model/MultiChannel/OpenUrlSuggestion.cs +++ b/CM.Text/BusinessMessaging/Model/MultiChannel/OpenUrlSuggestion.cs @@ -13,12 +13,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel [PublicAPI] public class OpenUrlSuggestion : SuggestionBase { - /// - /// The action of this suggestion - /// - [JsonPropertyName("action")] - public override string Action => "openUrl"; - /// /// The url the end user can open /// diff --git a/CM.Text/BusinessMessaging/Model/MultiChannel/ReplySuggestion.cs b/CM.Text/BusinessMessaging/Model/MultiChannel/ReplySuggestion.cs index d101b5f..2a1946e 100644 --- a/CM.Text/BusinessMessaging/Model/MultiChannel/ReplySuggestion.cs +++ b/CM.Text/BusinessMessaging/Model/MultiChannel/ReplySuggestion.cs @@ -9,12 +9,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel [PublicAPI] public class ReplySuggestion : SuggestionBase { - /// - /// The action of this suggestion - /// - [JsonPropertyName("action")] - public override string Action => "reply"; - /// /// Description of the Reply suggestion /// diff --git a/CM.Text/BusinessMessaging/Model/MultiChannel/SuggestionBase.cs b/CM.Text/BusinessMessaging/Model/MultiChannel/SuggestionBase.cs index 865d015..df675ec 100644 --- a/CM.Text/BusinessMessaging/Model/MultiChannel/SuggestionBase.cs +++ b/CM.Text/BusinessMessaging/Model/MultiChannel/SuggestionBase.cs @@ -6,16 +6,18 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel /// /// Suggestions can be used in several channels, not all channels /// support all suggestions. + /// + /// Requires a json derived type for serialization to work /// [PublicAPI] + [JsonPolymorphic(TypeDiscriminatorPropertyName = "action")] + [JsonDerivedType(typeof(CalendarSuggestion), "CreateCalendarEvent")] + [JsonDerivedType(typeof(DialSuggestion), "Dial")] + [JsonDerivedType(typeof(OpenUrlSuggestion), "openUrl")] + [JsonDerivedType(typeof(ReplySuggestion), "reply")] + [JsonDerivedType(typeof(ViewLocationSuggestion), "viewLocation")] public abstract class SuggestionBase { - /// - /// The action of this suggestion - /// - [JsonPropertyName("action")] - public virtual string Action { get; } - /// /// The text the end user will see /// diff --git a/CM.Text/BusinessMessaging/Model/MultiChannel/ViewLocationSuggestion.cs b/CM.Text/BusinessMessaging/Model/MultiChannel/ViewLocationSuggestion.cs index df20cf5..e9d988d 100644 --- a/CM.Text/BusinessMessaging/Model/MultiChannel/ViewLocationSuggestion.cs +++ b/CM.Text/BusinessMessaging/Model/MultiChannel/ViewLocationSuggestion.cs @@ -9,12 +9,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel [PublicAPI] public class ViewLocationSuggestion : SuggestionBase { - /// - /// The action of this suggestion - /// - [JsonPropertyName("action")] - public override string Action => "viewLocation"; - /// /// The location options /// diff --git a/CM.Text/CM.Text.csproj b/CM.Text/CM.Text.csproj index f8d9970..a96c07e 100644 --- a/CM.Text/CM.Text.csproj +++ b/CM.Text/CM.Text.csproj @@ -13,12 +13,12 @@ LICENSE icon.png $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/../CHANGELOG.md")) - 2.11.0 + 2.11.1 https://github.com/cmdotcom/text-sdk-dotnet en true - 2.11.0 - 2.11.0 + 2.11.1 + 2.11.1 True