Skip to content

Commit 4019ab6

Browse files
committed
Merge branch 'release/0.106.0'
2 parents ae876c3 + 4672984 commit 4019ab6

9 files changed

Lines changed: 91 additions & 155 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using Shouldly;
2+
using StrongGrid.Json;
3+
using StrongGrid.Models;
4+
using System;
5+
using System.Text.Json;
6+
using Xunit;
7+
8+
namespace StrongGrid.UnitTests.Models
9+
{
10+
public class SingleSendTests
11+
{
12+
private const string SINGLE_SEND_JSON = @"{
13+
""id"":""5e0555c5-cb50-11ee-a09e-6aa2ee6dcd4d"",
14+
""name"":""StrongGrid Unit Testing: single send"",
15+
""status"":""draft"",
16+
""categories"":[""category1"",""category2""],
17+
""send_at"":null,
18+
""send_to"":{
19+
""list_ids"":[""a21d5383-1f7c-4e7a-bf2e-511467f58e7d""],
20+
""segment_ids"":[],
21+
""all"":false
22+
},
23+
""updated_at"":""2024-02-14T15:47:34Z"",
24+
""created_at"":""2024-02-14T15:47:33Z"",
25+
""email_config"":{
26+
""subject"":""This is the subject"",
27+
""html_content"":""<html><body><b>This is the HTML conytent</b></body></html>"",
28+
""plain_content"":""This is the text content"",
29+
""generate_plain_content"":false,
30+
""editor"":""code"",
31+
""suppression_group_id"":54321,
32+
""custom_unsubscribe_url"":null,
33+
""sender_id"":12345,
34+
""ip_pool"":null
35+
}
36+
}";
37+
38+
[Fact]
39+
public void Parse_processed_JSON()
40+
{
41+
// Arrange
42+
43+
// Act
44+
var result = JsonSerializer.Deserialize<SingleSend>(SINGLE_SEND_JSON, JsonFormatter.DeserializerOptions);
45+
46+
// Assert
47+
result.Categories.ShouldBe(new[] { "category1", "category2" });
48+
result.EmailConfig.HtmlContent.ShouldBe("<html><body><b>This is the HTML conytent</b></body></html>");
49+
result.EmailConfig.IpPool.ShouldBeNull();
50+
result.EmailConfig.Subject.ShouldBe("This is the subject");
51+
result.EmailConfig.TextContent.ShouldBe("This is the text content");
52+
result.EmailConfig.CustomUnsubscribeUrl.ShouldBeNull();
53+
result.EmailConfig.EditorType.ShouldBe(EditorType.Code);
54+
result.EmailConfig.GeneratePlainContent.ShouldBeFalse();
55+
result.EmailConfig.SenderId.ShouldBe(12345);
56+
result.EmailConfig.SuppressionGroupId.ShouldBe(54321);
57+
result.CreatedOn.ShouldBe(new DateTime(2024, 2, 14, 15, 47, 33, DateTimeKind.Utc));
58+
result.Id.ShouldBe("5e0555c5-cb50-11ee-a09e-6aa2ee6dcd4d");
59+
result.Recipients.Lists.ShouldBe(new[] { "a21d5383-1f7c-4e7a-bf2e-511467f58e7d" });
60+
result.Recipients.Segments.ShouldBe(Array.Empty<string>());
61+
result.Name.ShouldBe("StrongGrid Unit Testing: single send");
62+
result.SendOn.ShouldBeNull();
63+
result.Status.ShouldBe(SingleSendStatus.Draft);
64+
result.UpdatedOn.ShouldBe(new DateTime(2024, 2, 14, 15, 47, 34, DateTimeKind.Utc));
65+
}
66+
}
67+
}

Source/StrongGrid/Json/EpochConverter.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@ internal class EpochConverter : BaseJsonConverter<DateTime>
1212
{
1313
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
1414
{
15-
var secondsSinceEpoch = reader.GetInt64();
16-
return secondsSinceEpoch.FromUnixTime();
15+
switch (reader.TokenType)
16+
{
17+
case JsonTokenType.Number:
18+
var secondsSinceEpoch = reader.GetInt64();
19+
return secondsSinceEpoch.FromUnixTime();
20+
default:
21+
throw new Exception($"Unable to convert {reader.TokenType.ToEnumString()} to DateTime");
22+
}
1723
}
1824

1925
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)

