Skip to content

Commit 1369f16

Browse files
Receipt sending implemented
1 parent 84ea2b8 commit 1369f16

File tree

14 files changed

+394
-47
lines changed

14 files changed

+394
-47
lines changed

TransactionProcessor.BusinessLogic.Tests/DomainEventHandlers/TransactionDomainEventHandlerTests.cs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using BusinessLogic.Services;
99
using EstateManagement.Client;
1010
using EventHandling;
11+
using MessagingService.Client;
1112
using Microsoft.Extensions.Configuration;
1213
using Moq;
1314
using SecurityService.Client;
@@ -39,6 +40,8 @@ public async Task TransactionDomainEventHandler_Handle_TransactionHasBeenComplet
3940
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
4041
securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);
4142

43+
Mock<ITransactionReceiptBuilder> transactionReceiptBulder = new Mock<ITransactionReceiptBuilder>();
44+
Mock<IMessagingServiceClient> messagingServiceClient = new Mock<IMessagingServiceClient>();
4245

4346
IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
4447
ConfigurationReader.Initialise(configurationRoot);
@@ -47,7 +50,9 @@ public async Task TransactionDomainEventHandler_Handle_TransactionHasBeenComplet
4750
TransactionDomainEventHandler transactionDomainEventHandler = new TransactionDomainEventHandler(transactionAggregateManager.Object,
4851
feeCalculationManager.Object,
4952
estateClient.Object,
50-
securityServiceClient.Object);
53+
securityServiceClient.Object,
54+
transactionReceiptBulder.Object,
55+
messagingServiceClient.Object);
5156

5257
await transactionDomainEventHandler.Handle(TestData.TransactionHasBeenCompletedEvent, CancellationToken.None);
5358
}
@@ -63,14 +68,19 @@ public async Task TransactionDomainEventHandler_Handle_TransactionHasBeenComplet
6368

6469
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
6570

71+
Mock<ITransactionReceiptBuilder> transactionReceiptBulder = new Mock<ITransactionReceiptBuilder>();
72+
Mock<IMessagingServiceClient> messagingServiceClient = new Mock<IMessagingServiceClient>();
73+
6674
IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
6775
ConfigurationReader.Initialise(configurationRoot);
6876
Logger.Initialise(NullLogger.Instance);
6977

7078
TransactionDomainEventHandler transactionDomainEventHandler = new TransactionDomainEventHandler(transactionAggregateManager.Object,
7179
feeCalculationManager.Object,
7280
estateClient.Object,
73-
securityServiceClient.Object);
81+
securityServiceClient.Object,
82+
transactionReceiptBulder.Object,
83+
messagingServiceClient.Object);
7484

7585
await transactionDomainEventHandler.Handle(TestData.TransactionHasBeenCompletedEvent, CancellationToken.None);
7686
}
@@ -86,14 +96,19 @@ public async Task TransactionDomainEventHandler_Handle_TransactionHasBeenComplet
8696

8797
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
8898

99+
Mock<ITransactionReceiptBuilder> transactionReceiptBulder = new Mock<ITransactionReceiptBuilder>();
100+
Mock<IMessagingServiceClient> messagingServiceClient = new Mock<IMessagingServiceClient>();
101+
89102
IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
90103
ConfigurationReader.Initialise(configurationRoot);
91104
Logger.Initialise(NullLogger.Instance);
92105

93106
TransactionDomainEventHandler transactionDomainEventHandler = new TransactionDomainEventHandler(transactionAggregateManager.Object,
94107
feeCalculationManager.Object,
95108
estateClient.Object,
96-
securityServiceClient.Object);
109+
securityServiceClient.Object,
110+
transactionReceiptBulder.Object,
111+
messagingServiceClient.Object);
97112

98113
await transactionDomainEventHandler.Handle(TestData.TransactionHasBeenCompletedEvent, CancellationToken.None);
99114
}
@@ -109,14 +124,19 @@ public async Task TransactionDomainEventHandler_Handle_TransactionHasBeenComplet
109124

110125
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
111126

127+
Mock<ITransactionReceiptBuilder> transactionReceiptBulder = new Mock<ITransactionReceiptBuilder>();
128+
Mock<IMessagingServiceClient> messagingServiceClient = new Mock<IMessagingServiceClient>();
129+
112130
IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
113131
ConfigurationReader.Initialise(configurationRoot);
114132
Logger.Initialise(NullLogger.Instance);
115133

116134
TransactionDomainEventHandler transactionDomainEventHandler = new TransactionDomainEventHandler(transactionAggregateManager.Object,
117135
feeCalculationManager.Object,
118136
estateClient.Object,
119-
securityServiceClient.Object);
137+
securityServiceClient.Object,
138+
transactionReceiptBulder.Object,
139+
messagingServiceClient.Object);
120140

121141
await transactionDomainEventHandler.Handle(TestData.TransactionHasBeenCompletedEvent, CancellationToken.None);
122142
}
@@ -132,16 +152,50 @@ public async Task TransactionDomainEventHandler_Handle_TransactionHasBeenComplet
132152

