Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions TransactionProcessor.IntegrationTesting.Helpers/EstateDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ public Guid GetMerchantId(String merchantName)
return Guid.Parse("D59320FA-4C3E-4900-A999-483F6A10C69A");
}

return this.Merchants.Single(m => m.MerchantName == merchantName).MerchantId;
TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantResponse? merchant = this.Merchants.SingleOrDefault(m => m.MerchantName == merchantName);
if (merchant == null)
{
throw new InvalidOperationException($"Merchant '{merchantName}' was not found on estate '{this.EstateName}'.");
}

return merchant.MerchantId;
}

public void AddTransactionResponse(Guid merchantId,
Expand Down Expand Up @@ -104,15 +110,21 @@ public void AddMerchant(TransactionProcessor.DataTransferObjects.Responses.Merch
// make sure the merchant does not already exist
if (this.Merchants.Any(m => m.MerchantId == merchant.MerchantId))
{
return;
throw new InvalidOperationException($"Merchant [{merchant.MerchantId}] already exists in estate [{this.EstateId}].");
}

this.Merchants.Add(merchant);
}

public Contract GetContract(String contractName)
{
return this.Contracts.Single(c => c.Description == contractName);
Contract? contract = this.Contracts.SingleOrDefault(c => c.Description == contractName);
if (contract == null)
{
throw new InvalidOperationException($"Contract '{contractName}' was not found on estate '{this.EstateName}'.");
}

return contract;
}
public Contract GetContract(Guid contractId)
{
Expand All @@ -121,7 +133,13 @@ public Contract GetContract(Guid contractId)

public TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantResponse GetMerchant(String merchantName)
{
return this.Merchants.SingleOrDefault(m => m.MerchantName == merchantName);
TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantResponse? merchant = this.Merchants.SingleOrDefault(m => m.MerchantName == merchantName);
if (merchant == null)
{
throw new InvalidOperationException($"Merchant '{merchantName}' was not found on estate '{this.EstateName}'.");
}

return merchant;
}

public List<TransactionProcessor.DataTransferObjects.Responses.Merchant.MerchantResponse> GetMerchants()
Expand Down Expand Up @@ -238,7 +256,13 @@ public Product GetProduct(Guid productId)

public Product GetProduct(String name)
{
return this.Products.SingleOrDefault(p => p.Name == name);
Product? product = this.Products.SingleOrDefault(p => p.Name == name);
if (product == null)
{
throw new InvalidOperationException($"Product '{name}' was not found on contract '{this.Description}'.");
}

return product;
}
}

Expand Down
136 changes: 78 additions & 58 deletions TransactionProcessor.IntegrationTesting.Helpers/SpecflowExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public class SettlementFeeDetails

public static SettlementDetails ToSettlementDetails(this DataTableRows tableRows, string estateName, List<EstateDetails> estateDetailsList)
{
tableRows.Count.ShouldBe(1, "Settlement details require exactly one table row.");
SettlementDetails result = new SettlementDetails();

EstateDetails estateDetails = estateDetailsList.SingleOrDefault(e => e.EstateName == estateName);
Expand Down Expand Up @@ -152,6 +153,7 @@ public static Guid CalculateSettlementAggregateId(DateTime settlementDate,
public static SettlementDetails ToSettlementDetails(this DataTableRows tableRows, string estateName,
string merchantName, List<EstateDetails> estateDetailsList)
{
tableRows.Count.ShouldBe(1, "Settlement details require exactly one table row.");
SettlementDetails result = new SettlementDetails();

EstateDetails estateDetails = estateDetailsList.SingleOrDefault(e => e.EstateName == estateName);
Expand Down Expand Up @@ -192,6 +194,7 @@ public static List<SettlementFeeDetails> ToSettlementFeeDetails(this DataTableRo
settlementFeeDetails.IsSettled = ReqnrollTableHelper.GetBooleanValue(tableRow, "IsSettled");
settlementFeeDetails.Operator = ReqnrollTableHelper.GetStringRowValue(tableRow, "Operator");
settlementFeeDetails.CalculatedValue = ReqnrollTableHelper.GetDecimalValue(tableRow, "CalculatedValue");
settlementFeeDetailsList.Add(settlementFeeDetails);
}
return settlementFeeDetailsList;
}
Expand All @@ -207,27 +210,24 @@ public static List<SettlementFeeDetails> ToSettlementFeeDetails(this DataTableRo
EstateDetails estateDetails = estateDetailsList.SingleOrDefault(e => e.EstateName == estateName);
estateDetails.ShouldNotBeNull();

foreach (DataTableRow dataTableRow in tableRows)
{

String merchantName = ReqnrollTableHelper.GetStringRowValue(tableRow, "MerchantName");
MerchantResponse merchant = estateDetails.GetMerchant(merchantName);
String merchantName = ReqnrollTableHelper.GetStringRowValue(tableRow, "MerchantName");
MerchantResponse merchant = estateDetails.GetMerchant(merchantName);

Guid addressId = merchant.Addresses.First().AddressId;
merchant.Addresses.ShouldHaveSingleItem();
Guid addressId = merchant.Addresses.Single().AddressId;

Address addressUpdateRequest = new Address()
{
AddressLine1 = ReqnrollTableHelper.GetStringRowValue(tableRow, "AddressLine1"),
AddressLine2 = ReqnrollTableHelper.GetStringRowValue(tableRow, "AddressLine2"),
AddressLine3 = ReqnrollTableHelper.GetStringRowValue(tableRow, "AddressLine3"),
AddressLine4 = ReqnrollTableHelper.GetStringRowValue(tableRow, "AddressLine4"),
Town = ReqnrollTableHelper.GetStringRowValue(tableRow, "Town"),
Region = ReqnrollTableHelper.GetStringRowValue(tableRow, "Region"),
Country = ReqnrollTableHelper.GetStringRowValue(tableRow, "Country"),
PostalCode = ReqnrollTableHelper.GetStringRowValue(tableRow, "PostalCode")
};
result.Add((estateDetails, merchant, addressId, addressUpdateRequest));
}
Address addressUpdateRequest = new Address()
{
AddressLine1 = ReqnrollTableHelper.GetStringRowValue(tableRow, "AddressLine1"),
AddressLine2 = ReqnrollTableHelper.GetStringRowValue(tableRow, "AddressLine2"),
AddressLine3 = ReqnrollTableHelper.GetStringRowValue(tableRow, "AddressLine3"),
AddressLine4 = ReqnrollTableHelper.GetStringRowValue(tableRow, "AddressLine4"),
Town = ReqnrollTableHelper.GetStringRowValue(tableRow, "Town"),
Region = ReqnrollTableHelper.GetStringRowValue(tableRow, "Region"),
Country = ReqnrollTableHelper.GetStringRowValue(tableRow, "Country"),
PostalCode = ReqnrollTableHelper.GetStringRowValue(tableRow, "PostalCode")
};
result.Add((estateDetails, merchant, addressId, addressUpdateRequest));

}

Expand All @@ -245,22 +245,19 @@ public static List<SettlementFeeDetails> ToSettlementFeeDetails(this DataTableRo
EstateDetails estateDetails = estateDetailsList.SingleOrDefault(e => e.EstateName == estateName);
estateDetails.ShouldNotBeNull();

foreach (DataTableRow dataTableRow in tableRows)
{

String merchantName = ReqnrollTableHelper.GetStringRowValue(tableRow, "MerchantName");
MerchantResponse merchant = estateDetails.GetMerchant(merchantName);
String merchantName = ReqnrollTableHelper.GetStringRowValue(tableRow, "MerchantName");
MerchantResponse merchant = estateDetails.GetMerchant(merchantName);

Guid contactId = merchant.Contacts.First().ContactId;
merchant.Contacts.ShouldHaveSingleItem();
Guid contactId = merchant.Contacts.Single().ContactId;

Contact contactUpdateRequest = new Contact()
{
ContactName = ReqnrollTableHelper.GetStringRowValue(tableRow, "ContactName"),
EmailAddress = ReqnrollTableHelper.GetStringRowValue(tableRow, "EmailAddress"),
PhoneNumber = ReqnrollTableHelper.GetStringRowValue(tableRow, "PhoneNumber"),
};
result.Add((estateDetails, merchant, contactId, contactUpdateRequest));
}
Contact contactUpdateRequest = new Contact()
{
ContactName = ReqnrollTableHelper.GetStringRowValue(tableRow, "ContactName"),
EmailAddress = ReqnrollTableHelper.GetStringRowValue(tableRow, "EmailAddress"),
PhoneNumber = ReqnrollTableHelper.GetStringRowValue(tableRow, "PhoneNumber"),
};
result.Add((estateDetails, merchant, contactId, contactUpdateRequest));
}

return result;
Expand Down Expand Up @@ -521,37 +518,60 @@ public static List<String> ToAutomaticDepositRequests(this DataTableRows tableRo
Guid contractId = Guid.Empty;
Guid productId = Guid.Empty;
Contract contract = null;
Product product = null;
try{
contract = estateDetails.GetContract(contractDescription);
}
catch(Exception ex){

// InvalidEstate is a deliberate negative-test fixture. It has enough metadata to
// build the request, but it intentionally has no real contracts or products.
// Keep this explicit exception local to that fixture; unknown names on normal
// estates must still fail fast instead of being converted to synthetic IDs.
if (estateDetails.EstateName == "InvalidEstate")
{
contractId = Guid.NewGuid();
productId = Guid.NewGuid();
}

if (contract != null){
contractId = contract.ContractId;
product = contract.GetProduct(productName);
if (product != null){
productId = product.ProductId;
else if (contractDescription == "EmptyContract")
{
contractId = Guid.Empty;
}
else if (contractDescription == "InvalidContract")
{
contractId = Guid.Parse("934d8164-f36a-448e-b27b-4d671d41d180");
}
else
{
try
{
contract = estateDetails.GetContract(contractDescription);
}
else{
productId = productName switch{
"EmptyProduct" => Guid.Empty,
"InvalidProduct" => Guid.Parse("934d8164-f36a-448e-b27b-4d671d41d180"),
_ => Guid.NewGuid(),
};
catch (InvalidOperationException)
{
throw new InvalidOperationException($"Contract '{contractDescription}' was not found on estate '{estateDetails.EstateName}'.");
}
}
else{
// This is a nasty hack atm...
contractId = contractDescription switch{
"EmptyContract" => Guid.Empty,
"InvalidContract" => Guid.Parse("934d8164-f36a-448e-b27b-4d671d41d180"),
_ => Guid.NewGuid(),
};

contractId = contract.ContractId;
}

if (contract != null)
{
if (productName == "EmptyProduct")
{
productId = Guid.Empty;
}
else if (productName == "InvalidProduct")
{
productId = Guid.Parse("934d8164-f36a-448e-b27b-4d671d41d180");
}
else
{
try
{
Product product = contract.GetProduct(productName);
productId = product.ProductId;
}
catch (InvalidOperationException)
{
throw new InvalidOperationException($"Product '{productName}' was not found on contract '{contractDescription}'.");
}
}
}

Guid operatorId = estateDetails.GetOperatorId(operatorName);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Linq;
using TransactionProcessor.DataTransferObjects.Requests.Contract;
using TransactionProcessor.DataTransferObjects.Responses.Contract;

namespace TransactionProcessor.IntegrationTesting.Helpers;

public static class TransactionFeeMatcher
{
public static ContractProductTransactionFee? Find(
IEnumerable<ContractProductTransactionFee> fees,
AddTransactionFeeForProductToContractRequest request)
{
return fees.SingleOrDefault(fee => fee.Description == request.Description &&
fee.CalculationType == request.CalculationType &&
fee.FeeType == request.FeeType &&
fee.Value == request.Value);
}
}
Loading
Loading