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)); }
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)); }
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); }); }
public void WithdrawMoney_FundsNotAvailable_Failure() { CashCard card = new CashCard(100, "12345678"); bool Success = card.Withdraw(1234, 150); Assert.AreEqual(card.Balance(1234), 100); }
public void WithdrawMoney_NegativeAmount_Success() { CashCard card = new CashCard(100, "12345678"); bool Success = card.Withdraw(1234, -50); Assert.AreEqual(card.Balance(1234), 100); }
public void WithdrawMoney_InvalidPin_Success() { CashCard card = new CashCard(100, "12345678"); bool Success = card.Withdraw(1111, 50); Assert.AreEqual(card.Balance(1234), 100); }
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); }
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)); }
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)); }
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); }
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); }
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); }
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); }
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); }