133153
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
134154

155+
Mock<ITransactionReceiptBuilder> transactionReceiptBulder = new Mock<ITransactionReceiptBuilder>();
156+
Mock<IMessagingServiceClient> messagingServiceClient = new Mock<IMessagingServiceClient>();
157+
135158
IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
136159
ConfigurationReader.Initialise(configurationRoot);
137160
Logger.Initialise(NullLogger.Instance);
138161

139162
TransactionDomainEventHandler transactionDomainEventHandler = new TransactionDomainEventHandler(transactionAggregateManager.Object,
140163
feeCalculationManager.Object,
141164
estateClient.Object,
142-
securityServiceClient.Object);
165+
securityServiceClient.Object,
166+
transactionReceiptBulder.Object,
167+
messagingServiceClient.Object);
143168

144169
await transactionDomainEventHandler.Handle(TestData.TransactionHasBeenCompletedEvent, CancellationToken.None);
145170
}
171+
172+
[Fact]
173+
public async Task TransactionDomainEventHandler_Handle_CustomerEmailReceiptRequestedEvent_EventIsHandled()
174+
{
175+
Mock<ITransactionAggregateManager> transactionAggregateManager = new Mock<ITransactionAggregateManager>();
176+
transactionAggregateManager.Setup(t => t.GetAggregate(It.IsAny<Guid>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
177+
.ReturnsAsync(TestData.GetCompletedAuthorisedSaleTransactionAggregate);
178+
Mock<IFeeCalculationManager> feeCalculationManager = new Mock<IFeeCalculationManager>();
179+
Mock<IEstateClient> estateClient = new Mock<IEstateClient>();
180+
181+
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
182+
securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);
183+
184+
Mock<ITransactionReceiptBuilder> transactionReceiptBulder = new Mock<ITransactionReceiptBuilder>();
185+
Mock<IMessagingServiceClient> messagingServiceClient = new Mock<IMessagingServiceClient>();
186+
187+
IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build();
188+
ConfigurationReader.Initialise(configurationRoot);
189+
Logger.Initialise(NullLogger.Instance);
190+
191+
TransactionDomainEventHandler transactionDomainEventHandler = new TransactionDomainEventHandler(transactionAggregateManager.Object,
192+
feeCalculationManager.Object,
193+
estateClient.Object,
194+
securityServiceClient.Object,
195+
transactionReceiptBulder.Object,
196+
messagingServiceClient.Object);
197+
198+
await transactionDomainEventHandler.Handle(TestData.CustomerEmailReceiptRequestedEvent, CancellationToken.None);
199+
}
146200
}
147201
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace TransactionProcessor.BusinessLogic.Tests.Services
6+
{
7+
using System.IO;
8+
using System.IO.Abstractions;
9+
using System.IO.Abstractions.TestingHelpers;
10+
using System.Reflection;
11+
using System.Threading;
12+
using System.Threading.Tasks;
13+
using BusinessLogic.Services;
14+
using EstateManagement.DataTransferObjects.Responses;
15+
using Models;
16+
using Shouldly;
17+
using Xunit;
18+
19+
public class TransactionReceiptBuilderTests
20+
{
21+
[Fact]
22+
public async Task TransactionReceiptBuilder_GetEmailReceiptMessage_MessageBuilt()
23+
{
24+
Transaction transaction = new Transaction
25+
{
26+
OperatorIdentifier = "Safaricom",
27+
TransactionNumber = "12345"
28+
};
29+
30+
var path = Directory.GetParent(Assembly.GetExecutingAssembly().Location);
31+
32+
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
33+
{
34+
{ $"{path}\\Receipts\\Email\\{transaction.OperatorIdentifier}\\TransactionAuthorised.html", new MockFileData("Transaction Number: [TransactionNumber]") }
35+
});
36+
37+
TransactionReceiptBuilder receiptBuilder = new TransactionReceiptBuilder(fileSystem);
38+
39+
String receiptMessage = await receiptBuilder.GetEmailReceiptMessage(transaction, new MerchantResponse(), CancellationToken.None);
40+
41+
receiptMessage.ShouldBe("Transaction Number: 12345");
42+
43+
44+
}
45+
}
46+
}

TransactionProcessor.BusinessLogic.Tests/TransactionProcessor.BusinessLogic.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
1111
<PackageReference Include="Moq" Version="4.14.4" />
1212
<PackageReference Include="Shouldly" Version="3.0.2" />
13+
<PackageReference Include="System.IO.Abstractions.TestingHelpers" Version="12.2.2" />
1314
<PackageReference Include="xunit" Version="2.4.1" />
1415
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.2">
1516
<PrivateAssets>all</PrivateAssets>

