Exemplo n.º 1
0
        public void Can_withdraw_multiple_amounts_simultaneously()
        {
            var pinValidationService = Substitute.For <IPinValidationService>();

            pinValidationService.IsPinCorrect(Arg.Any <EncryptedPin>(), Arg.Any <string>()).ReturnsForAnyArgs(true)
            .AndDoes(async _ => await Task.Delay(1000));

            var card = new CashCard(TestPin, pinValidationService);

            card.Deposit(100);

            var tf    = new TaskFactory();
            var tasks = new List <Task>();

            for (var i = 1; i <= 4; i++)
            {
                tasks.Add(tf.StartNew(() =>
                {
                    var resp = card.Withdraw(10, TestPin);
                    Assert.That(resp.Status, Is.EqualTo(WithdrawalStatus.Successful));
                }));
            }

            Task.WaitAll(tasks.ToArray());

            // One final one to ensure we end up with the right value
            var response = card.Withdraw(10, TestPin);

            Assert.That(response.Status, Is.EqualTo(WithdrawalStatus.Successful));
            Assert.That(response.ErrorMessage, Is.EqualTo(""));
            Assert.That(card.Balance, Is.EqualTo(50));
        }
Exemplo n.º 2
0
        public void Cannot_withdraw_more_than_balance_with_multiple_simultaneous_requests()
        {
            var pinValidationService = Substitute.For <IPinValidationService>();

            pinValidationService.IsPinCorrect(Arg.Any <EncryptedPin>(), Arg.Any <string>()).ReturnsForAnyArgs(true)
            .AndDoes(async _ => await Task.Delay(1500));

            var card = new CashCard(TestPin, pinValidationService);

            card.Deposit(25);

            var tf        = new TaskFactory();
            var tasks     = new List <Task>();
            var responses = new List <WithdrawalStatus>();

            for (var i = 1; i <= 4; i++)
            {
                tasks.Add(tf.StartNew(() =>
                {
                    var resp = card.Withdraw(10, TestPin);
                    responses.Add(resp.Status);
                }));
            }

            Task.WaitAll(tasks.ToArray());
            Assert.That(responses.Count(r => r == WithdrawalStatus.Successful), Is.EqualTo(2));
            Assert.That(responses.Count(r => r == WithdrawalStatus.InsufficientFunds), Is.EqualTo(2));

            Assert.That(card.Balance, Is.EqualTo(5));
        }
Exemplo n.º 3
0
        public async Task CanWithDrawAndTopupFromMultiplePlacesSameTime()
        {
            var cashCard   = new CashCard(GetMockValidator(), MOCK_CARDNUMBER);
            var prebalance = cashCard.Balance;
            await cashCard.TopupBalance(MOCK_PIN, 2300M);

            Assert.AreEqual(cashCard.Balance, decimal.Add(prebalance, 2300M));

            List <Task> tasksArray = new List <Task>();

            int totalCounter = 100;

            for (int index = 1; index <= totalCounter; index++)
            {
                if (index % 5 == 0)
                {
                    tasksArray.Add(Task.Factory.StartNew(async() => { await cashCard.Withdraw(MOCK_PIN, 500M); }));
                }
                else
                {
                    tasksArray.Add(Task.Factory.StartNew(async() => { await cashCard.TopupBalance(MOCK_PIN, 200M); }));
                }
            }

            var task = Task.Factory.ContinueWhenAll(tasksArray.ToArray(),
                                                    innerTasks =>
            {
                foreach (var innerTask in innerTasks)
                {
                    Assert.That(innerTask.IsFaulted, Is.False);
                }
                Assert.AreEqual(cashCard.Balance, 6000M);
            });
        }
Exemplo n.º 4
0
        public void WithdrawMoney_FundsNotAvailable_Failure()
        {
            CashCard card = new CashCard(100, "12345678");

            bool Success = card.Withdraw(1234, 150);

            Assert.AreEqual(card.Balance(1234), 100);
        }
