public void AssignWithdrawLimitsTest_TestsIfWithdrawLimitsGetAsignedProperlyWhenTier1IsNotVerified_VerifiesThroughReturnedValue() { IWithdrawApplicationService withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"]; IWithdrawLimitRepository withdrawLimitRepository = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"]; IWithdrawFeesRepository withdrawFeesRepository = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"]; StubTierLevelRetrievalService tierLevelRetrievalService = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService; Assert.IsNotNull(tierLevelRetrievalService); tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel0); AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); WithdrawLimit withdrawLimit = withdrawLimitRepository.GetLimitByTierLevelAndCurrency("Tier 1", LimitsCurrency.Default.ToString()); Assert.IsNotNull(withdrawLimit); WithdrawFees withdrawFees = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name); Assert.IsNotNull(withdrawFees); WithdrawLimitRepresentation withdrawLimitRepresentation = withdrawApplicationService.GetWithdrawLimitThresholds(accountId.Value, currency.Name); Assert.IsNotNull(withdrawLimitRepresentation); Assert.AreEqual(currency.Name, withdrawLimitRepresentation.Currency); Assert.AreEqual(accountId.Value, withdrawLimitRepresentation.AccountId); Assert.AreEqual(0, withdrawLimitRepresentation.DailyLimit); Assert.AreEqual(0, withdrawLimitRepresentation.MonthlyLimit); Assert.AreEqual(0, withdrawLimitRepresentation.DailyLimitUsed); Assert.AreEqual(0, withdrawLimitRepresentation.MonthlyLimitUsed); Assert.AreEqual(0, withdrawLimitRepresentation.CurrentBalance); Assert.AreEqual(withdrawFees.Fee, withdrawLimitRepresentation.Fee); Assert.AreEqual(withdrawFees.MinimumAmount, withdrawLimitRepresentation.MinimumAmount); Assert.AreEqual(0, withdrawLimitRepresentation.Withheld); Assert.AreEqual(0, withdrawLimitRepresentation.MaximumWithdraw); }
public void SaveWithdrawFeesAndRetreiveByCurrencyNameTest_SavesAnObjectToDatabaseAndManipulatesIt_ChecksIfItIsUpdatedAsExpected() { WithdrawFees retrievedWithdrawFees = _withdrawFeesRepository.GetWithdrawFeesByCurrencyName("LTC"); Assert.IsNotNull(retrievedWithdrawFees); Assert.Greater(retrievedWithdrawFees.MinimumAmount, 0); Assert.Greater(retrievedWithdrawFees.Fee, 0); }
public void DepositAndWithdrawTest_TestsIfThingsGoAsExpectedWhenWithdrawIsMadeAfterDeposit_ChecksBalanceToVerify() { // Scenario: Confirmed Deposit --> Withdraw --> Check Balance IFundsValidationService fundsValidationService = (IFundsValidationService)ContextRegistry.GetContext()["FundsValidationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IDepositIdGeneratorService depositIdGeneratorService = (IDepositIdGeneratorService)ContextRegistry.GetContext()["DepositIdGeneratorService"]; IWithdrawFeesRepository withdrawFeesRepository = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"]; AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); // Deposit Deposit deposit = new Deposit(currency, depositIdGeneratorService.GenerateId(), DateTime.Now, DepositType.Default, 1.4m, 0, TransactionStatus.Pending, accountId, new TransactionId("123"), new BitcoinAddress("bitcoin123")); deposit.IncrementConfirmations(7); fundsPersistenceRepository.SaveOrUpdate(deposit); // Retrieve balance Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNull(balance); bool depositResponse = fundsValidationService.DepositConfirmed(deposit); Assert.IsTrue(depositResponse); // Check balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(balance.CurrentBalance, deposit.Amount); Assert.AreEqual(balance.AvailableBalance, deposit.Amount); Assert.AreEqual(balance.PendingBalance, 0); // Withdraw Withdraw validateFundsForWithdrawal = fundsValidationService.ValidateFundsForWithdrawal(accountId, currency, 1.3M, new TransactionId("transaction123"), new BitcoinAddress("bitcoin123")); Assert.IsNotNull(validateFundsForWithdrawal); bool withdrawalExecuted = fundsValidationService.WithdrawalExecuted(validateFundsForWithdrawal); Assert.IsTrue(withdrawalExecuted); WithdrawFees withdrawFee = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name); // Check balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.CurrentBalance, 5)); Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.AvailableBalance, 5)); Assert.AreEqual(0, balance.PendingBalance); }
public void SaveWithdrawFeesAndRetreiveByCurrencyNameTest_SavesAnObjectToDatabaseAndManipulatesIt_ChecksIfItIsUpdatedAsExpected() { WithdrawFees withdrawFees = new WithdrawFees(new Currency("LTC", true), 4000, 500); _persistanceRepository.SaveOrUpdate(withdrawFees); WithdrawFees retrievedWithdrawFees = _withdrawFeesRepository.GetWithdrawFeesByCurrencyName("LTC"); Assert.IsNotNull(retrievedWithdrawFees); Assert.AreEqual(withdrawFees.MinimumAmount, retrievedWithdrawFees.MinimumAmount); Assert.AreEqual(withdrawFees.Fee, retrievedWithdrawFees.Fee); }
public void WithdrawSuccessfulTest_TestsIfWithdrawIsSuccessfulWhenTierLevelIsHighEnough_VerifiesThroughDatabaseQueries() { IWithdrawApplicationService withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"]; IWithdrawRepository withdrawRepository = (IWithdrawRepository)ContextRegistry.GetContext()["WithdrawRepository"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IWithdrawFeesRepository withdrawFeesRepository = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"]; StubTierLevelRetrievalService tierLevelRetrievalService = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService; IWithdrawLimitRepository withdrawLimitRepository = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"]; Assert.IsNotNull(tierLevelRetrievalService); tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel1); AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1"); WithdrawLimit withdrawLimit = withdrawLimitRepository.GetLimitByTierLevelAndCurrency(TierConstants.TierLevel1, LimitsCurrency.Default.ToString()); Assert.IsNotNull(withdrawLimit); decimal amount = withdrawLimit.DailyLimit; Balance balance = new Balance(currency, accountId, amount + 1, amount + 1); fundsPersistenceRepository.SaveOrUpdate(balance); CommitWithdrawResponse commitWithdrawResponse = withdrawApplicationService.CommitWithdrawal(new CommitWithdrawCommand(accountId.Value, currency.Name, currency.IsCryptoCurrency, bitcoinAddress.Value, amount)); Assert.IsNotNull(commitWithdrawResponse); Assert.IsTrue(commitWithdrawResponse.CommitSuccessful); Withdraw withdraw = withdrawRepository.GetWithdrawByWithdrawId(commitWithdrawResponse.WithdrawId); Assert.IsNotNull(withdraw); Assert.AreEqual(accountId.Value, withdraw.AccountId.Value); Assert.AreEqual(currency.Name, withdraw.Currency.Name); Assert.AreEqual(currency.IsCryptoCurrency, withdraw.Currency.IsCryptoCurrency); Assert.AreEqual(amount - withdraw.Fee, withdraw.Amount); Assert.AreEqual(TransactionStatus.Pending, withdraw.Status); WithdrawFees withdrawFees = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name); Assert.IsNotNull(withdrawFees); balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual((amount + 1) - (amount), balance.AvailableBalance); Assert.AreEqual(amount + 1, balance.CurrentBalance); Assert.AreEqual(amount, balance.PendingBalance); }
public void AssignWithdrawLimitsTest_TestsIfWithdrawLimitsGetAsignedProperlyWhenInvalidTierLevelIsSpecified_VerifiesThroughReturnedValue() { IWithdrawApplicationService withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"]; IWithdrawFeesRepository withdrawFeesRepository = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"]; StubTierLevelRetrievalService tierLevelRetrievalService = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService; Assert.IsNotNull(tierLevelRetrievalService); tierLevelRetrievalService.SetTierLevel("Tier 6"); AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); WithdrawFees withdrawFees = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name); Assert.IsNotNull(withdrawFees); withdrawApplicationService.GetWithdrawLimitThresholds(accountId.Value, currency.Name); }
/// <summary> /// Gets the limits allowed for the withdrawal, along with the amount that has been used by the user /// </summary> /// <param name="accountId"></param> /// <param name="currency"></param> /// <returns></returns> public AccountWithdrawLimits GetWithdrawThresholds(AccountId accountId, Currency currency) { Balance balance = GetBalanceForAccountId(accountId, currency); WithdrawFees withdrawFees = _withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name); // Get all the Withdraw Ledgers IList <Withdraw> withdrawLedgers = GetWithdrawalLedgers(currency, accountId); // Get the Current Tier Level for this user using the cross bounded context Tier retrieval service string currentTierLevel = _tierLevelRetrievalService.GetCurrentTierLevel(accountId.Value); // Get the withdraw fee and minimum amount decimal withdrawFee = 0; decimal minimumAmount = 0; if (withdrawFees != null) { withdrawFee = withdrawFees.Fee; minimumAmount = withdrawFees.MinimumAmount; } // Get the current and available balance decimal availableBalance = 0; decimal currentBalance = 0; if (balance != null) { availableBalance = balance.AvailableBalance; currentBalance = balance.CurrentBalance; } // Evaluate if the current withdrawal is within the limits of the maximum withdrawal allowed and // the balance available _limitsConfigurationService.AssignWithdrawLimits(currency.Name, currentTierLevel, withdrawLedgers, availableBalance, currentBalance); return(new AccountWithdrawLimits(currency, accountId, _withdrawLimitEvaluationService.DailyLimit, _withdrawLimitEvaluationService.DailyLimitUsed, _withdrawLimitEvaluationService.MonthlyLimit, _withdrawLimitEvaluationService.MonthlyLimitUsed, availableBalance, _withdrawLimitEvaluationService.MaximumWithdraw, _withdrawLimitEvaluationService.WithheldAmount, withdrawFee, minimumAmount)); }
public Withdraw ValidateFundsForWithdrawal(AccountId accountId, Currency currency, decimal amount, TransactionId transactionId, BitcoinAddress bitcoinAddress) { Tuple <bool, string> isTierVerified = IsTierVerified(accountId.Value, currency.IsCryptoCurrency); if (isTierVerified.Item1) { //if (currency.IsCryptoCurrency) //{ WithdrawFees withdrawFees = _withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name); if (withdrawFees != null) { // Check if the current withdrawal amount is greater than the amount required mentioned with the Fees if (amount >= withdrawFees.MinimumAmount) { Balance balance = GetBalanceForAccountId(accountId, currency); if (balance != null) { // Get all the Withdraw Ledgers IList <Withdraw> withdrawals = GetWithdrawalLedgers(currency, accountId); // Evaluate if the current withdrawal is within the limits of the maximum withdrawal allowed and // the balance available if (_limitsConfigurationService.EvaluateWithdrawLimits(currency.Name, isTierVerified.Item2, amount, withdrawals, balance.AvailableBalance, balance.CurrentBalance)) { Withdraw withdraw = new Withdraw(currency, _withdrawIdGeneratorService.GenerateNewId(), DateTime.Now, GetWithdrawType(currency.Name), amount - withdrawFees.Fee, withdrawFees.Fee, TransactionStatus.Pending, accountId, bitcoinAddress); // Set amount In US Dollars, which will be used in later calculations regarding withdrawals withdraw.SetAmountInUsd(_limitsConfigurationService.ConvertCurrencyToFiat(currency.Name, amount)); _fundsPersistenceRepository.SaveOrUpdate(withdraw); balance.AddPendingTransaction(withdraw.WithdrawId, PendingTransactionType.Withdraw, -(withdraw.Amount + withdrawFees.Fee)); _fundsPersistenceRepository.SaveOrUpdate(balance); return(withdraw); } else { throw new InvalidOperationException("Not enough balance or withdraw limit reached"); } } else { throw new InvalidOperationException(string.Format("No balance available AccountID = {0} | Currency = {1}", accountId.Value, currency.Name)); } } else { throw new InvalidOperationException(string.Format("Withdraw amount less than Minimum Amount: " + "AccountID = {0} | Currency = {1}", accountId.Value, currency.Name)); } } else { throw new InstanceNotFoundException(string.Format("No Withdraw Fees Found: " + "AccountID = {0} | Currency = {1}", accountId.Value, currency.Name)); } } else { throw new InvalidOperationException(string.Format("Required Tier not verified for Withdraw: Account ID = {0}", accountId.Value)); } }
public void Scenario1Test_TestsFundsValidationServiceOperationsInaRandomOrderToProceedInTheDesiredExpectenacy_VerifiesThroughDatabaseQuery() { // Deposit --> Order Validations --> Trade --> Withdraw IFundsValidationService fundsValidationService = (IFundsValidationService)ContextRegistry.GetContext()["FundsValidationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IDepositIdGeneratorService depositIdGeneratorService = (IDepositIdGeneratorService)ContextRegistry.GetContext()["DepositIdGeneratorService"]; IWithdrawFeesRepository withdrawFeesRepository = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"]; IFeeCalculationService feeCalculationService = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"]; IFeeRepository feeRepository = (IFeeRepository)ContextRegistry.GetContext()["FeeRepository"]; Tuple <string, string> splittedCurrencyPair = CurrencySplitterService.SplitCurrencyPair(feeRepository.GetAllFees().First().CurrencyPair); Currency baseCurrency = new Currency(splittedCurrencyPair.Item1); Currency quoteCurrency = new Currency(splittedCurrencyPair.Item2); AccountId user1Account = new AccountId(1); AccountId user2Account = new AccountId(2); decimal baseDepositAmount = 1.4m; decimal quoteDepositAmount = 1000; Balance user1QuoteInitialBalance = new Balance(quoteCurrency, user1Account, quoteDepositAmount, quoteDepositAmount); Balance user2QuoteInitialBalance = new Balance(quoteCurrency, user2Account, quoteDepositAmount, quoteDepositAmount); fundsPersistenceRepository.SaveOrUpdate(user1QuoteInitialBalance); fundsPersistenceRepository.SaveOrUpdate(user2QuoteInitialBalance); // Deposit Deposit deposit1 = new Deposit(baseCurrency, depositIdGeneratorService.GenerateId(), DateTime.Now, DepositType.Default, baseDepositAmount, 0, TransactionStatus.Pending, user1Account, new TransactionId("1"), new BitcoinAddress("bitcoin1")); deposit1.IncrementConfirmations(7); fundsPersistenceRepository.SaveOrUpdate(deposit1); Deposit deposit2 = new Deposit(baseCurrency, depositIdGeneratorService.GenerateId(), DateTime.Now, DepositType.Default, baseDepositAmount, 0, TransactionStatus.Pending, user2Account, new TransactionId("3"), new BitcoinAddress("bitcoin3")); deposit2.IncrementConfirmations(7); fundsPersistenceRepository.SaveOrUpdate(deposit2); // Retrieve Base Currency balance for user 1 bool depositResponse = fundsValidationService.DepositConfirmed(deposit1); Assert.IsTrue(depositResponse); Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(deposit1.Amount, balance.CurrentBalance); Assert.AreEqual(deposit1.Amount, balance.AvailableBalance); Assert.AreEqual(balance.PendingBalance, 0); // Retrieve Quote Currency balance for user 1 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(user1QuoteInitialBalance.CurrentBalance, balance.CurrentBalance); Assert.AreEqual(user1QuoteInitialBalance.AvailableBalance, balance.AvailableBalance); Assert.AreEqual(0, balance.PendingBalance); // Retrieve BTC balance for user 2 depositResponse = fundsValidationService.DepositConfirmed(deposit2); Assert.IsTrue(depositResponse); balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user2Account); Assert.IsNotNull(balance); Assert.AreEqual(deposit2.Amount, balance.CurrentBalance); Assert.AreEqual(deposit2.Amount, balance.AvailableBalance); Assert.AreEqual(balance.PendingBalance, 0); // Retrieve USD balance for user 2 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user2Account); Assert.IsNotNull(balance); Assert.AreEqual(user2QuoteInitialBalance.CurrentBalance, balance.CurrentBalance); Assert.AreEqual(user2QuoteInitialBalance.AvailableBalance, balance.AvailableBalance); Assert.AreEqual(0, balance.PendingBalance); // Order Validation for User 1's Account decimal volume = 1.2m; decimal price = 590; string buy = "buy"; string sell = "sell"; string buyOrderId = "buy123"; string sellOrderId = "sell123"; bool validationResponse = fundsValidationService.ValidateFundsForOrder(user1Account, baseCurrency, quoteCurrency, volume, price, buy, buyOrderId); Assert.IsTrue(validationResponse); decimal user1Fee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, user1Account, volume, price); decimal user2Fee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, user2Account, volume, price); // Base Currency Balance for User Account 1 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(baseDepositAmount, balance.AvailableBalance); Assert.AreEqual(baseDepositAmount, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); // Quote Currency Balance for User Account 1 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(quoteDepositAmount - (volume * price), balance.AvailableBalance); Assert.AreEqual(quoteDepositAmount, balance.CurrentBalance); Assert.AreEqual(volume * price, balance.PendingBalance); // Validation of User 2's order validationResponse = fundsValidationService.ValidateFundsForOrder(user2Account, baseCurrency, quoteCurrency, volume, price, sell, sellOrderId); Assert.IsTrue(validationResponse); // Base Currency Balance for User Account 2 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user2Account); Assert.IsNotNull(balance); Assert.AreEqual(baseDepositAmount - volume, balance.AvailableBalance); Assert.AreEqual(baseDepositAmount, balance.CurrentBalance); Assert.AreEqual(volume, balance.PendingBalance); // Quote Currency Balance for User Account 2 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user2Account); Assert.IsNotNull(balance); Assert.AreEqual(quoteDepositAmount, balance.AvailableBalance); Assert.AreEqual(quoteDepositAmount, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); string tradeId = "tradeid123"; bool tradeExecutedResponse = fundsValidationService.TradeExecuted(baseCurrency.Name, quoteCurrency.Name, volume, price, DateTime.Now, tradeId, user1Account.Value, user2Account.Value, buyOrderId, sellOrderId); Assert.IsTrue(tradeExecutedResponse); // Base Currency Balance for User Account 1 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(baseDepositAmount + volume, balance.AvailableBalance); Assert.AreEqual(baseDepositAmount + volume, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); // Quote Currency Balance for User Account 1 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(quoteDepositAmount - (volume * price) - user1Fee, balance.AvailableBalance); Assert.AreEqual(quoteDepositAmount - (volume * price) - user1Fee, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); // Base Currency Balance for User Account 2 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user2Account); Assert.IsNotNull(balance); Assert.AreEqual(baseDepositAmount - (volume), balance.AvailableBalance); Assert.AreEqual(baseDepositAmount - (volume), balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); // Quote Currency Balance for User Account 2 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, user2Account); Assert.IsNotNull(balance); Assert.AreEqual(quoteDepositAmount + (volume * price) - user2Fee, balance.AvailableBalance); Assert.AreEqual(quoteDepositAmount + (volume * price) - user2Fee, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); decimal withdrawAmount = 0.3M; // Withdraw Base Currency Withdraw validateFundsForWithdrawal = fundsValidationService.ValidateFundsForWithdrawal(user1Account, baseCurrency, withdrawAmount, new TransactionId("transaction123"), new BitcoinAddress("bitcoin123")); Assert.IsNotNull(validateFundsForWithdrawal); WithdrawFees withdrawFee = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(baseCurrency.Name); // Base Currency Balance for User Account 1 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.AvailableBalance); Assert.AreEqual(baseDepositAmount + volume, balance.CurrentBalance); Assert.AreEqual(withdrawAmount, balance.PendingBalance); bool withdrawalExecuted = fundsValidationService.WithdrawalExecuted(validateFundsForWithdrawal); Assert.IsTrue(withdrawalExecuted); // Base Currency Balance for User Account 1 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.AvailableBalance); Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); // EXCEPTION OCCURS HERE when the user tries to withdraw more than their remaining limit // Withdraw will fail because the amount requested is greater than the maximum limit threshold validateFundsForWithdrawal = fundsValidationService.ValidateFundsForWithdrawal(user1Account, baseCurrency, baseDepositAmount + volume /*Excluding previous withdrawal amount*/, new TransactionId("transaction123"), new BitcoinAddress("bitcoin123")); Assert.IsNull(validateFundsForWithdrawal); // Base Currency for User Account 1 balance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, user1Account); Assert.IsNotNull(balance); Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.AvailableBalance); Assert.AreEqual(baseDepositAmount + volume - withdrawAmount, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); }
public void DepositAndWithdrawTest2_TestsByMakingDepositsAndWIthdrawalsRandomly_VerifiesThroughDatabasequeriesAndReturnValues() { // Scenario: Withdraw(fail due to insufficient balance) --> // Deposit(Confirm) --> Withdraw(Pending) --> Withdraw(Fail due to insufficient available and enough // pending balance) --> Withdraw(Success) --> Deposit(Fail due to over the limit) IFundsValidationService fundsValidationService = (IFundsValidationService)ContextRegistry.GetContext()["FundsValidationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IDepositIdGeneratorService depositIdGeneratorService = (IDepositIdGeneratorService)ContextRegistry.GetContext()["DepositIdGeneratorService"]; IWithdrawFeesRepository withdrawFeesRepository = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"]; AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); Deposit deposit = new Deposit(currency, depositIdGeneratorService.GenerateId(), DateTime.Now, DepositType.Default, 1.4m, 0, TransactionStatus.Pending, accountId, new TransactionId("123"), new BitcoinAddress("bitcoin123")); deposit.IncrementConfirmations(7); fundsPersistenceRepository.SaveOrUpdate(deposit); // Retrieve balance Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNull(balance); // Deposit bool depositResponse = fundsValidationService.DepositConfirmed(deposit); Assert.IsTrue(depositResponse); // Check balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(deposit.Amount, balance.CurrentBalance); Assert.AreEqual(deposit.Amount, balance.AvailableBalance); Assert.AreEqual(balance.PendingBalance, 0); WithdrawFees withdrawFee = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name); // Withdraw Withdraw withdrawal = fundsValidationService.ValidateFundsForWithdrawal(accountId, currency, 1.3M, new TransactionId("transaction123"), new BitcoinAddress("bitcoin123")); Assert.IsNotNull(withdrawal); Assert.AreEqual(TransactionStatus.Pending, withdrawal.Status); // Check balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.AvailableBalance, 5)); Assert.AreEqual(Math.Round(1.4M, 5), Math.Round(balance.CurrentBalance, 5)); Assert.AreEqual(1.3m, balance.PendingBalance); // Withdraw # 1 Confirmed bool withdrawalExecuted = fundsValidationService.WithdrawalExecuted(withdrawal); Assert.IsTrue(withdrawalExecuted); Assert.AreEqual(TransactionStatus.Confirmed, withdrawal.Status); // Check balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.CurrentBalance, 5)); Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.AvailableBalance, 5)); Assert.AreEqual(0, balance.PendingBalance); // Withdraw # 2: Exception Expected withdrawal = fundsValidationService.ValidateFundsForWithdrawal(accountId, currency, 0.7M, new TransactionId("transaction123"), new BitcoinAddress("bitcoin123")); Assert.IsNull(withdrawal); // Check balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.CurrentBalance, 5)); Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.AvailableBalance, 5)); Assert.AreEqual(0, balance.PendingBalance); // Withdraw # 3 withdrawal = fundsValidationService.ValidateFundsForWithdrawal(accountId, currency, 0.098M, new TransactionId("transaction123"), new BitcoinAddress("bitcoin123")); Assert.IsNotNull(withdrawal); Assert.AreEqual(TransactionStatus.Pending, withdrawal.Status); balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(Math.Round(1.4M - 1.3M - 0.1M - (withdrawFee.Fee * 2), 5), Math.Round(balance.AvailableBalance, 5)); Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.CurrentBalance, 5)); Assert.AreEqual(0.1M, balance.PendingBalance); // Withdraw # 3 Confirmed withdrawalExecuted = fundsValidationService.WithdrawalExecuted(withdrawal); Assert.IsTrue(withdrawalExecuted); Assert.AreEqual(TransactionStatus.Confirmed, withdrawal.Status); // Check balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(Math.Round(1.4M - 1.3M - 0.1M - (withdrawFee.Fee * 2), 5), Math.Round(balance.CurrentBalance, 5)); Assert.AreEqual(Math.Round(1.4M - 1.3M - 0.1M - (withdrawFee.Fee * 2), 5), Math.Round(balance.AvailableBalance, 5)); Assert.AreEqual(0, balance.PendingBalance); // Over the limit Deposit deposit = new Deposit(currency, depositIdGeneratorService.GenerateId(), DateTime.Now, DepositType.Default, 1.4m, 0, TransactionStatus.Pending, accountId, new TransactionId("123"), new BitcoinAddress("bitcoin123")); deposit.IncrementConfirmations(7); fundsPersistenceRepository.SaveOrUpdate(deposit); fundsValidationService.DepositConfirmed(deposit); // Check balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(Math.Round(1.4M - 1.3M - 0.1M - (withdrawFee.Fee * 2), 5), Math.Round(balance.CurrentBalance, 5)); Assert.AreEqual(Math.Round(1.4M - 1.3M - 0.1M - (withdrawFee.Fee * 2), 5), Math.Round(balance.AvailableBalance, 5)); Assert.IsTrue(balance.IsFrozen); }
public void WithdrawExecutedEventTest_ChecksThatTheEventIsProperlyRaisedAndHandledWhenWithdrawIsSubmittedToTheNetwork_VerifiesThroughRaisedEvent() { // Withdraw is submitted and upon submission to network an event is raised confirming withdrawal execution which // is handled and balance is updated. This whole process of events firing and balance validation is checked by this // test case IWithdrawApplicationService withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"]; IWithdrawRepository withdrawRepository = (IWithdrawRepository)ContextRegistry.GetContext()["WithdrawRepository"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IWithdrawFeesRepository withdrawFeesRepository = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"]; IWithdrawLimitRepository withdrawLimitRepository = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"]; IClientInteractionService clientInteractionService = (IClientInteractionService)ContextRegistry.GetContext()["ClientInteractionService"]; StubTierLevelRetrievalService tierLevelRetrievalService = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService; Assert.IsNotNull(tierLevelRetrievalService); tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel1); AccountId accountId = new AccountId(123); Currency currency = new Currency(CurrencyConstants.Btc, true); BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1"); WithdrawLimit withdrawLimit = withdrawLimitRepository.GetLimitByTierLevelAndCurrency(TierConstants.TierLevel1, LimitsCurrency.Default.ToString()); Assert.IsNotNull(withdrawLimit); decimal amount = withdrawLimit.DailyLimit; Balance balance = new Balance(currency, accountId, amount + 1, amount + 1); fundsPersistenceRepository.SaveOrUpdate(balance); bool withdrawEventRaised = false; ManualResetEvent manualResetEvent = new ManualResetEvent(false); Withdraw receivedWithdraw = null; clientInteractionService.WithdrawExecuted += delegate(Withdraw incomingWithdraw) { withdrawEventRaised = true; receivedWithdraw = incomingWithdraw; manualResetEvent.Set(); }; CommitWithdrawResponse commitWithdrawResponse = withdrawApplicationService.CommitWithdrawal(new CommitWithdrawCommand(accountId.Value, currency.Name, currency.IsCryptoCurrency, bitcoinAddress.Value, amount)); Assert.IsNotNull(commitWithdrawResponse); Assert.IsTrue(commitWithdrawResponse.CommitSuccessful); manualResetEvent.WaitOne(); // Apply assertions after event has been handled Assert.IsTrue(withdrawEventRaised); Assert.IsNotNull(receivedWithdraw); Withdraw withdraw = withdrawRepository.GetWithdrawByWithdrawId(commitWithdrawResponse.WithdrawId); Assert.IsNotNull(withdraw); Assert.AreEqual(accountId.Value, withdraw.AccountId.Value); Assert.AreEqual(currency.Name, withdraw.Currency.Name); Assert.AreEqual(currency.IsCryptoCurrency, withdraw.Currency.IsCryptoCurrency); Assert.AreEqual(amount - withdraw.Fee, withdraw.Amount); Assert.AreEqual(TransactionStatus.Confirmed, withdraw.Status); Assert.AreEqual(receivedWithdraw.AccountId.Value, withdraw.AccountId.Value); Assert.AreEqual(receivedWithdraw.TransactionId.Value, withdraw.TransactionId.Value); Assert.AreEqual(receivedWithdraw.BitcoinAddress.Value, withdraw.BitcoinAddress.Value); Assert.AreEqual(receivedWithdraw.Currency.Name, withdraw.Currency.Name); Assert.AreEqual(TransactionStatus.Confirmed, withdraw.Status); Assert.AreEqual(receivedWithdraw.Amount, withdraw.Amount); Assert.AreEqual(receivedWithdraw.WithdrawId, withdraw.WithdrawId); WithdrawFees withdrawFees = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name); Assert.IsNotNull(withdrawFees); balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual((amount + 1) - (amount), balance.AvailableBalance); Assert.AreEqual((amount + 1) - (amount), balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); }