public void TestCaseAllRemoved() { Point[] oldPoints = new Point[] { new Point(1, 4), new Point(2, 5), new Point(2, 3) }; Point[] newPoints = Array.Empty <Point>(); var differences = DataTools.FindDifferences <Point, Point>(oldPoints, newPoints, (o, n) => o == n); Assert.IsTrue( differences.InsertedItems.Count == 0 && differences.RemovedItems.Count == 3 && differences.StayedItems.Count == 0 ); }
public void TestCaseInserted() { Point[] oldPoints = new Point[] { new Point(1, 4), new Point(2, 5), new Point(2, 3) }; Point[] newPoints = new Point[] { new Point(1, 4), new Point(2, 5), new Point(4, 3) }; var differences = DataTools.FindDifferences <Point, Point>(oldPoints, newPoints, (o, n) => o == n); Assert.IsTrue( differences.InsertedItems.First() == new Point(4, 3) && differences.RemovedItems.First() == new Point(2, 3) && differences.StayedItems.Count == 2 ); }
public void TestPointsWithSize() { Point[] oldPoints = new Point[] { new Point(1, 4), new Point(2, 5), new Point(2, 3) }; Size[] newPoints = new Size[] { new Size(1, 4), new Size(2, 5), new Size(4, 3) }; var differences = DataTools.FindDifferences <Point, Size>(oldPoints, newPoints, (o, n) => o.Equals(new Point(n))); Assert.IsTrue( differences.InsertedItems.First() == new Size(4, 3) && differences.RemovedItems.First() == new Point(2, 3) && differences.StayedItems.Count == 2 ); }
public async Task <IActionResult> Create([ModelBinder(typeof(BookModelBinder))] BookUpsertDTO book) { _Logger.LogTrace("Attempt to create the book"); try { if (book == null) { return(BookBadRequest("Attempt to insert empty book")); } if (!ModelState.IsValid) { return(BookBadRequest("Attempt to insert the invalid book", ModelState)); } Task <ImageData> imageUpload = null; CancellationTokenSource cts = null; if (book.ImageWasChanged) { cts = new CancellationTokenSource(); imageUpload = _ImageService.SetImage(book.Image, cts.Token, String.Empty); book.Image = String.Empty; } var user = await _SignInManager.UserManager.FindByEmailAsync(this.GetCurrentUserEmail()); Book bookRecord = _Mapper.Map <Book>(book); bookRecord.OwnerId = user.Id; var differences = DataTools.FindDifferences <BookAuthor, AuthorUpsertDTO>( bookRecord.BookAuthors, book.Authors, (old, nw) => old.AuthorId == nw.Id); foreach (var inserted in differences.InsertedItems) { Author author = await _BookStore.Authors.FindAsync(x => x.Id == inserted.Id); if (author != null) { bookRecord.BookAuthors.Add(new BookAuthor() { AuthorId = inserted.Id, Author = author, Book = bookRecord }); } else { cts?.Cancel(); return(StatusCode(StatusCodes.Status422UnprocessableEntity, "One of the book authors not exists in database, operation cancelled")); } } foreach (var removed in differences.RemovedItems) { bookRecord.BookAuthors.Remove(removed); } if (imageUpload != null) { ImageData imageData = await imageUpload; bookRecord.Image = imageData.Name; bookRecord.Thumbnail = imageData.Base64ThumbNail; } bool result = await _BookStore.Books.CreateAsync(bookRecord); result &= await _BookStore.SaveData(); if (result) { _Logger.LogInformation($"Book succesfully created, assigned id {bookRecord.Id}"); return(StatusCode(StatusCodes.Status201Created, bookRecord)); } else { return(InternalError("Failed to create book")); } } catch (AggregateException e) { _Logger.LogError(e.Flatten(), e.Flatten().Message, e.Flatten().InnerExceptions?.Select(ie => $"{ie.Message}/n{new string('-', 20)}/n{ie.StackTrace}")); return(InternalError("Failed to create the book", e)); } catch (Exception e) { _Logger.LogError(e, e.Message); return(InternalError("Failed to create bool", e)); } }
public async Task <IActionResult> Update(int bookId, [ModelBinder(typeof(BookModelBinder))] BookUpsertDTO book) { _Logger.LogInformation("Attempting to update book"); try { if (book == null) { return(BookBadRequest("Book object must be not empty")); } if (bookId <= 0) { return(BookBadRequest($"Book id you provided ({bookId}) is inferior of 0 and not exists in database")); } if (!ModelState.IsValid) { return(BookBadRequest("Book data not passed the validation", ModelState)); } var user = await _SignInManager.UserManager.FindByEmailAsync(this.GetCurrentUserEmail()); var isUserAdministrator = await _SignInManager.UserManager.IsInRoleAsync(user, AppDataSeeder.Administrator); var srcBook = await _BookStore.Books.FindAsync(idPredicate : (x) => x.Id == bookId, includes : new Expression <Func <Book, object> >[] { x => x.BookAuthors }); if (srcBook == null) { return(BookNotFound($"Book id you provided ({bookId}) not found and can not be updated")); } if (!(srcBook.OwnerId == user.Id || isUserAdministrator)) { _Logger.LogWarning($"{user.Email} tried edit others book"); return(StatusCode(StatusCodes.Status403Forbidden, "Cant edit other's record")); } Task <ImageData> imageTask = null; CancellationTokenSource cancellationTokenSource = null; string originalImageName = srcBook.Image; if (book.ImageWasChanged) { cancellationTokenSource = new CancellationTokenSource(); imageTask = _ImageService.SetImage(book.Image, cancellationTokenSource.Token, srcBook.Image); book.Image = srcBook.Image; } else { book.Image = srcBook.Image; } #region Updating authors list var differences = DataTools.FindDifferences <BookAuthor, AuthorUpsertDTO>( srcBook.BookAuthors, book.Authors, (old, nw) => old.AuthorId == nw.Id); foreach (var inserted in differences.InsertedItems) { Author author = await _BookStore.Authors.FindAsync(x => x.Id == inserted.Id); if (author != null) { srcBook.BookAuthors.Add(new BookAuthor() { AuthorId = inserted.Id, Author = author, Book = srcBook, BookId = srcBook.Id }); } else { cancellationTokenSource?.Cancel(); return(StatusCode(StatusCodes.Status422UnprocessableEntity, "One of the book authors not exists in database, operation cancelled")); } } foreach (var removed in differences.RemovedItems) { srcBook.BookAuthors.Remove(removed); } srcBook = _Mapper.Map <BookUpsertDTO, Book>(book, srcBook); #endregion if (imageTask != null) { var imageData = await imageTask; srcBook.Image = imageData.Name; srcBook.Thumbnail = imageData.Base64ThumbNail; } bool result = await _BookStore.Books.UpdateAsync(srcBook); result &= await _BookStore.SaveData(); if (result) { _Logger.LogTrace("Book id {bookId} was updated in the database"); return(StatusCode(StatusCodes.Status200OK, srcBook)); } else { return(InternalError($"Failed to update book {bookId}")); } } catch (Exception e) { return(InternalError("Failed to update the book", e)); } }
public async Task <IActionResult> Update(int authorId, [ModelBinder(typeof(AuthorModelBinder))] AuthorUpsertDTO author) { try { _Logger.LogTrace($"Author {authorId} attempt"); if (author == null) { _Logger.LogTrace($"Author {authorId} attempt"); return(StatusCode(StatusCodes.Status400BadRequest, "Empty objecy is not allowed")); } if (!ModelState.IsValid) { return(StatusCode(StatusCodes.Status400BadRequest, ModelState)); } var authorToUpdate = await _BookStore.Authors.FindAsync( idPredicate : (x) => x.Id == authorId, includes : new Expression <Func <Author, object> >[] { x => x.Books }); if (authorToUpdate == null) { return(NotFound($"Unable to find author to update")); } var user = await _SignInManager.UserManager.FindByEmailAsync(this.GetCurrentUserEmail()); var isUserAdmin = await _SignInManager.UserManager.IsInRoleAsync(user, AppDataSeeder.Administrator); if (!(authorToUpdate.OwnerId == user.Id || isUserAdmin)) { _Logger.LogWarning($"{user.Email} tried edit others author"); return(StatusCode(StatusCodes.Status403Forbidden, "Cant edit other's record")); } var differences = DataTools.FindDifferences <Book, BookUpsertDTO>( authorToUpdate.Books, author.Books, (o, n) => o.Id == n.Id); if (differences.InsertedItems?.Count > 0) { foreach (var newAuthorBook in differences.InsertedItems) { var authorBook = await _BookStore.Books.FindAsync(b => b.Id == newAuthorBook.Id); if (authorBook != null) { authorToUpdate.AuthorBooks.Add(new BookAuthor() { Author = authorToUpdate, AuthorId = authorToUpdate.Id, BookId = authorBook.Id, Book = authorBook }); } else { string message = $"Failed to find book with id {newAuthorBook.Id}"; _Logger.LogWarning(message); return(StatusCode(StatusCodes.Status422UnprocessableEntity, message)); } } foreach (var removedAuthorBook in differences.RemovedItems) { authorToUpdate.Books.Remove(removedAuthorBook); } } authorToUpdate = _Mapper.Map <AuthorUpsertDTO, Author>(author, authorToUpdate); bool succeed = await _BookStore.Authors.UpdateAsync(authorToUpdate); succeed &= await _BookStore.SaveData(); if (succeed) { return(StatusCode(StatusCodes.Status200OK, _Mapper.Map <AuthorUpsertDTO>(authorToUpdate))); } else { return(StatusCode(StatusCodes.Status500InternalServerError, "Unexpected error while updating the author")); } } catch (Exception e) { return(InternalError(e, "Unexpected error while updating the author")); } }
public async Task <IActionResult> Create([ModelBinder(typeof(AuthorModelBinder))] AuthorUpsertDTO author) { _Logger.LogInformation($"Author submition"); try { if (author == null) { _Logger.LogWarning($"Empty request was submited"); return(StatusCode(StatusCodes.Status400BadRequest)); } if (!ModelState.IsValid) { _Logger.LogWarning( $"Attempting to submit invalid data: {ModelState.Values.SelectMany(x => x.Errors).Select(e => e.ErrorMessage).Aggregate((fm, lm) => fm + '\n' + lm)}"); return(BadRequest(ModelState)); } var user = await _SignInManager.UserManager.FindByEmailAsync(this.GetCurrentUserEmail()); var similarAuthors = await _BookStore.Authors.WhereAsync(filter : x => x.Firstname.ToLower().Equals(author.Firstname.ToLower()) && x.Lastname.ToLower().Equals(author.Firstname.ToLower()) && x.OwnerId == user.Id ); if (similarAuthors.Count > 0) { _Logger.LogWarning($"Possible duplicate for author {author.Firstname} {author.Lastname.ToUpper()}"); } Author writer = _Mapper.Map <Author>(author); writer.OwnerId = user.Id; var differences = DataTools.FindDifferences <Book, BookUpsertDTO>( writer.Books, author.Books, (o, n) => o.Id == n.Id); if (differences.InsertedItems?.Count > 0) { foreach (var newAuthorBook in differences.InsertedItems) { var authorBook = await _BookStore.Books.FindAsync(b => b.Id == newAuthorBook.Id); if (authorBook != null) { writer.AuthorBooks.Add(new BookAuthor() { Author = writer, BookId = authorBook.Id, Book = authorBook }); } else { string message = $"Failed to find book with id {newAuthorBook.Id}"; _Logger.LogWarning(message); return(StatusCode(StatusCodes.Status422UnprocessableEntity, message)); } } } var isSucceed = await _BookStore.Authors.CreateAsync(writer); isSucceed &= await _BookStore.SaveData(); if (!isSucceed) { _Logger.LogError("No records was inserted to database when creating the author"); return(StatusCode(StatusCodes.Status500InternalServerError, "Failed to save author")); } else { _Logger.LogInformation("Author creates successfully"); return(Created("Create", _Mapper.Map <AuthorUpsertDTO>(writer))); } } catch (Exception e) { return(InternalError(e, $"Unable to create author {author.Firstname} {author.Lastname}")); } }