Skip to content

Commit 7a953ea

Browse files
Merge pull request #68 from StuartFerguson/task/#67_reconciliationmessage
Added Reconcilitation Message Support
2 parents a61d7e7 + 41b3927 commit 7a953ea

23 files changed

Lines changed: 957 additions & 85 deletions

File tree

TransactionProcessorACL.BusinessLogic.Tests/RequestHandlerTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,30 @@ public async Task ProcessSaleTransactionRequestHandler_Handle_RequestIsHandled()
7373
response.ResponseMessage.ShouldBe(TestData.ResponseMessage);
7474
}
7575

76+
[Fact]
77+
public async Task ProcessReconciliationRequestHandler_Handle_RequestIsHandled()
78+
{
79+
Mock<ITransactionProcessorACLApplicationService> applicationService = new Mock<ITransactionProcessorACLApplicationService>();
80+
applicationService
81+
.Setup(a => a.ProcessReconciliation(It.IsAny<Guid>(),
82+
It.IsAny<Guid>(),
83+
It.IsAny<DateTime>(),
84+
It.IsAny<String>(),
85+
It.IsAny<Int32>(),
86+
It.IsAny<Decimal>(),
87+
It.IsAny<CancellationToken>())).ReturnsAsync(TestData.ProcessReconciliationResponse);
88+
ProcessReconciliationRequestHandler requestHandler = new ProcessReconciliationRequestHandler(applicationService.Object);
89+
90+
ProcessReconciliationRequest request = TestData.ProcessReconciliationRequest;
91+
ProcessReconciliationResponse response = await requestHandler.Handle(request, CancellationToken.None);
92+
93+
response.ShouldNotBeNull();
94+
response.ResponseCode.ShouldBe(TestData.ResponseCode);
95+
response.ResponseMessage.ShouldBe(TestData.ResponseMessage);
96+
response.EstateId.ShouldBe(TestData.EstateId);
97+
response.MerchantId.ShouldBe(TestData.MerchantId);
98+
}
99+
76100
#endregion
77101
}
78102
}

TransactionProcessorACL.BusinessLogic.Tests/RequestTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,24 @@ public void ProcessSaleTransactionRequest_CanBeCreated_IsCreated()
6161
request.ProductId.ShouldBe(TestData.ProductId);
6262
}
6363

64+
[Fact]
65+
public void ProcessReconciliationRequest_CanBeCreated_IsCreated()
66+
{
67+
ProcessReconciliationRequest request = ProcessReconciliationRequest.Create(TestData.EstateId,
68+
TestData.MerchantId,
69+
TestData.TransactionDateTime,
70+
TestData.DeviceIdentifier,
71+
TestData.ReconciliationTransactionCount,
72+
TestData.ReconciliationTransactionValue);
73+
74+
request.EstateId.ShouldBe(TestData.EstateId);
75+
request.MerchantId.ShouldBe(TestData.MerchantId);
76+
request.TransactionDateTime.ShouldBe(TestData.TransactionDateTime);
77+
request.DeviceIdentifier.ShouldBe(TestData.DeviceIdentifier);
78+
request.TransactionCount.ShouldBe(TestData.ReconciliationTransactionCount);
79+
request.TransactionValue.ShouldBe(TestData.ReconciliationTransactionValue);
80+
}
81+
6482
#endregion
6583
}
6684
}

