public MakePaymentResult MakePayment(MakePaymentRequest request) { // Although the implementation of the datastores is quite straightforward, we will more likely than not, want to expand it // by making it runtime configurable, in a more dynamic fashion than an app.config file var dataStore = DataStoreService.GetAccountDataStore(); var account = dataStore.GetAccount(request.DebtorAccountNumber); var result = new MakePaymentResult { Success = RulesService.IsMovementAuthorized(account, request.PaymentScheme, request.Amount) }; if (!result.Success) { LogService.LogException( new ConstraintException("Unable to make payment, rules engine rejected the operation")); return(result); } account.Balance -= request.Amount; // Update debtor account dataStore.UpdateAccount(account); // Question pending: does the creditor account not need to have the funds deposited? // Log the successfull operation LogService.LogOperation(request, result); return(result); }
public void MakePayment_ReturnsFailureIfAccountNotFound() { // Arrange var dataStore = new Mock <IAccountDataStore>(); dataStore.Setup(ds => ds.GetAccount(It.IsAny <string>())).Returns((Account)null); var accountDataStoreFactory = new Mock <IAccountDataStoreFactory>(); accountDataStoreFactory.Setup(f => f.BuildAccountDataStore()).Returns(dataStore.Object); var validator = new Mock <IValidator>(); validator.Setup(v => v.AccountCanMakePayment(It.IsAny <Account>())).Returns(true); var validatorFactory = new Mock <IValidatorFactory>(); validatorFactory.Setup(vf => vf.BuildValidator(It.IsAny <MakePaymentRequest>())).Returns(validator.Object); var service = new PaymentService(accountDataStoreFactory.Object, validatorFactory.Object); // Act MakePaymentResult result = service.MakePayment(new MakePaymentRequest()); // Assert Assert.IsFalse(result.Success); dataStore.Verify(ds => ds.UpdateAccount(It.IsAny <Account>()), Times.Never); }
public void Test_PaymentService_MakePayment_Success() { // arrange MakePaymentRequest makePaymentRequest = new MakePaymentRequest { Amount = 50, CreditorAccountNumber = "PR2408", DebtorAccountNumber = "DC2404", PaymentDate = DateTime.Now, PaymentScheme = PaymentScheme.Bacs }; Account account = new Account { AccountNumber = "PR2408", AllowedPaymentSchemes = AllowedPaymentSchemes.Bacs | AllowedPaymentSchemes.Chaps, Balance = 250, Status = AccountStatus.Live, }; MakePaymentResult makePaymentResult = new MakePaymentResult { Success = true }; _accountDataStore.Setup(x => x.GetAccount(makePaymentRequest.DebtorAccountNumber)).Returns(account); _accountDataStoreFactory.Setup(x => x.AccountDataStore(It.IsAny <string>())).Returns(_accountDataStore.Object); _makePaymentRequestValidator.Setup(x => x.IsAccountValidToMakePayment(account, makePaymentRequest)).Returns(makePaymentResult); // act makePaymentResult = _paymentSrevice.MakePayment(makePaymentRequest); // assert Assert.AreEqual(account.Balance, 200); Assert.AreEqual(makePaymentResult.Success, true); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { Account account = GetAccount(request.DebitorAccountNumber) ?? null; var result = new MakePaymentResult(); if (IsPaymentAllowed(request, account)) { try { account.Balance -= request.Amount; // A call to do the actual transfer should be here result.Success = true; _datastore.UpdateAccount(account); } catch (Exception e) { Console.WriteLine("An error occurred while making the payment: '{0}'", e); } } else { result.Success = false; } return(result); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { var result = new MakePaymentResult(); var dataStoreType = ConfigurationManager.AppSettings["DataStoreType"] ?? String.Empty; var accountDataStore = _accountDataStoreFactory.Create(dataStoreType); var account = accountDataStore.GetAccount(request.DebtorAccountNumber); if (account == null) { return(result); } var paymentRule = _paymentRuleFactory.Create(request.PaymentScheme); if (paymentRule.IsPaymentAllowed(account, request.Amount)) { account.Balance -= request.Amount; accountDataStore.UpdateAccount(account); //Have incorporated unit of work so account check and update can be atomic accountDataStore.Commit(); result.Success = true; } return(result); }
public void MakePaymentRequestWithInvalidPayementScheme() { Dictionary <String, Object> debitorAccount = (Dictionary <String, Object>)context["DebitorAccount"]; Dictionary <String, Object> creditorAccount = (Dictionary <String, Object>)context["CreditorAccount"]; DateTime paymentDate = DateTime.Now; string creditorAccountNumber = creditorAccount["AccountNumber"].ToString(); string debitorAccountNumber = debitorAccount["AccountNumber"].ToString(); decimal debitAmount = (decimal)context["DebitAmount"]; // Object status = Enum.Parse(typeof(AccountStatus), debitorAccount["AccountStatus"].ToString()); PaymentScheme debitorPaymentScheme = (PaymentScheme)Enum.Parse(typeof(PaymentScheme), debitorAccount["PaymentScheme"].ToString()); //Get invalid payment scheme var values = Enum.GetValues(typeof(PaymentScheme)); foreach (var val in values) { if (!(val.ToString().Equals(debitorAccount["PaymentScheme"].ToString()))) { debitorPaymentScheme = (PaymentScheme)Enum.Parse(typeof(PaymentScheme), val.ToString()); break; } } MakePaymentRequest request = new MakePaymentRequest(creditorAccountNumber, debitorAccountNumber, debitAmount, paymentDate, debitorPaymentScheme); PaymentService paymentService = new PaymentService(); MakePaymentResult result = paymentService.MakePayment(request); context["MakePaymentResult"] = result; }
public void VerifyPaymentResult(bool expectedResult) { MakePaymentResult actualResult = (MakePaymentResult)context["MakePaymentResult"]; Assert.AreEqual(expectedResult, actualResult.Success, "Verify expected payment result"); Console.WriteLine("Make payment expected result : [" + expectedResult + "], actual result : [" + actualResult.Success + "]"); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { var dataStoreType = ConfigurationManager.AppSettings["DataStoreType"]; Account account = null; if (dataStoreType == "Backup") { var accountDataStore = new BackupAccountDataStore(); account = accountDataStore.GetAccount(request.DebtorAccountNumber); } else { var accountDataStore = new AccountDataStore(); account = accountDataStore.GetAccount(request.DebtorAccountNumber); } var result = new MakePaymentResult(); CheckPaymentScheme(request, account, result); ProcessPayment(request, dataStoreType, account, result); return(result); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { var result = new MakePaymentResult(); Account account = _accountDataStore.GetAccount(request.DebtorAccountNumber); if (account != null) { IPaymentRequestValidator paymentRequestValidator = _paymentSchemeValidatorService.GetPaymentSchemeValidator(request.PaymentScheme); if (paymentRequestValidator == null) { result.Success = false; } else { result.Success = paymentRequestValidator.IsValid(account, request); } } if (result.Success) { account.Balance -= request.Amount; _accountDataStore.UpdateAccount(account); } return result; }
public MakePaymentResult MakePayment(MakePaymentRequest request) { var result = new MakePaymentResult() { Success = false }; //NOTE : We could move this validation logic to PaymentController class var validator = _paymentValidator.IsValid(request); if (!validator.IsValid) { return(result); } // To check the payment scheme and validations var paymentScheme = _paymentFact.GetPaymentScheme(request.PaymentScheme); if (paymentScheme == null) { return(result); } var debtorAccount = _accountRepo.AccountDataStore.GetAccount(request.DebtorAccountNumber); if (paymentScheme.MakePayment(debtorAccount, request)) { _accountRepo.AccountDataStore.UpdateAccount(debtorAccount); result.Success = true; } return(result); }
// Abstract away following private helper methods into seprate sub-classes based and // may consider into Factories and write test cases accordingly, BUT for now I decided // not to do this at these stage - kept is simple for the purpose of readability. // NOTE: The account.AllowedPaymentSchemes.HasFlag(xxx) can be refactored into Is<T>Valid() private static MakePaymentResult TakePayment(MakePaymentRequest paymentRequest, Account accountInfo) { var paymentResult = new MakePaymentResult(); // TODO: Factory pattern for each type of payment! // For now just call appropriate helper methods switch (paymentRequest.PaymentScheme) { case PaymentScheme.Bacs: BacsPaymentProcess(accountInfo, paymentResult); break; case PaymentScheme.Chaps: ChapsPaymentProcess(accountInfo, paymentResult); break; case PaymentScheme.FasterPayments: FasterPaymentProcess(paymentRequest, accountInfo, paymentResult); break; default: throw new InvalidEnumArgumentException("Invalid PaymentScheme enum"); } return(paymentResult); }
public MakePaymentResult MakePayment(IPaymentRequest request) { IAccount account = DataStore.GetAccount(request.DebtorAccountNumber); // Assume will be unsuccessful var result = new MakePaymentResult() { Success = false }; // Conditions for success if (account != null && account.Status == AccountStatus.Live && account.Balance >= request.Amount && account.AllowedPaymentSchemes.Contains(request.PaymentScheme)) { result.Success = true; } if (result.Success) { account.Balance -= request.Amount; DataStore.UpdateAccount(account); } return(result); }
public void Test_PaymentService_MakePayment_UnSuccess_when_Account_Is_Null() { // arrange MakePaymentRequest makePaymentRequest = new MakePaymentRequest { Amount = 50, CreditorAccountNumber = "PR2408", DebtorAccountNumber = "DC2404", PaymentDate = DateTime.Now, PaymentScheme = PaymentScheme.Bacs }; MakePaymentResult makePaymentResult = new MakePaymentResult { Success = false }; _accountDataStore.Setup(x => x.GetAccount(makePaymentRequest.DebtorAccountNumber)).Returns <Account>(null); _accountDataStoreFactory.Setup(x => x.AccountDataStore(It.IsAny <string>())).Returns(_accountDataStore.Object); _makePaymentRequestValidator.Setup(x => x.IsAccountValidToMakePayment(null, makePaymentRequest)).Returns(makePaymentResult); // act makePaymentResult = _paymentSrevice.MakePayment(makePaymentRequest); // assert Assert.AreEqual(makePaymentResult.Success, false); _accountDataStore.Verify(x => x.UpdateAccount(null), Times.Never); }
public void MakePaymentNotEligible() { //arrange makePaymentRequest.Amount = 10; makePaymentRequest.DebtorAccountNumber = "12345"; makePaymentRequest.PaymentScheme = PaymentScheme.Bacs; makePaymentRequest.PaymentDate = DateTime.Now; var makePaymentResult = new MakePaymentResult() { Success = false }; var mockResolvePaymentValidator = new Mock <IPaymentValidator>(); mockResolvePaymentValidator.SetupAllProperties(); mockResolvePaymentValidator.Setup(x => x.CheckPaymentEligible(PaymentScheme.Bacs, It.IsAny <Account>(), It.IsAny <decimal>())).Returns(makePaymentResult); paymentService = new PaymentService(mockResolvePaymentValidator.Object); //act var result = paymentService.MakePayment(makePaymentRequest); //assert Assert.IsFalse(result.Success); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { var result = new MakePaymentResult { Success = false }; accountDataStores = AccountDataStores.Get(); var accountDataStore = accountDataStores.FirstOrDefault(x => x.CheckAccountType()); if (accountDataStore == null) { return(result); } account = accountDataStore.GetAccount(request.DebtorAccountNumber); if (account == null) { return(result); } if (!account.IsAllowedPaymentScheme(request.PaymentScheme)) { return(result); } result.Success = account.Decrease(request.Amount); return(result); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { var result = new MakePaymentResult { Success = false }; if (request == null) { return(result); } IAccountDataStore accountDataStore = _accountDataStoreFactory.BuildAccountDataStore(); IValidator validator = _validatorFactory.BuildValidator(request); Account account = accountDataStore.GetAccount(request.DebtorAccountNumber); if (account == null || !validator.AccountCanMakePayment(account)) { return(result); } account.Balance -= request.Amount; accountDataStore.UpdateAccount(account); result.Success = true; return(result); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { var datastore = _dataStoreFactory.Create(_appConfig.GetKeyValue("DataStoreType")); var account = datastore.GetAccount(request.DebtorAccountNumber); var result = new MakePaymentResult(); switch (request.PaymentScheme) { case PaymentScheme.Bacs: result.Success = _accountValidatorBacs.Validate(request, account); break; case PaymentScheme.FasterPayments: result.Success = _accountValidatorFasterPayments.Validate(request, account); break; case PaymentScheme.Chaps: result.Success = _accountValidatorChaps.Validate(request, account); break; } if (result.Success) { account.Balance -= request.Amount; datastore.UpdateAccount(account); } return(result); }
public void MakePayment_ReturnsNotNull() { // Arrange var dataStore = new Mock <IAccountDataStore>(); dataStore.Setup(ds => ds.GetAccount(It.IsAny <string>())).Returns(new Account()); var accountDataStoreFactory = new Mock <IAccountDataStoreFactory>(); accountDataStoreFactory.Setup(f => f.BuildAccountDataStore()).Returns(dataStore.Object); var validator = new Mock <IValidator>(); validator.Setup(v => v.AccountCanMakePayment(It.IsAny <Account>())).Returns(true); var validatorFactory = new Mock <IValidatorFactory>(); validatorFactory.Setup(vf => vf.BuildValidator(It.IsAny <MakePaymentRequest>())).Returns(validator.Object); var service = new PaymentService(accountDataStoreFactory.Object, validatorFactory.Object); // Act MakePaymentResult result = service.MakePayment(new MakePaymentRequest()); // Assert Assert.IsNotNull(result); }
private static void BacsPaymentProcess(Account account, MakePaymentResult result) { if (account == null) { return; } result.Success = !account.AllowedPaymentSchemes.HasFlag(AllowedPaymentSchemes.Bacs); }
public void MakePaymentFasterPaymentRequestProcessReturnsTrue() { var reqPay = new MakePaymentRequest { PaymentScheme = PaymentScheme.FasterPayments }; _res = _ps.MakePayment(reqPay); Assert.True(_res.Success); }
public MakePaymentResult Validate(Account account, decimal requestAmount = 0) { var result = new MakePaymentResult(); if (account != null && account.AllowedPaymentSchemes.HasFlag(AllowedPaymentSchemes.Bacs)) { result.Success = true; } return(result); }
public void Test() { MakePaymentResult result = _paymentService.MakePayment(_paymentRequest); Assert.True(result.Success); Assert.Equal(5, _account.Balance); _mockAccountDataStore.Verify(d => d.GetAccount(_account.AccountNumber), Times.Once); _mockPaymentSchemeValidationHandler.Verify(v => v.IsPaymentValid(_paymentRequest, _account), Times.Once); _mockAccountDataStore.Verify(d => d.UpdateAccount(_account), Times.Once); }
public void Payment_Succeeds() { // Arrange PaymentService service = new PaymentService(dataStoreMock.Object); // Act MakePaymentResult result = service.MakePayment(requestMock.Object); // Assert Assert.IsTrue(result.Success, "Should succeed when all conditions are met"); }
protected override void Observe() { var paymentRequestBuilder = new PaymentRequestBuilder() .WithDebtorAccountNumber(accountNumber) .WithAmount(1000m) .WithPaymentDate(DateTime.Now) .WithPaymentScheme(PaymentScheme.FasterPayments) .Build(); makePaymentResult = paymentService.MakePayment(paymentRequestBuilder); }
public void Test_Verify_ChapsPaymentSchemeValidator_Result_With_Null_Account() { // arrange ChapsPaymentSchemeValidator chapsPaymentSchemeValidator = new ChapsPaymentSchemeValidator(); // act MakePaymentResult makePaymentResult = chapsPaymentSchemeValidator.IsAccountValid(null, _makePaymentRequest); // assert Assert.IsFalse(makePaymentResult.Success); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { var account = _accountService.GetAccount(request.DebtorAccountNumber); if (_paymentsValidationService.ValidatePayment(account, request.Amount, request.PaymentScheme)) { _accountService.UpdateAccount(account, request.Amount); return(MakePaymentResult.OK()); } return(MakePaymentResult.Fail()); }
public void WhenValidatorReturnsFalseResultIsFalse() { _mockValidator.Setup(a => a.ValidatePayment(It.IsAny <Account>(), It.IsAny <decimal>())).Returns(false); PaymentService sut = GetSystemUnderTest(); MakePaymentResult result = sut.MakePayment(_paymentRequest); _mockAccountAccess.Verify(a => a.GetAccount(_paymentRequest.DebtorAccountNumber), Times.Once); _mockAccountAccess.Verify(a => a.UpdateAccount(It.IsAny <Account>()), Times.Never); Assert.False(result.Success); }
public MakePaymentResult Validate() { var result = new MakePaymentResult(); if (!ValidateAccount()) { return(result); } result.Success = Account.AllowedPaymentSchemes.HasFlag(AllowedPaymentSchemes.Bacs); return(result); }
public void Payment_FailsWhenPaymentSchemeNotAvailable() { // Arrange PaymentService service = new PaymentService(dataStoreMock.Object); requestMock.Setup(x => x.PaymentScheme).Returns(PaymentScheme.FasterPayments); // Act MakePaymentResult result = service.MakePayment(requestMock.Object); // Assert Assert.IsFalse(result.Success, "Should fail when payment scheme not available"); }
public MakePaymentResult MakePayment(MakePaymentRequest request) { Account account = _accountDataStore.GetAccount(request.DebtorAccountNumber); MakePaymentResult result = _validationService.Validate(request.PaymentScheme, account, request); if (result.Success) { account.Balance -= request.Amount; _accountDataStore.UpdateAccount(account); } return(result); }