Skip to content

Commit d6b2d46

Browse files
authored
Merge pull request #78 from Martijnvos/fix/suggestions-missing-derived-types
Add derived types to Suggestions
2 parents 7001c91 + 60d8e6e commit d6b2d46

10 files changed

+142
-41
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2.11.1] - 2025-01-31
8+
### Added
9+
- Derived type declarations on `SuggestionBase`
10+
711
## [2.11.0] - 2025-01-10
812
### Added
913
- Context.MessageId on RichMessages supporting WhatsApp for referencing a previous message

CM.Text.Tests/SuggestionsTests.cs

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System.Text.Json;
2+
using CM.Text.BusinessMessaging.Model.MultiChannel;
3+
using FluentAssertions;
4+
5+
namespace CM.Text.Tests
6+
{
7+
[TestClass]
8+
public class SuggestionsTests
9+
{
10+
[TestMethod]
11+
public void SerializationCalendarSuggestionTest()
12+
{
13+
var calenderSuggestion = new CalendarSuggestion()
14+
{
15+
Calendar = new CalendarOptions()
16+
{
17+
Title = "Appointment selection",
18+
Description = "Schedule an appointment with us",
19+
EndTime = DateTime.UtcNow,
20+
StartTime = DateTime.UtcNow,
21+
}
22+
};
23+
24+
var serialized= JsonSerializer.Serialize<SuggestionBase>(calenderSuggestion);
25+
26+
serialized.Should().NotBeNullOrWhiteSpace();
27+
28+
var deserialized = JsonSerializer.Deserialize<SuggestionBase>(serialized);
29+
30+
deserialized.Should().BeOfType<CalendarSuggestion>();
31+
var deserializedCalendarSuggestion = deserialized as CalendarSuggestion;
32+
deserializedCalendarSuggestion.Should().BeEquivalentTo(calenderSuggestion);
33+
}
34+
35+
[TestMethod]
36+
public void SerializationDialSuggestionTest()
37+
{
38+
var dialSuggestion = new DialSuggestion()
39+
{
40+
Dial = new Dial()
41+
{
42+
PhoneNumber = "0031612345678"
43+
}
44+
};
45+
46+
var serialized= JsonSerializer.Serialize<SuggestionBase>(dialSuggestion);
47+
48+
serialized.Should().NotBeNullOrWhiteSpace();
49+
50+
var deserialized = JsonSerializer.Deserialize<SuggestionBase>(serialized);
51+
52+
deserialized.Should().BeOfType<DialSuggestion>();
53+
var deserializedDialSuggestion = deserialized as DialSuggestion;
54+
deserializedDialSuggestion.Should().BeEquivalentTo(dialSuggestion);
55+
}
56+
57+
[TestMethod]
58+
public void SerializationOpenUrlSuggestionTest()
59+
{
60+
var openUrlSuggestion = new OpenUrlSuggestion()
61+
{
62+
Url = "https://www.cm.com"
63+
};
64+
65+
var serialized= JsonSerializer.Serialize<SuggestionBase>(openUrlSuggestion);
66+
67+
serialized.Should().NotBeNullOrWhiteSpace();
68+
69+
var deserialized = JsonSerializer.Deserialize<SuggestionBase>(serialized);
70+
71+
deserialized.Should().BeOfType<OpenUrlSuggestion>();
72+
var deserializedOpenUrlSuggestion = deserialized as OpenUrlSuggestion;
73+
deserializedOpenUrlSuggestion.Should().BeEquivalentTo(openUrlSuggestion);
74+
}
75+
76+
[TestMethod]
77+
public void SerializationViewLocationSuggestionTest()
78+
{
79+
var viewLocationSuggestion = new ViewLocationSuggestion()
80+
{
81+
Location = new ViewLocationOptions()
82+
{
83+
Label = "CM.com headquarters",
84+
Latitude = "51.602885",
85+
Longitude = "4.7683932",
86+
SearchQuery = "CM.com headquarters",
87+
Radius = 5
88+
}
89+
};
90+
91+
var serialized= JsonSerializer.Serialize<SuggestionBase>(viewLocationSuggestion);
92+
93+
serialized.Should().NotBeNullOrWhiteSpace();
94+
95+
var deserialized = JsonSerializer.Deserialize<SuggestionBase>(serialized);
96+
97+
deserialized.Should().BeOfType<ViewLocationSuggestion>();
98+
var deserializedViewLocationSuggestion = deserialized as ViewLocationSuggestion;
99+
deserializedViewLocationSuggestion.Should().BeEquivalentTo(viewLocationSuggestion);
100+
}
101+
102+
[TestMethod]
103+
public void SerializationReplySuggestionTest()
104+
{
105+
var replySuggestion = new ReplySuggestion()
106+
{
107+
Label = "Some label",
108+
PostbackData = "LABEL",
109+
Description = "Description of the label",
110+
Media = new MediaContent("Test image", "https://example.com", "image/jpg")
111+
};
112+
var serialized= JsonSerializer.Serialize<SuggestionBase>(replySuggestion);
113+
114+
serialized.Should().NotBeNullOrWhiteSpace();
115+
116+
var deserialized = JsonSerializer.Deserialize<SuggestionBase>(serialized);
117+
118+
deserialized.Should().BeOfType<ReplySuggestion>();
119+
var deserializedReplySuggestion = deserialized as ReplySuggestion;
120+
deserializedReplySuggestion.Should().BeEquivalentTo(replySuggestion);
121+
}
122+
}
123+
}

