public void WithdrawLimitScenario2NotEnoughBalanceTest_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue() { // Balance is less than the evaluated Maximum Withdrawal threshold IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService(); decimal dailyLimit = 1000; decimal monthlyLimit = 5000; // Balance is less than the calculated maximum threshold decimal availableBalance = 1000 - 1.09m; decimal currentBalance = 1000 - 1.09m; List <Withdraw> ledgers = new List <Withdraw>(); WithdrawLimit withdrawLimit = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit); bool evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(999, ledgers, withdrawLimit, availableBalance, currentBalance); Assert.IsFalse(evaluationResponse); Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit); Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit); Assert.AreEqual(0, withdrawLimitEvaluationService.DailyLimitUsed); Assert.AreEqual(0, withdrawLimitEvaluationService.MonthlyLimitUsed); Assert.AreEqual(Math.Round(availableBalance, 5), withdrawLimitEvaluationService.MaximumWithdraw); Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount); }
public void WithdrawLimitScenario3Test_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue() { // Scenario: DailyLimit = 0/1000, MonthlyLimit = 0/5000 IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService(); Currency currency = new Currency("XBT"); string withdrawId = "withdrawid123"; AccountId accountId = new AccountId(123); decimal dailyLimit = 1000; decimal monthlyLimit = 5000; // Balance is less than the calculated maximum threshold decimal availableBalance = 1000 - 1.09m; decimal currentBalance = 1000 - 1.09m; List <Withdraw> withdraws = new List <Withdraw>(); Withdraw withdraw = new Withdraw(currency, "withdrawid123", DateTime.Now.AddDays(-40), WithdrawType.Bitcoin, 500, 0.001m, TransactionStatus.Pending, accountId, new BitcoinAddress("bitcoin123")); withdraws.Add(withdraw); WithdrawLimit withdrawLimit = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit); bool evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(999, withdraws, withdrawLimit, availableBalance, currentBalance); Assert.IsFalse(evaluationResponse); Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit); Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit); Assert.AreEqual(0, withdrawLimitEvaluationService.DailyLimitUsed); Assert.AreEqual(0, withdrawLimitEvaluationService.MonthlyLimitUsed); Assert.AreEqual(Math.Round(availableBalance, 5), withdrawLimitEvaluationService.MaximumWithdraw); Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount); }
public void WithdrawLimitScenario15Test_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue() { // Check to see the withheld amount IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService(); decimal dailyLimit = 1000; decimal monthlyLimit = 5000; // We have suficient balance for this case decimal availableBalance = 1000 + 100; decimal currentBalance = 1000 + 110; List <Withdraw> withdraws = new List <Withdraw>(); WithdrawLimit withdrawLimit = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit); bool evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(900, withdraws, withdrawLimit, availableBalance, currentBalance); Assert.IsTrue(evaluationResponse); Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit); Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit); Assert.AreEqual(0, withdrawLimitEvaluationService.DailyLimitUsed); Assert.AreEqual(0, withdrawLimitEvaluationService.MonthlyLimitUsed); Assert.AreEqual(1000, withdrawLimitEvaluationService.MaximumWithdraw); Assert.AreEqual(currentBalance - availableBalance, withdrawLimitEvaluationService.WithheldAmount); }
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 WithdrawFailedTest_TestsIfWithdrawFailsBecauseOfNotEnoughBalance_VerifiesThroughDatabaseQueries() { IWithdrawApplicationService withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"]; StubTierLevelRetrievalService tierLevelRetrievalService = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService; IWithdrawLimitRepository withdrawLimitRepository = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; 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 + 0.001M; Balance balance = new Balance(currency, accountId, amount - 1, amount - 1); fundsPersistenceRepository.SaveOrUpdate(balance); withdrawApplicationService.CommitWithdrawal(new CommitWithdrawCommand(accountId.Value, currency.Name, currency.IsCryptoCurrency, bitcoinAddress.Value, amount)); }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Object"/> class. /// </summary> public MockWithdrawLimitRepository() { WithdrawLimit withdrawLimit1 = new WithdrawLimit("Tier 0", 1000, 5000); WithdrawLimit withdrawLimit2 = new WithdrawLimit("Tier 1", 1000, 5000); _withdrawLimits.Add(withdrawLimit1); _withdrawLimits.Add(withdrawLimit2); }
public void SaveWithdrawLimitAndRetreiveByTierLevelTest_SavesAnObjectToDatabaseAndManipulatesIt_ChecksIfItIsUpdatedAsExpected() { WithdrawLimit withdrawLimit = new WithdrawLimit("tierlevel1", 4000, 500); _persistanceRepository.SaveOrUpdate(withdrawLimit); WithdrawLimit retrievedWithdrawLimit = _withdrawLimitRepository.GetWithdrawLimitByTierLevel("tierlevel1"); Assert.IsNotNull(retrievedWithdrawLimit); Assert.AreEqual(withdrawLimit.DailyLimit, retrievedWithdrawLimit.DailyLimit); Assert.AreEqual(withdrawLimit.MonthlyLimit, retrievedWithdrawLimit.MonthlyLimit); }
public void WithdrawLimitScenario14Test_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue() { // Scenario: DailyLimit = 500/1000, MonthlyLimit = 4500/5000 with insufficient balance IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService(); Currency currency = new Currency("XBT"); AccountId accountId = new AccountId(123); decimal dailyLimit = 1000; decimal monthlyLimit = 5000; // Balance is less than the calculated maximum threshold foor the remaining quantity from the daily limit used decimal availableBalance = 500 - 0.09m; decimal currentBalance = 500 - 0.09m; // Amount that can be safely withdrawn decimal safeAmount = availableBalance; decimal fee = 0.001m; List <Withdraw> withdraws = new List <Withdraw>(); Withdraw withdraw = new Withdraw(currency, "withdrawid123", DateTime.Now.AddDays(-29), WithdrawType.Bitcoin, 4000, fee, TransactionStatus.Pending, accountId, new BitcoinAddress("bitcoin123")); Withdraw withdraw2 = new Withdraw(currency, "withdrawid123", DateTime.Now.AddMinutes(-29), WithdrawType.Bitcoin, 500, fee, TransactionStatus.Pending, accountId, new BitcoinAddress("bitcoin123")); withdraws.Add(withdraw); withdraws.Add(withdraw2); WithdrawLimit withdrawLimit = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit); bool evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(500, withdraws, withdrawLimit, availableBalance, currentBalance); Assert.IsFalse(evaluationResponse); Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit); Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit); Assert.AreEqual(500 + fee, withdrawLimitEvaluationService.DailyLimitUsed); Assert.AreEqual(4500 + fee * 2, withdrawLimitEvaluationService.MonthlyLimitUsed); Assert.AreEqual(Math.Round(availableBalance, 5), withdrawLimitEvaluationService.MaximumWithdraw); Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount); // Withdraw below the threshold limit evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(safeAmount - 10, withdraws, withdrawLimit, availableBalance, currentBalance); Assert.IsTrue(evaluationResponse); Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit); Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit); Assert.AreEqual(500 + fee, withdrawLimitEvaluationService.DailyLimitUsed); Assert.AreEqual(4500 + fee * 2, withdrawLimitEvaluationService.MonthlyLimitUsed); Assert.AreEqual(Math.Round(availableBalance, 5), withdrawLimitEvaluationService.MaximumWithdraw); Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount); }
public void WithdrawLimitScenario7Test_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue() { // Scenario: DailyLimit = 500/1000, MonthlyLimit = 4000/5000 IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService(); Currency currency = new Currency("XBT"); AccountId accountId = new AccountId(123); decimal dailyLimit = 1000; decimal monthlyLimit = 5000; decimal availableBalance = 1000; decimal currentBalance = 1000; decimal fee = 0.001m; List <Withdraw> withdraws = new List <Withdraw>(); Withdraw withdraw = new Withdraw(currency, "withdrawid123", DateTime.Now.AddDays(-29), WithdrawType.Bitcoin, 3500, fee, TransactionStatus.Pending, accountId, new BitcoinAddress("bitcoin123")); Withdraw withdraw2 = new Withdraw(currency, "withdrawid123", DateTime.Now.AddMinutes(-5), WithdrawType.Bitcoin, 500, fee, TransactionStatus.Pending, accountId, new BitcoinAddress("bitcoin123")); withdraws.Add(withdraw); withdraws.Add(withdraw2); WithdrawLimit withdrawLimit = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit); bool evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(600 - fee * 2, withdraws, withdrawLimit, availableBalance, currentBalance); Assert.IsFalse(evaluationResponse); Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit); Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit); Assert.AreEqual(500 + fee, withdrawLimitEvaluationService.DailyLimitUsed); Assert.AreEqual(4000 + fee * 2, withdrawLimitEvaluationService.MonthlyLimitUsed); Assert.AreEqual(500 - fee, withdrawLimitEvaluationService.MaximumWithdraw); Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount); // Withdraw below the threshold limit evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(500 - fee * 2, withdraws, withdrawLimit, availableBalance, currentBalance); Assert.IsTrue(evaluationResponse); Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit); Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit); Assert.AreEqual(500 + fee, withdrawLimitEvaluationService.DailyLimitUsed); Assert.AreEqual(4000 + fee * 2, withdrawLimitEvaluationService.MonthlyLimitUsed); Assert.AreEqual(500 - fee, withdrawLimitEvaluationService.MaximumWithdraw); Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount); }
/// <summary> /// Assign The Withdraw Limits /// </summary> /// <param name="baseCurrency"></param> /// <param name="tierLevel"></param> /// <param name="withdrawals"></param> /// <param name="availableBalance"></param> /// <param name="currentBalance"></param> public void AssignWithdrawLimits(string baseCurrency, string tierLevel, IList <Withdraw> withdrawals, decimal availableBalance, decimal currentBalance) { // If the admin has specified the limits to be calculated as the currency itself if (_adminDefinedLimitsCurrency == LimitsCurrency.Default.ToString()) { Log.Debug(string.Format("Limits representation Currency = {0}", _adminDefinedLimitsCurrency)); // Get the Current Withdraw limits for this user WithdrawLimit withdrawLimit = _withdrawLimitRepository.GetLimitByTierLevelAndCurrency(tierLevel, _adminDefinedLimitsCurrency); if (withdrawLimit != null) { // Check if the current Withdraw transaction is within the Withdraw limits _withdrawLimitEvaluationService.AssignWithdrawLimits(withdrawals, withdrawLimit, availableBalance, currentBalance); } else { throw new InvalidOperationException( string.Format("No Withdraw Limit found for Tier: Tier Level = {0} & " + "CurrencyType = {1}", tierLevel, _adminDefinedLimitsCurrency)); } } // If the admin has specified that limits must be calculated in a FIAT currency else { Log.Debug(string.Format("Limits representation Currency = {0}", _adminDefinedLimitsCurrency)); // Get the Current Withdraw limits for this user which will be in a FIAT currency WithdrawLimit withdrawLimit = _withdrawLimitRepository.GetLimitByTierLevelAndCurrency(tierLevel, _adminDefinedLimitsCurrency); if (withdrawLimit != null) { // Get the best bid and best ask Tuple <decimal, decimal> bestBidBestAsk = _bboCrossContextService.GetBestBidBestAsk(baseCurrency, _adminDefinedLimitsCurrency); // Assign the withdraw limits in FIAT amounts _withdrawLimitEvaluationService.AssignWithdrawLimits(withdrawals, withdrawLimit, availableBalance, currentBalance, bestBidBestAsk.Item1, bestBidBestAsk.Item2); } else { throw new InvalidOperationException( string.Format("No Withdraw Limit found for Tier: Tier Level = {0} & " + "CurrencyType = {1}", tierLevel, _adminDefinedLimitsCurrency)); } } }
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); }
/// <summary> /// Evaluate the threshold limits and limits used for withdraw /// </summary> /// <returns></returns> public bool EvaluateWithdrawLimits(string baseCurrency, string tierLevel, decimal amount, IList <Withdraw> withdrawals, decimal availableBalance, decimal currentBalance) { // If the admin has specified the limits to be calculated as the currency itself if (_adminDefinedLimitsCurrency == LimitsCurrency.Default.ToString()) { // Get the Current Withdraw limits for this user WithdrawLimit withdrawLimit = _withdrawLimitRepository.GetLimitByTierLevelAndCurrency(tierLevel, _adminDefinedLimitsCurrency); if (withdrawLimit != null) { // Check if the current Withdraw transaction is within the Withdraw limits return(_withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(amount, withdrawals, withdrawLimit, availableBalance, currentBalance)); } throw new InvalidOperationException(string.Format("No Withdraw Limit found for Tier: Tier Level = {0} & " + "CurrencyType = {1}", tierLevel, _adminDefinedLimitsCurrency)); } // If the admin has specified that limits must be calculated in a FIAT currency else { // Get the Current Withdraw limits for this user which will be in a FIAT currency WithdrawLimit withdrawLimit = _withdrawLimitRepository.GetLimitByTierLevelAndCurrency(tierLevel, _adminDefinedLimitsCurrency); if (withdrawLimit != null) { // Convert the currency to FIAT decimal amountInFiat = ConvertCurrencyToFiat(baseCurrency, amount); // Check if the current Withdraw transaction is within the Withdraw limits // NOTE: If there is no best bid and best ask, then the limits will be specified in the default crypto currency // itself return(_withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(amountInFiat, withdrawals, withdrawLimit, availableBalance, currentBalance, _bestBidBestAsk.Item1, _bestBidBestAsk.Item2)); } throw new InvalidOperationException(string.Format("No Withdraw Limit found for Tier: Tier Level = {0} & " + "CurrencyType = {1}", tierLevel, _adminDefinedLimitsCurrency)); } }
public bool AssignWithdrawLimits(IList <Withdraw> depositLedgers, WithdrawLimit withdrawLimit, decimal balance, decimal currentBalance, decimal bestBid = 0, decimal bestAsk = 0) { throw new NotImplementedException(); }
public bool EvaluateMaximumWithdrawLimit(decimal withdrawalAmount, IList <Withdraw> depositLedgers, WithdrawLimit withdrawLimit, decimal balance, decimal currentBalance, decimal bestBid = 0, decimal bestAsk = 0) { throw new NotImplementedException(); }
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); }