Skip to content

Commit 2013c5a

Browse files
Merge pull request #191 from TransactionProcessing/bug/#190_missing_command_registrations
Add update message status functionality for email/SMS
2 parents db691b8 + 355a383 commit 2013c5a

File tree

9 files changed

+141
-5
lines changed

9 files changed

+141
-5
lines changed

MessagingService.BusinessLogic.Tests/Mediator/DummyMessagingDomainService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Text;
66
using System.Threading.Tasks;
7+
using MessagingService.BusinessLogic.Requests;
78
using SimpleResults;
89

910
namespace MessagingService.BusinessLogic.Tests.Mediator
@@ -34,5 +35,11 @@ public async Task<Result> ResendEmailMessage(Guid connectionIdentifier,
3435
Guid messageId,
3536
CancellationToken cancellationToken) => Result.Success();
3637
public async Task<Result> ResendSMSMessage(Guid connectionIdentifier, Guid messageId, CancellationToken cancellationToken) => Result.Success();
38+
39+
public async Task<Result> UpdateMessageStatus(EmailCommands.UpdateMessageStatusCommand command,
40+
CancellationToken cancellationToken) => Result.Success();
41+
42+
public async Task<Result> UpdateMessageStatus(SMSCommands.UpdateMessageStatusCommand command,
43+
CancellationToken cancellationToken) => Result.Success();
3744
}
3845
}

MessagingService.BusinessLogic.Tests/Mediator/MediatorTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public MediatorTests() {
2828
this.Requests.Add(TestData.SendSMSCommand);
2929
this.Requests.Add(TestData.ResendSMSCommand);
3030
this.Requests.Add(TestData.SendEmailCommandWithAttachments);
31+
this.Requests.Add(TestData.UpdateEmailMessageStatusCommand);
32+
this.Requests.Add(TestData.UpdateSMSMessageStatusCommand);
3133
}
3234

3335
[Fact]

MessagingService.BusinessLogic.Tests/MessagingService.BusinessLogic.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
5-
<DebugType>Full</DebugType>
5+
<DebugType>None</DebugType>
66
<IsPackable>false</IsPackable>
77
</PropertyGroup>
88

MessagingService.BusinessLogic.Tests/Services/MessagingDomainServiceTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Text;
4+
using MessagingService.BusinessLogic.Requests;
45

56
namespace MessagingService.BusinessLogic.Tests.Services
67
{
@@ -416,6 +417,52 @@ await messagingDomainService.ResendSMSMessage(TestData.ConnectionIdentifier,
416417
CancellationToken.None);
417418
}
418419

420+
[Theory]
421+
[InlineData(BusinessLogic.Services.SMSServices.MessageStatus.Delivered)]
422+
[InlineData(BusinessLogic.Services.SMSServices.MessageStatus.InProgress)]
423+
[InlineData(BusinessLogic.Services.SMSServices.MessageStatus.Expired)]
424+
[InlineData(BusinessLogic.Services.SMSServices.MessageStatus.Rejected)]
425+
[InlineData(BusinessLogic.Services.SMSServices.MessageStatus.Sent)]
426+
[InlineData(BusinessLogic.Services.SMSServices.MessageStatus.Undeliverable)]
427+
[InlineData(BusinessLogic.Services.SMSServices.MessageStatus.Incoming)]
428+
public async Task MessagingDomainService_UpdateSMSMessageStatus_MessageUpdated(BusinessLogic.Services.SMSServices.MessageStatus status)
429+
{
430+
Mock<IAggregateRepository<EmailAggregate, DomainEvent>> emailAggregateRepository = new Mock<IAggregateRepository<EmailAggregate, DomainEvent>>();
431+
Mock<IAggregateRepository<SMSAggregate, DomainEvent>> smsAggregateRepository = new Mock<IAggregateRepository<SMSAggregate, DomainEvent>>();
432+
smsAggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetSentSMSAggregate());
433+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
434+
Mock<ISMSServiceProxy> smsServiceProxy = new Mock<ISMSServiceProxy>();
435+
MessagingDomainService messagingDomainService =
436+
new MessagingDomainService(emailAggregateRepository.Object, smsAggregateRepository.Object, emailServiceProxy.Object, smsServiceProxy.Object);
437+
438+
SMSCommands.UpdateMessageStatusCommand command = new(TestData.MessageId, status, TestData.ProviderStatusDescription, TestData.BouncedDateTime);
439+
Should.NotThrow(async () => {
440+
await messagingDomainService.UpdateMessageStatus(command, CancellationToken.None);
441+
});
442+
}
443+
444+
[Theory]
445+
[InlineData(BusinessLogic.Services.EmailServices.MessageStatus.Delivered)]
446+
[InlineData(BusinessLogic.Services.EmailServices.MessageStatus.Rejected)]
447+
[InlineData(BusinessLogic.Services.EmailServices.MessageStatus.Bounced)]
448+
[InlineData(BusinessLogic.Services.EmailServices.MessageStatus.Failed)]
449+
[InlineData(BusinessLogic.Services.EmailServices.MessageStatus.Spam)]
450+
451+
public async Task MessagingDomainService_UpdateEmailMessageStatus_MessageUpdated(BusinessLogic.Services.EmailServices.MessageStatus status)
452+
{
453+
Mock<IAggregateRepository<EmailAggregate, DomainEvent>> emailAggregateRepository = new Mock<IAggregateRepository<EmailAggregate, DomainEvent>>();
454+
emailAggregateRepository.Setup(a => a.GetLatestVersion(It.IsAny<Guid>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.GetSentEmailAggregate());
455+
Mock<IAggregateRepository<SMSAggregate, DomainEvent>> smsAggregateRepository = new Mock<IAggregateRepository<SMSAggregate, DomainEvent>>();
456+
Mock<IEmailServiceProxy> emailServiceProxy = new Mock<IEmailServiceProxy>();
457+
Mock<ISMSServiceProxy> smsServiceProxy = new Mock<ISMSServiceProxy>();
458+
MessagingDomainService messagingDomainService =
459+
new MessagingDomainService(emailAggregateRepository.Object, smsAggregateRepository.Object, emailServiceProxy.Object, smsServiceProxy.Object);
460+
461+
EmailCommands.UpdateMessageStatusCommand command = new(TestData.MessageId, status, TestData.ProviderStatusDescription, TestData.BouncedDateTime);
462+
Should.NotThrow(async () => {
463+
await messagingDomainService.UpdateMessageStatus(command, CancellationToken.None);
464+
});
465+
}
419466
}
420467