CM.Text/BusinessMessaging/Model/MultiChannel/CalendarOptions.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ public class CalendarOptions
1313
/// <summary>
1414
/// The end of the appointment.
1515
/// </summary>
16-
[JsonPropertyName("endTime")] public DateTime EndTime;
16+
[JsonPropertyName("endTime")]
17+
public DateTime EndTime { get; set; }
1718

1819
/// <summary>
1920
/// The start of the appointment.
2021
/// </summary>
21-
[JsonPropertyName("startTime")] public DateTime StartTime;
22+
[JsonPropertyName("startTime")]
23+
public DateTime StartTime { get; set; }
2224

2325
/// <summary>
2426
/// The description which will appear in the calendar app

CM.Text/BusinessMessaging/Model/MultiChannel/CalendarSuggestion.cs

-6
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel
1111
[PublicAPI]
1212
public class CalendarSuggestion : SuggestionBase
1313
{
14-
/// <summary>
15-
/// The action of this suggestion
16-
/// </summary>
17-
[JsonPropertyName("action")]
18-
public override string Action => "CreateCalendarEvent";
19-
2014
/// <summary>
2115
/// The options of the agenda item
2216
/// </summary>

CM.Text/BusinessMessaging/Model/MultiChannel/DialSuggestion.cs

-6
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel
1111
[PublicAPI]
1212
public class DialSuggestion : SuggestionBase
1313
{
14-
/// <summary>
15-
/// The action of this suggestion
16-
/// </summary>
17-
[JsonPropertyName("action")]
18-
public override string Action => "Dial";
19-
2014
/// <summary>
2115
/// The dial options
2216
/// </summary>

CM.Text/BusinessMessaging/Model/MultiChannel/OpenUrlSuggestion.cs

-6
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel
1313
[PublicAPI]
1414
public class OpenUrlSuggestion : SuggestionBase
1515
{
16-
/// <summary>
17-
/// The action of this suggestion
18-
/// </summary>
19-
[JsonPropertyName("action")]
20-
public override string Action => "openUrl";
21-
2216
/// <summary>
2317
/// The url the end user can open
2418
/// </summary>

CM.Text/BusinessMessaging/Model/MultiChannel/ReplySuggestion.cs

-6
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel
99
[PublicAPI]
1010
public class ReplySuggestion : SuggestionBase
1111
{
12-
/// <summary>
13-
/// The action of this suggestion
14-
/// </summary>
15-
[JsonPropertyName("action")]
16-
public override string Action => "reply";
17-
1812
/// <summary>
1913
/// Description of the Reply suggestion
2014
/// </summary>

CM.Text/BusinessMessaging/Model/MultiChannel/SuggestionBase.cs

+8-6
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel
66
/// <summary>
77
/// Suggestions can be used in several channels, not all channels
88
/// support all suggestions.
9+
///
10+
/// Requires a json derived type for serialization to work
911
/// </summary>
1012
[PublicAPI]
13+
[JsonPolymorphic(TypeDiscriminatorPropertyName = "action")]
14+
[JsonDerivedType(typeof(CalendarSuggestion), "CreateCalendarEvent")]
15+
[JsonDerivedType(typeof(DialSuggestion), "Dial")]
16+
[JsonDerivedType(typeof(OpenUrlSuggestion), "openUrl")]
17+
[JsonDerivedType(typeof(ReplySuggestion), "reply")]
18+
[JsonDerivedType(typeof(ViewLocationSuggestion), "viewLocation")]
1119
public abstract class SuggestionBase
1220
{
13-
/// <summary>
14-
/// The action of this suggestion
15-
/// </summary>
16-
[JsonPropertyName("action")]
17-
public virtual string Action { get; }
18-
1921
/// <summary>
2022
/// The text the end user will see
2123
/// </summary>

CM.Text/BusinessMessaging/Model/MultiChannel/ViewLocationSuggestion.cs

-6
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@ namespace CM.Text.BusinessMessaging.Model.MultiChannel
99
[PublicAPI]
1010
public class ViewLocationSuggestion : SuggestionBase
1111
{
12-
/// <summary>
13-
/// The action of this suggestion
14-
/// </summary>
15-
[JsonPropertyName("action")]
16-
public override string Action => "viewLocation";
17-
1812
/// <summary>
1913
/// The location options
2014
/// </summary>

CM.Text/CM.Text.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
<PackageLicenseFile>LICENSE</PackageLicenseFile>
1414
<PackageIcon>icon.png</PackageIcon>
1515
<PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/../CHANGELOG.md"))</PackageReleaseNotes>
16-
<Version>2.11.0</Version>
16+
<Version>2.11.1</Version>
1717
<PackageProjectUrl>https://github.com/cmdotcom/text-sdk-dotnet</PackageProjectUrl>
1818
<NeutralLanguage>en</NeutralLanguage>
1919
<GenerateDocumentationFile>true</GenerateDocumentationFile>
20-
<AssemblyVersion>2.11.0</AssemblyVersion>
21-
<FileVersion>2.11.0</FileVersion>
20+
<AssemblyVersion>2.11.1</AssemblyVersion>
21+
<FileVersion>2.11.1</FileVersion>
2222
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
2323
</PropertyGroup>
2424

0 commit comments

Comments
 (0)