Beispiel #1
0
        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
                );
        }
Beispiel #2
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
                );
        }
Beispiel #3
0
        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
                );
        }
Beispiel #4
0
        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));
            }
        }
Beispiel #5
0
        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));
            }
        }
Beispiel #6
0
        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"));
            }
        }
Beispiel #7
0
        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}"));
            }
        }