Exemplo n.º 5
0
        public void WithdrawMoney_NegativeAmount_Success()
        {
            CashCard card = new CashCard(100, "12345678");

            bool Success = card.Withdraw(1234, -50);

            Assert.AreEqual(card.Balance(1234), 100);
        }
Exemplo n.º 6
0
        public void WithdrawMoney_InvalidPin_Success()
        {
            CashCard card = new CashCard(100, "12345678");


            bool Success = card.Withdraw(1111, 50);

            Assert.AreEqual(card.Balance(1234), 100);
        }
Exemplo n.º 7
0
        public async Task WithdrawFailOnNegativeDecimalAmount()
        {
            var cashCard   = new CashCard(GetMockValidator(), MOCK_CARDNUMBER);
            var prebalance = cashCard.Balance;
            var result     = await cashCard.Withdraw(MOCK_PIN, -1M);

            Assert.That(result, Is.False);
            Assert.AreEqual(0M, cashCard.Balance);
        }
Exemplo n.º 8
0
        public void Cannot_withdraw_with_incorrect_pin()
        {
            var card = new CashCard(TestPin, _pinValidationService);

            card.Deposit(50);

            var response = card.Withdraw(25, "4321");

            Assert.That(response.Status, Is.EqualTo(WithdrawalStatus.Error));
            Assert.That(response.ErrorMessage, Is.EqualTo(ErrorCodes.InvalidPin));
            Assert.That(card.Balance, Is.EqualTo(50));
        }
Exemplo n.º 9
0
        public void Can_withdraw_amount(decimal balance, decimal withdrawalAmount, decimal finalBalance, WithdrawalStatus expectedStatus, string expectedErrorMessage)
        {
            var card = new CashCard(TestPin, _pinValidationService);

            card.Deposit(balance);

            var response = card.Withdraw(withdrawalAmount, TestPin);

            Assert.That(response.Status, Is.EqualTo(expectedStatus));
            Assert.That(response.ErrorMessage, Is.EqualTo(expectedErrorMessage));
            Assert.That(card.Balance, Is.EqualTo(finalBalance));
        }
Exemplo n.º 10
0
        public void WithdrawMoney_MultipleInstances_Success()
        {
            CashCard card1 = new CashCard(100, "12345678");
            CashCard card2 = new CashCard();

            bool Success = card1.Withdraw(1234, 20);

            Success = card2.Withdraw(1234, 10);

            Assert.AreEqual(card1.Balance(1234), 70);
            Assert.AreEqual(card2.Balance(1234), 70);
        }
