diff --git a/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs b/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs index f37361b7..09c81a63 100644 --- a/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs @@ -232,8 +232,6 @@ public async Task TransactionDomainService_ProcessReconciliationTransaction_Inva this.ValidateResponse(response, TransactionResponseCode.InvalidMerchantId); } - //###### - [Fact] public async Task TransactionDomainService_ProcessLogonTransaction_TransactionIsProcessed() { @@ -1119,6 +1117,59 @@ public async Task TransactionDomainService_ProcessSaleTransaction_OperatorNotSup this.ValidateResponse(response, TransactionResponseCode.OperatorNotValidForMerchant); } + [Fact] + public async Task TransactionDomainService_ProcessSaleTransaction_ErrorInOperatorComms_TransactionIsProcessed() + { + IConfigurationRoot configurationRoot = new ConfigurationBuilder().AddInMemoryCollection(TestData.DefaultAppSettings).Build(); + ConfigurationReader.Initialise(configurationRoot); + + Logger.Initialise(NullLogger.Instance); + + Mock transactionAggregateManager = new Mock(); + Mock estateClient = new Mock(); + Mock securityServiceClient = new Mock(); + + securityServiceClient.Setup(s => s.GetToken(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(TestData.TokenResponse); + estateClient.Setup(e => e.GetEstate(It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(TestData.GetEstateResponseWithOperator1); + estateClient.Setup(e => e.GetMerchant(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(TestData.GetMerchantResponseWithOperator1); + transactionAggregateManager.Setup(t => t.GetAggregate(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(TestData.GetLocallyDeclinedTransactionAggregate(TransactionResponseCode.OperatorCommsError)); + + Mock operatorProxy = new Mock(); + operatorProxy.Setup(o => o.ProcessSaleMessage(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny>(), + It.IsAny())).ThrowsAsync(new Exception("Comms Error")); + Func operatorProxyResolver = (operatorName) => { return operatorProxy.Object; }; + + Mock> reconciliationAggregateRepository = + new Mock>(); + + TransactionDomainService transactionDomainService = + new TransactionDomainService(transactionAggregateManager.Object, estateClient.Object, securityServiceClient.Object, + operatorProxyResolver, reconciliationAggregateRepository.Object); + + ProcessSaleTransactionResponse response = await transactionDomainService.ProcessSaleTransaction(TestData.TransactionId, + TestData.EstateId, + TestData.MerchantId, + TestData.TransactionDateTime, + TestData.TransactionNumber, + TestData.DeviceIdentifier, + TestData.OperatorIdentifier1, + TestData.CustomerEmailAddress, + TestData.AdditionalTransactionMetaData, + TestData.ContractId, + TestData.ProductId, + CancellationToken.None); + + this.ValidateResponse(response, TransactionResponseCode.OperatorCommsError); + } + private void ValidateResponse(ProcessLogonTransactionResponse response, TransactionResponseCode transactionResponseCode) { diff --git a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs index 6827a144..d6a6ff87 100644 --- a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs @@ -218,50 +218,58 @@ await this.TransactionAggregateManager.RecordAdditionalRequestData(estateId, // Do the online processing with the operator here MerchantResponse merchant = await this.GetMerchant(estateId, merchantId, cancellationToken); - IOperatorProxy operatorProxy = this.OperatorProxyResolver(operatorIdentifier); - OperatorResponse operatorResponse = - await operatorProxy.ProcessSaleMessage(this.TokenResponse.AccessToken, - transactionId, - operatorIdentifier, - merchant, - transactionDateTime, - transactionReference, - additionalTransactionMetadata, - cancellationToken); - - if (operatorResponse.IsSuccessful) - { - TransactionResponseCode transactionResponseCode = TransactionResponseCode.Success; - String responseMessage = "SUCCESS"; - - await this.TransactionAggregateManager.AuthoriseTransaction(estateId, - transactionId, - operatorIdentifier, - operatorResponse, - transactionResponseCode, - responseMessage, - cancellationToken); - } - else + OperatorResponse operatorResponse = await this.ProcessMessageWithOperator(merchant, transactionId, transactionDateTime, operatorIdentifier, additionalTransactionMetadata, transactionReference, cancellationToken); + + // Act on the operator response + if (operatorResponse == null) { - TransactionResponseCode transactionResponseCode = TransactionResponseCode.TransactionDeclinedByOperator; - String responseMessage = "DECLINED BY OPERATOR"; + // Failed to perform sed/receive with the operator + TransactionResponseCode transactionResponseCode = TransactionResponseCode.OperatorCommsError; + String responseMessage = "OPERATOR COMMS ERROR"; - await this.TransactionAggregateManager.DeclineTransaction(estateId, + await this.TransactionAggregateManager.DeclineTransactionLocally(estateId, transactionId, - operatorIdentifier, - operatorResponse, - transactionResponseCode, - responseMessage, + (responseMessage, transactionResponseCode), cancellationToken); } + else + { - // Record any additional operator response metadata - await this.TransactionAggregateManager.RecordAdditionalResponseData(estateId, + + if (operatorResponse.IsSuccessful) + { + TransactionResponseCode transactionResponseCode = TransactionResponseCode.Success; + String responseMessage = "SUCCESS"; + + await this.TransactionAggregateManager.AuthoriseTransaction(estateId, transactionId, operatorIdentifier, - operatorResponse.AdditionalTransactionResponseMetadata, + operatorResponse, + transactionResponseCode, + responseMessage, cancellationToken); + } + else + { + TransactionResponseCode transactionResponseCode = TransactionResponseCode.TransactionDeclinedByOperator; + String responseMessage = "DECLINED BY OPERATOR"; + + await this.TransactionAggregateManager.DeclineTransaction(estateId, + transactionId, + operatorIdentifier, + operatorResponse, + transactionResponseCode, + responseMessage, + cancellationToken); + } + + // Record any additional operator response metadata + await this.TransactionAggregateManager.RecordAdditionalResponseData(estateId, + transactionId, + operatorIdentifier, + operatorResponse.AdditionalTransactionResponseMetadata, + cancellationToken); + } } else { @@ -292,6 +300,36 @@ await this.TransactionAggregateManager.RecordAdditionalResponseData(estateId, }; } + private async Task ProcessMessageWithOperator(MerchantResponse merchant, + Guid transactionId, + DateTime transactionDateTime, + String operatorIdentifier, + Dictionary additionalTransactionMetadata, + String transactionReference, + CancellationToken cancellationToken) + { + IOperatorProxy operatorProxy = this.OperatorProxyResolver(operatorIdentifier); + OperatorResponse operatorResponse = null; + try + { + operatorResponse = await operatorProxy.ProcessSaleMessage(this.TokenResponse.AccessToken, + transactionId, + operatorIdentifier, + merchant, + transactionDateTime, + transactionReference, + additionalTransactionMetadata, + cancellationToken); + } + catch(Exception e) + { + // Log out the error + Logger.LogError(e); + } + + return operatorResponse; + } + /// /// Processes the reconciliation transaction. /// diff --git a/TransactionProcessor.BusinessLogic/Services/TransactionResponseCode.cs b/TransactionProcessor.BusinessLogic/Services/TransactionResponseCode.cs index 5c38e778..1a6789d5 100644 --- a/TransactionProcessor.BusinessLogic/Services/TransactionResponseCode.cs +++ b/TransactionProcessor.BusinessLogic/Services/TransactionResponseCode.cs @@ -14,6 +14,7 @@ public enum TransactionResponseCode OperatorNotValidForMerchant = 1007, TransactionDeclinedByOperator = 1008, MerchantDoesNotHaveEnoughCredit = 1009, + OperatorCommsError = 1010, // A Catch All generic Error where reason has not been identified UnknownFailure = 9999 diff --git a/TransactionProcessor.IntegrationTests/SaleTransaction/SaleTransactionFeature.feature.cs b/TransactionProcessor.IntegrationTests/SaleTransaction/SaleTransactionFeature.feature.cs index 5aa74e27..1ab7f91b 100644 --- a/TransactionProcessor.IntegrationTests/SaleTransaction/SaleTransactionFeature.feature.cs +++ b/TransactionProcessor.IntegrationTests/SaleTransaction/SaleTransactionFeature.feature.cs @@ -1,3 +1,970 @@ -#error Could not find a reference to SpecFlow in project 'TransactionProcessor.IntegrationTests'. -#error Please add the 'TechTalk.SpecFlow' package to the project and use MSBuild generation instead of using SpecFlowSingleFileGenerator. -#error For more information see https://specflow.org/documentation/Generate-Tests-from-MsBuild/ \ No newline at end of file +// ------------------------------------------------------------------------------ +// +// This code was generated by SpecFlow (https://www.specflow.org/). +// SpecFlow Version:3.5.0.0 +// SpecFlow Generator Version:3.5.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +#region Designer generated code +#pragma warning disable +namespace TransactionProcessor.IntegrationTests.SaleTransaction +{ + using TechTalk.SpecFlow; + using System; + using System.Linq; + + + [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.5.0.0")] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [Xunit.TraitAttribute("Category", "base")] + [Xunit.TraitAttribute("Category", "shared")] + public partial class SaleTransactionFeature : object, Xunit.IClassFixture, System.IDisposable + { + + private static TechTalk.SpecFlow.ITestRunner testRunner; + + private string[] _featureTags = new string[] { + "base", + "shared"}; + + private Xunit.Abstractions.ITestOutputHelper _testOutputHelper; + +#line 1 "SaleTransactionFeature.feature" +#line hidden + + public SaleTransactionFeature(SaleTransactionFeature.FixtureData fixtureData, TransactionProcessor_IntegrationTests_XUnitAssemblyFixture assemblyFixture, Xunit.Abstractions.ITestOutputHelper testOutputHelper) + { + this._testOutputHelper = testOutputHelper; + this.TestInitialize(); + } + + public static void FeatureSetup() + { + testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(); + TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "SaleTransaction", "SaleTransaction", null, ProgrammingLanguage.CSharp, new string[] { + "base", + "shared"}); + testRunner.OnFeatureStart(featureInfo); + } + + public static void FeatureTearDown() + { + testRunner.OnFeatureEnd(); + testRunner = null; + } + + public virtual void TestInitialize() + { + } + + public virtual void TestTearDown() + { + testRunner.OnScenarioEnd(); + } + + public virtual void ScenarioInitialize(TechTalk.SpecFlow.ScenarioInfo scenarioInfo) + { + testRunner.OnScenarioInitialize(scenarioInfo); + testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(_testOutputHelper); + } + + public virtual void ScenarioStart() + { + testRunner.OnScenarioStart(); + } + + public virtual void ScenarioCleanup() + { + testRunner.CollectScenarioErrors(); + } + + public virtual void FeatureBackground() + { +#line 4 +#line hidden + TechTalk.SpecFlow.Table table38 = new TechTalk.SpecFlow.Table(new string[] { + "Name", + "DisplayName", + "Description"}); + table38.AddRow(new string[] { + "estateManagement", + "Estate Managememt REST Scope", + "A scope for Estate Managememt REST"}); + table38.AddRow(new string[] { + "transactionProcessor", + "Transaction Processor REST Scope", + "A scope for Transaction Processor REST"}); + table38.AddRow(new string[] { + "voucherManagement", + "Voucher Management REST Scope", + "A scope for Voucher Management REST"}); +#line 6 + testRunner.Given("I create the following api scopes", ((string)(null)), table38, "Given "); +#line hidden + TechTalk.SpecFlow.Table table39 = new TechTalk.SpecFlow.Table(new string[] { + "ResourceName", + "DisplayName", + "Secret", + "Scopes", + "UserClaims"}); + table39.AddRow(new string[] { + "estateManagement", + "Estate Managememt REST", + "Secret1", + "estateManagement", + "MerchantId, EstateId, role"}); + table39.AddRow(new string[] { + "transactionProcessor", + "Transaction Processor REST", + "Secret1", + "transactionProcessor", + ""}); + table39.AddRow(new string[] { + "voucherManagement", + "Voucher Management REST", + "Secret1", + "voucherManagement", + ""}); +#line 12 + testRunner.Given("the following api resources exist", ((string)(null)), table39, "Given "); +#line hidden + TechTalk.SpecFlow.Table table40 = new TechTalk.SpecFlow.Table(new string[] { + "ClientId", + "ClientName", + "Secret", + "AllowedScopes", + "AllowedGrantTypes"}); + table40.AddRow(new string[] { + "serviceClient", + "Service Client", + "Secret1", + "estateManagement,transactionProcessor,voucherManagement", + "client_credentials"}); +#line 18 + testRunner.Given("the following clients exist", ((string)(null)), table40, "Given "); +#line hidden + TechTalk.SpecFlow.Table table41 = new TechTalk.SpecFlow.Table(new string[] { + "ClientId"}); + table41.AddRow(new string[] { + "serviceClient"}); +#line 22 + testRunner.Given("I have a token to access the estate management and transaction processor resource" + + "s", ((string)(null)), table41, "Given "); +#line hidden + TechTalk.SpecFlow.Table table42 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName"}); + table42.AddRow(new string[] { + "Test Estate 1"}); + table42.AddRow(new string[] { + "Test Estate 2"}); +#line 26 + testRunner.Given("I have created the following estates", ((string)(null)), table42, "Given "); +#line hidden + TechTalk.SpecFlow.Table table43 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "OperatorName", + "RequireCustomMerchantNumber", + "RequireCustomTerminalNumber"}); + table43.AddRow(new string[] { + "Test Estate 1", + "Safaricom", + "True", + "True"}); + table43.AddRow(new string[] { + "Test Estate 1", + "Voucher", + "True", + "True"}); + table43.AddRow(new string[] { + "Test Estate 2", + "Safaricom", + "True", + "True"}); + table43.AddRow(new string[] { + "Test Estate 2", + "Voucher", + "True", + "True"}); +#line 31 + testRunner.Given("I have created the following operators", ((string)(null)), table43, "Given "); +#line hidden + TechTalk.SpecFlow.Table table44 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "OperatorName", + "ContractDescription"}); + table44.AddRow(new string[] { + "Test Estate 1", + "Safaricom", + "Safaricom Contract"}); + table44.AddRow(new string[] { + "Test Estate 1", + "Voucher", + "Hospital 1 Contract"}); + table44.AddRow(new string[] { + "Test Estate 2", + "Safaricom", + "Safaricom Contract"}); + table44.AddRow(new string[] { + "Test Estate 2", + "Voucher", + "Hospital 1 Contract"}); +#line 38 + testRunner.Given("I create a contract with the following values", ((string)(null)), table44, "Given "); +#line hidden + TechTalk.SpecFlow.Table table45 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "OperatorName", + "ContractDescription", + "ProductName", + "DisplayText", + "Value"}); + table45.AddRow(new string[] { + "Test Estate 1", + "Safaricom", + "Safaricom Contract", + "Variable Topup", + "Custom", + ""}); + table45.AddRow(new string[] { + "Test Estate 1", + "Voucher", + "Hospital 1 Contract", + "10 KES", + "10 KES", + ""}); + table45.AddRow(new string[] { + "Test Estate 2", + "Safaricom", + "Safaricom Contract", + "Variable Topup", + "Custom", + ""}); + table45.AddRow(new string[] { + "Test Estate 2", + "Voucher", + "Hospital 1 Contract", + "10 KES", + "10 KES", + ""}); +#line 45 + testRunner.When("I create the following Products", ((string)(null)), table45, "When "); +#line hidden + TechTalk.SpecFlow.Table table46 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "OperatorName", + "ContractDescription", + "ProductName", + "CalculationType", + "FeeDescription", + "Value"}); + table46.AddRow(new string[] { + "Test Estate 1", + "Safaricom", + "Safaricom Contract", + "Variable Topup", + "Fixed", + "Merchant Commission", + "2.50"}); + table46.AddRow(new string[] { + "Test Estate 2", + "Safaricom", + "Safaricom Contract", + "Variable Topup", + "Percentage", + "Merchant Commission", + "0.85"}); +#line 52 + testRunner.When("I add the following Transaction Fees", ((string)(null)), table46, "When "); +#line hidden + TechTalk.SpecFlow.Table table47 = new TechTalk.SpecFlow.Table(new string[] { + "MerchantName", + "AddressLine1", + "Town", + "Region", + "Country", + "ContactName", + "EmailAddress", + "EstateName"}); + table47.AddRow(new string[] { + "Test Merchant 1", + "Address Line 1", + "TestTown", + "Test Region", + "United Kingdom", + "Test Contact 1", + "testcontact1@merchant1.co.uk", + "Test Estate 1"}); + table47.AddRow(new string[] { + "Test Merchant 2", + "Address Line 1", + "TestTown", + "Test Region", + "United Kingdom", + "Test Contact 2", + "testcontact2@merchant2.co.uk", + "Test Estate 1"}); + table47.AddRow(new string[] { + "Test Merchant 3", + "Address Line 1", + "TestTown", + "Test Region", + "United Kingdom", + "Test Contact 3", + "testcontact3@merchant2.co.uk", + "Test Estate 2"}); +#line 57 + testRunner.Given("I create the following merchants", ((string)(null)), table47, "Given "); +#line hidden + TechTalk.SpecFlow.Table table48 = new TechTalk.SpecFlow.Table(new string[] { + "OperatorName", + "MerchantName", + "MerchantNumber", + "TerminalNumber", + "EstateName"}); + table48.AddRow(new string[] { + "Safaricom", + "Test Merchant 1", + "00000001", + "10000001", + "Test Estate 1"}); + table48.AddRow(new string[] { + "Voucher", + "Test Merchant 1", + "00000001", + "10000001", + "Test Estate 1"}); + table48.AddRow(new string[] { + "Safaricom", + "Test Merchant 2", + "00000002", + "10000002", + "Test Estate 1"}); + table48.AddRow(new string[] { + "Voucher", + "Test Merchant 2", + "00000002", + "10000002", + "Test Estate 1"}); + table48.AddRow(new string[] { + "Safaricom", + "Test Merchant 3", + "00000003", + "10000003", + "Test Estate 2"}); + table48.AddRow(new string[] { + "Voucher", + "Test Merchant 3", + "00000003", + "10000003", + "Test Estate 2"}); +#line 63 + testRunner.Given("I have assigned the following operator to the merchants", ((string)(null)), table48, "Given "); +#line hidden + TechTalk.SpecFlow.Table table49 = new TechTalk.SpecFlow.Table(new string[] { + "DeviceIdentifier", + "MerchantName", + "EstateName"}); + table49.AddRow(new string[] { + "123456780", + "Test Merchant 1", + "Test Estate 1"}); + table49.AddRow(new string[] { + "123456781", + "Test Merchant 2", + "Test Estate 1"}); + table49.AddRow(new string[] { + "123456782", + "Test Merchant 3", + "Test Estate 2"}); +#line 72 + testRunner.Given("I have assigned the following devices to the merchants", ((string)(null)), table49, "Given "); +#line hidden + TechTalk.SpecFlow.Table table50 = new TechTalk.SpecFlow.Table(new string[] { + "Reference", + "Amount", + "DateTime", + "MerchantName", + "EstateName"}); + table50.AddRow(new string[] { + "Deposit1", + "210.00", + "Today", + "Test Merchant 1", + "Test Estate 1"}); + table50.AddRow(new string[] { + "Deposit1", + "110.00", + "Today", + "Test Merchant 2", + "Test Estate 1"}); + table50.AddRow(new string[] { + "Deposit1", + "110.00", + "Today", + "Test Merchant 3", + "Test Estate 2"}); +#line 78 + testRunner.Given("I make the following manual merchant deposits", ((string)(null)), table50, "Given "); +#line hidden + } + + void System.IDisposable.Dispose() + { + this.TestTearDown(); + } + + [Xunit.SkippableFactAttribute(DisplayName="Sale Transactions")] + [Xunit.TraitAttribute("FeatureTitle", "SaleTransaction")] + [Xunit.TraitAttribute("Description", "Sale Transactions")] + [Xunit.TraitAttribute("Category", "PRTest")] + public virtual void SaleTransactions() + { + string[] tagsOfScenario = new string[] { + "PRTest"}; + System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Sale Transactions", null, tagsOfScenario, argumentsOfScenario); +#line 85 +this.ScenarioInitialize(scenarioInfo); +#line hidden + bool isScenarioIgnored = default(bool); + bool isFeatureIgnored = default(bool); + if ((tagsOfScenario != null)) + { + isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((this._featureTags != null)) + { + isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((isScenarioIgnored || isFeatureIgnored)) + { + testRunner.SkipScenario(); + } + else + { + this.ScenarioStart(); +#line 4 +this.FeatureBackground(); +#line hidden + TechTalk.SpecFlow.Table table51 = new TechTalk.SpecFlow.Table(new string[] { + "DateTime", + "TransactionNumber", + "TransactionType", + "MerchantName", + "DeviceIdentifier", + "EstateName", + "OperatorName", + "TransactionAmount", + "CustomerAccountNumber", + "CustomerEmailAddress", + "ContractDescription", + "ProductName", + "RecipientEmail", + "RecipientMobile"}); + table51.AddRow(new string[] { + "Today", + "1", + "Sale", + "Test Merchant 1", + "123456780", + "Test Estate 1", + "Safaricom", + "100.00", + "123456789", + "", + "Safaricom Contract", + "Variable Topup", + "", + ""}); + table51.AddRow(new string[] { + "Today", + "2", + "Sale", + "Test Merchant 2", + "123456781", + "Test Estate 1", + "Safaricom", + "100.00", + "123456789", + "", + "Safaricom Contract", + "Variable Topup", + "", + ""}); + table51.AddRow(new string[] { + "Today", + "3", + "Sale", + "Test Merchant 3", + "123456782", + "Test Estate 2", + "Safaricom", + "100.00", + "123456789", + "", + "Safaricom Contract", + "Variable Topup", + "", + ""}); + table51.AddRow(new string[] { + "Today", + "4", + "Sale", + "Test Merchant 1", + "123456780", + "Test Estate 1", + "Safaricom", + "100.00", + "123456789", + "testcustomer@customer.co.uk", + "Safaricom Contract", + "Variable Topup", + "", + ""}); + table51.AddRow(new string[] { + "Today", + "5", + "Sale", + "Test Merchant 1", + "123456780", + "Test Estate 1", + "Voucher", + "10.00", + "", + "", + "Hospital 1 Contract", + "10 KES", + "test@recipient.co.uk", + ""}); + table51.AddRow(new string[] { + "Today", + "6", + "Sale", + "Test Merchant 2", + "123456781", + "Test Estate 1", + "Voucher", + "10.00", + "", + "", + "Hospital 1 Contract", + "10 KES", + "", + "123456789"}); + table51.AddRow(new string[] { + "Today", + "7", + "Sale", + "Test Merchant 3", + "123456782", + "Test Estate 2", + "Voucher", + "10.00", + "", + "", + "Hospital 1 Contract", + "10 KES", + "test@recipient.co.uk", + ""}); +#line 87 + testRunner.When("I perform the following transactions", ((string)(null)), table51, "When "); +#line hidden + TechTalk.SpecFlow.Table table52 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "MerchantName", + "TransactionNumber", + "ResponseCode", + "ResponseMessage"}); + table52.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "1", + "0000", + "SUCCESS"}); + table52.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 2", + "2", + "0000", + "SUCCESS"}); + table52.AddRow(new string[] { + "Test Estate 2", + "Test Merchant 3", + "3", + "0000", + "SUCCESS"}); + table52.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "4", + "0000", + "SUCCESS"}); + table52.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "5", + "0000", + "SUCCESS"}); + table52.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 2", + "6", + "0000", + "SUCCESS"}); + table52.AddRow(new string[] { + "Test Estate 2", + "Test Merchant 3", + "7", + "0000", + "SUCCESS"}); +#line 97 + testRunner.Then("transaction response should contain the following information", ((string)(null)), table52, "Then "); +#line hidden + } + this.ScenarioCleanup(); + } + + [Xunit.SkippableFactAttribute(DisplayName="Sale Transaction with Invalid Device")] + [Xunit.TraitAttribute("FeatureTitle", "SaleTransaction")] + [Xunit.TraitAttribute("Description", "Sale Transaction with Invalid Device")] + [Xunit.TraitAttribute("Category", "PRTest")] + public virtual void SaleTransactionWithInvalidDevice() + { + string[] tagsOfScenario = new string[] { + "PRTest"}; + System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Sale Transaction with Invalid Device", null, tagsOfScenario, argumentsOfScenario); +#line 108 +this.ScenarioInitialize(scenarioInfo); +#line hidden + bool isScenarioIgnored = default(bool); + bool isFeatureIgnored = default(bool); + if ((tagsOfScenario != null)) + { + isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((this._featureTags != null)) + { + isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((isScenarioIgnored || isFeatureIgnored)) + { + testRunner.SkipScenario(); + } + else + { + this.ScenarioStart(); +#line 4 +this.FeatureBackground(); +#line hidden + TechTalk.SpecFlow.Table table53 = new TechTalk.SpecFlow.Table(new string[] { + "DateTime", + "TransactionNumber", + "TransactionType", + "MerchantName", + "DeviceIdentifier", + "EstateName", + "OperatorName", + "TransactionAmount", + "CustomerAccountNumber", + "CustomerEmailAddress", + "ContractDescription", + "ProductName"}); + table53.AddRow(new string[] { + "Today", + "1", + "Sale", + "Test Merchant 1", + "123456781", + "Test Estate 1", + "Safaricom", + "100.00", + "123456789", + "testcustomer@customer.co.uk", + "Safaricom Contract", + "Variable Topup"}); +#line 110 + testRunner.When("I perform the following transactions", ((string)(null)), table53, "When "); +#line hidden + TechTalk.SpecFlow.Table table54 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "MerchantName", + "TransactionNumber", + "ResponseCode", + "ResponseMessage"}); + table54.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "1", + "1000", + "Device Identifier 123456781 not valid for Merchant Test Merchant 1"}); +#line 114 + testRunner.Then("transaction response should contain the following information", ((string)(null)), table54, "Then "); +#line hidden + } + this.ScenarioCleanup(); + } + + [Xunit.SkippableFactAttribute(DisplayName="Sale Transaction with Invalid Estate")] + [Xunit.TraitAttribute("FeatureTitle", "SaleTransaction")] + [Xunit.TraitAttribute("Description", "Sale Transaction with Invalid Estate")] + public virtual void SaleTransactionWithInvalidEstate() + { + string[] tagsOfScenario = ((string[])(null)); + System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Sale Transaction with Invalid Estate", null, tagsOfScenario, argumentsOfScenario); +#line 118 +this.ScenarioInitialize(scenarioInfo); +#line hidden + bool isScenarioIgnored = default(bool); + bool isFeatureIgnored = default(bool); + if ((tagsOfScenario != null)) + { + isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((this._featureTags != null)) + { + isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((isScenarioIgnored || isFeatureIgnored)) + { + testRunner.SkipScenario(); + } + else + { + this.ScenarioStart(); +#line 4 +this.FeatureBackground(); +#line hidden + TechTalk.SpecFlow.Table table55 = new TechTalk.SpecFlow.Table(new string[] { + "DateTime", + "TransactionNumber", + "TransactionType", + "MerchantName", + "DeviceIdentifier", + "EstateName", + "OperatorName", + "TransactionAmount", + "CustomerAccountNumber", + "CustomerEmailAddress", + "ContractDescription", + "ProductName"}); + table55.AddRow(new string[] { + "Today", + "1", + "Sale", + "Test Merchant 1", + "123456780", + "InvalidEstate", + "Safaricom", + "100.00", + "123456789", + "testcustomer@customer.co.uk", + "Safaricom Contract", + "Variable Topup"}); +#line 120 + testRunner.When("I perform the following transactions", ((string)(null)), table55, "When "); +#line hidden + TechTalk.SpecFlow.Table table56 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "MerchantName", + "TransactionNumber", + "ResponseCode", + "ResponseMessage"}); + table56.AddRow(new string[] { + "InvalidEstate", + "Test Merchant 1", + "1", + "1001", + "Estate Id [79902550-64df-4491-b0c1-4e78943928a3] is not a valid estate"}); +#line 124 + testRunner.Then("transaction response should contain the following information", ((string)(null)), table56, "Then "); +#line hidden + } + this.ScenarioCleanup(); + } + + [Xunit.SkippableFactAttribute(DisplayName="Sale Transaction with Invalid Merchant")] + [Xunit.TraitAttribute("FeatureTitle", "SaleTransaction")] + [Xunit.TraitAttribute("Description", "Sale Transaction with Invalid Merchant")] + public virtual void SaleTransactionWithInvalidMerchant() + { + string[] tagsOfScenario = ((string[])(null)); + System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Sale Transaction with Invalid Merchant", null, tagsOfScenario, argumentsOfScenario); +#line 128 +this.ScenarioInitialize(scenarioInfo); +#line hidden + bool isScenarioIgnored = default(bool); + bool isFeatureIgnored = default(bool); + if ((tagsOfScenario != null)) + { + isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((this._featureTags != null)) + { + isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((isScenarioIgnored || isFeatureIgnored)) + { + testRunner.SkipScenario(); + } + else + { + this.ScenarioStart(); +#line 4 +this.FeatureBackground(); +#line hidden + TechTalk.SpecFlow.Table table57 = new TechTalk.SpecFlow.Table(new string[] { + "DateTime", + "TransactionNumber", + "TransactionType", + "MerchantName", + "DeviceIdentifier", + "EstateName", + "OperatorName", + "TransactionAmount", + "CustomerAccountNumber", + "CustomerEmailAddress", + "ContractDescription", + "ProductName"}); + table57.AddRow(new string[] { + "Today", + "1", + "Sale", + "InvalidMerchant", + "123456780", + "Test Estate 1", + "Safaricom", + "100.00", + "123456789", + "testcustomer@customer.co.uk", + "Safaricom Contract", + "Variable Topup"}); +#line 130 + testRunner.When("I perform the following transactions", ((string)(null)), table57, "When "); +#line hidden + TechTalk.SpecFlow.Table table58 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "MerchantName", + "TransactionNumber", + "ResponseCode", + "ResponseMessage"}); + table58.AddRow(new string[] { + "Test Estate 1", + "InvalidMerchant", + "1", + "1002", + "Merchant Id [d59320fa-4c3e-4900-a999-483f6a10c69a] is not a valid merchant for es" + + "tate [Test Estate 1]"}); +#line 134 + testRunner.Then("transaction response should contain the following information", ((string)(null)), table58, "Then "); +#line hidden + } + this.ScenarioCleanup(); + } + + [Xunit.SkippableFactAttribute(DisplayName="Sale Transaction with Not Enough Credit Available")] + [Xunit.TraitAttribute("FeatureTitle", "SaleTransaction")] + [Xunit.TraitAttribute("Description", "Sale Transaction with Not Enough Credit Available")] + [Xunit.TraitAttribute("Category", "PRTest")] + public virtual void SaleTransactionWithNotEnoughCreditAvailable() + { + string[] tagsOfScenario = new string[] { + "PRTest"}; + System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Sale Transaction with Not Enough Credit Available", null, tagsOfScenario, argumentsOfScenario); +#line 139 +this.ScenarioInitialize(scenarioInfo); +#line hidden + bool isScenarioIgnored = default(bool); + bool isFeatureIgnored = default(bool); + if ((tagsOfScenario != null)) + { + isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((this._featureTags != null)) + { + isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); + } + if ((isScenarioIgnored || isFeatureIgnored)) + { + testRunner.SkipScenario(); + } + else + { + this.ScenarioStart(); +#line 4 +this.FeatureBackground(); +#line hidden + TechTalk.SpecFlow.Table table59 = new TechTalk.SpecFlow.Table(new string[] { + "DateTime", + "TransactionNumber", + "TransactionType", + "MerchantName", + "DeviceIdentifier", + "EstateName", + "OperatorName", + "TransactionAmount", + "CustomerAccountNumber", + "CustomerEmailAddress", + "ContractDescription", + "ProductName"}); + table59.AddRow(new string[] { + "Today", + "1", + "Sale", + "Test Merchant 1", + "123456780", + "Test Estate 1", + "Safaricom", + "300.00", + "123456789", + "testcustomer@customer.co.uk", + "Safaricom Contract", + "Variable Topup"}); +#line 141 + testRunner.When("I perform the following transactions", ((string)(null)), table59, "When "); +#line hidden + TechTalk.SpecFlow.Table table60 = new TechTalk.SpecFlow.Table(new string[] { + "EstateName", + "MerchantName", + "TransactionNumber", + "ResponseCode", + "ResponseMessage"}); + table60.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "1", + "1009", + "Merchant [Test Merchant 1] does not have enough credit available [210.0] to perfo" + + "rm transaction amount [300.00]"}); +#line 146 + testRunner.Then("transaction response should contain the following information", ((string)(null)), table60, "Then "); +#line hidden + } + this.ScenarioCleanup(); + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.5.0.0")] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class FixtureData : System.IDisposable + { + + public FixtureData() + { + SaleTransactionFeature.FeatureSetup(); + } + + void System.IDisposable.Dispose() + { + SaleTransactionFeature.FeatureTearDown(); + } + } + } +} +#pragma warning restore +#endregion