Exemplo n.º 1
0
        public void DepositAndWithdrawTest_TestsIfThingsGoAsExpectedWhenWithdrawIsMadeAfterDeposit_ChecksBalanceToVerify()
        {
            // Scenario: Confirmed Deposit --> Withdraw --> Check Balance
            IFundsValidationService     fundsValidationService     = (IFundsValidationService)ContextRegistry.GetContext()["FundsValidationService"];
            IFundsPersistenceRepository fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];
            IBalanceRepository          balanceRepository          = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"];
            IDepositIdGeneratorService  depositIdGeneratorService  = (IDepositIdGeneratorService)ContextRegistry.GetContext()["DepositIdGeneratorService"];
            IWithdrawFeesRepository     withdrawFeesRepository     = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"];

            AccountId accountId = new AccountId(123);
            Currency  currency  = new Currency("BTC", true);

            // Deposit
            Deposit deposit = new Deposit(currency, depositIdGeneratorService.GenerateId(), DateTime.Now,
                                          DepositType.Default, 1.4m, 0, TransactionStatus.Pending, accountId,
                                          new TransactionId("123"), new BitcoinAddress("bitcoin123"));

            deposit.IncrementConfirmations(7);
            fundsPersistenceRepository.SaveOrUpdate(deposit);

            // Retrieve balance
            Balance balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId);

            Assert.IsNull(balance);
            bool depositResponse = fundsValidationService.DepositConfirmed(deposit);

            Assert.IsTrue(depositResponse);

            // Check balance
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId);
            Assert.IsNotNull(balance);
            Assert.AreEqual(balance.CurrentBalance, deposit.Amount);
            Assert.AreEqual(balance.AvailableBalance, deposit.Amount);
            Assert.AreEqual(balance.PendingBalance, 0);

            // Withdraw
            Withdraw validateFundsForWithdrawal = fundsValidationService.ValidateFundsForWithdrawal(accountId, currency,
                                                                                                    1.3M, new TransactionId("transaction123"), new BitcoinAddress("bitcoin123"));

            Assert.IsNotNull(validateFundsForWithdrawal);
            bool withdrawalExecuted = fundsValidationService.WithdrawalExecuted(validateFundsForWithdrawal);

            Assert.IsTrue(withdrawalExecuted);

            WithdrawFees withdrawFee = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name);

            // Check balance
            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId);
            Assert.IsNotNull(balance);
            Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.CurrentBalance, 5));
            Assert.AreEqual(Math.Round(1.4M - 1.3M, 5), Math.Round(balance.AvailableBalance, 5));
            Assert.AreEqual(0, balance.PendingBalance);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }