public async Task AddExpense_WhenAddingDuplicatedExpenseWithoutComment_ShouldThrowAnExceptionWithTheCorrectErrorCode() { // Arrange var dtoExpense1 = new DTOExpense() { Amount = (decimal)1457.23, Category = "Restaurant", Comment = "A comment", Currency = "USD", PurchasedOn = this.currentTime.AddDays(-1), UserId = anthonyUser.Id }; await this.expensesService.AddExpense(dtoExpense1); var dtoExpense2 = new DTOExpense() { Amount = (decimal)1457.23, Category = "Restaurant", Comment = "", Currency = "USD", PurchasedOn = this.currentTime.AddDays(-1), UserId = anthonyUser.Id }; // Act Func <Task> addExpense = () => this.expensesService.AddExpense(dtoExpense2); // Assert ExpenseValidationException ex = await Assert.ThrowsAsync <ExpenseValidationException>(addExpense); var errorCodes = ex.GetErrorCodes(); errorCodes.Should().HaveCount(2); errorCodes.Should().Contain(ExpenseErrorCode.DuplicatedExpense); errorCodes.Should().Contain(ExpenseErrorCode.CommentIsMandatory); }
public Expenses(DTOExpense dtoExpense) : this() { // TODO use a mapper this.UserId = dtoExpense.UserId; this.PurchasedOn = dtoExpense.PurchasedOn; this.Currency = dtoExpense.Currency; this.Comment = dtoExpense.Comment; this.Category = (ExpenseCategory)Enum.Parse(typeof(ExpenseCategory), dtoExpense.Category); this.Amount = dtoExpense.Amount; }
public async Task <DTOExpense> AddExpense(DTOExpense dtoExpense) { using (LuccaContext context = this.serviceProvider.GetService <LuccaContext>()) { this.ThrowIfExpenseInvalid(context, dtoExpense); var expenseToAdd = new Expenses(dtoExpense); context.Expenses.Add(expenseToAdd); await context.SaveChangesAsync(); return(expenseToAdd.ToDTOExpense(context)); } }
public async Task AddExpense_WhenWellConfigured_ShouldNotThrowAnException() { // Arrange var dtoExpense = new DTOExpense() { Amount = (decimal)1457.23, Category = "Restaurant", Comment = "A comment", Currency = "USD", PurchasedOn = this.currentTime.AddDays(-1), UserId = anthonyUser.Id }; // Act await this.expensesService.AddExpense(dtoExpense); // Assert var expenses = await this.expensesService.GetExpenses(new ExpensesQuery()); expenses.Should().HaveCount(1); }
private void ThrowIfExpenseInvalid(LuccaContext context, DTOExpense expense) { var errors = new Dictionary <ExpenseErrorCode, string>(); if (expense.PurchasedOn > this.timeService.GetCurrentUtcTime()) { errors.Add(ExpenseErrorCode.PurchaseInFuture, $"Expense cannot be recorded for this date {expense.PurchasedOn}"); } else if (DateTime.UtcNow - expense.PurchasedOn > TimeSpan.FromDays(90)) { errors.Add(ExpenseErrorCode.PurchaseMoreThan3MonthOld, $"The expense is older than 90 days: {expense.PurchasedOn}"); } if (string.IsNullOrEmpty(expense.Comment)) { errors.Add(ExpenseErrorCode.CommentIsMandatory, $"The expense comment is mandatory"); } var user = context.UserInfo.Where(user => user.Id == expense.UserId).FirstOrDefault(); if (user == null) { errors.Add(ExpenseErrorCode.UserNotFound, $"The user {expense.UserId} cannot be found"); } else { var userExpenses = context.Expenses.Where(exp => exp.UserId == expense.UserId); if (userExpenses.Any(exp => exp.PurchasedOn == expense.PurchasedOn && exp.Amount == expense.Amount)) { errors.Add(ExpenseErrorCode.DuplicatedExpense, $"The expense purchased on {expense.PurchasedOn} with an amount of {expense.Amount} seems already recorded."); } if (expense.Currency != user.Currency) { errors.Add(ExpenseErrorCode.ExpenseCurrencyDifferentThanUserCurrency, $"The expense currency {expense.Currency} should be the same than the user currency {user.Currency}"); } } if (errors.Any()) { throw new ExpenseValidationException(errors); } }
public async Task AddExpense_WhenPurchaseMoreThan3MonthAgo_ShouldThrowAnExceptionWithTheCorrectErrorCode() { // Arrange var dtoExpense = new DTOExpense() { Amount = (decimal)10.23, Category = "Restaurant", Comment = "A comment", Currency = "USD", PurchasedOn = this.currentTime.AddDays(-100), UserId = anthonyUser.Id }; // Act Func <Task> addExpense = () => this.expensesService.AddExpense(dtoExpense); // Assert ExpenseValidationException ex = await Assert.ThrowsAsync <ExpenseValidationException>(addExpense); var errorCodes = ex.GetErrorCodes(); errorCodes.Should().HaveCount(1); errorCodes.First().Should().Be(ExpenseErrorCode.PurchaseMoreThan3MonthOld); }
public async Task <ActionResult <DTOExpense> > PostExpenses(DTOExpense expense) { var expenseAdded = await this.expensesService.AddExpense(expense); return(expenseAdded); }