public async Task EditAsync_ShouldEditACard() { using (var db = new ATMContext(TestOptions.TestDbContextOptions <ATMContext>())) { // Arrange var initCards = SampleData.CREDITCARDS; await db.AddRangeAsync(initCards); await db.SaveChangesAsync(); IRepository <CreditCard> repository = new DbCreditCardRepository(db); var expectedCards = await repository.GetAllAsync(); var cardToEdit = expectedCards.First(); expectedCards.Remove(cardToEdit); cardToEdit.Balance -= 1.00M; expectedCards.Add(cardToEdit); // Act await repository.EditAsync(cardToEdit); var result = await repository.GetAllAsync(); // Assert var actualCards = Assert.IsAssignableFrom <List <CreditCard> >(result); Assert.Equal( expectedCards.OrderBy(x => x.Id).Select(x => (id: x.Id, number: x.Number, pin: x.Pin, balance: x.Balance, isValid: x.IsValid)), actualCards.OrderBy(x => x.Id).Select(x => (id: x.Id, number: x.Number, pin: x.Pin, balance: x.Balance, isValid: x.IsValid))); } }
public ATMServicesController(IConfiguration configuration, IMediator mediator, ATMContext context, IAccountQueries accountQueries) { _mediator = mediator; _context = context; _accountQueries = accountQueries; _configuration = configuration; }
public void CheckRecordAmount() { Database.SetInitializer( new DropCreateDatabaseAlways <ATMContext>()); decimal money = 2000; decimal toWithdraw = 1000; int number = 1111111111; int cardPin = 1111; using (var db = new ATMContext()) { db.CardAccounts.Add(new CardAccount() { CardCash = money, CardNumber = number, CardPIN = cardPin }); db.SaveChanges(); ATMActions.WithdrawMoney(cardPin, number, toWithdraw, db); db.SaveChanges(); var actual = (from c in db.TransactionsHistory select c).First(); Assert.AreEqual(1000, actual.Ammount); db.Dispose(); } }
private IKernel RegisterApplicationComponents(IApplicationBuilder app) { // IKernelConfiguration config = new KernelConfiguration(); var kernel = new StandardKernel(); // Register application services foreach (var ctrlType in app.GetControllerTypes()) { kernel.Bind(ctrlType).ToSelf().InScope(RequestScope); } var options = new DbContextOptionsBuilder <ATMContext>() .UseInMemoryDatabase(databaseName: "ATMContext") .Options; var context = new ATMContext(options); // This is where our bindings are configurated kernel.Bind <IRepository <Operation> >().To <OperationRepository>().InScope(RequestScope); kernel.Bind <IService <CreditCard> >().To <CreditCardService>().InScope(RequestScope); kernel.Bind <IRepository <CreditCard> >().To <CreditCardRepository>().InScope(RequestScope); kernel.Bind <ATMContext>().ToConstant(context); // Cross-wire required framework services kernel.BindToMethod(app.GetRequestService <IViewBufferScope>); return(kernel); }
public async Task AddAsync_ShouldAddANewAction() { using (var db = new ATMContext(TestOptions.TestDbContextOptions <ATMContext>())) { // Arrange var expectedDbAction = ACTION_NOT_IN_SEEDING_ACTIONS; var initActions = ACTION_RESULTS; if (initActions.Exists(a => a.Id == expectedDbAction.Id)) { throw new InvalidOperationException($"Seeding actions already contain the action that is not supposed to be there: {expectedDbAction}"); } await db.AddRangeAsync(initActions); await db.SaveChangesAsync(); IRepository <UserActionResult> repository = new DBUserActionResultRepository(db); var expectedActions = await repository.GetAllAsync(); expectedActions.Add(expectedDbAction); // Act await repository.AddAsync(expectedDbAction); var result = await repository.GetAllAsync(); // Assert var actualActions = Assert.IsAssignableFrom <List <UserActionResult> >(result); Assert.Equal( expectedActions.OrderBy(x => x.Id).Select(x => (id: x.Id, cid: x.CreditCardId, time: x.TimeStamp, operationCode: x.OperationCode, withdrawal: x.WithdrawalAmount)), actualActions.OrderBy(x => x.Id).Select(x => (id: x.Id, cid: x.CreditCardId, time: x.TimeStamp, operationCode: x.OperationCode, withdrawal: x.WithdrawalAmount))); } }
public static void RetrieveMoneyFromAccount(ATMContext context, string cardPin, string cardNumber, decimal amount) { using (TransactionScope transaction = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead })) { var card = VerifyCard(context, cardPin, cardNumber); if (card == null) { throw new ArgumentNullException("The card does not exist."); } bool cardHasSufficientAmount = amount <= card.CardCash; if (!cardHasSufficientAmount) { throw new Exception("The card has insufficient funds"); } card.CardCash = card.CardCash - amount; context.SaveChanges(); CreateLog(context, cardNumber, amount); //Here is where you can test the isolation level. It locks only the record(row) which is being modified, //the rest records from the table are selectable during the transaction. //Thread.Sleep(5000); transaction.Complete(); } }
public async Task AddAsync_ShouldAddANewCard() { using (var db = new ATMContext(TestOptions.TestDbContextOptions <ATMContext>())) { // Arrange var expectedDbCard = SampleData.CARD_NOT_ON_THE_LIST; var initCards = SampleData.CREDITCARDS; if (initCards.Exists(cc => cc.Id == expectedDbCard.Id || cc.Number == expectedDbCard.Number)) { throw new InvalidOperationException($"Seeding cards already contain the card that is not supposed to be there: {expectedDbCard}"); } await db.AddRangeAsync(initCards); await db.SaveChangesAsync(); IRepository <CreditCard> repository = new DbCreditCardRepository(db); var expectedCards = await repository.GetAllAsync(); expectedCards.Add(expectedDbCard); // Act await repository.AddAsync(expectedDbCard); var result = await repository.GetAllAsync(); // Assert var actualCards = Assert.IsAssignableFrom <List <CreditCard> >(result); Assert.Equal( expectedCards.OrderBy(x => x.Id).Select(x => (id: x.Id, number: x.Number, pin: x.Pin, balance: x.Balance, isValid: x.IsValid)), actualCards.OrderBy(x => x.Id).Select(x => (id: x.Id, number: x.Number, pin: x.Pin, balance: x.Balance, isValid: x.IsValid))); } }
static void Main(string[] args) { using (var atmContext = new ATMContext()) { atmContext.CardAccounts.Count(); } }
static void SeedDatabase() { ATMContext context = new ATMContext(); context.CardAccounts.Add(new CardAccount() { CardCash = 500, CardNumber = "2001", CardPIN = "1112" }); context.CardAccounts.Add(new CardAccount() { CardCash = 800, CardNumber = "2002", CardPIN = "1113" }); context.CardAccounts.Add(new CardAccount() { CardCash = 1000, CardNumber = "2003", CardPIN = "1114" }); context.SaveChanges(); }
private static void InitialDataImport() { using (var db = new ATMContext()) { var account1 = new CardAccount { CardNumber = "1234567893", CardPin = "1234", CardCash = 5000.00m }; var account2 = new CardAccount { CardNumber = "1234567894", CardPin = "2234", CardCash = 5000.00m }; var account3 = new CardAccount { CardNumber = "1234567895", CardPin = "3234", CardCash = 5000.00m }; db.CardAccounts.Add(account1); db.CardAccounts.Add(account2); db.CardAccounts.Add(account3); db.SaveChanges(); db.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX IX_CardNumber ON CardAccounts (CardNumber)"); } }
public async Task EditAsync_ShouldEditACard() { using (var db = new ATMContext(TestOptions.TestDbContextOptions <ATMContext>())) { // Arrange var initCards = ACTION_RESULTS; await db.AddRangeAsync(initCards); await db.SaveChangesAsync(); IRepository <UserActionResult> repository = new DBUserActionResultRepository(db); var expectedCards = await repository.GetAllAsync(); var cardToEdit = expectedCards.First(); expectedCards.Remove(cardToEdit); cardToEdit.WithdrawalAmount += 1.00M; expectedCards.Add(cardToEdit); // Act await repository.EditAsync(cardToEdit); var result = await repository.GetAllAsync(); // Assert var actualCards = Assert.IsAssignableFrom <List <UserActionResult> >(result); Assert.Equal( expectedCards.OrderBy(x => x.Id).Select(x => (id: x.Id, cid: x.CreditCardId, time: x.TimeStamp, operationCode: x.OperationCode, withdrawal: x.WithdrawalAmount)), actualCards.OrderBy(x => x.Id).Select(x => (id: x.Id, cid: x.CreditCardId, time: x.TimeStamp, operationCode: x.OperationCode, withdrawal: x.WithdrawalAmount))); } }
public static void Main() { Database.SetInitializer( new MigrateDatabaseToLatestVersion <ATMContext, Configuration>()); // Uncomment the seed method in Configuration to populate. ATMActions.ShowCards(); int pin = 2222; int cardNumber = 1222222222; decimal moneyToWithdraw = 300m; using (ATMContext db = new ATMContext()) { if (ATMActions.WithdrawMoney(pin, cardNumber, moneyToWithdraw, db)) { Console.WriteLine("Money withdrawn"); } else { Console.WriteLine("Money withdrawn"); } } Console.WriteLine("\nNew cards: "); ATMActions.ShowCards(); }
static void Main() { var context = new ATMContext(); using (var dbContextTransaction = context.Database.BeginTransaction()) { try { Console.Write("Card Number: "); string cardNumber = Console.ReadLine(); var cardAccount = context.CardAccounts .FirstOrDefault(c => c.CardNumber == cardNumber); if (cardAccount == null) { throw new InvalidOperationException($"Account with card number: {cardNumber} doesn't exist"); } Console.Write("Card Pin: "); string cardPin = Console.ReadLine(); if (cardAccount.CardPIN != cardPin) { throw new InvalidOperationException("Wrong Pin."); } Console.Write("Withdraw amount: "); decimal withdrawAmount = decimal.Parse(Console.ReadLine()); if (cardAccount.CardCash < withdrawAmount) { throw new InvalidOperationException("Not enough money."); } else { cardAccount.CardCash -= withdrawAmount; } dbContextTransaction.Commit(); context.TransactionHistory.Add(new TransactionHistory { CardNumber = cardNumber, TransactionDate = DateTime.Now, WithdrawAmount = withdrawAmount }); context.SaveChanges(); Console.WriteLine($"Succesfully withdrawed {withdrawAmount}, current amount {cardAccount.CardCash:0.00}"); } catch (Exception ex) { Console.WriteLine(ex.Message); dbContextTransaction.Rollback(); } } }
public bool CheckCardNumber(long cardNumber) { using (var dbContext = new ATMContext()) { var cardNumberString = GetMD5String(cardNumber.ToString(CultureInfo.InvariantCulture)); var activeCardIsPresent = dbContext.Cards.Any(x => x.Active && x.CardNumber == cardNumberString); return(activeCardIsPresent); } }
static void Main(string[] args) { using (var dbContext = new ATMContext()) { var getCards = FillCardNumbers(); dbContext.Cards.AddRange(getCards); dbContext.SaveChanges(); var cards = dbContext.Cards.ToList(); } }
private static void ShowCardAccounts() { using (ATMContext db = new ATMContext()) { foreach (var account in db.CardAccounts) { Console.WriteLine("Id: {0}- Cash: {1}", account.Id, account.CardCash); } } }
static void PreserveTransactionHistory(ATMContext context, string cardNumber, decimal amount) { TransactionHistory transactionHistory = new TransactionHistory(); transactionHistory.Amount = amount; transactionHistory.CardNumber = cardNumber; context.TransactionHistories.Add(transactionHistory); }
public static void ShowCards() { using (ATMContext db = new ATMContext()) { foreach (var item in db.CardAccounts) { Console.WriteLine("ID:{0}, Monies: {1}", item.Id, item.CardCash); } } }
static void SaveWithdraw(CardAccount cardAccount, decimal amount, ATMContext db) { cardAccount.CardCash -= amount; db.TransactionHistory.Add(new TransactionHistory() { CardNumber = cardAccount.CardNumber, Amount = amount }); db.SaveChanges(); }
public static void Main() { var atmContext = new ATMContext(); string card = "8949848946"; string pin = "4892"; decimal requestedSum = 60m; using (var dbContextTransaction = atmContext.Database.BeginTransaction()) { try { var cardAccount = atmContext.CardAccount .Where(a => a.CardNumber == card && a.CardPin == pin) .FirstOrDefault(); if (cardAccount == null) { throw new InvalidOperationException("Invalid card number or pin."); } cardAccount.Money -= requestedSum; if (cardAccount.Money < 0) { throw new InvalidOperationException("There are not enough funds in your card."); } TransactionHistory currentTransaction = new TransactionHistory( cardAccount.CardNumber, DateTime.Now, requestedSum); atmContext.TransactionHistory.Add(currentTransaction); atmContext.SaveChanges(); dbContextTransaction.Commit(); } catch (DbUpdateConcurrencyException exc) { dbContextTransaction.Rollback(); Console.WriteLine("Conflict! Try again."); } catch (DataException exc) { Console.WriteLine("Invalid value!"); } catch (InvalidOperationException exc) { Console.WriteLine(exc.Message); } } }
public static void CashWithdraw(string cardNumber, string cardPin, decimal sum) { using (var db = new ATMContext()) { bool success = false; using (TransactionScope transaction = new TransactionScope()) { try { // get card number and pin var card = db.CardAccounts. Where(c => c.CardNumber == cardNumber). Where(p => p.CardPin == cardPin).First(); if (card.CardCash >= sum) { // withdraw sum card.CardCash -= sum; } else { Console.WriteLine("Insufficient funds!"); } transaction.Complete(); success = true; } catch (Exception ex) { Console.WriteLine("Wrong PIN or Invalid card!"); } } if (success) { // save in history var log = new TransactionsHistory() { CardNumber = cardNumber, TransactionDate = DateTime.Now, Ammount = sum }; db.TransactionsHisory.Add(log); db.SaveChanges(); Console.WriteLine("Transaction successful!"); } } }
public long GetCardBalance(long cardNumber) { using (var dbContext = new ATMContext()) { var cardNumberString = GetMD5String(cardNumber.ToString(CultureInfo.InvariantCulture)); var card = dbContext.Cards.First(x => x.Active || x.CardNumber == cardNumberString); var logInfo = new LogInfo { CardId = cardNumber, OperationCode = 1 }; dbContext.Logs.Add(logInfo); dbContext.SaveChanges(); return(card.Balance); } }
public static void Initialize(IServiceProvider serviceProvider) { using (var context = new ATMContext( serviceProvider.GetRequiredService < DbContextOptions <ATMContext> >())) { if (context.CreditCards.Any()) { return; } context.CreditCards.AddRange(ATMContext.GetSeedingCards()); context.SaveChanges(); } }
private static CardAccount VerifyCard(ATMContext context, string cardPin, string cardNumber) { var card = context.CardAccounts.Where(account => account.CardPin == cardPin) .Where(account => account.CardNumber == cardNumber) .FirstOrDefault(); if (card != null) { return(card); } else { return(null); } }
static void Main() { SeedDatabase(); Console.Write("Enter Card Number: "); string cardNumber = Console.ReadLine(); Console.Write("Enter Card PIN: "); string cardPIN = Console.ReadLine(); var context = new ATMContext(); var cardAccount = context.CardAccounts .Where(c => c.CardPIN == cardPIN && c.CardNumber == cardNumber) .FirstOrDefault(); if (cardAccount != null) { Console.Write("How much would you like to withdraw? "); decimal amount = decimal.Parse(Console.ReadLine()); TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }); using (transactionScope) { if (cardAccount.CardCash >= amount) { cardAccount.CardCash -= amount; Console.WriteLine("Withdrawal successful."); } else { throw new InvalidOperationException("Insufficient amount of money in the card."); } PreserveTransactionHistory(context, cardNumber, amount); context.SaveChanges(); transactionScope.Complete(); } } else { throw new InvalidOperationException("Invalid Card Number or PIN"); } }
public ATMRepository(ATMContext context) { Customer c = new Customer(Guid.NewGuid(), "F", "L"); Card d = new Card(Guid.NewGuid(), CardTypes.MasterCard, "1234"); BankAccount ac = new BankAccount(Guid.NewGuid(), c.Id, d.Id, "A", 3200.87); Transaction t = new Transaction(Guid.NewGuid(), ac.Id, 50); _context = context; if (_context.BankAccounts.Count() == 0) { _context.Customers.Add(c); _context.Cards.Add(d); _context.BankAccounts.Add(ac); _context.Transactions.Add(t); _context.SaveChanges(); } }
static void Main(string[] args) { using (var db = new ATMContext()) { Database.SetInitializer(new MigrateDatabaseToLatestVersion <ATMContext, Configuration>()); Console.WriteLine("What is your card number: "); string cardNumber = Console.ReadLine(); Console.WriteLine("What is your card pin: "); string cardPin = Console.ReadLine(); Console.WriteLine("How much money to withdraw: "); decimal amount = decimal.Parse(Console.ReadLine()); Withdraw(cardNumber, cardPin, amount); } }
public static void RecordWithdrawal(int cardNumber, decimal ammount, ATMContext db) { using (var scope = new TransactionScope( TransactionScopeOption.RequiresNew, new TransactionOptions() { IsolationLevel = IsolationLevel.RepeatableRead })) { db.TransactionsHistory.Add(new TransactionHistory() { TransactionDate = DateTime.Now, Ammount = ammount, CardNumber = cardNumber }); scope.Complete(); } }
public static void Main() { Database.SetInitializer(new MigrateDatabaseToLatestVersion<ATMContext, Configuration>()); var context = new ATMContext(); using (var dbContextTransaction = context.Database.BeginTransaction()) { try { Console.Write("Please, enter card number: "); var cardNumber = Console.ReadLine(); Console.Write("Please, enter PIN: "); var pinCode = Console.ReadLine(); var account = ATMManager.GetAccount(context, cardNumber, pinCode); Console.Write("Please, enter amount: "); var amount = decimal.Parse(Console.ReadLine()); ATMManager.ValidateAccountAmount(account, amount); account.CardCash -= amount; var transaction = new TransactionsHistory() { CardNumber = cardNumber, Amount = amount, TransactionDate = DateTime.Now }; context.TransactionHistories.Add(transaction); context.SaveChanges(); dbContextTransaction.Commit(); Console.WriteLine("Withdraw complete."); } catch (Exception ex) { Console.WriteLine(ex.Message); dbContextTransaction.Rollback(); } } }
private static void Withdraw(string cardNumber, string cardPIN, decimal moneyAmount) { using (var atmContext = new ATMContext()) { using (var transaction = atmContext.Database.BeginTransaction()) { if (atmContext.CardAccounts.Any(cardAccount => cardAccount.CardNumber == cardNumber && cardAccount.CardPIN == cardPIN)) { var theAccount = atmContext.CardAccounts.First(cardAccount => cardAccount.CardNumber == cardNumber && cardAccount.CardPIN == cardPIN); if (theAccount.CardCash < moneyAmount) { throw new Exception("nsufficient amount of money."); transaction.Rollback(); } else { theAccount.CardCash -= moneyAmount; atmContext.SaveChanges(); atmContext.TransactionHistories.Add(new TransactionHistory() { CardNumber = theAccount.CardNumber, Amount = moneyAmount, TransactionDate = DateTime.Now }); atmContext.SaveChanges(); transaction.Commit(); } } else { throw new Exception("Wrong combination of card number and pin code."); transaction.Rollback(); } } } }
static void Main(string[] args) { Database.SetInitializer(new MigrateDatabaseToLatestVersion <ATMContext, Configuration>()); Random randGen = new Random(); using (ATMContext dbContext = new ATMContext()) { //for (int i = 0; i < 50; i++) //{ // dbContext.CardAccounts.Add(new CardAccount() { CardPIN = 9999, CardCash = 100 * i, CardNumber = randGen.Next(10000, 20000) }); //} //for (int i = 0; i < 50; i++) //{ // dbContext.TransactionsHistory.Add(new TransactionHistory() { Ammount = 50 * i, CardNumber = randGen.Next(10000, 20000), TransactionDate = DateTime.Now }); //} //dbContext.SaveChanges(); // Uncomment the seed method in Configuration to populate. ATMUtils.ShowCards(); int pin = 9999; int cardNumber = 14665; decimal moneyToWithdraw = 300m; using (ATMContext db = new ATMContext()) { if (ATMUtils.WithdrawMoney(pin, cardNumber, moneyToWithdraw, db)) { Console.WriteLine("Money withdrawn"); } else { Console.WriteLine("Transactions canceled"); } } Console.WriteLine("New cards: "); ATMUtils.ShowCards(); } }
public async Task GetBuIdAsync_ShouldReturnNoCard() { using (var db = new ATMContext(TestOptions.TestDbContextOptions <ATMContext>())) { // Arrange await db.AddRangeAsync(SampleData.CREDITCARDS); await db.SaveChangesAsync(); CreditCard expectedDbCard = null; int cardId = db.CreditCards.OrderBy(x => x.Id).Last().Id + 1; IRepository <CreditCard> repository = new DbCreditCardRepository(db); // Act var result = await repository.GetByIdAsync(cardId); // Assert Assert.Equal(expectedDbCard, result); } }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ATMContext context) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } var logRepository = LogManager.GetRepository(System.Reflection.Assembly.GetEntryAssembly()); log4net.Config.XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config")); DbInitializer.Initialize(context); app.UseSwagger(config => { config.Path = "/swagger/v1/swagger.json"; }); app.UseSwaggerUi3(); app.UseAuthentication(); // app.UseExcuteMiddleware(); app.UseMvc(); }
public async Task AddAsync_ShouldNotAddAAction() { using (var db = new ATMContext(TestOptions.TestDbContextOptions <ATMContext>())) { // Arrange var expectedAction = ACTION_RESULTS.First(); await db.AddRangeAsync(ACTION_RESULTS); await db.SaveChangesAsync(); IRepository <UserActionResult> repository = new DBUserActionResultRepository(db); var expectedActions = await repository.GetAllAsync(); // Act Func <Task> action = async() => await repository.AddAsync(expectedAction); // Assert await Assert.ThrowsAsync <ArgumentException>(action); } }
public async Task GetBuIdAsync_ShouldReturnNoAction() { using (var db = new ATMContext(TestOptions.TestDbContextOptions <ATMContext>())) { // Arrange await db.AddRangeAsync(ACTION_RESULTS); await db.SaveChangesAsync(); UserActionResult expectedDbAction = null; int actionId = db.ActionResults.OrderBy(x => x.Id).Last().Id + 1; IRepository <UserActionResult> repository = new DBUserActionResultRepository(db); // Act var result = await repository.GetByIdAsync(actionId); // Assert Assert.Equal(expectedDbAction, result); } }
public async Task GetBuIdAsync_ShouldReturnAAction() { using (var db = new ATMContext(TestOptions.TestDbContextOptions <ATMContext>())) { // Arrange var expectedAction = ACTION_RESULTS.First(); await db.AddRangeAsync(ACTION_RESULTS); await db.SaveChangesAsync(); var expectedDbAction = ACTION_RESULTS.First(); int actionId = expectedDbAction.Id; IRepository <UserActionResult> repository = new DBUserActionResultRepository(db); // Act var result = await repository.GetByIdAsync(actionId); // Assert Assert.Equal(expectedDbAction, result); } }