TransactionProcessor.BusinessLogic/EventHandling/TransactionDomainEventHandler.cs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using EstateManagement.DataTransferObjects.Responses;
1010
using Manager;
1111
using MessagingService.BusinessLogic.EventHandling;
12+
using MessagingService.Client;
13+
using MessagingService.DataTransferObjects;
1214
using Models;
1315
using SecurityService.Client;
1416
using SecurityService.DataTransferObjects.Responses;
@@ -44,6 +46,8 @@ public class TransactionDomainEventHandler : IDomainEventHandler
4446

4547
private readonly ITransactionReceiptBuilder TransactionReceiptBuilder;
4648

49+
private readonly IMessagingServiceClient MessagingServiceClient;
50+
4751
/// <summary>
4852
/// The token response
4953
/// </summary>
@@ -66,17 +70,20 @@ public class TransactionDomainEventHandler : IDomainEventHandler
6670
/// <param name="estateClient">The estate client.</param>
6771
/// <param name="securityServiceClient">The security service client.</param>
6872
/// <param name="transactionReceiptBuilder">The transaction receipt builder.</param>
73+
/// <param name="messagingServiceClient">The messaging service client.</param>
6974
public TransactionDomainEventHandler(ITransactionAggregateManager transactionAggregateManager,
7075
IFeeCalculationManager feeCalculationManager,
7176
IEstateClient estateClient,
7277
ISecurityServiceClient securityServiceClient,
73-
ITransactionReceiptBuilder transactionReceiptBuilder)
78+
ITransactionReceiptBuilder transactionReceiptBuilder,
79+
IMessagingServiceClient messagingServiceClient)
7480
{
7581
this.TransactionAggregateManager = transactionAggregateManager;
7682
this.FeeCalculationManager = feeCalculationManager;
7783
this.EstateClient = estateClient;
7884
this.SecurityServiceClient = securityServiceClient;
7985
this.TransactionReceiptBuilder = transactionReceiptBuilder;
86+
this.MessagingServiceClient = messagingServiceClient;
8087
}
8188

8289
#endregion
@@ -184,26 +191,60 @@ private async Task HandleSpecificDomainEvent(TransactionHasBeenCompletedEvent do
184191
}
185192
}
186193

194+
/// <summary>
195+
/// Handles the specific domain event.
196+
/// </summary>
197+
/// <param name="domainEvent">The domain event.</param>
198+
/// <param name="cancellationToken">The cancellation token.</param>
187199
private async Task HandleSpecificDomainEvent(CustomerEmailReceiptRequestedEvent domainEvent,
188200
CancellationToken cancellationToken)
189201
{
202+
this.TokenResponse = await this.GetToken(cancellationToken);
203+
190204
TransactionAggregate transactionAggregate = await this.TransactionAggregateManager.GetAggregate(domainEvent.EstateId, domainEvent.TransactionId, cancellationToken);
191205

192-
// TODO: Add DTO method to aggregate
206+
var merchant = await this.EstateClient.GetMerchant(this.TokenResponse.AccessToken, domainEvent.EstateId, domainEvent.MerchantId, cancellationToken);
207+
193208
// Determine the body of the email
194-
var receiptMessage = await this.TransactionReceiptBuilder.GetEmailReceiptMessage(new Transaction(), cancellationToken);
209+
String receiptMessage = await this.TransactionReceiptBuilder.GetEmailReceiptMessage(transactionAggregate.GetTransaction(), merchant, cancellationToken);
195210

196211
// Send the message
197-
await this.SendEmailMessage("Transaction Successful", receiptMessage, domainEvent.CustomerEmailAddress, cancellationToken);
212+
await this.SendEmailMessage(this.TokenResponse.AccessToken, domainEvent.EstateId, "Transaction Successful", receiptMessage, domainEvent.CustomerEmailAddress, cancellationToken);
198213

199214
}
200215

201-
private async Task SendEmailMessage(String subject,
216+
/// <summary>
217+
/// Sends the email message.
218+
/// </summary>
219+
/// <param name="accessToken">The access token.</param>
220+
/// <param name="estateId">The estate identifier.</param>
221+
/// <param name="subject">The subject.</param>
222+
/// <param name="body">The body.</param>
223+
/// <param name="emailAddress">The email address.</param>
224+
/// <param name="cancellationToken">The cancellation token.</param>
225+
private async Task SendEmailMessage(String accessToken,
226+
Guid estateId,
227+
String subject,
202228
String body,
203229
String emailAddress,
204230
CancellationToken cancellationToken)
205231
{
206-
232+
SendEmailRequest sendEmailRequest = new SendEmailRequest
233+
{
234+
Body = body,
235+
ConnectionIdentifier = estateId,
236+
FromAddress = "[email protected]", // TODO: lookup from config
237+
IsHtml = true,
238+
Subject = subject,
239+
ToAddresses = new List<String>
240+
{
241+
emailAddress
242+
}
243+
};
244+
245+
// TODO: may decide to record the message Id againsts the Transaction Aggregate in future, but for now
246+
// we wont do this...
247+
await this.MessagingServiceClient.SendEmail(accessToken, sendEmailRequest, cancellationToken);
207248
}
208249

209250
#endregion

0 commit comments

Comments
 (0)