TransactionProcessorACL.BusinessLogic.Tests/TransactionProcessorACLApplicationServiceTests.cs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,5 +276,117 @@ public async Task TransactionProcessorACLApplicationService_ProcessSaleTransacti
276276
saleResponse.ResponseMessage.ShouldBe(TestData.GeneralErrorResponseMessage);
277277
saleResponse.ResponseCode.ShouldBe(TestData.GeneralErrorResponseCode);
278278
}
279+
280+
[Fact]
281+
public async Task TransactionProcessorACLApplicationService_ProcessReconciliation_TransactionIsSuccessful()
282+
{
283+
IConfigurationRoot configuration = this.SetupMemoryConfiguration();
284+
ConfigurationReader.Initialise(configuration);
285+
286+
Mock<ITransactionProcessorClient> transactionProcessorClient = new Mock<ITransactionProcessorClient>();
287+
transactionProcessorClient.Setup(t => t.PerformTransaction(It.IsAny<String>(), It.IsAny<SerialisedMessage>(), It.IsAny<CancellationToken>()))
288+
.ReturnsAsync(TestData.SerialisedMessageResponse);
289+
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
290+
securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);
291+
292+
ITransactionProcessorACLApplicationService applicationService =
293+
new TransactionProcessorACLApplicationService(transactionProcessorClient.Object, securityServiceClient.Object);
294+
295+
ProcessReconciliationResponse reconciliationResponse = await applicationService.ProcessReconciliation(TestData.EstateId,
296+
TestData.MerchantId,
297+
TestData.TransactionDateTime,
298+
TestData.DeviceIdentifier,
299+
TestData.ReconciliationTransactionCount,
300+
TestData.ReconciliationTransactionValue,
301+
CancellationToken.None);
302+
303+
reconciliationResponse.ShouldNotBeNull();
304+
reconciliationResponse.ResponseMessage.ShouldBe(TestData.ResponseMessage);
305+
reconciliationResponse.ResponseCode.ShouldBe(TestData.ResponseCode);
306+
}
307+
308+
[Fact]
309+
public async Task TransactionProcessorACLApplicationService_ProcessReconciliation_InvalidOperationExceptionErrorInReconciliation_TransactionIsNotSuccessful()
310+
{
311+
IConfigurationRoot configuration = this.SetupMemoryConfiguration();
312+
ConfigurationReader.Initialise(configuration);
313+
314+
Mock<ITransactionProcessorClient> transactionProcessorClient = new Mock<ITransactionProcessorClient>();
315+
transactionProcessorClient.Setup(t => t.PerformTransaction(It.IsAny<String>(), It.IsAny<SerialisedMessage>(), It.IsAny<CancellationToken>()))
316+
.ThrowsAsync(new Exception("Error", new InvalidOperationException(TestData.InvalidOperationErrorResponseMessage)));
317+
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
318+
securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);
319+
320+
ITransactionProcessorACLApplicationService applicationService =
321+
new TransactionProcessorACLApplicationService(transactionProcessorClient.Object, securityServiceClient.Object);
322+
323+
ProcessReconciliationResponse reconciliationResponse = await applicationService.ProcessReconciliation(TestData.EstateId,
324+
TestData.MerchantId,
325+
TestData.TransactionDateTime,
326+
TestData.DeviceIdentifier,
327+
TestData.ReconciliationTransactionCount,
328+
TestData.ReconciliationTransactionValue,
329+
CancellationToken.None);
330+
331+
reconciliationResponse.ShouldNotBeNull();
332+
reconciliationResponse.ResponseMessage.ShouldBe(TestData.InvalidOperationErrorResponseMessage);
333+
reconciliationResponse.ResponseCode.ShouldBe(TestData.InvalidOperationErrorResponseCode);
334+
}
335+
336+
[Fact]
337+
public async Task TransactionProcessorACLApplicationService_ProcessReconciliation_HttpRequestExceptionErrorInReconciliation_TransactionIsNotSuccessful()
338+
{
339+
IConfigurationRoot configuration = this.SetupMemoryConfiguration();
340+
ConfigurationReader.Initialise(configuration);
341+
342+
Mock<ITransactionProcessorClient> transactionProcessorClient = new Mock<ITransactionProcessorClient>();
343+
transactionProcessorClient.Setup(t => t.PerformTransaction(It.IsAny<String>(), It.IsAny<SerialisedMessage>(), It.IsAny<CancellationToken>()))
344+
.ThrowsAsync(new Exception("Error", new HttpRequestException(TestData.HttpRequestErrorResponseMessage)));
345+
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
346+
securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);
347+
348+
ITransactionProcessorACLApplicationService applicationService =
349+
new TransactionProcessorACLApplicationService(transactionProcessorClient.Object, securityServiceClient.Object);
350+
351+
ProcessReconciliationResponse reconciliationResponse = await applicationService.ProcessReconciliation(TestData.EstateId,
352+
TestData.MerchantId,
353+
TestData.TransactionDateTime,
354+
TestData.DeviceIdentifier,
355+
TestData.ReconciliationTransactionCount,
356+
TestData.ReconciliationTransactionValue,
357+
CancellationToken.None);
358+
359+
reconciliationResponse.ShouldNotBeNull();
360+
reconciliationResponse.ResponseMessage.ShouldBe(TestData.HttpRequestErrorResponseMessage);
361+
reconciliationResponse.ResponseCode.ShouldBe(TestData.HttpRequestErrorResponseCode);
362+
}
363+
364+
[Fact]
365+
public async Task TransactionProcessorACLApplicationService_ProcessReconciliation_OtherExceptionErrorInReconciliation_TransactionIsNotSuccessful()
366+
{
367+
IConfigurationRoot configuration = this.SetupMemoryConfiguration();
368+
ConfigurationReader.Initialise(configuration);
369+
370+
Mock<ITransactionProcessorClient> transactionProcessorClient = new Mock<ITransactionProcessorClient>();
371+
transactionProcessorClient.Setup(t => t.PerformTransaction(It.IsAny<String>(), It.IsAny<SerialisedMessage>(), It.IsAny<CancellationToken>()))
372+
.ThrowsAsync(new Exception("Error", new Exception(TestData.GeneralErrorResponseMessage)));
373+
Mock<ISecurityServiceClient> securityServiceClient = new Mock<ISecurityServiceClient>();
374+
securityServiceClient.Setup(s => s.GetToken(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>())).ReturnsAsync(TestData.TokenResponse);
375+
376+
ITransactionProcessorACLApplicationService applicationService =
377+
new TransactionProcessorACLApplicationService(transactionProcessorClient.Object, securityServiceClient.Object);
378+
379+
ProcessReconciliationResponse reconciliationResponse = await applicationService.ProcessReconciliation(TestData.EstateId,
380+
TestData.MerchantId,
381+
TestData.TransactionDateTime,
382+
TestData.DeviceIdentifier,
383+
TestData.ReconciliationTransactionCount,
384+
TestData.ReconciliationTransactionValue,
385+
CancellationToken.None);
386+
387+
reconciliationResponse.ShouldNotBeNull();
388+
reconciliationResponse.ResponseMessage.ShouldBe(TestData.GeneralErrorResponseMessage);
389+
reconciliationResponse.ResponseCode.ShouldBe(TestData.GeneralErrorResponseCode);
390+
}
279391
}
280392
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
namespace TransactionProcessorACL.BusinessLogic.RequestHandlers
2+
{
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using MediatR;
6+
using Models;
7+
using Requests;
8+
using Services;
9+
10+
public class ProcessReconciliationRequestHandler : IRequestHandler<ProcessReconciliationRequest, ProcessReconciliationResponse>
11+
{
12+
#region Fields
13+
14+
/// <summary>
15+
/// The application service
16+
/// </summary>
17+
private readonly ITransactionProcessorACLApplicationService ApplicationService;
18+
19+
#endregion
20+
21+
#region Constructors
22+
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="ProcessLogonTransactionRequestHandler"/> class.
25+
/// </summary>
26+
/// <param name="applicationService">The application service.</param>
27+
public ProcessReconciliationRequestHandler(ITransactionProcessorACLApplicationService applicationService)
28+
{
29+
this.ApplicationService = applicationService;
30+
}
31+
32+
#endregion
33+
34+
#region Methods
35+
36+
/// <summary>
37+
/// Handles the specified request.
38+
/// </summary>
39+
/// <param name="request">The request.</param>
40+
/// <param name="cancellationToken">The cancellation token.</param>
41+
/// <returns>
42+
/// Response from the request
43+
/// </returns>
44+
public async Task<ProcessReconciliationResponse> Handle(ProcessReconciliationRequest request,
45+
CancellationToken cancellationToken)
46+
{
47+
return await this.ApplicationService.ProcessReconciliation(request.EstateId,
48+
request.MerchantId,
49+
request.TransactionDateTime,
50+
request.DeviceIdentifier,
51+
request.TransactionCount,
52+
request.TransactionValue,
53+
cancellationToken);
54+
}
55+
56+
#endregion
57+
}
58+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
namespace TransactionProcessorACL.BusinessLogic.Requests
2+
{
3+
using System;
4+
using System.Diagnostics.CodeAnalysis;
5+
using MediatR;
6+
using Models;
7+
8+
/// <summary>
9+
///
10+
/// </summary>
11+
/// <seealso cref="MediatR.IRequest{TransactionProcessorACL.Models.ProcessReconciliationResponse}" />
12+
/// <seealso cref="MediatR.IRequest{System.Object}" />
13+
public class ProcessReconciliationRequest : IRequest<ProcessReconciliationResponse>
14+
{
15+
#region Constructors
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="ProcessReconciliationRequest"/> class.
19+
/// </summary>
20+
[ExcludeFromCodeCoverage]
21+
public ProcessReconciliationRequest()
22+
{
23+
}
24+
25+
/// <summary>
26+
/// Initializes a new instance of the <see cref="ProcessReconciliationRequest" /> class.
27+
/// </summary>
28+
/// <param name="estateId">The estate identifier.</param>
29+
/// <param name="merchantId">The merchant identifier.</param>
30+
/// <param name="transactionDateTime">The transaction date time.</param>
31+
/// <param name="deviceIdentifier">The device identifier.</param>
32+
/// <param name="transactionCount">The transaction count.</param>
33+
/// <param name="transactionValue">The transaction value.</param>
34+
private ProcessReconciliationRequest(Guid estateId,
35+
Guid merchantId,
36+
DateTime transactionDateTime,
37+
String deviceIdentifier,
38+
Int32 transactionCount,
39+
Decimal transactionValue)
40+
{
41+
this.EstateId = estateId;
42+
this.MerchantId = merchantId;
43+
this.DeviceIdentifier = deviceIdentifier;
44+
this.TransactionCount = transactionCount;
45+
this.TransactionValue = transactionValue;
46+
this.TransactionDateTime = transactionDateTime;
47+
}
48+
49+
#endregion
50+
51+
#region Properties
52+
53+
/// <summary>
54+
/// Gets the device identifier.
55+
/// </summary>
56+
/// <value>
57+
/// The device identifier.
58+
/// </value>
59+
public String DeviceIdentifier { get; }
60+
61+
/// <summary>
62+
/// Gets the estate identifier.
63+
/// </summary>
64+
/// <value>
65+
/// The estate identifier.
66+
/// </value>
67+
public Guid EstateId { get; }
68+
69+
/// <summary>
70+
/// Gets the merchant identifier.
71+
/// </summary>
72+
/// <value>
73+
/// The merchant identifier.
74+
/// </value>
75+
public Guid MerchantId { get; }
76+
77+
/// <summary>
78+
/// Gets the transaction count.
79+
/// </summary>
80+
/// <value>
81+
/// The transaction count.
82+
/// </value>
83+
public Int32 TransactionCount { get; }
84+
85+
/// <summary>
86+
/// Gets the transaction date time.
87+
/// </summary>
88+
/// <value>
89+
/// The transaction date time.
90+
/// </value>
91+
public DateTime TransactionDateTime { get; }
92+
93+
/// <summary>
94+
/// Gets the transaction value.
95+
/// </summary>
96+
/// <value>
97+
/// The transaction value.
98+
/// </value>
99+
public Decimal TransactionValue { get; }
100+
101+
#endregion
102+
103+
#region Methods
104+
105+
/// <summary>
106+
/// Creates the specified estate identifier.
107+
/// </summary>
108+
/// <param name="estateId">The estate identifier.</param>
109+
/// <param name="merchantId">The merchant identifier.</param>
110+
/// <param name="transactionDateTime">The transaction date time.</param>
111+
/// <param name="deviceIdentifier">The device identifier.</param>
112+
/// <param name="transactionCount">The transaction count.</param>
113+
/// <param name="transactionValue">The transaction value.</param>
114+
/// <returns></returns>
115+
public static ProcessReconciliationRequest Create(Guid estateId,
116+
Guid merchantId,
117+
DateTime transactionDateTime,
118+
String deviceIdentifier,
119+
Int32 transactionCount,
120+
Decimal transactionValue)
121+
{
122+
return new ProcessReconciliationRequest(estateId, merchantId, transactionDateTime, deviceIdentifier, transactionCount, transactionValue);
123+
}
124+
125+
#endregion
126+
}
127+
}

0 commit comments

Comments
 (0)