421468
public class DomainServiceHelperTests

MessagingService.BusinessLogic/RequestHandlers/MessagingRequestHandler.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace MessagingService.BusinessLogic.RequestHandlers{
88
using MediatR;
99
using Requests;
1010
using Services;
11+
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
1112
using EmailAttachment = Models.EmailAttachment;
1213
using FileType = Models.FileType;
1314

@@ -18,7 +19,10 @@ namespace MessagingService.BusinessLogic.RequestHandlers{
1819
public class MessagingRequestHandler : IRequestHandler<EmailCommands.SendEmailCommand, Result<Guid>>,
1920
IRequestHandler<SMSCommands.SendSMSCommand, Result<Guid>>,
2021
IRequestHandler<EmailCommands.ResendEmailCommand,Result>,
21-
IRequestHandler<SMSCommands.ResendSMSCommand, Result>{
22+
IRequestHandler<SMSCommands.ResendSMSCommand, Result>,
23+
IRequestHandler<SMSCommands.UpdateMessageStatusCommand, Result>,
24+
IRequestHandler<EmailCommands.UpdateMessageStatusCommand, Result>
25+
{
2226
#region Fields
2327

2428
/// <summary>
@@ -102,5 +106,16 @@ private FileType ConvertFileType(Requests.FileType emailAttachmentFileType){
102106
}
103107

104108
#endregion
109+
110+
public async Task<Result> Handle(SMSCommands.UpdateMessageStatusCommand command,
111+
CancellationToken cancellationToken) {
112+
113+
return await this.MessagingDomainService.UpdateMessageStatus(command,cancellationToken);
114+
}
115+
116+
public async Task<Result> Handle(EmailCommands.UpdateMessageStatusCommand command,
117+
CancellationToken cancellationToken) {
118+
return await this.MessagingDomainService.UpdateMessageStatus(command, cancellationToken);
119+
}
105120
}
106121
}

MessagingService.BusinessLogic/Services/IMessagingDomainService.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using SimpleResults;
1+
using MessagingService.BusinessLogic.Requests;
2+
using SimpleResults;
23

34
namespace MessagingService.BusinessLogic.Services
45
{
@@ -40,6 +41,9 @@ Task<Result> ResendSMSMessage(Guid connectionIdentifier,
4041
Guid messageId,
4142
CancellationToken cancellationToken);
4243

44+
Task<Result> UpdateMessageStatus(EmailCommands.UpdateMessageStatusCommand command, CancellationToken cancellationToken);
45+
Task<Result> UpdateMessageStatus(SMSCommands.UpdateMessageStatusCommand command, CancellationToken cancellationToken);
46+
4347
#endregion
4448
}
4549
}

MessagingService.BusinessLogic/Services/MessagingDomainService.cs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Shared.Results;
1+
using MessagingService.BusinessLogic.Requests;
2+
using Shared.Results;
23
using SimpleResults;
34

45
namespace MessagingService.BusinessLogic.Services
@@ -231,6 +232,59 @@ public async Task<Result> ResendSMSMessage(Guid connectionIdentifier, Guid messa
231232
}, messageId, cancellationToken);
232233
return result;
233234
}
235+
236+
public async Task<Result> UpdateMessageStatus(EmailCommands.UpdateMessageStatusCommand command,
237+
CancellationToken cancellationToken) {
238+
Result result = await ApplyEmailUpdates(async (EmailAggregate emailAggregate) => {
239+
switch (command.Status) {
240+
case EmailServices.MessageStatus.Bounced:
241+
emailAggregate.MarkMessageAsBounced(command.Description, command.Timestamp);
242+
break;
243+
case EmailServices.MessageStatus.Delivered:
244+
emailAggregate.MarkMessageAsDelivered(command.Description, command.Timestamp);
245+
break;
246+
case EmailServices.MessageStatus.Failed:
247+
case EmailServices.MessageStatus.Unknown:
248+
emailAggregate.MarkMessageAsFailed(command.Description, command.Timestamp);
249+
break;
250+
case EmailServices.MessageStatus.Rejected:
251+
emailAggregate.MarkMessageAsRejected(command.Description, command.Timestamp);
252+
break;
253+
case EmailServices.MessageStatus.Spam:
254+
emailAggregate.MarkMessageAsSpam(command.Description, command.Timestamp);
255+
break;
256+
}
257+
258+
return Result.Success();
259+
}, command.MessageId, cancellationToken);
260+
return result;
261+
}
262+
263+
public async Task<Result> UpdateMessageStatus(SMSCommands.UpdateMessageStatusCommand command,
264+
CancellationToken cancellationToken) {
265+
Result result = await ApplySMSUpdates(async (SMSAggregate smsAggregate) => {
266+
267+
switch (command.Status) {
268+
case SMSServices.MessageStatus.Delivered:
269+
case SMSServices.MessageStatus.Sent:
270+
case SMSServices.MessageStatus.InProgress:
271+
smsAggregate.MarkMessageAsDelivered(command.Description, command.Timestamp);
272+
break;
273+
case SMSServices.MessageStatus.Expired:
274+
smsAggregate.MarkMessageAsExpired(command.Description, command.Timestamp);
275+
break;
276+
case SMSServices.MessageStatus.Rejected:
277+
smsAggregate.MarkMessageAsRejected(command.Description, command.Timestamp);
278+
break;
279+
case SMSServices.MessageStatus.Undeliverable:
280+
smsAggregate.MarkMessageAsUndeliverable(command.Description, command.Timestamp);
281+
break;
282+
}
283+
284+
return Result.Success();
285+
}, command.MessageId, cancellationToken);
286+
return result;
287+
}
234288
}
235289