Source/StrongGrid/Json/StrongGridJsonSerializerContext.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ namespace StrongGrid.Json
170170
[JsonSerializable(typeof(StrongGrid.Models.SenderReputation))]
171171
[JsonSerializable(typeof(StrongGrid.Models.SingleSend))]
172172
[JsonSerializable(typeof(StrongGrid.Models.SingleSendEmailConfig))]
173-
[JsonSerializable(typeof(StrongGrid.Models.SingleSendSendTo))]
173+
[JsonSerializable(typeof(StrongGrid.Models.SingleSendRecipients))]
174174
[JsonSerializable(typeof(StrongGrid.Models.SingleSendStatus))]
175175
[JsonSerializable(typeof(StrongGrid.Models.SpamCheckingSettings))]
176176
[JsonSerializable(typeof(StrongGrid.Models.SpamCheckSettings))]
@@ -378,7 +378,7 @@ namespace StrongGrid.Json
378378
[JsonSerializable(typeof(StrongGrid.Models.SenderReputation[]))]
379379
[JsonSerializable(typeof(StrongGrid.Models.SingleSend[]))]
380380
[JsonSerializable(typeof(StrongGrid.Models.SingleSendEmailConfig[]))]
381-
[JsonSerializable(typeof(StrongGrid.Models.SingleSendSendTo[]))]
381+
[JsonSerializable(typeof(StrongGrid.Models.SingleSendRecipients[]))]
382382
[JsonSerializable(typeof(StrongGrid.Models.SingleSendStatus[]))]
383383
[JsonSerializable(typeof(StrongGrid.Models.SpamCheckingSettings[]))]
384384
[JsonSerializable(typeof(StrongGrid.Models.SpamCheckSettings[]))]

Source/StrongGrid/Models/SingleSend.cs

Lines changed: 5 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -72,152 +72,15 @@ public class SingleSend
7272
public DateTime? CreatedOn { get; set; }
7373

7474
/// <summary>
75-
/// Gets or sets the subject.
75+
/// Gets or sets the configuration about the email that will be sent to the recipients.
7676
/// </summary>
77-
/// <value>
78-
/// The subject.
79-
/// </value>
80-
[JsonIgnore]
81-
public string Subject
82-
{
83-
get => EmailConfig.Subject;
84-
set => EmailConfig.Subject = value;
85-
}
86-
87-
/// <summary>
88-
/// Gets or sets the HTML content.
89-
/// </summary>
90-
/// <value>
91-
/// The HTML content.
92-
/// </value>
93-
[JsonIgnore]
94-
public string HtmlContent
95-
{
96-
get => EmailConfig.HtmlContent;
97-
set => EmailConfig.HtmlContent = value;
98-
}
99-
100-
/// <summary>
101-
/// Gets or sets the plain text content.
102-
/// </summary>
103-
/// <value>
104-
/// The plain text content.
105-
/// </value>
106-
[JsonIgnore]
107-
public string TextContent
108-
{
109-
get => EmailConfig.TextContent;
110-
set => EmailConfig.TextContent = value;
111-
}
112-
113-
/// <summary>
114-
/// Gets or sets a value indicating whether the plain content should be generated.
115-
/// </summary>
116-
/// <value>
117-
/// The generate_plain_content.
118-
/// </value>
119-
[JsonIgnore]
120-
public bool GeneratePlainContent
121-
{
122-
get => EmailConfig.GeneratePlainContent;
123-
set => EmailConfig.GeneratePlainContent = value;
124-
}
125-
126-
/// <summary>
127-
/// Gets or sets the type of editor used in the UI.
128-
/// </summary>
129-
/// <value>
130-
/// The type of editor.
131-
/// </value>
132-
[JsonIgnore]
133-
public EditorType EditorType
134-
{
135-
get => EmailConfig.EditorType;
136-
set => EmailConfig.EditorType = value;
137-
}
138-
139-
/// <summary>
140-
/// Gets or sets the sender identifier.
141-
/// </summary>
142-
/// <value>
143-
/// The sender identifier.
144-
/// </value>
145-
[JsonIgnore]
146-
public long SenderId
147-
{
148-
get => EmailConfig.SenderId;
149-
set => EmailConfig.SenderId = value;
150-
}
151-
152-
/// <summary>
153-
/// Gets or sets the custom unsubscribe URL.
154-
/// </summary>
155-
/// <value>
156-
/// The custom unsubscribe URL.
157-
/// </value>
158-
[JsonIgnore]
159-
public string CustomUnsubscribeUrl
160-
{
161-
get => EmailConfig.CustomUnsubscribeUrl;
162-
set => EmailConfig.CustomUnsubscribeUrl = value;
163-
}
164-
165-
/// <summary>
166-
/// Gets or sets the suppression group identifier.
167-
/// </summary>
168-
/// <value>
169-
/// The suppression group identifier.
170-
/// </value>
171-
[JsonIgnore]
172-
public long? SuppressionGroupId
173-
{
174-
get => EmailConfig.SuppressionGroupId;
175-
set => EmailConfig.SuppressionGroupId = value;
176-
}
177-
178-
/// <summary>
179-
/// Gets or sets the ip pool.
180-
/// </summary>
181-
/// <value>
182-
/// The ip pool.
183-
/// </value>
184-
[JsonIgnore]
185-
public string IpPool
186-
{
187-
get => EmailConfig.IpPool;
188-
set => EmailConfig.IpPool = value;
189-
}
190-
191-
/// <summary>
192-
/// Gets or sets the lists.
193-
/// </summary>
194-
/// <value>
195-
/// The lists.
196-
/// </value>
197-
[JsonIgnore]
198-
public string[] Lists
199-
{
200-
get => SendTo.Lists;
201-
set => SendTo.Lists = value;
202-
}
77+
[JsonPropertyName("email_config")]
78+
public SingleSendEmailConfig EmailConfig { get; set; }
20379

