From 5427dbc67b82b33a2b66e7c90cae1eac5eb8bc00 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Fri, 17 Jan 2020 20:19:14 +0000 Subject: [PATCH] Update domain logic on device identifier --- .../Commands/CommandTests.cs | 4 +- .../Services/TransactionDomainServiceTests.cs | 2 +- .../TransactionCommandHandler.cs | 2 +- .../ProcessLogonTransactionCommand.cs | 20 +- .../Services/ITransactionDomainService.cs | 8 +- .../Services/TransactionDomainService.cs | 16 +- .../LogonTransactionRequest.cs | 6 +- .../Shared/SharedSteps.cs | 4 +- TransactionProcessor.Testing/TestData.cs | 10 +- .../TransactionHasStartedEvent.cs | 18 +- .../DomainEventTests.cs | 4 +- .../TransactionAggregateTests.cs | 46 +-- .../TransactionAggregate.cs | 281 +++++++++++++----- .../Controllers/TransactionController.cs | 2 +- 14 files changed, 284 insertions(+), 139 deletions(-) diff --git a/TransactionProcessor.BusinessLogic.Tests/Commands/CommandTests.cs b/TransactionProcessor.BusinessLogic.Tests/Commands/CommandTests.cs index 72912d23..6b94e5d8 100644 --- a/TransactionProcessor.BusinessLogic.Tests/Commands/CommandTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/Commands/CommandTests.cs @@ -14,14 +14,14 @@ public class CommandTests [Fact] public void ProcessLogonTransactionCommand_CanBeCreated_IsCreated() { - ProcessLogonTransactionCommand processLogonTransactionCommand = ProcessLogonTransactionCommand.Create(TestData.TransactionId, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber,TestData.TransactionType, TestData.TransactionDateTime, + ProcessLogonTransactionCommand processLogonTransactionCommand = ProcessLogonTransactionCommand.Create(TestData.TransactionId, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier,TestData.TransactionType, TestData.TransactionDateTime, TestData.TransactionNumber); processLogonTransactionCommand.ShouldNotBeNull(); processLogonTransactionCommand.CommandId.ShouldNotBe(Guid.Empty); processLogonTransactionCommand.EstateId.ShouldBe(TestData.EstateId); processLogonTransactionCommand.MerchantId.ShouldBe(TestData.MerchantId); - processLogonTransactionCommand.IMEINumber.ShouldBe(TestData.IMEINumber); + processLogonTransactionCommand.DeviceIdentifier.ShouldBe(TestData.DeviceIdentifier); processLogonTransactionCommand.TransactionType.ShouldBe(TestData.TransactionType); processLogonTransactionCommand.TransactionDateTime.ShouldBe(TestData.TransactionDateTime); processLogonTransactionCommand.TransactionNumber.ShouldBe(TestData.TransactionNumber); diff --git a/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs b/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs index 0affbb99..b668c3fe 100644 --- a/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs +++ b/TransactionProcessor.BusinessLogic.Tests/Services/TransactionDomainServiceTests.cs @@ -39,7 +39,7 @@ public async Task TransactionDomainService_ProcessLogonTransaction_TransactionIs TestData.MerchantId, TestData.TransactionDateTime, TestData.TransactionNumber, - TestData.IMEINumber, + TestData.DeviceIdentifier, CancellationToken.None); response.ShouldNotBeNull(); diff --git a/TransactionProcessor.BusinessLogic/CommandHandlers/TransactionCommandHandler.cs b/TransactionProcessor.BusinessLogic/CommandHandlers/TransactionCommandHandler.cs index ee74906b..295f3ce5 100644 --- a/TransactionProcessor.BusinessLogic/CommandHandlers/TransactionCommandHandler.cs +++ b/TransactionProcessor.BusinessLogic/CommandHandlers/TransactionCommandHandler.cs @@ -57,7 +57,7 @@ private async Task HandleCommand(ProcessLogonTransactionCommand command, CancellationToken cancellationToken) { ProcessLogonTransactionResponse logonResponse = await this.TransactionDomainService.ProcessLogonTransaction(command.TransactionId, command.EstateId, - command.MerchantId, command.TransactionDateTime, command.TransactionNumber, command.IMEINumber, cancellationToken); + command.MerchantId, command.TransactionDateTime, command.TransactionNumber, command.DeviceIdentifier, cancellationToken); command.Response = logonResponse; } diff --git a/TransactionProcessor.BusinessLogic/Commands/ProcessLogonTransactionCommand.cs b/TransactionProcessor.BusinessLogic/Commands/ProcessLogonTransactionCommand.cs index b0be20f8..43e9c585 100644 --- a/TransactionProcessor.BusinessLogic/Commands/ProcessLogonTransactionCommand.cs +++ b/TransactionProcessor.BusinessLogic/Commands/ProcessLogonTransactionCommand.cs @@ -17,9 +17,10 @@ public class ProcessLogonTransactionCommand : Command /// Initializes a new instance of the class. /// + /// The transaction identifier. /// The estate identifier. /// The merchant identifier. - /// The imei number. + /// The device identifier. /// Type of the transaction. /// The transaction date time. /// The transaction number. @@ -27,7 +28,7 @@ public class ProcessLogonTransactionCommand : Command - /// Gets the imei number. + /// Gets the device identifier. /// /// - /// The imei number. + /// The device identifier. /// - public String IMEINumber { get; } + public String DeviceIdentifier { get; } /// /// Gets the merchant identifier. @@ -101,9 +102,10 @@ private ProcessLogonTransactionCommand(Guid transactionId, /// /// Creates the specified estate identifier. /// + /// The transaction identifier. /// The estate identifier. /// The merchant identifier. - /// The imei number. + /// The device identifier. /// Type of the transaction. /// The transaction date time. /// The transaction number. @@ -111,12 +113,12 @@ private ProcessLogonTransactionCommand(Guid transactionId, public static ProcessLogonTransactionCommand Create(Guid transactionId, Guid estateId, Guid merchantId, - String imeiNumber, + String deviceIdentifier, String transactionType, DateTime transactionDateTime, String transactionNumber) { - return new ProcessLogonTransactionCommand(transactionId, estateId, merchantId, imeiNumber, transactionType, transactionDateTime, transactionNumber, Guid.NewGuid()); + return new ProcessLogonTransactionCommand(transactionId, estateId, merchantId, deviceIdentifier, transactionType, transactionDateTime, transactionNumber, Guid.NewGuid()); } #endregion diff --git a/TransactionProcessor.BusinessLogic/Services/ITransactionDomainService.cs b/TransactionProcessor.BusinessLogic/Services/ITransactionDomainService.cs index 878d3d50..91a78f1b 100644 --- a/TransactionProcessor.BusinessLogic/Services/ITransactionDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/ITransactionDomainService.cs @@ -15,10 +15,16 @@ public interface ITransactionDomainService /// /// Processes the logon transaction. /// + /// The transaction identifier. + /// The estate identifier. + /// The merchant identifier. + /// The transaction date time. + /// The transaction number. + /// The device identifier. /// The cancellation token. /// Task ProcessLogonTransaction(Guid transactionId, Guid estateId, Guid merchantId, DateTime transactionDateTime, - String transactionNumber, String imeiNumber, CancellationToken cancellationToken); + String transactionNumber, String deviceIdentifier, CancellationToken cancellationToken); #endregion } diff --git a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs index 702ba22d..45b84af1 100644 --- a/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs +++ b/TransactionProcessor.BusinessLogic/Services/TransactionDomainService.cs @@ -26,21 +26,21 @@ public TransactionDomainService(IAggregateRepositoryManager aggregateRepositoryM /// /// Processes the logon transaction. /// - /// - /// - /// - /// - /// - /// + /// The transaction identifier. + /// The estate identifier. + /// The merchant identifier. + /// The transaction date time. + /// The transaction number. + /// The device identifier. /// The cancellation token. /// public async Task ProcessLogonTransaction(Guid transactionId, Guid estateId, Guid merchantId, DateTime transactionDateTime, - String transactionNumber, String imeiNumber, CancellationToken cancellationToken) + String transactionNumber, String deviceIdentifier, CancellationToken cancellationToken) { IAggregateRepository transactionAggregateRepository = this.AggregateRepositoryManager.GetAggregateRepository(estateId); TransactionAggregate transactionAggregate = await transactionAggregateRepository.GetLatestVersion(transactionId, cancellationToken); - transactionAggregate.StartTransaction(transactionDateTime, transactionNumber, "Logon", estateId, merchantId, imeiNumber); + transactionAggregate.StartTransaction(transactionDateTime, transactionNumber, "Logon", estateId, merchantId, deviceIdentifier); await transactionAggregateRepository.SaveChanges(transactionAggregate, cancellationToken); transactionAggregate = await transactionAggregateRepository.GetLatestVersion(transactionId, cancellationToken); diff --git a/TransactionProcessor.DataTransferObjects/LogonTransactionRequest.cs b/TransactionProcessor.DataTransferObjects/LogonTransactionRequest.cs index b26a5c66..93915a29 100644 --- a/TransactionProcessor.DataTransferObjects/LogonTransactionRequest.cs +++ b/TransactionProcessor.DataTransferObjects/LogonTransactionRequest.cs @@ -12,12 +12,12 @@ public class LogonTransactionRequest : DataTransferObject #region Properties /// - /// Gets or sets the imei number. + /// Gets or sets the device identifier. /// /// - /// The imei number. + /// The device identifier. /// - public String IMEINumber { get; set; } + public String DeviceIdentifier { get; set; } /// /// Gets or sets the transaction date time. diff --git a/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs b/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs index d4e4874c..91dd9b72 100644 --- a/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs +++ b/TransactionProcessor.IntegrationTests/Shared/SharedSteps.cs @@ -246,7 +246,7 @@ public async Task WhenIPerformTheFollowingTransactions(Table table) } } - private async Task PerformLogonTransaction(Guid estateId, Guid merchantId, DateTime transactionDateTime, String transactionType, String transactionNumber, String imeiNumber, CancellationToken cancellationToken) + private async Task PerformLogonTransaction(Guid estateId, Guid merchantId, DateTime transactionDateTime, String transactionType, String transactionNumber, String deviceIdentifier, CancellationToken cancellationToken) { LogonTransactionRequest logonTransactionRequest = new LogonTransactionRequest { @@ -254,7 +254,7 @@ private async Task PerformLogonTransaction(Guid estateId, Gui EstateId = estateId, TransactionDateTime = transactionDateTime, TransactionNumber = transactionNumber, - IMEINumber = imeiNumber, + DeviceIdentifier = deviceIdentifier, TransactionType = transactionType }; diff --git a/TransactionProcessor.Testing/TestData.cs b/TransactionProcessor.Testing/TestData.cs index 5b62519b..a8bc5737 100644 --- a/TransactionProcessor.Testing/TestData.cs +++ b/TransactionProcessor.Testing/TestData.cs @@ -25,11 +25,11 @@ public class TestData public static Guid TransactionId = Guid.Parse("AE89B2F6-307B-46F4-A8E7-CEF27097D766"); public static ProcessLogonTransactionCommand ProcessLogonTransactionCommand = ProcessLogonTransactionCommand.Create( TestData.TransactionId, TestData.EstateId, TestData.MerchantId, - TestData.IMEINumber, TestData.TransactionType, + TestData.DeviceIdentifier, TestData.TransactionType, TestData.TransactionDateTime, TestData.TransactionNumber); - public static String IMEINumber = "1234567890"; + public static String DeviceIdentifier = "1234567890"; public static String TransactionType = "Logon"; @@ -51,7 +51,7 @@ public static TransactionAggregate GetStartedTransactionAggregate() TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); transactionAggregate.StartTransaction(TestData.TransactionDateTime,TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, - TestData.IMEINumber); + TestData.DeviceIdentifier); return transactionAggregate; } @@ -61,7 +61,7 @@ public static TransactionAggregate GetLocallyAuthorisedTransactionAggregate() TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, - TestData.IMEINumber); + TestData.DeviceIdentifier); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); @@ -73,7 +73,7 @@ public static TransactionAggregate GetCompletedTransactionAggregate() TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, - TestData.IMEINumber); + TestData.DeviceIdentifier); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); diff --git a/TransactionProcessor.Transaction.DomainEvents/TransactionHasStartedEvent.cs b/TransactionProcessor.Transaction.DomainEvents/TransactionHasStartedEvent.cs index 72375625..7ccda29d 100644 --- a/TransactionProcessor.Transaction.DomainEvents/TransactionHasStartedEvent.cs +++ b/TransactionProcessor.Transaction.DomainEvents/TransactionHasStartedEvent.cs @@ -32,7 +32,7 @@ public TransactionHasStartedEvent() /// The transaction date time. /// The transaction number. /// Type of the transaction. - /// The imei number. + /// The device identifier. public TransactionHasStartedEvent(Guid aggregateId, Guid eventId, Guid estateId, @@ -40,7 +40,7 @@ public TransactionHasStartedEvent(Guid aggregateId, DateTime transactionDateTime, String transactionNumber, String transactionType, - String imeiNumber) : base(aggregateId, eventId) + String deviceIdentifier) : base(aggregateId, eventId) { this.TransactionId = aggregateId; this.EstateId = estateId; @@ -48,7 +48,7 @@ public TransactionHasStartedEvent(Guid aggregateId, this.TransactionDateTime = transactionDateTime; this.TransactionNumber = transactionNumber; this.TransactionType = transactionType; - this.ImeiNumber = imeiNumber; + this.DeviceIdentifier = deviceIdentifier; } #endregion @@ -65,13 +65,13 @@ public TransactionHasStartedEvent(Guid aggregateId, public Guid EstateId { get; private set; } /// - /// Gets the imei number. + /// Gets the device identifier. /// /// - /// The imei number. + /// The device identifier. /// [JsonProperty] - public String ImeiNumber { get; private set; } + public String DeviceIdentifier { get; private set; } /// /// Gets the merchant identifier. @@ -131,7 +131,7 @@ public TransactionHasStartedEvent(Guid aggregateId, /// The transaction date time. /// The transaction number. /// Type of the transaction. - /// The imei number. + /// The device identifier. /// public static TransactionHasStartedEvent Create(Guid aggregateId, Guid estateId, @@ -139,9 +139,9 @@ public static TransactionHasStartedEvent Create(Guid aggregateId, DateTime transactionDateTime, String transactionNumber, String transactionType, - String imeiNumber) + String deviceIdentifier) { - return new TransactionHasStartedEvent(aggregateId, Guid.NewGuid(), estateId, merchantId, transactionDateTime, transactionNumber, transactionType, imeiNumber); + return new TransactionHasStartedEvent(aggregateId, Guid.NewGuid(), estateId, merchantId, transactionDateTime, transactionNumber, transactionType, deviceIdentifier); } #endregion diff --git a/TransactionProcessor.TransactionAggregate.Tests/DomainEventTests.cs b/TransactionProcessor.TransactionAggregate.Tests/DomainEventTests.cs index c08e76e0..348e749b 100644 --- a/TransactionProcessor.TransactionAggregate.Tests/DomainEventTests.cs +++ b/TransactionProcessor.TransactionAggregate.Tests/DomainEventTests.cs @@ -20,14 +20,14 @@ public void TransactionHasStartedEvent_CanBeCreated_IsCreated() TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, - TestData.IMEINumber); + TestData.DeviceIdentifier); transactionHasStartedEvent.ShouldNotBeNull(); transactionHasStartedEvent.AggregateId.ShouldBe(TestData.TransactionId); transactionHasStartedEvent.EventCreatedDateTime.ShouldNotBe(DateTime.MinValue); transactionHasStartedEvent.EventId.ShouldNotBe(Guid.Empty); transactionHasStartedEvent.TransactionId.ShouldBe(TestData.TransactionId); transactionHasStartedEvent.EstateId.ShouldBe(TestData.EstateId); - transactionHasStartedEvent.ImeiNumber.ShouldBe(TestData.IMEINumber); + transactionHasStartedEvent.DeviceIdentifier.ShouldBe(TestData.DeviceIdentifier); transactionHasStartedEvent.MerchantId.ShouldBe(TestData.MerchantId); transactionHasStartedEvent.TransactionDateTime.ShouldBe(TestData.TransactionDateTime); transactionHasStartedEvent.TransactionNumber.ShouldBe(TestData.TransactionNumber); diff --git a/TransactionProcessor.TransactionAggregate.Tests/TransactionAggregateTests.cs b/TransactionProcessor.TransactionAggregate.Tests/TransactionAggregateTests.cs index 61df6af4..bf0cf4cd 100644 --- a/TransactionProcessor.TransactionAggregate.Tests/TransactionAggregateTests.cs +++ b/TransactionProcessor.TransactionAggregate.Tests/TransactionAggregateTests.cs @@ -20,7 +20,7 @@ public void TransactionAggregate_CanBeCreated_IsCreated() public void TransactionAggregate_StartTransaction_TransactionIsStarted() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); transactionAggregate.IsStarted.ShouldBeTrue(); transactionAggregate.TransactionDateTime.ShouldBe(TestData.TransactionDateTime); @@ -28,14 +28,14 @@ public void TransactionAggregate_StartTransaction_TransactionIsStarted() transactionAggregate.TransactionType.ShouldBe(TestData.TransactionType); transactionAggregate.EstateId.ShouldBe(TestData.EstateId); transactionAggregate.MerchantId.ShouldBe(TestData.MerchantId); - transactionAggregate.IMEINumber.ShouldBe(TestData.IMEINumber); + transactionAggregate.DeviceIdentifier.ShouldBe(TestData.DeviceIdentifier); } [Fact] public void TransactionAggregate_StartTransaction_TransactionAlreadyStarted_ErrorThrown() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); Should.Throw(() => { @@ -44,7 +44,7 @@ public void TransactionAggregate_StartTransaction_TransactionAlreadyStarted_Erro TestData.TransactionType, TestData.EstateId, TestData.MerchantId, - TestData.IMEINumber); + TestData.DeviceIdentifier); }); } @@ -52,7 +52,7 @@ public void TransactionAggregate_StartTransaction_TransactionAlreadyStarted_Erro public void TransactionAggregate_StartTransaction_TransactionAlreadyCompleted_ErrorThrown() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); transactionAggregate.CompleteTransaction(); @@ -63,24 +63,24 @@ public void TransactionAggregate_StartTransaction_TransactionAlreadyCompleted_Er TestData.TransactionType, TestData.EstateId, TestData.MerchantId, - TestData.IMEINumber); + TestData.DeviceIdentifier); }); } [Theory] - [InlineData(false, "0001", "Logon", true, true, "1234567890" )] - [InlineData(true, "", "Logon", true, true, "1234567890")] - [InlineData(true, null, "Logon", true, true, "1234567890")] - [InlineData(true, "ABCD", "Logon", true, true, "1234567890")] - [InlineData(true, "0001", "", true, true, "1234567890")] - [InlineData(true, "0001", null, true, true, "1234567890")] - [InlineData(true, "0001", "Invalid", true, true, "1234567890")] - [InlineData(true, "0001", "Logon", false, true, "1234567890")] - [InlineData(true, "0001", "Logon", true, false, "1234567890")] + [InlineData(false, "0001", "Logon", true, true, "A1234567890" )] + [InlineData(true, "", "Logon", true, true, "A1234567890")] + [InlineData(true, null, "Logon", true, true, "A1234567890")] + [InlineData(true, "ABCD", "Logon", true, true, "A1234567890")] + [InlineData(true, "0001", "", true, true, "A1234567890")] + [InlineData(true, "0001", null, true, true, "A1234567890")] + [InlineData(true, "0001", "Invalid", true, true, "A1234567890")] + [InlineData(true, "0001", "Logon", false, true, "A1234567890")] + [InlineData(true, "0001", "Logon", true, false, "A1234567890")] [InlineData(true, "0001", "Logon", true, true, "")] [InlineData(true, "0001", "Logon", true, true, null)] - [InlineData(true, "0001", "Logon", true, true, "ABCD")] - public void TransactionAggregate_StartTransaction_InvalidData_ErrorThrown(Boolean validTransactionDateTime, String transactionNumber, String transactionType, Boolean validEstateId, Boolean validMerchantId, String imeiNumber) + [InlineData(true, "0001", "Logon", true, true, "A!234567890")] + public void TransactionAggregate_StartTransaction_InvalidData_ErrorThrown(Boolean validTransactionDateTime, String transactionNumber, String transactionType, Boolean validEstateId, Boolean validMerchantId, String deviceIdentifier) { DateTime transactionDateTime = validTransactionDateTime ? TestData.TransactionDateTime : DateTime.MinValue; Guid estateId = validEstateId ? TestData.EstateId : Guid.Empty; @@ -95,7 +95,7 @@ public void TransactionAggregate_StartTransaction_InvalidData_ErrorThrown(Boolea transactionType, estateId, merchantId, - imeiNumber); + deviceIdentifier); }); } @@ -103,7 +103,7 @@ public void TransactionAggregate_StartTransaction_InvalidData_ErrorThrown(Boolea public void TransactionAggregate_AuthoriseTransactionLocally_TransactionIsAuthorised() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); @@ -131,7 +131,7 @@ public void TransactionAggregate_AuthoriseTransactionLocally_TransactionNotStart public void TransactionAggregate_AuthoriseTransactionLocally_TransactionAlreadyAuthorised_ErrorThrown() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); Should.Throw(() => @@ -146,7 +146,7 @@ public void TransactionAggregate_AuthoriseTransactionLocally_TransactionAlreadyA public void TransactionAggregate_CompleteTransaction_TransactionIsCompleted() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); transactionAggregate.CompleteTransaction(); @@ -169,7 +169,7 @@ public void TransactionAggregate_CompleteTransaction_TransactionNotStarted_Error public void TransactionAggregate_CompleteTransaction_TransactionNotAuthorised_ErrorThrown() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); Should.Throw(() => { @@ -180,7 +180,7 @@ public void TransactionAggregate_CompleteTransaction_TransactionNotAuthorised_Er public void TransactionAggregate_CompleteTransaction_TransactionAlreadyCompleted_ErrorThrown() { TransactionAggregate transactionAggregate = TransactionAggregate.Create(TestData.TransactionId); - transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.IMEINumber); + transactionAggregate.StartTransaction(TestData.TransactionDateTime, TestData.TransactionNumber, TestData.TransactionType, TestData.EstateId, TestData.MerchantId, TestData.DeviceIdentifier); transactionAggregate.AuthoriseTransactionLocally(TestData.AuthorisationCode, TestData.ResponseCode, TestData.ResponseMessage); transactionAggregate.CompleteTransaction(); diff --git a/TransactionProcessor.TransactionAgrgegate/TransactionAggregate.cs b/TransactionProcessor.TransactionAgrgegate/TransactionAggregate.cs index 4eb08eba..796ce00d 100644 --- a/TransactionProcessor.TransactionAgrgegate/TransactionAggregate.cs +++ b/TransactionProcessor.TransactionAgrgegate/TransactionAggregate.cs @@ -2,6 +2,7 @@ { using System; using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; using Shared.DomainDrivenDesign.EventSourcing; using Shared.DomainDrivenDesign.EventStore; using Shared.General; @@ -37,6 +38,114 @@ private TransactionAggregate(Guid aggregateId) #endregion + #region Properties + + /// + /// Gets the authorisation code. + /// + /// + /// The authorisation code. + /// + public String AuthorisationCode { get; private set; } + + /// + /// Gets the device identifier. + /// + /// + /// The device identifier. + /// + public String DeviceIdentifier { get; private set; } + + /// + /// Gets the estate identifier. + /// + /// + /// The estate identifier. + /// + public Guid EstateId { get; private set; } + + /// + /// Gets a value indicating whether this instance is authorised. + /// + /// + /// true if this instance is authorised; otherwise, false. + /// + public Boolean IsAuthorised { get; private set; } + + /// + /// Gets a value indicating whether this instance is completed. + /// + /// + /// true if this instance is completed; otherwise, false. + /// + public Boolean IsCompleted { get; private set; } + + /// + /// Gets a value indicating whether this instance is locally authorised. + /// + /// + /// true if this instance is locally authorised; otherwise, false. + /// + public Boolean IsLocallyAuthorised { get; private set; } + + /// + /// Gets a value indicating whether this instance is started. + /// + /// + /// true if this instance is started; otherwise, false. + /// + public Boolean IsStarted { get; private set; } + + /// + /// Gets the merchant identifier. + /// + /// + /// The merchant identifier. + /// + public Guid MerchantId { get; private set; } + + /// + /// Gets the response code. + /// + /// + /// The response code. + /// + public String ResponseCode { get; private set; } + + /// + /// Gets the response message. + /// + /// + /// The response message. + /// + public String ResponseMessage { get; private set; } + + /// + /// Gets the transaction date time. + /// + /// + /// The transaction date time. + /// + public DateTime TransactionDateTime { get; private set; } + + /// + /// Gets the transaction number. + /// + /// + /// The transaction number. + /// + public String TransactionNumber { get; private set; } + + /// + /// Gets the type of the transaction. + /// + /// + /// The type of the transaction. + /// + public String TransactionType { get; private set; } + + #endregion + #region Methods /// @@ -46,33 +155,15 @@ private TransactionAggregate(Guid aggregateId) /// The response code. /// The response message. public void AuthoriseTransactionLocally(String authorisationCode, - String responseCode, - String responseMessage) + String responseCode, + String responseMessage) { this.CheckTransactionHasBeenStarted(); this.CheckTransactionNotAlreadyAuthorised(); - TransactionHasBeenLocallyAuthorisedEvent transactionHasBeenLocallyAuthorisedEvent = TransactionHasBeenLocallyAuthorisedEvent.Create(this.AggregateId, this.EstateId, this.MerchantId, authorisationCode, responseCode, responseMessage); + TransactionHasBeenLocallyAuthorisedEvent transactionHasBeenLocallyAuthorisedEvent = + TransactionHasBeenLocallyAuthorisedEvent.Create(this.AggregateId, this.EstateId, this.MerchantId, authorisationCode, responseCode, responseMessage); this.ApplyAndPend(transactionHasBeenLocallyAuthorisedEvent); - - - } - - private void CheckTransactionNotAlreadyAuthorised() - { - if (this.IsLocallyAuthorised || this.IsAuthorised) - { - String authtype = this.IsLocallyAuthorised ? " locally " : " "; - throw new InvalidOperationException($"Transaction [{this.AggregateId}] has already been{authtype}authorised"); - } - } - - private void CheckTransactionHasBeenStarted() - { - if (this.IsStarted == false) - { - throw new InvalidOperationException($"Transaction [{this.AggregateId}] has not been started"); - } } /// @@ -84,21 +175,12 @@ public void CompleteTransaction() this.CheckTransactionHasBeenAuthorised(); this.CheckTransactionNotAlreadyCompleted(); - TransactionHasBeenCompletedEvent transactionHasBeenCompletedEvent = TransactionHasBeenCompletedEvent.Create(this.AggregateId, this.EstateId, this.MerchantId, - this.ResponseCode, this.ResponseMessage, - true); + TransactionHasBeenCompletedEvent transactionHasBeenCompletedEvent = + TransactionHasBeenCompletedEvent.Create(this.AggregateId, this.EstateId, this.MerchantId, this.ResponseCode, this.ResponseMessage, true); this.ApplyAndPend(transactionHasBeenCompletedEvent); } - private void CheckTransactionHasBeenAuthorised() - { - if (this.IsAuthorised == false && this.IsLocallyAuthorised == false) - { - throw new InvalidOperationException($"Transaction [{this.AggregateId}] has not been authorised"); - } - } - /// /// Creates the specified aggregate identifier. /// @@ -116,20 +198,6 @@ public void DeclineTransaction() { } - public DateTime TransactionDateTime { get; private set; } - public String TransactionNumber { get; private set; } - public String TransactionType { get; private set; } - public Guid EstateId { get; private set; } - public Guid MerchantId { get; private set; } - public String IMEINumber { get; private set; } - public Boolean IsStarted { get; private set; } - public Boolean IsCompleted { get; private set; } - - public Boolean IsLocallyAuthorised { get; private set; } - public String AuthorisationCode { get; private set; } - public String ResponseCode { get; private set; } - public String ResponseMessage { get; private set; } - public Boolean IsAuthorised { get; private set; } /// /// Starts the transaction. /// @@ -138,50 +206,117 @@ public void DeclineTransaction() /// Type of the transaction. /// The estate identifier. /// The merchant identifier. - /// The imei number. + /// The device identifier. + /// + /// Transaction Number must be numeric + /// or + /// Invalid Transaction Type [{transactionType}] + /// or + /// Device Identifier must be alphanumeric + /// public void StartTransaction(DateTime transactionDateTime, String transactionNumber, String transactionType, Guid estateId, Guid merchantId, - String imeiNumber) + String deviceIdentifier) { Guard.ThrowIfInvalidDate(transactionDateTime, typeof(ArgumentException), $"Transaction Date Time must not be [{DateTime.MinValue}]"); Guard.ThrowIfNullOrEmpty(transactionNumber, typeof(ArgumentException), "Transaction Number must not be null or empty"); - if (Int32.TryParse(transactionNumber, out Int32 txnnumber) == false) + if (int.TryParse(transactionNumber, out Int32 txnnumber) == false) { throw new ArgumentException("Transaction Number must be numeric"); } + Guard.ThrowIfNullOrEmpty(transactionType, typeof(ArgumentException), "Transaction Type must not be null or empty"); // Temporary validation until using enum if (transactionType != "Logon") { - throw new ArgumentException($"Invalid Transaction Type [{transactionType}]"); + throw new ArgumentException($"Invalid Transaction Type [{transactionType}]"); } + Guard.ThrowIfInvalidGuid(estateId, typeof(ArgumentException), $"Estate Id must not be [{Guid.Empty}]"); Guard.ThrowIfInvalidGuid(merchantId, typeof(ArgumentException), $"Merchant Id must not be [{Guid.Empty}]"); - Guard.ThrowIfNullOrEmpty(imeiNumber, typeof(ArgumentException), "IMEI Number must not be null or empty"); - if (Int32.TryParse(imeiNumber, out Int32 imei) == false) + Guard.ThrowIfNullOrEmpty(deviceIdentifier, typeof(ArgumentException), "Device Identifier must not be null or empty"); + + Regex r = new Regex("^[a-zA-Z0-9]*$"); + if (r.IsMatch(deviceIdentifier) == false) { - throw new ArgumentException("IMEI Number must be numeric"); + throw new ArgumentException("Device Identifier must be alphanumeric"); } this.CheckTransactionNotAlreadyStarted(); this.CheckTransactionNotAlreadyCompleted(); - TransactionHasStartedEvent transactionHasStartedEvent = TransactionHasStartedEvent.Create(this.AggregateId, estateId, merchantId, transactionDateTime, transactionNumber,transactionType, imeiNumber); + TransactionHasStartedEvent transactionHasStartedEvent = + TransactionHasStartedEvent.Create(this.AggregateId, estateId, merchantId, transactionDateTime, transactionNumber, transactionType, deviceIdentifier); this.ApplyAndPend(transactionHasStartedEvent); } - private void CheckTransactionNotAlreadyStarted() + /// + /// Gets the metadata. + /// + /// + [ExcludeFromCodeCoverage] + protected override Object GetMetadata() { - if (this.IsStarted) + return new + { + this.EstateId + }; + } + + /// + /// Plays the event. + /// + /// The domain event. + protected override void PlayEvent(DomainEvent domainEvent) + { + this.PlayEvent((dynamic)domainEvent); + } + + /// + /// Checks the transaction has been authorised. + /// + /// Transaction [{this.AggregateId}] has not been authorised + private void CheckTransactionHasBeenAuthorised() + { + if (this.IsAuthorised == false && this.IsLocallyAuthorised == false) { - throw new InvalidOperationException($"Transaction Id [{this.AggregateId}] has already been started"); + throw new InvalidOperationException($"Transaction [{this.AggregateId}] has not been authorised"); } } + /// + /// Checks the transaction has been started. + /// + /// Transaction [{this.AggregateId}] has not been started + private void CheckTransactionHasBeenStarted() + { + if (this.IsStarted == false) + { + throw new InvalidOperationException($"Transaction [{this.AggregateId}] has not been started"); + } + } + + /// + /// Checks the transaction not already authorised. + /// + /// Transaction [{this.AggregateId}] has already been{authtype}authorised + private void CheckTransactionNotAlreadyAuthorised() + { + if (this.IsLocallyAuthorised || this.IsAuthorised) + { + String authtype = this.IsLocallyAuthorised ? " locally " : " "; + throw new InvalidOperationException($"Transaction [{this.AggregateId}] has already been{authtype}authorised"); + } + } + + /// + /// Checks the transaction not already completed. + /// + /// Transaction Id [{this.AggregateId}] has already been completed private void CheckTransactionNotAlreadyCompleted() { if (this.IsCompleted) @@ -191,38 +326,36 @@ private void CheckTransactionNotAlreadyCompleted() } /// - /// Gets the metadata. + /// Checks the transaction not already started. /// - /// - [ExcludeFromCodeCoverage] - protected override Object GetMetadata() + /// Transaction Id [{this.AggregateId}] has already been started + private void CheckTransactionNotAlreadyStarted() { - return new - { - EstateId = this.EstateId - }; + if (this.IsStarted) + { + throw new InvalidOperationException($"Transaction Id [{this.AggregateId}] has already been started"); + } } /// /// Plays the event. /// /// The domain event. - protected override void PlayEvent(DomainEvent domainEvent) - { - this.PlayEvent((dynamic)domainEvent); - } - private void PlayEvent(TransactionHasStartedEvent domainEvent) { this.MerchantId = domainEvent.MerchantId; this.EstateId = domainEvent.EstateId; - this.IMEINumber = domainEvent.ImeiNumber; + this.DeviceIdentifier = domainEvent.DeviceIdentifier; this.IsStarted = true; this.TransactionDateTime = domainEvent.TransactionDateTime; this.TransactionNumber = domainEvent.TransactionNumber; this.TransactionType = domainEvent.TransactionType; } + /// + /// Plays the event. + /// + /// The domain event. private void PlayEvent(TransactionHasBeenLocallyAuthorisedEvent domainEvent) { this.IsLocallyAuthorised = true; @@ -231,6 +364,10 @@ private void PlayEvent(TransactionHasBeenLocallyAuthorisedEvent domainEvent) this.AuthorisationCode = domainEvent.AuthorisationCode; } + /// + /// Plays the event. + /// + /// The domain event. private void PlayEvent(TransactionHasBeenCompletedEvent domainEvent) { this.IsStarted = false; // Transaction has reached its final state diff --git a/TransactionProcessor/Controllers/TransactionController.cs b/TransactionProcessor/Controllers/TransactionController.cs index 96293022..0cdfa703 100644 --- a/TransactionProcessor/Controllers/TransactionController.cs +++ b/TransactionProcessor/Controllers/TransactionController.cs @@ -104,7 +104,7 @@ private async Task ProcessSpecificMessage(LogonTransactionReq ProcessLogonTransactionCommand command = ProcessLogonTransactionCommand.Create(transactionId, logonTransactionRequest.EstateId, logonTransactionRequest.MerchantId, - logonTransactionRequest.IMEINumber, + logonTransactionRequest.DeviceIdentifier, logonTransactionRequest.TransactionType, logonTransactionRequest.TransactionDateTime, logonTransactionRequest.TransactionNumber);