From 5e343824061f58e5c8df29b72183736c5500b2c6 Mon Sep 17 00:00:00 2001 From: Albin Ljunghusen Date: Wed, 13 Nov 2019 09:28:39 +0100 Subject: [PATCH 1/2] Did the things and the whatnot --- ALM.Test/ALM.Test.csproj | 5 ++ ALM.Test/TransactionTests.cs | 70 ++++++++++++++++++ ALM.Test/UnitTest1.cs | 14 ---- ALM.Web/ALM.Web.csproj | 8 ++- ALM.Web/BankRepository.cs | 5 ++ ALM.Web/Controllers/HomeController.cs | 5 -- ALM.Web/Controllers/TransactionController.cs | 72 +++++++++++++++++++ .../Exceptions/AccountNotFoundException.cs | 14 ++++ .../Exceptions/InvalidTransactionException.cs | 14 ++++ ALM.Web/Models/TransactionViewModel.cs | 22 ++++++ ALM.Web/Startup.cs | 1 + ALM.Web/TransactionType.cs | 13 ++++ ALM.Web/Transactioner.cs | 62 ++++++++++++++++ ALM.Web/Views/Home/Privacy.cshtml | 6 -- ALM.Web/Views/Shared/_Layout.cshtml | 7 +- ALM.Web/Views/Transaction/Transact.cshtml | 24 +++++++ 16 files changed, 313 insertions(+), 29 deletions(-) create mode 100644 ALM.Test/TransactionTests.cs delete mode 100644 ALM.Test/UnitTest1.cs create mode 100644 ALM.Web/Controllers/TransactionController.cs create mode 100644 ALM.Web/Exceptions/AccountNotFoundException.cs create mode 100644 ALM.Web/Exceptions/InvalidTransactionException.cs create mode 100644 ALM.Web/Models/TransactionViewModel.cs create mode 100644 ALM.Web/TransactionType.cs create mode 100644 ALM.Web/Transactioner.cs delete mode 100644 ALM.Web/Views/Home/Privacy.cshtml create mode 100644 ALM.Web/Views/Transaction/Transact.cshtml diff --git a/ALM.Test/ALM.Test.csproj b/ALM.Test/ALM.Test.csproj index 26e7570..cba813e 100644 --- a/ALM.Test/ALM.Test.csproj +++ b/ALM.Test/ALM.Test.csproj @@ -8,9 +8,14 @@ + + + + + diff --git a/ALM.Test/TransactionTests.cs b/ALM.Test/TransactionTests.cs new file mode 100644 index 0000000..6c2dc22 --- /dev/null +++ b/ALM.Test/TransactionTests.cs @@ -0,0 +1,70 @@ +using ALM.Web; +using ALM.Web.Models; +using Shouldly; +using System; +using Xunit; + +namespace ALM.Test +{ + //public class Fixture + //{ + // public BankRepository Repository { get; set; } + // public Transactioner TransactionManager { get; set; } + + // public Fixture() + // { + // Repository = new BankRepository(); + // Repository.Initialize(); + // TransactionManager = new Transactioner(Repository); + // } + //} + + public class TransactionTests + { + [Theory] + [InlineData(1337)] + [InlineData(9000)] + [InlineData(80085)] + public void DepositTest(decimal amount) + { + var account = new Account(); + var transactioner = new Transactioner(); + decimal originalBalance = account.Balance; + + transactioner.Deposit(account, amount); + + account.Balance.ShouldBe(originalBalance + amount); + } + + [Theory] + [InlineData(1337, 500)] + [InlineData(9000, 100)] + [InlineData(80085, 80085)] + public void WithdrawTest(decimal initial, decimal amount) + { + var account = new Account(); + account.Credit(initial); + var transactioner = new Transactioner(); + decimal originalBalance = account.Balance; + + transactioner.Deposit(account, amount); + + account.Balance.ShouldBe(originalBalance + amount); + } + + [Theory] + [InlineData(1337, 1338)] + [InlineData(1111.111, 9999.999)] + [InlineData(1, 1.000000001)] + [InlineData(0, 1)] + public void WithdrawMoreThanBalance(decimal initial, decimal amount) + { + var account = new Account(); + account.Credit(initial); + var transactioner = new Transactioner(); + decimal originalBalance = account.Balance; + + Should.Throw(() => transactioner.Withdraw(account, amount)); + } + } +} diff --git a/ALM.Test/UnitTest1.cs b/ALM.Test/UnitTest1.cs deleted file mode 100644 index 1224eb0..0000000 --- a/ALM.Test/UnitTest1.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Xunit; - -namespace ALM.Test -{ - public class UnitTest1 - { - [Fact] - public void Test1() - { - - } - } -} diff --git a/ALM.Web/ALM.Web.csproj b/ALM.Web/ALM.Web.csproj index 8eacdc1..5e18e79 100644 --- a/ALM.Web/ALM.Web.csproj +++ b/ALM.Web/ALM.Web.csproj @@ -4,8 +4,14 @@ netcoreapp3.0 - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/ALM.Web/BankRepository.cs b/ALM.Web/BankRepository.cs index 97729fa..5e5370e 100644 --- a/ALM.Web/BankRepository.cs +++ b/ALM.Web/BankRepository.cs @@ -41,5 +41,10 @@ public Account AddAccount(Customer owner) return account; } + public Account GetAccount(int accountId) + { + return Accounts.FirstOrDefault(a => a.AccountId == accountId); + } + } } diff --git a/ALM.Web/Controllers/HomeController.cs b/ALM.Web/Controllers/HomeController.cs index 66beb19..00f65db 100644 --- a/ALM.Web/Controllers/HomeController.cs +++ b/ALM.Web/Controllers/HomeController.cs @@ -28,11 +28,6 @@ public IActionResult Index() return View(model); } - public IActionResult Privacy() - { - return View(); - } - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { diff --git a/ALM.Web/Controllers/TransactionController.cs b/ALM.Web/Controllers/TransactionController.cs new file mode 100644 index 0000000..0187c3c --- /dev/null +++ b/ALM.Web/Controllers/TransactionController.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using ALM.Web.Models; +using Microsoft.AspNetCore.Mvc; + +namespace ALM.Web.Controllers +{ + public class TransactionController : Controller + { + private readonly Transactioner _transactioner; + private readonly BankRepository _repository; + + public TransactionController(Transactioner transactioner, BankRepository repository) + { + _transactioner = transactioner; + _repository = repository; + } + + [HttpGet] + public IActionResult Index() + { + return RedirectToAction("Transact"); + } + + [HttpGet] + public IActionResult Transact() + { + var model = new TransactionViewModel(); + return View(model); + } + + [HttpPost] + public IActionResult Transact(TransactionViewModel model, TransactionType type) + { + if (!ModelState.IsValid) + { + return View(model); + } + try + { + var account = _repository.GetAccount(model.AccountId); + model.Account = account; + switch (type) + { + case TransactionType.Deposit: + _transactioner.Deposit(account, model.Amount); + break; + case TransactionType.Withdrawal: + _transactioner.Withdraw(account, model.Amount); + break; + default: + break; + } + } + catch (AccountNotFoundException ex) + { + ModelState.AddModelError("account", ex.Message); + return View(model); + } + catch (InvalidTransactionException ex) + { + ModelState.AddModelError("balance", ex.Message); + return View(model); + } + + return View(model); + } + + } +} \ No newline at end of file diff --git a/ALM.Web/Exceptions/AccountNotFoundException.cs b/ALM.Web/Exceptions/AccountNotFoundException.cs new file mode 100644 index 0000000..11a2cdb --- /dev/null +++ b/ALM.Web/Exceptions/AccountNotFoundException.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ALM.Web +{ + public class AccountNotFoundException : Exception + { + public AccountNotFoundException(string message) : base(message) + { + } + } +} diff --git a/ALM.Web/Exceptions/InvalidTransactionException.cs b/ALM.Web/Exceptions/InvalidTransactionException.cs new file mode 100644 index 0000000..a2e058c --- /dev/null +++ b/ALM.Web/Exceptions/InvalidTransactionException.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ALM.Web +{ + public class InvalidTransactionException:Exception + { + public InvalidTransactionException(string message) : base(message) + { + } + } +} diff --git a/ALM.Web/Models/TransactionViewModel.cs b/ALM.Web/Models/TransactionViewModel.cs new file mode 100644 index 0000000..1d461ea --- /dev/null +++ b/ALM.Web/Models/TransactionViewModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; + +namespace ALM.Web.Models +{ + public class TransactionViewModel + { + [Required] + [Display(Name = "Account ID")] + public int AccountId { get; set; } = 0; + + [Required] + [Display(Name = "Amount")] + [DataType(DataType.Currency)] + public decimal Amount { get; set; } = 0; + + public Account Account { get; set; } + } +} diff --git a/ALM.Web/Startup.cs b/ALM.Web/Startup.cs index 98add4c..41b8b7b 100644 --- a/ALM.Web/Startup.cs +++ b/ALM.Web/Startup.cs @@ -25,6 +25,7 @@ public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSingleton(); + services.AddScoped(); } diff --git a/ALM.Web/TransactionType.cs b/ALM.Web/TransactionType.cs new file mode 100644 index 0000000..ee4de8d --- /dev/null +++ b/ALM.Web/TransactionType.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ALM.Web +{ + public enum TransactionType + { + Deposit, + Withdrawal + } +} diff --git a/ALM.Web/Transactioner.cs b/ALM.Web/Transactioner.cs new file mode 100644 index 0000000..1008319 --- /dev/null +++ b/ALM.Web/Transactioner.cs @@ -0,0 +1,62 @@ +using ALM.Web.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ALM.Web +{ + public class Transactioner + { + private readonly BankRepository _repository; + + public Transactioner(BankRepository repository) + { + _repository = repository; + } + + public Transactioner() + { + + } + + public decimal Deposit(Account account, decimal amount) + { + account.Credit(amount); + return account.Balance; + } + + public decimal Deposit(int accountId, decimal amount) + { + var account = _repository.GetAccount(accountId); + if (account == null) + { + throw new AccountNotFoundException($"Account #{accountId} not found"); + } + return Deposit(account, amount); + } + + + public decimal Withdraw(Account account, decimal amount) + { + if (account.Balance < amount) + { + throw new InvalidTransactionException($"Cant Withdraw {amount} from account #{account.AccountId}. Balance is only {account.Balance}."); + } + account.Debit(amount); + return account.Balance; + } + + public decimal Withdraw(int accountId, decimal amount) + { + var account = _repository.GetAccount(accountId); + if (account == null) + { + throw new AccountNotFoundException($"Account #{accountId} not found"); + } + return Withdraw(account, amount); + } + + + } +} diff --git a/ALM.Web/Views/Home/Privacy.cshtml b/ALM.Web/Views/Home/Privacy.cshtml deleted file mode 100644 index af4fb19..0000000 --- a/ALM.Web/Views/Home/Privacy.cshtml +++ /dev/null @@ -1,6 +0,0 @@ -@{ - ViewData["Title"] = "Privacy Policy"; -} -

@ViewData["Title"]

- -

Use this page to detail your site's privacy policy.

diff --git a/ALM.Web/Views/Shared/_Layout.cshtml b/ALM.Web/Views/Shared/_Layout.cshtml index e1ba017..c906c59 100644 --- a/ALM.Web/Views/Shared/_Layout.cshtml +++ b/ALM.Web/Views/Shared/_Layout.cshtml @@ -18,11 +18,12 @@ diff --git a/ALM.Web/Views/Transaction/Transact.cshtml b/ALM.Web/Views/Transaction/Transact.cshtml new file mode 100644 index 0000000..4313778 --- /dev/null +++ b/ALM.Web/Views/Transaction/Transact.cshtml @@ -0,0 +1,24 @@ +@model TransactionViewModel +@{ + ViewData["Title"] = "Index"; +} + +

Transaction Time!

+ +
+ + + + +
+ +

@ViewBag.Message

+ +@if (Model.Account != null) +{ +

The new balance of account #@Model.Account.AccountId is now @Model.Account.Balance

+} +
+ + + From c1f3b3bab6948c2cc6a7302de480148406ea0136 Mon Sep 17 00:00:00 2001 From: Albin Ljunghusen Date: Wed, 13 Nov 2019 09:50:57 +0100 Subject: [PATCH 2/2] Fixed the no account found stuff alriiight --- ALM.Web/BankRepository.cs | 7 ++++++- ALM.Web/Exceptions/AccountNotFoundException.cs | 2 +- ALM.Web/Transactioner.cs | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ALM.Web/BankRepository.cs b/ALM.Web/BankRepository.cs index 5e5370e..5209bb8 100644 --- a/ALM.Web/BankRepository.cs +++ b/ALM.Web/BankRepository.cs @@ -43,7 +43,12 @@ public Account AddAccount(Customer owner) public Account GetAccount(int accountId) { - return Accounts.FirstOrDefault(a => a.AccountId == accountId); + var account = Accounts.FirstOrDefault(a => a.AccountId == accountId); + if (account == null) + { + throw new AccountNotFoundException(accountId); + } + return account; } } diff --git a/ALM.Web/Exceptions/AccountNotFoundException.cs b/ALM.Web/Exceptions/AccountNotFoundException.cs index 11a2cdb..4f398de 100644 --- a/ALM.Web/Exceptions/AccountNotFoundException.cs +++ b/ALM.Web/Exceptions/AccountNotFoundException.cs @@ -7,7 +7,7 @@ namespace ALM.Web { public class AccountNotFoundException : Exception { - public AccountNotFoundException(string message) : base(message) + public AccountNotFoundException(int accountId) : base($"Account #{accountId} not found") { } } diff --git a/ALM.Web/Transactioner.cs b/ALM.Web/Transactioner.cs index 1008319..50e4a19 100644 --- a/ALM.Web/Transactioner.cs +++ b/ALM.Web/Transactioner.cs @@ -31,7 +31,7 @@ public decimal Deposit(int accountId, decimal amount) var account = _repository.GetAccount(accountId); if (account == null) { - throw new AccountNotFoundException($"Account #{accountId} not found"); + throw new AccountNotFoundException(accountId); } return Deposit(account, amount); } @@ -52,7 +52,7 @@ public decimal Withdraw(int accountId, decimal amount) var account = _repository.GetAccount(accountId); if (account == null) { - throw new AccountNotFoundException($"Account #{accountId} not found"); + throw new AccountNotFoundException(accountId); } return Withdraw(account, amount); }