From fa2a5720d0277b98a64729bf7623bbaa529a6e4f Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Mon, 16 Mar 2020 17:17:49 +0000 Subject: [PATCH] Safaricom Proxy unit tests added --- .../SafaricomPinlessProxyTests.cs | 110 ++++++++++++++++++ .../Services/TransactionDomainServiceTests.cs | 1 + .../OperatorInterfaces/OperatorResponse.cs | 10 ++ .../SafaricomConfiguration.cs | 2 + .../SafaricomPinless/SafaricomPinlessProxy.cs | 6 +- .../SafaricomPinless/SafaricomResponse.cs | 14 ++- TransactionProcessor.Testing/TestData.cs | 22 ++++ 7 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 TransactionProcessor.BusinessLogic.Tests/OperatorInterfaces/SafaricomPinlessProxyTests.cs diff --git a/TransactionProcessor.BusinessLogic.Tests/OperatorInterfaces/SafaricomPinlessProxyTests.cs b/TransactionProcessor.BusinessLogic.Tests/OperatorInterfaces/SafaricomPinlessProxyTests.cs new file mode 100644 index 00000000..4ecdec39 --- /dev/null +++ b/TransactionProcessor.BusinessLogic.Tests/OperatorInterfaces/SafaricomPinlessProxyTests.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace TransactionProcessor.BusinessLogic.Tests.OperatorInterfaces +{ + using System.Net; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + using BusinessLogic.OperatorInterfaces; + using BusinessLogic.OperatorInterfaces.SafaricomPinless; + using Moq; + using Moq.Protected; + using Shouldly; + using Testing; + using Xunit; + + public class SafaricomPinlessProxyTests + { + [Fact] + public async Task SafaricomPinlessProxy_ProcessSaleMessage_TopupSuccessful_SaleMessageIsProcessed() + { + HttpResponseMessage responseMessage = new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(TestData.SuccessfulSafaricomTopup) + }; + + SafaricomConfiguration safaricomConfiguration = TestData.SafaricomConfiguration; + HttpClient httpClient = SetupMockHttpClient(responseMessage); + + IOperatorProxy safaricomPinlessproxy = new SafaricomPinlessProxy(safaricomConfiguration, httpClient); + + OperatorResponse operatorResponse = await safaricomPinlessproxy.ProcessSaleMessage(TestData.TransactionId, + TestData.Merchant, + TestData.TransactionDateTime, + TestData.AdditionalTransactionMetaData, + CancellationToken.None); + + operatorResponse.ShouldNotBeNull(); + operatorResponse.IsSuccessful.ShouldBeTrue(); + operatorResponse.ResponseCode.ShouldBe("200"); + operatorResponse.ResponseMessage.ShouldBe("Topup Successful"); + } + + [Fact] + public async Task SafaricomPinlessProxy_ProcessSaleMessage_TopupFailed_SaleMessageIsProcessed() + { + HttpResponseMessage responseMessage = new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(TestData.FailedSafaricomTopup) + }; + + SafaricomConfiguration safaricomConfiguration = TestData.SafaricomConfiguration; + HttpClient httpClient = SetupMockHttpClient(responseMessage); + + IOperatorProxy safaricomPinlessproxy = new SafaricomPinlessProxy(safaricomConfiguration, httpClient); + + OperatorResponse operatorResponse = await safaricomPinlessproxy.ProcessSaleMessage(TestData.TransactionId, + TestData.Merchant, + TestData.TransactionDateTime, + TestData.AdditionalTransactionMetaData, + CancellationToken.None); + + operatorResponse.ShouldNotBeNull(); + operatorResponse.IsSuccessful.ShouldBeFalse(); + operatorResponse.ResponseCode.ShouldBe("500"); + operatorResponse.ResponseMessage.ShouldBe("Topup failed"); + } + + [Fact] + public async Task SafaricomPinlessProxy_ProcessSaleMessage_FailedToSend_ErrorThrown() + { + HttpResponseMessage responseMessage = new HttpResponseMessage + { + StatusCode = HttpStatusCode.InternalServerError + }; + + SafaricomConfiguration safaricomConfiguration = TestData.SafaricomConfiguration; + HttpClient httpClient = SetupMockHttpClient(responseMessage); + + IOperatorProxy safaricomPinlessproxy = new SafaricomPinlessProxy(safaricomConfiguration, httpClient); + + Should.Throw(async () => + { + await safaricomPinlessproxy.ProcessSaleMessage(TestData.TransactionId, + TestData.Merchant, + TestData.TransactionDateTime, + TestData.AdditionalTransactionMetaData, + CancellationToken.None); + }); + } + + private HttpClient SetupMockHttpClient(HttpResponseMessage responseMessage) + { + Mock handlerMock = new Mock(MockBehavior.Strict); + handlerMock.Protected().Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .ReturnsAsync(responseMessage); + + var httpClient = new HttpClient(handlerMock.Object) + { + BaseAddress = new Uri("http://test.com") + }; + + return httpClient; + } + } +} diff --git a/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs b/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs index ed1b3a78..536e94c9 100644 --- a/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs @@ -6,6 +6,7 @@ namespace TransactionProcessor.BusinessLogic.Tests.Services { using System.Threading; using System.Threading.Tasks; + using BusinessLogic.OperatorInterfaces; using BusinessLogic.Services; using EstateManagement.Client; using Microsoft.Extensions.Configuration; diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/OperatorResponse.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/OperatorResponse.cs index 65ee845e..34d3cc7f 100644 --- a/TransactionProcessor.BusinessLogic/OperatorInterfaces/OperatorResponse.cs +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/OperatorResponse.cs @@ -1,10 +1,12 @@ namespace TransactionProcessor.BusinessLogic.OperatorInterfaces { using System; + using System.Diagnostics.CodeAnalysis; /// /// /// + [ExcludeFromCodeCoverage] public class OperatorResponse { #region Properties @@ -33,6 +35,14 @@ public class OperatorResponse /// public String ResponseMessage { get; set; } + /// + /// Gets or sets a value indicating whether this instance is successful. + /// + /// + /// true if this instance is successful; otherwise, false. + /// + public Boolean IsSuccessful { get; set; } + #endregion } } \ No newline at end of file diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomConfiguration.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomConfiguration.cs index f0ef90cc..52156c31 100644 --- a/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomConfiguration.cs +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomConfiguration.cs @@ -1,10 +1,12 @@ namespace TransactionProcessor.BusinessLogic.OperatorInterfaces.SafaricomPinless { using System; + using System.Diagnostics.CodeAnalysis; /// /// /// + [ExcludeFromCodeCoverage] public class SafaricomConfiguration { #region Properties diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomPinlessProxy.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomPinlessProxy.cs index 1631a24c..65164205 100644 --- a/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomPinlessProxy.cs +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomPinlessProxy.cs @@ -135,8 +135,10 @@ private OperatorResponse CreateFrom(String responseContent) return new OperatorResponse { AuthorisationCode = "ABCD1234", - ResponseCode = cl.TXNSTATUS.ToString(), - ResponseMessage = cl.MESSAGE + ResponseCode = cl.TransactionStatus.ToString(), + ResponseMessage = cl.Message, + IsSuccessful = cl.TransactionStatus == 200 + }; } diff --git a/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomResponse.cs b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomResponse.cs index 1bbd514e..9dec2c86 100644 --- a/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomResponse.cs +++ b/TransactionProcessor.BusinessLogic/OperatorInterfaces/SafaricomPinless/SafaricomResponse.cs @@ -2,6 +2,7 @@ { using System; using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; using System.Xml.Serialization; /// @@ -11,6 +12,7 @@ [DesignerCategory("code")] [XmlType(AnonymousType = true)] [XmlRoot(Namespace = "", IsNullable = false, ElementName = "COMMAND")] + [ExcludeFromCodeCoverage] public class SafaricomResponse { #region Properties @@ -22,7 +24,7 @@ public class SafaricomResponse /// The type. /// [XmlElement(ElementName = "TYPE")] - public String TYPE { get; set; } + public String TransactionType { get; set; } /// /// Gets or sets the txnstatus. @@ -31,7 +33,7 @@ public class SafaricomResponse /// The txnstatus. /// [XmlElement(ElementName = "TXNSTATUS")] - public Int32 TXNSTATUS { get; set; } + public Int32 TransactionStatus { get; set; } /// /// Gets or sets the date. @@ -40,7 +42,7 @@ public class SafaricomResponse /// The date. /// [XmlElement(ElementName = "DATE")] - public String DATE { get; set; } + public String TransactionDate { get; set; } /// /// Gets or sets the extrefnum. @@ -49,7 +51,7 @@ public class SafaricomResponse /// The extrefnum. /// [XmlElement(ElementName = "EXTREFNUM")] - public String EXTREFNUM { get; set; } + public String ExternalReferenceNumber { get; set; } /// /// Gets or sets the txnid. @@ -58,7 +60,7 @@ public class SafaricomResponse /// The txnid. /// [XmlElement(ElementName = "TXNID")] - public String TXNID { get; set; } + public String TransactionId { get; set; } /// /// Gets or sets the message. @@ -67,7 +69,7 @@ public class SafaricomResponse /// The message. /// [XmlElement(ElementName = "MESSAGE")] - public String MESSAGE { get; set; } + public String Message { get; set; } #endregion } diff --git a/TransactionProcessor.Testing/TestData.cs b/TransactionProcessor.Testing/TestData.cs index c2103d38..de59382c 100644 --- a/TransactionProcessor.Testing/TestData.cs +++ b/TransactionProcessor.Testing/TestData.cs @@ -4,6 +4,7 @@ namespace TransactionProcessor.Testing { + using BusinessLogic.OperatorInterfaces.SafaricomPinless; using BusinessLogic.Requests; using BusinessLogic.Services; using EstateManagement.DataTransferObjects.Responses; @@ -197,5 +198,26 @@ public static String GetResponseCodeMessage(TransactionResponseCode transactionR { return transactionResponseCode.ToString(); } + + public static SafaricomConfiguration SafaricomConfiguration = new SafaricomConfiguration + { + ExtCode = "ExtCode1", + LoginId = "LoginId", + MSISDN = "123456789", + Password = "Password", + Url = "http://localhost", + Pin = "1234" + }; + + public static MerchantResponse Merchant = new MerchantResponse + { + EstateId = TestData.EstateId, + MerchantId = TestData.MerchantId, + MerchantName = TestData.MerchantName + }; + + public static String SuccessfulSafaricomTopup = "EXRCTRFRESP20002-JUL-201810002281420200314231322847Topup Successful"; + + public static String FailedSafaricomTopup = "EXRCTRFRESP50002-JUL-201810002281420200314231322847Topup failed"; } }