public void AssignWithdrawLimitsTest_TestsIfWithdrawLimitsGetAsignedProperlyWhenNoBalanceisPresent_VerifiesThroughReturnedValue() { IWithdrawApplicationService withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"]; IWithdrawLimitRepository withdrawLimitRepository = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IWithdrawFeesRepository withdrawFeesRepository = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"]; StubTierLevelRetrievalService tierLevelRetrievalService = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService; Assert.IsNotNull(tierLevelRetrievalService); tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel1); 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(withdrawLimit.DailyLimit, withdrawLimitRepresentation.DailyLimit); Assert.AreEqual(withdrawLimit.MonthlyLimit, 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 GetFeeTest_TestsIfTheFeeIsasReturnedAsExpectedWhenFinalElementInTheTableIsReached_VerifiesThroughDatabaseQueries() { IFeeCalculationService feeCalculationService = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"]; IFeeRepository feeRepository = (IFeeRepository)ContextRegistry.GetContext()["FeeRepository"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; AccountId accountId = new AccountId(1); List <Fee> allFees = feeRepository.GetAllFees(); Assert.IsNotNull(allFees); string currencyPair = allFees[0].CurrencyPair; Tuple <string, string> splittedCurrencyPair = CurrencySplitterService.SplitCurrencyPair(currencyPair); // As amount, the value is so large that it is always greater than any fee in the table Ledger ledger = new Ledger("1", DateTime.Now, LedgerType.Trade, new Currency(splittedCurrencyPair.Item2), 2000000, 0, 0, 0, "1", "1", false, accountId); fundsPersistenceRepository.SaveOrUpdate(ledger); List <Fee> feeByCurrencyPair = feeRepository.GetFeeByCurrencyPair(currencyPair); Assert.IsNotNull(feeByCurrencyPair); decimal lastElementFee = (feeByCurrencyPair.Last().PercentageFee / 100) * (1000 * 2000); decimal feeFromService = feeCalculationService.GetFee(new Currency(splittedCurrencyPair.Item1), new Currency(splittedCurrencyPair.Item2), accountId, 1000, 2000); Assert.AreEqual(lastElementFee, feeFromService); }
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 FundsValidationService(ITransactionService transactionService, IFundsPersistenceRepository fundsPersistenceRepository, IBalanceRepository balanceRepository, IFeeCalculationService feeCalculationService, IWithdrawFeesRepository withdrawFeesRepository, IWithdrawIdGeneratorService withdrawIdGeneratorService, ILedgerRepository ledgerRepository, IDepositLimitEvaluationService depositLimitEvaluationService, IDepositLimitRepository depositLimitRepository, IWithdrawLimitEvaluationService withdrawLimitEvaluationService, IWithdrawLimitRepository withdrawLimitRepository, ITierLevelRetrievalService tierLevelRetrievalService, IWithdrawRepository withdrawRepository, ITierValidationService tierValidationService, ILimitsConfigurationService limitsConfigurationService) { _transactionService = transactionService; _fundsPersistenceRepository = fundsPersistenceRepository; _balanceRepository = balanceRepository; _feeCalculationService = feeCalculationService; _withdrawFeesRepository = withdrawFeesRepository; _withdrawIdGeneratorService = withdrawIdGeneratorService; _ledgerRepository = ledgerRepository; _depositLimitEvaluationService = depositLimitEvaluationService; _depositLimitRepository = depositLimitRepository; _withdrawLimitEvaluationService = withdrawLimitEvaluationService; _withdrawLimitRepository = withdrawLimitRepository; _tierLevelRetrievalService = tierLevelRetrievalService; _withdrawRepository = withdrawRepository; _tierValidationService = tierValidationService; _limitsConfigurationService = limitsConfigurationService; }
/// <summary> /// Parameterized Constructor /// </summary> /// <param name="fundsPersistenceRepository"> </param> /// <param name="ledgerIdGeneratorService"></param> /// <param name="limitsConfigurationService"> </param> public TransactionService(IFundsPersistenceRepository fundsPersistenceRepository, ILedgerIdGeneraterService ledgerIdGeneratorService, ILimitsConfigurationService limitsConfigurationService) { _fundsPersistenceRepository = fundsPersistenceRepository; _ledgerIdGeneraterService = ledgerIdGeneratorService; _limitsConfigurationService = limitsConfigurationService; }
public void GetFeeTest_TestsIfTheFeeIsasReturnedAsExpectedWhenMiddleElementsAreReached_VerifiesThroughDatabaseQueries() { IFeeCalculationService feeCalculationService = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"]; IFeeRepository feeRepository = (IFeeRepository)ContextRegistry.GetContext()["FeeRepository"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; AccountId accountId = new AccountId(1); List <Fee> allFees = feeRepository.GetAllFees(); Assert.IsNotNull(allFees); string currencyPair = allFees[0].CurrencyPair; Tuple <string, string> splittedCurrencyPair = CurrencySplitterService.SplitCurrencyPair(currencyPair); List <Fee> feeByCurrencyPair = feeRepository.GetFeeByCurrencyPair(currencyPair); Assert.IsNotNull(feeByCurrencyPair); if (feeByCurrencyPair.Count > 4) { decimal amount = feeByCurrencyPair[feeByCurrencyPair.Count - 2].Amount; Ledger ledger = new Ledger("1", DateTime.Now, LedgerType.Trade, new Currency(splittedCurrencyPair.Item2), amount, 0, 0, 0, "1", "1", false, accountId); fundsPersistenceRepository.SaveOrUpdate(ledger); decimal lastElementFee = (feeByCurrencyPair[feeByCurrencyPair.Count - 2].PercentageFee / 100) * (10 * 20); decimal feeFromService = feeCalculationService.GetFee(new Currency(splittedCurrencyPair.Item1), new Currency(splittedCurrencyPair.Item2), accountId, 10, 20); Assert.AreEqual(lastElementFee, feeFromService); } }
public void DepositArrivedAndConfirmedTest_ChecksThatANewDepositInstanceIsCreatedAndConfirmedAsExpected_VerifiesThroughDatabaseQuery() { IDepositApplicationService depositApplicationService = (IDepositApplicationService)ContextRegistry.GetContext()["DepositApplicationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IDepositRepository depositRepository = (IDepositRepository)ContextRegistry.GetContext()["DepositRepository"]; IDepositLimitRepository depositLimitRepository = (IDepositLimitRepository)ContextRegistry.GetContext()["DepositLimitRepository"]; AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1"); TransactionId transactionId = new TransactionId("transactionid1"); string category = BitcoinConstants.ReceiveCategory; DepositAddress depositAddress = new DepositAddress(currency, bitcoinAddress, AddressStatus.New, DateTime.Now, accountId); fundsPersistenceRepository.SaveOrUpdate(depositAddress); DepositLimit depositLimit = depositLimitRepository.GetLimitByTierLevelAndCurrency("Tier 1", "Default"); Assert.IsNotNull(depositLimit, "DepositLimit used initially to compare later"); List <Tuple <string, string, decimal, string> > transactionsList = new List <Tuple <string, string, decimal, string> >(); // Provide the amount which is greater than the daily limit transactionsList.Add(new Tuple <string, string, decimal, string>(bitcoinAddress.Value, transactionId.Value, depositLimit.DailyLimit - 0.01M, category)); depositApplicationService.OnDepositArrival(currency.Name, transactionsList); // Deposit Transaction first arrival Deposit deposit = depositRepository.GetDepositByTransactionId(transactionId); Assert.IsNotNull(deposit); Assert.AreEqual(depositLimit.DailyLimit - 0.01M, deposit.Amount); Assert.AreEqual(transactionId.Value, deposit.TransactionId.Value); Assert.AreEqual(accountId.Value, deposit.AccountId.Value); Assert.AreEqual(bitcoinAddress.Value, deposit.BitcoinAddress.Value); Assert.AreEqual(TransactionStatus.Pending, deposit.Status); Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNull(balance); // Deposit Confirmation depositApplicationService.OnDepositConfirmed(transactionId.Value, 7); deposit = depositRepository.GetDepositByTransactionId(transactionId); Assert.IsNotNull(deposit); Assert.AreEqual(depositLimit.DailyLimit - 0.01M, deposit.Amount); Assert.AreEqual(transactionId.Value, deposit.TransactionId.Value); Assert.AreEqual(accountId.Value, deposit.AccountId.Value); Assert.AreEqual(bitcoinAddress.Value, deposit.BitcoinAddress.Value); Assert.AreEqual(TransactionStatus.Confirmed, deposit.Status); // Balance instance now will have been created balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(depositLimit.DailyLimit - 0.01M, balance.AvailableBalance); Assert.AreEqual(depositLimit.DailyLimit - 0.01M, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); Assert.IsFalse(balance.IsFrozen); }
public void DepositArrivedStandaloneFailedTest_TestsIfTheOperationIsAbortedWhenAmountIshigherThanThresholdLimit_VerifiesThroughQueryingDatabaseIsntances() { // Tests the event handler DepositArrived by directly sending data IDepositApplicationService depositApplicationService = (IDepositApplicationService)ContextRegistry.GetContext()["DepositApplicationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; ILedgerRepository ledgerRepository = (ILedgerRepository)ContextRegistry.GetContext()["LedgerRepository"]; IDepositRepository depositRepository = (IDepositRepository)ContextRegistry.GetContext()["DepositRepository"]; IDepositLimitRepository depositLimitRepository = (IDepositLimitRepository)ContextRegistry.GetContext()["DepositLimitRepository"]; StubTierLevelRetrievalService tierLevelRetrievalService = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService; Assert.IsNotNull(tierLevelRetrievalService); tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel1); AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1"); TransactionId transactionId = new TransactionId("transactionid1"); DepositLimit depositLimit = depositLimitRepository.GetLimitByTierLevelAndCurrency(TierConstants.TierLevel1, LimitsCurrency.Default.ToString()); decimal amount = depositLimit.DailyLimit + 0.001M; string category = BitcoinConstants.ReceiveCategory; DepositAddress depositAddress = new DepositAddress(currency, bitcoinAddress, AddressStatus.New, DateTime.Now, accountId); fundsPersistenceRepository.SaveOrUpdate(depositAddress); Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNull(balance); IList <Ledger> ledgers = ledgerRepository.GetLedgerByAccountIdAndCurrency(currency.Name, accountId); Assert.AreEqual(ledgers.Count, 0); List <Tuple <string, string, decimal, string> > transactionsList = new List <Tuple <string, string, decimal, string> >(); transactionsList.Add(new Tuple <string, string, decimal, string>(bitcoinAddress.Value, transactionId.Value, amount, category)); depositApplicationService.OnDepositArrival(currency.Name, transactionsList); Deposit deposit = depositRepository.GetDepositByTransactionId(transactionId); Assert.IsNotNull(deposit); Assert.AreEqual(amount, deposit.Amount); Assert.AreEqual(currency.Name, deposit.Currency.Name); Assert.AreEqual(accountId.Value, deposit.AccountId.Value); Assert.AreEqual(bitcoinAddress.Value, deposit.BitcoinAddress.Value); Assert.AreEqual(transactionId.Value, deposit.TransactionId.Value); Assert.AreEqual(TransactionStatus.Frozen, deposit.Status); // Confirm that the balance for the user has been frozen for this account balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.IsTrue(balance.IsFrozen); }
public void Setup() { _withdrawLimitRepository = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"]; _persistanceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; var connection = ConfigurationManager.ConnectionStrings["MySql"].ToString(); _databaseUtility = new DatabaseUtility(connection); _databaseUtility.Create(); _databaseUtility.Populate(); }
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); }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Object"/> class. /// </summary> public ClientInteractionService(IFundsPersistenceRepository fundsPersistenceRepository, IWithdrawRepository withdrawRepository, ICoinClientService bitcoinClientService, ICoinClientService litecoinClientService) { _fundsPersistenceRepository = fundsPersistenceRepository; _withdrawRepository = withdrawRepository; _bitcoinClientService = bitcoinClientService; _litecoinClientService = litecoinClientService; _withdrawSubmissioInterval = Convert.ToDouble(ConfigurationManager.AppSettings.Get("WithdrawSubmitInterval")); Log.Debug(string.Format("Withdraw submission interval = {0}", _withdrawSubmissioInterval)); HookEventHandlers(); }
/// <summary> /// Default Constructor /// </summary> private DepositApplicationService(IFundsValidationService fundsValidationService, IClientInteractionService clientInteractionService, IFundsPersistenceRepository fundsPersistenceRepository, IDepositAddressRepository depositAddressRepository, IBalanceRepository balanceRepository, IDepositRepository depositRepository, IDepositLimitRepository depositLimitRepository) { _fundsValidationService = fundsValidationService; _clientInteractionService = clientInteractionService; _fundsPersistenceRepository = fundsPersistenceRepository; _depositAddressRepository = depositAddressRepository; _balanceRepository = balanceRepository; _depositRepository = depositRepository; _depositLimitRepository = depositLimitRepository; _clientInteractionService.DepositArrived += OnDepositArrival; _clientInteractionService.DepositConfirmed += OnDepositConfirmed; }
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> /// Initializes a new instance of the <see cref="T:System.Object"/> class. /// </summary> public WithdrawApplicationService(IFundsPersistenceRepository fundsPersistenceRepository, IWithdrawAddressRepository withdrawAddressRepository, IFundsValidationService fundsValidationService, IWithdrawRepository withdrawRepository, IClientInteractionService clientInteractionService, IDepositAddressRepository depositAddressRepository, IWithdrawLimitRepository withdrawLimitRepository, IBalanceRepository balanceRepository) { _fundsPersistenceRepository = fundsPersistenceRepository; _withdrawAddressRepository = withdrawAddressRepository; _fundsValidationService = fundsValidationService; _withdrawRepository = withdrawRepository; _withdrawSubmissionService = clientInteractionService; _depositAddressRepository = depositAddressRepository; _withdrawLimitRepository = withdrawLimitRepository; _balanceRepository = balanceRepository; _withdrawSubmissionService.WithdrawExecuted += this.WithdrawExecuted; }
public void TestBalanceQueryService_WhenAccountIdIsSupplied_ItShouldReturnListOfBalanceDetails() { IFundsPersistenceRepository repository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; Balance balance = new Balance(new Currency("BTC"), new AccountId(1), 1000, 1000); Balance balance2 = new Balance(new Currency("LTC"), new AccountId(1), 2000, 2000); repository.SaveOrUpdate(balance); repository.SaveOrUpdate(balance2); IBalanceQueryService _balanceQueryService = (IBalanceQueryService)ContextRegistry.GetContext()["BalanceQueryService"]; List <BalanceDetails> balanceDetailses = _balanceQueryService.GetBalances(new AccountId(1)); Assert.NotNull(balanceDetailses); Assert.AreEqual(2, balanceDetailses.Count); Assert.AreEqual(balanceDetailses[0].Currency, "BTC"); Assert.AreEqual(balanceDetailses[0].Balance, 1000); Assert.AreEqual(balanceDetailses[1].Currency, "LTC"); Assert.AreEqual(balanceDetailses[1].Balance, 2000); }
public void SendMultipleOrdersTest_TestsIfSendingMultipleOrdersIsHandledAsExpected_VerifiesThroughTheReturnesValue() { IFundsValidationService fundsValidationService = (IFundsValidationService)ContextRegistry.GetContext()["FundsValidationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IFeeCalculationService feeCalculationService = (IFeeCalculationService)ContextRegistry.GetContext()["FeeCalculationService"]; IFeeRepository feeRepository = (IFeeRepository)ContextRegistry.GetContext()["FeeRepository"]; AccountId accountId = new AccountId(123); List <Fee> allFees = feeRepository.GetAllFees(); Tuple <string, string> splittedCurrencyPair = CurrencySplitterService.SplitCurrencyPair(allFees.First().CurrencyPair); Currency baseCurrency = new Currency(splittedCurrencyPair.Item1); Currency quoteCurrency = new Currency(splittedCurrencyPair.Item2); Balance baseCurrencyBalance = new Balance(baseCurrency, accountId, 400, 400); fundsPersistenceRepository.SaveOrUpdate(baseCurrencyBalance); Balance quoteCurrencyBalance = new Balance(quoteCurrency, accountId, 40000, 40000); fundsPersistenceRepository.SaveOrUpdate(quoteCurrencyBalance); bool validateFundsForOrder = fundsValidationService.ValidateFundsForOrder(accountId, baseCurrency, quoteCurrency, 40, 100, "buy", "order123"); Assert.IsTrue(validateFundsForOrder); // Get the fee corresponding to the current volume of the quote currency decimal usdFee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, accountId, 40, 100); Assert.Greater(usdFee, 0); baseCurrencyBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, accountId); Assert.AreEqual(400, baseCurrencyBalance.CurrentBalance); Assert.AreEqual(400, baseCurrencyBalance.AvailableBalance); Assert.AreEqual(0, baseCurrencyBalance.PendingBalance); quoteCurrencyBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, accountId); Assert.AreEqual(40000 - (40 * 100), quoteCurrencyBalance.AvailableBalance); Assert.AreEqual(40000, quoteCurrencyBalance.CurrentBalance); Assert.AreEqual(40 * 100, quoteCurrencyBalance.PendingBalance); }
public void DepositArrivedFailTest_VerifiesThatNewDepositWithAMountGreaterThanLimitsIsSuspendedAndAccountBalanceFrozen_VerifiesThroughDatabaseQuery() { IDepositApplicationService depositApplicationService = (IDepositApplicationService)ContextRegistry.GetContext()["DepositApplicationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IDepositRepository depositRepository = (IDepositRepository)ContextRegistry.GetContext()["DepositRepository"]; IDepositLimitRepository depositLimitRepository = (IDepositLimitRepository)ContextRegistry.GetContext()["DepositLimitRepository"]; AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1"); TransactionId transactionId = new TransactionId("transactionid1"); string category = BitcoinConstants.ReceiveCategory; DepositAddress depositAddress = new DepositAddress(currency, bitcoinAddress, AddressStatus.New, DateTime.Now, accountId); fundsPersistenceRepository.SaveOrUpdate(depositAddress); DepositLimit depositLimit = depositLimitRepository.GetLimitByTierLevelAndCurrency("Tier 1", "Default"); Assert.IsNotNull(depositLimit, "DepositLimit used initially to compare later"); List <Tuple <string, string, decimal, string> > transactionsList = new List <Tuple <string, string, decimal, string> >(); // Provide the amount which is greater than the daily limit transactionsList.Add(new Tuple <string, string, decimal, string>(bitcoinAddress.Value, transactionId.Value, depositLimit.DailyLimit + 0.001M, category)); depositApplicationService.OnDepositArrival(currency.Name, transactionsList); Deposit deposit = depositRepository.GetDepositByTransactionId(transactionId); Assert.IsNotNull(deposit); Assert.AreEqual(TransactionStatus.Frozen, deposit.Status); Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.IsTrue(balance.IsFrozen); }
public void AssignDepositLimits2Test_ChecksThatDepositLimitsAreAssignedProperlyWhenLevel1IsVerifiedAndBalanceIsAlreadyPresent_VerifiesThroughReturnedValues() { IDepositApplicationService depositApplicationService = (IDepositApplicationService)ContextRegistry.GetContext()["DepositApplicationService"]; IDepositLimitRepository depositLimitRepository = (IDepositLimitRepository)ContextRegistry.GetContext()["DepositLimitRepository"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; DepositLimit depositLimit = depositLimitRepository.GetLimitByTierLevelAndCurrency("Tier 1", LimitsCurrency.Default.ToString()); AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); decimal balanceAmount = 100; Balance balance = new Balance(currency, accountId, balanceAmount, balanceAmount); fundsPersistenceRepository.SaveOrUpdate(balance); DepositLimitThresholdsRepresentation depositLimitThresholds = depositApplicationService.GetThresholdLimits(accountId.Value, currency.Name); Assert.IsNotNull(depositLimitThresholds); Assert.AreEqual(depositLimit.DailyLimit, depositLimitThresholds.DailyLimit); Assert.AreEqual(depositLimit.MonthlyLimit, depositLimitThresholds.MonthlyLimit); Assert.AreEqual(0, depositLimitThresholds.DailyLimitUsed); Assert.AreEqual(0, depositLimitThresholds.MonthlyLimitUsed); Assert.AreEqual(balanceAmount, depositLimitThresholds.CurrentBalance); Assert.AreEqual(depositLimit.DailyLimit, depositLimitThresholds.MaximumDeposit); }
public void ValidateOrderAndHandleTradeTest_CheksIfEnoughBalanceIsAvailableForAnOrderToBeSentAndHandlesTradeWhenItExectues_VerifiesThroughDatabaseQueryAndValueReturned() { 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"]; Currency baseCurrency = new Currency("BTC"); Currency quoteCurrency = new Currency("USD"); decimal volume = 1.4m; decimal price = 590m; string buyOrderId = "buy123"; string sellOrderId = "sell123"; string buy = "buy"; string sell = "sell"; AccountId buyAccountId = new AccountId(1); AccountId sellAccountId = new AccountId(2); Balance buyBaseBalance = new Balance(baseCurrency, buyAccountId, 20, 20); Balance buyQuoteBalance = new Balance(quoteCurrency, buyAccountId, 15000, 15000); Balance sellBaseBalance = new Balance(baseCurrency, sellAccountId, 20, 20); Balance sellQuoteBalance = new Balance(quoteCurrency, sellAccountId, 15000, 15000); fundsPersistenceRepository.SaveOrUpdate(buyBaseBalance); fundsPersistenceRepository.SaveOrUpdate(buyQuoteBalance); fundsPersistenceRepository.SaveOrUpdate(sellBaseBalance); fundsPersistenceRepository.SaveOrUpdate(sellQuoteBalance); bool validationResponse = fundsValidationService.ValidateFundsForOrder(buyAccountId, baseCurrency, quoteCurrency, volume, price, buy, buyOrderId); Assert.IsTrue(validationResponse); validationResponse = fundsValidationService.ValidateFundsForOrder(sellAccountId, baseCurrency, quoteCurrency, volume, price, sell, sellOrderId); Assert.IsTrue(validationResponse); buyBaseBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, buyAccountId); Assert.AreEqual(20, buyBaseBalance.AvailableBalance); Assert.AreEqual(20, buyBaseBalance.CurrentBalance); Assert.AreEqual(0, buyBaseBalance.PendingBalance); buyQuoteBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, buyAccountId); Assert.AreEqual(15000 - (price * volume), buyQuoteBalance.AvailableBalance); Assert.AreEqual(15000, buyQuoteBalance.CurrentBalance); Assert.AreEqual(price * volume, buyQuoteBalance.PendingBalance); sellBaseBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, sellAccountId); Assert.AreEqual(20 - volume, sellBaseBalance.AvailableBalance); Assert.AreEqual(20, sellBaseBalance.CurrentBalance); Assert.AreEqual(volume, sellBaseBalance.PendingBalance); sellQuoteBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, sellAccountId); Assert.AreEqual(15000, sellQuoteBalance.AvailableBalance); Assert.AreEqual(15000, sellQuoteBalance.CurrentBalance); Assert.AreEqual(0, sellQuoteBalance.PendingBalance); string tradeId = "tradeid123"; bool tradeExecutedResponse = fundsValidationService.TradeExecuted(baseCurrency.Name, quoteCurrency.Name, volume, price, DateTime.Now, tradeId, buyAccountId.Value, sellAccountId.Value, buyOrderId, sellOrderId); Assert.IsTrue(tradeExecutedResponse); decimal buySideFee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, buyAccountId, volume, price); decimal sellSidefee = feeCalculationService.GetFee(baseCurrency, quoteCurrency, sellAccountId, volume, price); buyBaseBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, buyAccountId); Assert.AreEqual(20 + volume, buyBaseBalance.AvailableBalance); Assert.AreEqual(20 + volume, buyBaseBalance.CurrentBalance); Assert.AreEqual(0, buyBaseBalance.PendingBalance); buyQuoteBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, buyAccountId); Assert.AreEqual(15000 - (price * volume) - buySideFee, buyQuoteBalance.AvailableBalance); Assert.AreEqual(15000 - (price * volume) - buySideFee, buyQuoteBalance.CurrentBalance); Assert.AreEqual(0, buyQuoteBalance.PendingBalance); sellBaseBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(baseCurrency, sellAccountId); Assert.AreEqual(20 - volume, sellBaseBalance.AvailableBalance); Assert.AreEqual(20 - volume, sellBaseBalance.CurrentBalance); Assert.AreEqual(0, sellBaseBalance.PendingBalance); sellQuoteBalance = balanceRepository.GetBalanceByCurrencyAndAccountId(quoteCurrency, sellAccountId); Assert.AreEqual(15000 + (price * volume) - sellSidefee, sellQuoteBalance.AvailableBalance); Assert.AreEqual(15000 + (price * volume) - sellSidefee, sellQuoteBalance.CurrentBalance); Assert.AreEqual(0, sellQuoteBalance.PendingBalance); }
public void DepositCheckNewTransactionsTest_TestIfDepositHandlingIsDoneAsExpected_VerifiesThroughReturnedValue() { // Submits withdraw to own address, after the first NewTransactionInterval has been elapsed. // Checks if new deposit has been created by the DepositAPplicationService and DepositAddress marked used if (_shouldRunTests) { ICoinClientService coinClientService = (ICoinClientService)ContextRegistry.GetContext()["BitcoinClientService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IDepositAddressRepository depositAddressRepository = (IDepositAddressRepository)ContextRegistry.GetContext()["DepositAddressRepository"]; IDepositRepository depositRepository = (IDepositRepository)ContextRegistry.GetContext()["DepositRepository"]; Currency currency = new Currency("BTC", true); AccountId accountId = new AccountId(1); string newAddress = coinClientService.CreateNewAddress(); BitcoinAddress bitcoinAddress = new BitcoinAddress(newAddress); DepositAddress depositAddress = new DepositAddress(currency, bitcoinAddress, AddressStatus.New, DateTime.Now, accountId); fundsPersistenceRepository.SaveOrUpdate(depositAddress); // Check that there is no deposit with htis address present List <Deposit> deposits = depositRepository.GetDepositsByBitcoinAddress(bitcoinAddress); Assert.AreEqual(0, deposits.Count); ManualResetEvent manualResetEvent = new ManualResetEvent(false); // Wait for the first interval to elapse, and then withdraw, because only then we will be able to figure if a // new transaction has been received manualResetEvent.WaitOne(Convert.ToInt32(coinClientService.PollingInterval + 3000)); manualResetEvent.Reset(); bool eventFired = false; coinClientService.DepositArrived += delegate(string curr, List <Tuple <string, string, decimal, string> > pendingList) { eventFired = true; manualResetEvent.Set(); }; Withdraw withdraw = new Withdraw(currency, Guid.NewGuid().ToString(), DateTime.Now, WithdrawType.Bitcoin, Amount, 0.001m, TransactionStatus.Pending, accountId, new BitcoinAddress(newAddress)); string withdrawTransactionId = coinClientService.CommitWithdraw(withdraw.BitcoinAddress.Value, withdraw.Amount); Assert.IsNotNull(withdrawTransactionId); Assert.IsFalse(string.IsNullOrEmpty(withdrawTransactionId)); manualResetEvent.WaitOne(); Assert.IsTrue(eventFired); depositAddress = depositAddressRepository.GetDepositAddressByAddress(bitcoinAddress); Assert.IsNotNull(depositAddress); Assert.AreEqual(AddressStatus.Used, depositAddress.Status); // See If DepositApplicationService created the deposit instance deposits = depositRepository.GetDepositsByBitcoinAddress(bitcoinAddress); Deposit deposit = deposits.Single(); Assert.IsNotNull(deposit); Assert.AreEqual(Amount, deposit.Amount); Assert.AreEqual(currency.Name, deposit.Currency.Name); Assert.IsFalse(string.IsNullOrEmpty(deposit.TransactionId.Value)); Assert.AreEqual(bitcoinAddress.Value, deposit.BitcoinAddress.Value); Assert.AreEqual(DepositType.Default, deposit.Type); Assert.AreEqual(0, deposit.Confirmations); Assert.AreEqual(accountId.Value, deposit.AccountId.Value); Assert.AreEqual(TransactionStatus.Pending, deposit.Status); Assert.AreEqual(withdrawTransactionId, deposit.TransactionId.Value); } }
public void DepositArrivedAndConfirmedEventTest_TestsThatDepositArrivedEventIsHandledAsExpected_VerifiesThroughRaisedEvent() { // Withdraw is submitted and events are actually raised from the CoinClientService // Over the limit deposit so account and deposit are frozen IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; IDepositRepository depositRepository = (IDepositRepository)ContextRegistry.GetContext()["DepositRepository"]; IWithdrawRepository withdrawRepository = (IWithdrawRepository)ContextRegistry.GetContext()["WithdrawRepository"]; IDepositLimitRepository depositLimitRepository = (IDepositLimitRepository)ContextRegistry.GetContext()["DepositLimitRepository"]; IWithdrawApplicationService withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"]; AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1"); TransactionId transactionId = new TransactionId("transactionid1"); DepositAddress depositAddress = new DepositAddress(currency, bitcoinAddress, AddressStatus.New, DateTime.Now, accountId); fundsPersistenceRepository.SaveOrUpdate(depositAddress); DepositLimit depositLimit = depositLimitRepository.GetLimitByTierLevelAndCurrency("Tier 1", "Default"); Assert.IsNotNull(depositLimit, "DepositLimit used initially to compare later"); decimal amount = depositLimit.DailyLimit - 0.001M; ManualResetEvent manualResetEvent = new ManualResetEvent(false); Balance balance = new Balance(currency, accountId, 10, 10); 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); // Get the interval after which the withdraw will be submitted. Once submitted to the StubClientService, the events // of DepositArrived will be raised and handled in Deposit APplicationService, which will create a new Deposit // instance and save in database int withdrawInterval = Convert.ToInt16(ConfigurationManager.AppSettings.Get("WithdrawSubmitInterval")); manualResetEvent.WaitOne(withdrawInterval + 2000); Withdraw withdraw = withdrawRepository.GetWithdrawByWithdrawId(commitWithdrawResponse.WithdrawId); Assert.IsNotNull(withdraw); Deposit deposit = depositRepository.GetDepositByTransactionId(transactionId); Assert.IsNotNull(deposit); Assert.AreEqual(amount - withdraw.Fee, deposit.Amount); Assert.AreEqual(withdraw.TransactionId.Value, deposit.TransactionId.Value); Assert.AreEqual(accountId.Value, deposit.AccountId.Value); Assert.AreEqual(bitcoinAddress.Value, deposit.BitcoinAddress.Value); Assert.AreEqual(TransactionStatus.Confirmed, deposit.Status); balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); // Balance instance now will have been created balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(0, balance.PendingBalance); Assert.IsFalse(balance.IsFrozen); }
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 DepositConfirmedTest_TestsIfTheOperationProceedsAsExpectedWhenADepositIsConfirmed_VerifiesThroughQueryingDatabaseIsntances() { IDepositApplicationService depositApplicationService = (IDepositApplicationService)ContextRegistry.GetContext()["DepositApplicationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; ILedgerRepository ledgerRepository = (ILedgerRepository)ContextRegistry.GetContext()["LedgerRepository"]; IDepositRepository depositRepository = (IDepositRepository)ContextRegistry.GetContext()["DepositRepository"]; IDepositAddressRepository depositAddressRepository = (IDepositAddressRepository)ContextRegistry.GetContext()["DepositAddressRepository"]; StubTierLevelRetrievalService tierLevelRetrievalService = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService; if (tierLevelRetrievalService != null) { tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel1); } AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1"); TransactionId transactionId = new TransactionId("transactionid1"); decimal amount = 1.02m; string category = BitcoinConstants.ReceiveCategory; DepositAddress depositAddress = new DepositAddress(currency, bitcoinAddress, AddressStatus.New, DateTime.Now, accountId); fundsPersistenceRepository.SaveOrUpdate(depositAddress); Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNull(balance); IList <Ledger> ledgers = ledgerRepository.GetLedgerByAccountIdAndCurrency(currency.Name, accountId); Assert.AreEqual(ledgers.Count, 0); List <Tuple <string, string, decimal, string> > transactionsList = new List <Tuple <string, string, decimal, string> >(); transactionsList.Add(new Tuple <string, string, decimal, string>(bitcoinAddress.Value, transactionId.Value, amount, category)); depositApplicationService.OnDepositArrival(currency.Name, transactionsList); Deposit deposit = depositRepository.GetDepositByTransactionId(transactionId); Assert.IsNotNull(deposit); Assert.AreEqual(deposit.Amount, amount); Assert.AreEqual(deposit.Currency.Name, currency.Name); Assert.IsTrue(deposit.Currency.IsCryptoCurrency); Assert.AreEqual(deposit.TransactionId.Value, transactionId.Value); Assert.AreEqual(deposit.BitcoinAddress.Value, bitcoinAddress.Value); Assert.AreEqual(TransactionStatus.Pending, deposit.Status); depositAddress = depositAddressRepository.GetDepositAddressByAddress(bitcoinAddress); Assert.IsNotNull(depositAddress); Assert.AreEqual(AddressStatus.Used, depositAddress.Status); balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNull(balance); ledgers = ledgerRepository.GetLedgerByAccountIdAndCurrency(currency.Name, accountId); Assert.AreEqual(0, ledgers.Count); depositApplicationService.OnDepositConfirmed(transactionId.Value, 7); deposit = depositRepository.GetDepositByTransactionId(transactionId); Assert.IsNotNull(deposit); Assert.AreEqual(deposit.Status, TransactionStatus.Confirmed); balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNotNull(balance); Assert.AreEqual(amount, balance.AvailableBalance); Assert.AreEqual(amount, balance.CurrentBalance); Assert.AreEqual(0, balance.PendingBalance); ledgers = ledgerRepository.GetLedgerByAccountIdAndCurrency(currency.Name, accountId); Assert.AreEqual(1, ledgers.Count); var ledger = ledgers.SingleOrDefault(); Assert.IsNotNull(ledger); Assert.AreEqual(LedgerType.Deposit, ledger.LedgerType); Assert.AreEqual(accountId.Value, ledger.AccountId.Value); Assert.AreEqual(amount, ledger.Amount); Assert.AreEqual(deposit.DepositId, ledger.DepositId); Assert.AreEqual(0, ledger.Fee); }
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 DepositArrivedStandaloneTest_TestsIfTheOperationProceedsAsExpectedWHenANewDepositArrives_VerifiesThroughQueryingDatabaseIsntances() { // Tests the event handler DepositArrived by directly sending data IDepositApplicationService depositApplicationService = (IDepositApplicationService)ContextRegistry.GetContext()["DepositApplicationService"]; IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"]; IBalanceRepository balanceRepository = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"]; ILedgerRepository ledgerRepository = (ILedgerRepository)ContextRegistry.GetContext()["LedgerRepository"]; IDepositRepository depositRepository = (IDepositRepository)ContextRegistry.GetContext()["DepositRepository"]; IDepositAddressRepository depositAddressRepository = (IDepositAddressRepository)ContextRegistry.GetContext()["DepositAddressRepository"]; IDepositLimitRepository depositLimitRepository = (IDepositLimitRepository)ContextRegistry.GetContext()["DepositLimitRepository"]; StubTierLevelRetrievalService tierLevelRetrieval = (StubTierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"]; tierLevelRetrieval.SetTierLevel(TierConstants.TierLevel1); AccountId accountId = new AccountId(123); Currency currency = new Currency("BTC", true); BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1"); TransactionId transactionId = new TransactionId("transactionid1"); DepositLimit depositLimit = depositLimitRepository.GetLimitByTierLevelAndCurrency(TierConstants.TierLevel1, LimitsCurrency.Default.ToString()); decimal amount = depositLimit.DailyLimit - 0.001M; string category = BitcoinConstants.ReceiveCategory; DepositAddress depositAddress = new DepositAddress(currency, bitcoinAddress, AddressStatus.New, DateTime.Now, accountId); fundsPersistenceRepository.SaveOrUpdate(depositAddress); Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNull(balance); IList <Ledger> ledgers = ledgerRepository.GetLedgerByAccountIdAndCurrency(currency.Name, accountId); Assert.AreEqual(ledgers.Count, 0); List <Tuple <string, string, decimal, string> > transactionsList = new List <Tuple <string, string, decimal, string> >(); transactionsList.Add(new Tuple <string, string, decimal, string>(bitcoinAddress.Value, transactionId.Value, amount, category)); depositApplicationService.OnDepositArrival(currency.Name, transactionsList); ManualResetEvent manualResetEvent = new ManualResetEvent(false); manualResetEvent.WaitOne(2000); Deposit deposit = depositRepository.GetDepositByTransactionId(transactionId); Assert.IsNotNull(deposit); Assert.AreEqual(deposit.Amount, amount); Assert.AreEqual(deposit.Currency.Name, currency.Name); Assert.IsTrue(deposit.Currency.IsCryptoCurrency); Assert.AreEqual(deposit.TransactionId.Value, transactionId.Value); Assert.AreEqual(deposit.BitcoinAddress.Value, bitcoinAddress.Value); Assert.AreEqual(deposit.Status, TransactionStatus.Pending); depositAddress = depositAddressRepository.GetDepositAddressByAddress(bitcoinAddress); Assert.IsNotNull(depositAddress); Assert.AreEqual(depositAddress.Status, AddressStatus.Used); balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId); Assert.IsNull(balance); ledgers = ledgerRepository.GetLedgerByAccountIdAndCurrency(currency.Name, accountId); Assert.AreEqual(ledgers.Count, 0); }
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); }