236290
public static class DomainServiceHelper
@@ -259,4 +313,4 @@ public static Result<T> HandleGetAggregateResult<T>(Result<T> result, Guid aggre
259313
}
260314

261315
#endregion
262-
}
316+
}

MessagingService.Testing/TestData.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,11 @@ public class TestData
243243
public static String EmailErrorCode = "404";
244244
public static String EmailError = "NotFound";
245245

246+
public static SMSCommands.UpdateMessageStatusCommand UpdateSMSMessageStatusCommand =>
247+
new (TestData.MessageId, SMSMessageStatusDelivered, TestData.ProviderStatusDescription, TestData.DeliveredDateTime);
248+
public static EmailCommands.UpdateMessageStatusCommand UpdateEmailMessageStatusCommand=>
249+
new (TestData.MessageId, TestData.EmailMessageStatusDelivered, TestData.ProviderStatusDescription, TestData.DeliveredDateTime);
250+
246251
public static EmailCommands.ResendEmailCommand ResendEmailCommand => new EmailCommands.ResendEmailCommand(TestData.ConnectionIdentifier, TestData.MessageId);
247252

248253
public static SMSCommands.ResendSMSCommand ResendSMSCommand => new(TestData.ConnectionIdentifier, TestData.MessageId);

MessagingService/Bootstrapper/MediatorRegistry.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public MediatorRegistry()
2222
this.AddSingleton<IRequestHandler<SMSCommands.SendSMSCommand, Result<Guid>>, MessagingRequestHandler>();
2323
this.AddSingleton<IRequestHandler<EmailCommands.ResendEmailCommand,Result>, MessagingRequestHandler>();
2424
this.AddSingleton<IRequestHandler<SMSCommands.ResendSMSCommand,Result>, MessagingRequestHandler>();
25+
this.AddSingleton<IRequestHandler<SMSCommands.UpdateMessageStatusCommand, Result>, MessagingRequestHandler>();
26+
this.AddSingleton<IRequestHandler<EmailCommands.UpdateMessageStatusCommand, Result>, MessagingRequestHandler>();
2527

2628
this.AddSingleton<Func<String, String>>(container => (serviceName) =>
2729
{

0 commit comments

Comments
 (0)