Exemplo n.º 11
0
        public async Task Test_Withdraw_FromMultipleSourcesOneWrongPin()
        {
            CashCard cashCard = new CashCard();
            var      addInitialBalanceSuccess = await cashCard.TopUp(1234, 10000M);

            var initialBalance = cashCard.Balance;

            var task1   = cashCard.Withdraw(1234, 100M);
            var task2   = cashCard.Withdraw(1234, 500M);
            var task3   = cashCard.Withdraw(4321, 1000M);
            var task4   = cashCard.Withdraw(1234, 10M);
            var task5   = cashCard.Withdraw(1234, 50M);
            var results = await Task.WhenAll(task1, task2, task3, task4, task5);

            Assert.IsTrue(results[0]);
            Assert.IsTrue(results[1]);
            Assert.IsFalse(results[2]);
            Assert.IsTrue(results[3]);
            Assert.IsTrue(results[4]);
            Assert.AreEqual(initialBalance - 100M - 500M - 10M - 50M, cashCard.Balance);
        }
 public async Task CanWithdrawAmountWhenSufficientBalance()
 {
     var cashCard = new CashCard(GetMockValidator(), MOCK_CARDNUMBER);
     var prebalance = cashCard.Balance;
     var result = await cashCard.TopupBalance(MOCK_PIN, 200M);
     Assert.That(result, Is.True);
     Assert.AreEqual(decimal.Add(prebalance, 200M), cashCard.Balance);
     prebalance = cashCard.Balance;
     result = await cashCard.Withdraw(MOCK_PIN, 100M);
     Assert.That(result, Is.True);
     Assert.AreEqual(decimal.Subtract(prebalance, 100M), cashCard.Balance);
 }
        public async Task CanWithDrawFromMultiplePlacesSameTime()
        {
            var cashCard = new CashCard(GetMockValidator(), MOCK_CARDNUMBER);
            var prebalance = cashCard.Balance;
            await cashCard.TopupBalance(MOCK_PIN, 900M);
            Assert.AreEqual(cashCard.Balance, decimal.Add(prebalance, 900M));

            
            Task innerTask1 = Task.Factory.StartNew(async () => { await cashCard.Withdraw(MOCK_PIN, 100M ); });
            Task innerTask2 = Task.Factory.StartNew(async () => { await cashCard.Withdraw(MOCK_PIN, 300M ); });
            Task innerTask3 = Task.Factory.StartNew(async () => { await cashCard.Withdraw(MOCK_PIN, 400M ); });

            var task = Task.Factory.ContinueWhenAll(
                new[] { innerTask1, innerTask2, innerTask3 },
                innerTasks =>
                {
                    foreach (var innerTask in innerTasks)
                        Assert.That(innerTask.IsFaulted, Is.False);
                    Assert.AreEqual(cashCard.Balance, decimal.Subtract(prebalance, 800M));
                });
        }
        public async Task WithdrawFailOnPinVerificationFailure()
        {
            var cashCard = new CashCard(GetMockValidator(), MOCK_CARDNUMBER);
            var prebalance = cashCard.Balance;
            var result = await cashCard.TopupBalance(MOCK_PIN, 200M);
            Assert.That(result, Is.True);
            Assert.AreEqual(decimal.Add(prebalance, 200M), cashCard.Balance);
            prebalance = cashCard.Balance;

            int invalidPin = MOCK_PIN + 900;
            result = await cashCard.Withdraw(invalidPin, 100M);
            Assert.That(result, Is.False);
            Assert.AreEqual(prebalance, cashCard.Balance);
        }
Exemplo n.º 15
0
        public async Task Test_Withdraw_FailOnPin()
        {
            CashCard cashCard = new CashCard();
            // add an initial balance of 10,000
            var addInitialBalanceSuccess = await cashCard.TopUp(1234, 10000M);

            Assert.IsTrue(addInitialBalanceSuccess);

            // try to withdraw 1,000 but use a wrong PIN
            var initialBalance  = cashCard.Balance;
            var withdrawAmount  = 1000M;
            var withdrawSuccess = await cashCard.Withdraw(4321, withdrawAmount);

            Assert.IsFalse(withdrawSuccess);
            Assert.AreEqual(initialBalance, cashCard.Balance);
        }
Exemplo n.º 16
0
        public async Task Test_Withdraw_FailOnInsufficientBalance()
        {
            CashCard cashCard = new CashCard();
            // add an initial balance of 500
            var addInitialBalanceSuccess = await cashCard.TopUp(1234, 500M);

            Assert.IsTrue(addInitialBalanceSuccess);

            // try to withdraw 1,000
            var initialBalance = cashCard.Balance;
            var withdrawAmount = 1000M;

            Assert.That(async() => await cashCard.Withdraw(1234, withdrawAmount),
                        Throws.TypeOf <TaskCanceledException>());
            Assert.AreEqual(initialBalance, cashCard.Balance);
        }
Exemplo n.º 17
0
        public async Task Test_Withdraw_Basic()
        {
            CashCard cashCard = new CashCard();
            // add an initial balance of 10,000
            var addInitialBalanceSuccess = await cashCard.TopUp(1234, 10000M);

            Assert.IsTrue(addInitialBalanceSuccess);

            // try to withdraw 1,000
            var initialBalance  = cashCard.Balance;
            var withdrawAmount  = 1000M;
            var withdrawSuccess = await cashCard.Withdraw(1234, withdrawAmount);

            Assert.IsTrue(withdrawSuccess);
            Assert.AreEqual(initialBalance - withdrawAmount, cashCard.Balance);
        }