20480
/// <summary>
205-
/// Gets or sets the segments.
81+
/// Gets or sets the information about who will receive this Single Send.
20682
/// </summary>
207-
/// <value>
208-
/// The segments.
209-
/// </value>
210-
[JsonIgnore]
211-
public string[] Segments
212-
{
213-
get => SendTo.Segments;
214-
set => SendTo.Segments = value;
215-
}
216-
217-
[JsonPropertyName("email_config")]
218-
private SingleSendEmailConfig EmailConfig { get; set; }
219-
22083
[JsonPropertyName("send_to")]
221-
private SingleSendSendTo SendTo { get; set; }
84+
public SingleSendRecipients Recipients { get; set; }
22285
}
22386
}

Source/StrongGrid/Models/SingleSendEmailConfig.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace StrongGrid.Models
55
/// <summary>
66
/// Single Send email config.
77
/// </summary>
8-
internal class SingleSendEmailConfig
8+
public class SingleSendEmailConfig
99
{
1010
/// <summary>
1111
/// Gets or sets the subject.

Source/StrongGrid/Models/SingleSendSendTo.cs renamed to Source/StrongGrid/Models/SingleSendRecipients.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
namespace StrongGrid.Models
44
{
55
/// <summary>
6-
/// Single Send send to.
6+
/// The recipients of a Single Send.
77
/// </summary>
8-
internal class SingleSendSendTo
8+
public class SingleSendRecipients
99
{
1010
/// <summary>
1111
/// Gets or sets the lists.

Source/StrongGrid/Resources/Mail.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ public async Task<string> SendAsync(
150150
foreach (var personalization in personalizationsCopy)
151151
{
152152
// Make sure the arrays are not null otherwise Linq's 'Except' method will throw a ArgumentNull exception (See GH-286).
153-
if (personalization.To == null) personalization.To = Array.Empty<MailAddress>();
154-
if (personalization.Cc == null) personalization.Cc = Array.Empty<MailAddress>();
155-
if (personalization.Bcc == null) personalization.Bcc = Array.Empty<MailAddress>();
153+
personalization.To ??= Array.Empty<MailAddress>();
154+
personalization.Cc ??= Array.Empty<MailAddress>();
155+
personalization.Bcc ??= Array.Empty<MailAddress>();
156156

157157
// Avoid duplicate addresses. This is important because SendGrid does not throw any
158158
// exception when a recipient is duplicated (which gives you the impression the email

build.cake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
#tool dotnet:?package=GitVersion.Tool&version=5.12.0
33
#tool dotnet:?package=coveralls.net&version=4.0.1
44
#tool nuget:https://f.feedz.io/jericho/jericho/nuget/?package=GitReleaseManager&version=0.17.0-collaborators0003
5-
#tool nuget:?package=ReportGenerator&version=5.2.0
6-
#tool nuget:?package=xunit.runner.console&version=2.6.6
5+
#tool nuget:?package=ReportGenerator&version=5.2.1
6+
#tool nuget:?package=xunit.runner.console&version=2.7.0
77
#tool nuget:?package=CodecovUploader&version=0.7.1
88

99
// Install addins.

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "8.0.101",
3+
"version": "8.0.201",
44
"rollForward": "patch",
55
"allowPrerelease": false
66
}

0 commit comments

Comments
 (0)