From d026396924a21705fd2d971272dfe2687d7fcb59 Mon Sep 17 00:00:00 2001 From: Omar Faruk Date: Thu, 18 Jan 2024 18:29:58 +0000 Subject: [PATCH] Articles (#20) --- .../ChangePassword/WhenChangingPassword.cs | 3 +- .../WhenOldPasswordIsIncorrect.cs | 3 +- .../Asserts/ArticleAssert.cs | 468 ++++++++---- .../Asserts/ArticleContentAssert.cs | 84 +-- .../Asserts/AuthorAssert.cs | 3 +- .../Asserts/BookAsserts.cs | 4 + .../Asserts/BookPageAssert.cs | 4 +- .../Asserts/IssueArticleAssert.cs | 399 ++++++++++ .../Asserts/IssueArticleContentAssert.cs | 202 +++++ .../Asserts/IssueAssert.cs | 3 +- .../Asserts/LibraryAssert.cs | 1 - .../Asserts/PeriodicalAssert.cs | 1 - .../DataBuilders/AccountDataBuilder.cs | 2 - .../DataBuilders/ArticlesDataBuilder.cs | 349 +++++++++ .../DataBuilders/AuthorsDataBuilder.cs | 37 +- .../DataBuilders/BooksDataBuilder.cs | 8 +- .../DataBuilders/CategoriesDataBuilder.cs | 2 +- .../DataBuilders/IssueDataBuilder.cs | 24 +- .../DataBuilders/LibraryDataBuilder.cs | 1 - .../DataBuilders/PeriodicalsDataBuilder.cs | 5 +- .../DataHelpers/ArticleDataHelper.cs | 151 ++-- .../DataHelpers/AuthorDataHelper.cs | 8 + .../DataHelpers/BookDataHelper.cs | 2 +- .../DataHelpers/BookShelfDataHelper.cs | 1 - .../DataHelpers/CategoryDataHelper.cs | 16 + .../DataHelpers/FileDataHelper.cs | 4 +- .../DataHelpers/IssueArticleDataHelper.cs | 131 ++++ .../DataHelpers/IssueDataHelper.cs | 1 - src/Inshapardaz.Api.Tests/Dto/AccountDto.cs | 3 +- src/Inshapardaz.Api.Tests/Dto/ArticleDto.cs | 57 +- src/Inshapardaz.Api.Tests/Dto/BookDto.cs | 4 +- .../Dto/IssueArticleDto.cs | 55 ++ src/Inshapardaz.Api.Tests/Dto/IssueDto.cs | 3 +- src/Inshapardaz.Api.Tests/Dto/IssueFileDto.cs | 4 +- .../Helpers/HttpExtensions.cs | 1 - .../Helpers/LinkAssertions.cs | 5 +- src/Inshapardaz.Api.Tests/Helpers/Random.cs | 1 - .../Inshapardaz.Api.Tests.csproj | 16 +- ...WhenAddingLibraryForUserAlreadyExisting.cs | 1 - .../Articles/AddArticle/WhenAddingArticle.cs | 68 ++ .../AddArticle/WhenAddingArticleAsReader.cs | 42 ++ .../WhenAddingArticleAsUnauthorized.cs | 37 + .../WhenAddingArticleWithInvalidData.cs | 191 +++++ .../WhenAddingArticleWithMultipleAuthors.cs | 81 ++ .../WhenAddingArticleWithPermissions.cs | 84 +++ .../WhenAddingArticleContentAsReader.cs | 48 ++ .../WhenAddingArticleContentAsUnauthorized.cs | 42 ++ ...dingArticleContentForNonExistingArticle.cs | 46 ++ .../WhenAddingArticleContentWithPermission.cs | 73 ++ ...enAddArticleToFavoriteAlreadyInFavorite.cs | 53 ++ .../WhenAddArticleToFavoriteAsUnauthorized.cs | 35 + ...henAddArticleToFavoriteThatDoesNotExist.cs | 38 + ...WhenAddArticleToFavoriteWithPermissions.cs | 54 ++ .../WhenAssignArticleToReader.cs | 43 ++ .../WhenAssignArticleToSelfForReviewing.cs | 65 ++ .../WhenAssignArticleToSelfForWriting.cs | 61 ++ .../WhenAssignArticleToUserAsReader.cs | 42 ++ .../WhenAssignArticleToUserAsUnauthorised.cs | 36 + .../WhenAssignArticleToUserForReviewing.cs | 63 ++ .../WhenAssignArticleToUserForWriting.cs | 63 ++ .../WhenDeletingArticleAsAnonymous.cs | 35 + .../WhenDeletingArticleAsReader.cs | 40 + .../WhenDeletingArticleWithPermission.cs | 86 +++ .../WhenDeletingNonExistinArticle.cs | 37 + ...DeletingArticleContentThatDoesNotExists.cs | 41 + .../WhenDeletingArticleContentsAsReader.cs | 42 ++ ...enDeletingArticleContentsAsUnauthorized.cs | 36 + ...nDeletingArticlesContentsWithPermission.cs | 52 ++ .../WhenGettingArticleByIdAsAnonymous.cs | 77 ++ .../WhenGettingArticleByIdAsReader.cs | 81 ++ .../WhenGettingArticleByIdThatDoesNotExist.cs | 32 + ...cleByIdWithMultipleAuthrosAndCategories.cs | 103 +++ .../WhenGettingArticleByIdWithPermission.cs | 101 +++ ...ettingArticleContentLanguageNotExisting.cs | 42 ++ ...gArticleContentWhenArtcileDoesNotExists.cs | 41 + .../WhenGettingArticleContentWhenNoContent.cs | 41 + ...henGettingArticleContentWithoutLanguage.cs | 77 ++ ...henGettingPrivateArticleContentAsReader.cs | 71 ++ ...tingPrivateArticleContentAsUnauthorised.cs | 38 + ...tingPrivateArticleContentWithPermission.cs | 80 ++ ...WhenGettingPublicArticleContentAsReader.cs | 71 ++ ...ttingPublicArticleContentAsUnauthorised.cs | 41 + ...ttingPublicArticleContentWithPermission.cs | 83 ++ .../WhenGettingArticlesAsAnonymous.cs | 102 +++ .../WhenGettingArticlesAsReader.cs | 104 +++ .../WhenGettingArticlesByAuthorAsReader.cs | 113 +++ .../WhenGettingArticlesFirstPage.cs | 92 +++ .../WhenGettingArticlesLastPage.cs | 92 +++ .../WhenGettingArticlesOrderByLastModified.cs | 95 +++ ...ngArticlesOrderByLastModifiedDescending.cs | 97 +++ ...enGettingArticlesOrderByTitleDescending.cs | 94 +++ .../WhenGettingArticlesPageInMiddle.cs | 92 +++ ...WhenGettingArticlesPageThatDoesNotExist.cs | 76 ++ .../WhenGettingArticlesReadbyMultipleUsers.cs | 96 +++ .../WhenGettingArticlesSinglePage.cs | 92 +++ ...WhenGettingArticlesWithAssignedToReview.cs | 80 ++ .../WhenGettingArticlesWithAssignedToWrite.cs | 80 ++ ...rticlesWithMultipleAuthorsAndCategories.cs | 99 +++ ...WhenGettingArticlesWithWritePermissions.cs | 89 +++ .../WhenGettingFavoriteArticles.cs | 90 +++ .../GetArticles/WhenGettingReadArticles.cs | 89 +++ .../WhenGettingingArticlesByStatus.cs | 90 +++ .../WhenGettingingArticlesByType.cs | 99 +++ ...rticlesWithMultipleAuthorsAndCategories.cs | 90 +++ .../WhenSearchingArticlesByStatus.cs | 93 +++ .../WhenSearchingArticlesByTitle.cs | 89 +++ .../WhenSearchingArticlesByTitleAndAuthor.cs | 96 +++ .../WhenSearchingArticlesByTitleAndType.cs | 103 +++ ...enSearchingArticlesByTitleAuthorAndType.cs | 102 +++ .../WhenSearchingFavoriteArticles.cs | 78 ++ .../GetArticles/WhenSearchingReadArticles.cs | 77 ++ .../WhenAddBookToFavoriteThatDoesNotExist.cs | 45 ++ ...RemoveArticleFromFavoriteAsUnauthorized.cs | 32 + ...emoveArticleFromFavoriteWithPermissions.cs | 55 ++ ...henRemoveNonFavoriteArticleFromFavorite.cs | 52 ++ .../WhenUpdatingArticleAsReader.cs | 40 + .../WhenUpdatingArticleAsUnauthorized.cs | 35 + .../WhenUpdatingArticleThatDoesNotExist.cs | 71 ++ ...UpdatingArticleWithAdditionalCategories.cs | 91 +++ .../WhenUpdatingArticleWithInvalidData.cs | 242 ++++++ .../WhenUpdatingArticleWithMultipleAuthors.cs | 91 +++ .../WhenUpdatingArticleWithPermissions.cs | 93 +++ .../WhenUpdatingArticleContentsAsReader.cs | 57 ++ ...enUpdatingArticleContentsAsUnauthorized.cs | 52 ++ ...ngArticleContentsWhereContentNotPresent.cs | 91 +++ ...ingArticleContentsWithDifferentLanguage.cs | 88 +++ ...enUpdatingArticleContentsWithPermission.cs | 84 +++ .../WhenUploadingArticleImageAsReader.cs | 54 ++ ...WhenUploadingArticleImageAsUnauthorized.cs | 48 ++ ...ploadingArticleImageWhenNoExistingImage.cs | 63 ++ ...henUploadingArticleImageWithPermissions.cs | 54 ++ .../WhenGettingAuthorWithPermission.cs | 2 +- .../WhenGettingAuthorsWithPermission.cs | 2 +- .../Author/GetAuthors/WhenSearchingAuthors.cs | 2 +- ...gAuthorProperties.cs => WhenAddingBook.cs} | 6 +- .../AddBook/WhenAddingBookWithInvalidData.cs | 4 +- ...enRemoveBookFromFavoriteAsUnauthorized.cs} | 2 +- ...RemoveBookFromFavoriteThatDoesNotExist.cs} | 4 +- ...henUpdatingBookWithAdditionalCategories.cs | 2 +- .../WhenUpdatingBookWithInvalidData.cs | 4 +- .../WhenUpdatingBookWithMultipleAuthors.cs | 2 +- .../WhenUpdatingBookWithPermissions.cs | 4 +- ...henUpdatingBookPageWhenPageDoesNotExist.cs | 2 +- .../WhenDeletingBookFromBookShelf.cs | 1 - ...eletingBookFromBookShelfAsAnonymousUser.cs | 1 - .../WhenDeletingBookShelfAsAnonymous.cs | 1 - .../WhenAddingChapterWithoutChapterNumber.cs | 1 - .../WhenAssignChapterToReader.cs | 1 - .../WhenAssignChapterToSelfForWriting.cs | 1 - .../WhenAssignChapterToUserAsReader.cs | 1 - .../WhenAssignChapterToUserAsUnauthorised.cs | 2 - .../WhenAssignChapterToUserForReviewing.cs | 1 - .../WhenAssignChapterToUserForWriting.cs | 1 - .../WhenDeletingChapterContentsAsReader.cs | 1 - ...enDeletingChapterContentsAsUnauthorized.cs | 1 - ...enDeletingChapterContentsWithPermission.cs | 1 - ...ettingChapterContentLanguageNotExisting.cs | 4 +- ...henGettingChapterContentWithoutLanguage.cs | 2 - ...henGettingPrivateChapterContentAsReader.cs | 2 - ...tingPrivateChapterContentAsUnauthorised.cs | 2 - ...tingPrivateChapterContentWithPermission.cs | 2 - ...WhenGettingPublicChapterContentAsReader.cs | 2 - ...ttingPublicChapterContentAsUnauthorised.cs | 2 - ...ttingPublicChapterContentWithPermission.cs | 2 - .../WhenUpdatingChapterContentsAsReader.cs | 1 - ...enUpdatingChapterContentsAsUnauthorized.cs | 1 - ...ingChapterContentsWithDifferentLanguage.cs | 1 - .../WhenDeletingLibraryWithPermission.cs | 1 - .../GetLibraries/WhenGettingLibrariesAs.cs | 3 +- .../WhenAddingPeriodicalWithPermissions.cs | 13 +- .../WhenDeletingPeriodicalWithPermission.cs | 3 +- .../WhenGettingPeriodicalByIdAsAnonymous.cs | 3 +- .../WhenGettingPeriodicalByIdAsReader.cs | 3 +- ...ingPeriodicalByIdWithMultipleCategories.cs | 3 +- ...WhenGettingPeriodicalByIdWithPermission.cs | 3 +- .../WhenGettingPeriodicalsAsReader.cs | 4 +- .../WhenGettingPeriodicalsAsUnauthorised.cs | 5 +- ...ettingPeriodicalsWithMultipleCategories.cs | 4 +- ...nGettingPeriodicalsWithWritePermissions.cs | 4 +- .../WhenAddingIssueThatAlreadyExists.cs | 6 +- .../AddIssue/WhenAddingIssueWithPermission.cs | 1 - ...eByIdHavingContentsWithWritePermissions.cs | 1 - .../WhenGettingIssueContentWithPermissions.cs | 1 - .../WhenGettingIssuesByPeriodicalAsReader.cs | 1 - ...GettingIssuesByPeriodicalAsUnauthorized.cs | 1 - .../WhenGettingIssuesByPeriodicalFirstPage.cs | 4 - .../WhenGettingIssuesByPeriodicalForYear.cs | 3 - .../WhenGettingIssuesByPeriodicalLastPage.cs | 4 - ...WhenGettingIssuesByPeriodicalMiddlePage.cs | 4 - ...ByPeriodicalSortedByIssueDateDescending.cs | 4 - ...yPeriodicalSortedByVolumeAndIssueNumber.cs | 4 - ...eriodicalSortedByVolumeNumberDescending.cs | 4 - ...ingIssuesByPeriodicalWithCustomPageSize.cs | 4 - ...gIssuesByPeriodicalWithWritePermissions.cs | 1 - ...enAddingIssueArticleAsUnauthorizedUser.cs} | 4 +- ...dingIssueArticleForIssueInOtherLibrary.cs} | 6 +- ...nAddingIssueArticleForNonExistingIssue.cs} | 6 +- .../WhenAddingIssueArticleWithPermission.cs} | 6 +- .../WhenIssueAddingArticleAsReader.cs} | 6 +- ...WhenAddingIssueArticleContentsAsReader.cs} | 6 +- ...dingIssueArticleContentsAsUnauthorized.cs} | 4 +- ...gIssueArticleContentsForMissingArticle.cs} | 6 +- ...ingIssueArticleContentsForMissingIssue.cs} | 6 +- ...sueArticleContentsForMissingPeriodical.cs} | 6 +- ...ingIssueArticleContentsForWrongLibrary.cs} | 6 +- ...dingIssueArticleContentsWithPermission.cs} | 13 +- ...ingIssueArticleContentsWithoutLanguage.cs} | 12 +- .../WhenDeletingIssueArticleAsReader.cs} | 6 +- ...WhenDeletingIssueArticleAsUnauthorized.cs} | 4 +- ...WhenDeletingIssueArticleWithPermission.cs} | 8 +- .../WhenDeletingNonExistingIssueArticle.cs} | 6 +- ...ngIssueArticleContentThatDoesNotExists.cs} | 7 +- ...enDeletingIssueArticleContentsAsReader.cs} | 6 +- ...tingIssueArticleContentsAsUnauthorized.cs} | 4 +- ...tingIssueArticleContentsWithPermission.cs} | 12 +- .../WhenGettingArticlesByIssueAsReader.cs | 0 ...henGettingArticlesByIssueAsUnauthorized.cs | 0 ...henGettingArticlesByIssueWithNoArticles.cs | 0 ...tingArticlesByIssueWithWritePermissions.cs | 0 .../WhenGettingArticlesForNonExistingIssue.cs | 1 - .../WhenGettingArticleFromMiddleOfIssue.cs | 4 +- .../WhenGettingFirstArticleOfIssue.cs | 4 +- ...WhenGettingIssueArticleByIdAsAnonymous.cs} | 7 +- .../WhenGettingIssueArticleByIdAsReader.cs} | 9 +- ...ettingIssueArticleByIdThatDoesNotExist.cs} | 4 +- ...ngIssueArticleByIdWithWritePermissions.cs} | 9 +- .../WhenGettingLastArticleOfIssue.cs | 4 +- ...WhenGettingIssueArticleContentAsReader.cs} | 15 +- ...ttingIssueArticleContentAsUnauthorised.cs} | 4 +- ...IssueArticleContentLanguageNotExisting.cs} | 6 +- ...ueArticleContentWhenNoChapterNotExists.cs} | 6 +- ...ettingIssueArticleContentWhenNoContent.cs} | 7 +- ...ttingIssueArticleContentWithPermission.cs} | 14 +- ...tingIssueArticleContentWithoutLanguage.cs} | 15 +- .../WhenUpdatingArticleContentsAsReader.cs | 5 +- ...enUpdatingArticleContentsAsUnauthorised.cs | 4 +- ...ngArticleContentsWhereContentNotPresent.cs | 7 +- ...ingArticleContentsWithDifferentLanguage.cs | 7 +- ...enUpdatingArticleContentsWithPermission.cs | 7 +- .../WhenUpdatingIssueArticleAsReader.cs} | 6 +- ...WhenUpdatingIssueArticleAsUnauthorized.cs} | 4 +- ...enUpdatingIssueArticleThatDoesNotExist.cs} | 6 +- ...ssueArticleWithDifferentSequenceNumber.cs} | 6 +- ...WhenUpdatingIssueArticleWithPermission.cs} | 6 +- .../WhenUpdatingIssueThatDoesNotExist.cs | 1 - .../GetIssuePages/WhenGettingAllIssuePages.cs | 4 +- .../WhenUpdatingPeriodicalThatDoesNotExist.cs | 9 +- ...atingPeriodicalWithAdditionalCategories.cs | 3 +- .../WhenUpdatingPeriodicalWithInvalidData.cs | 21 +- .../WhenUpdatingPeriodicalWithPermissions.cs | 1 - src/Inshapardaz.Api.Tests/TestBase.cs | 25 +- .../WhenAddingCorrectionAsAdmin.cs | 1 - .../WhenDeletingCorrectionAsAdmin.cs | 1 - .../WhenDeletingCorrectionAsAnonymous.cs | 1 - .../WhenUpdatingCorrectionAsAnonymous.cs | 1 - .../Configuration/DatabaseConfiguration.cs | 3 +- .../Controllers/ArticleController.cs | 316 ++++++++ .../Controllers/AuthorController.cs | 7 +- .../Controllers/BookController.cs | 23 +- .../Controllers/BookPageController.cs | 4 +- .../Controllers/BookShelfController.cs | 2 +- .../Controllers/ChapterController.cs | 4 +- .../Controllers/FileController.cs | 14 + .../Controllers/IssueArticleController.cs | 8 +- .../Controllers/IssueController.cs | 14 +- .../Controllers/IssuePageController.cs | 2 +- .../Controllers/LibraryController.cs | 2 +- .../Controllers/PeriodicalController.cs | 2 +- .../Controllers/SeriesController.cs | 2 +- .../Controllers/UserController.cs | 2 +- .../Converters/ArticleRenderer.cs | 359 +++++++++ .../Converters/AuthorRenderer.cs | 4 +- .../Converters/BookPageRenderer.cs | 12 +- .../Converters/BookRenderer.cs | 29 +- .../Converters/BookShelfRenderer.cs | 4 +- .../Converters/FileRenderer.cs | 8 +- .../Converters/IssueArticleRenderer.cs | 10 +- .../Converters/IssuePageRenderer.cs | 12 +- .../Converters/IssueRenderer.cs | 8 +- .../Converters/LibraryRenderer.cs | 5 +- .../Converters/PeriodicalRenderer.cs | 4 +- .../Converters/SeriesRenderer.cs | 4 +- .../Helpers/AuthorizeAttribute.cs | 3 +- .../Infrastructure}/TokenGenerator.cs | 13 +- src/Inshapardaz.Api/Inshapardaz.Api.csproj | 18 +- src/Inshapardaz.Api/Mappings/ArticleMapper.cs | 71 ++ src/Inshapardaz.Api/Mappings/AuthorMapper.cs | 1 + src/Inshapardaz.Api/Mappings/BookMapper.cs | 9 +- .../Mappings/PeriodicalMapper.cs | 10 +- src/Inshapardaz.Api/Startup.cs | 1 + .../Views/Library/ArticleContentView.cs | 11 +- .../Views/Library/ArticleView.cs | 18 +- ...terAssignmentView.cs => AssignmentView.cs} | 5 +- .../Views/Library/AuthorView.cs | 1 + .../Views/Library/BookContentView.cs | 4 +- src/Inshapardaz.Api/Views/Library/BookView.cs | 2 + .../Views/Library/IssueArticleContentView.cs | 19 + .../Views/Library/IssueArticleView.cs | 38 + ...ArticleSequenceView.cs => SequenceView.cs} | 2 +- src/Inshapardaz.Api/Views/LibraryView.cs | 4 +- .../Inshapardaz.Database.SqlServer.csproj | 2 +- .../Repositories/Library/ArticleRepository.cs | 709 +++++++++--------- .../Repositories/Library/AuthorRepository.cs | 24 +- .../Library/BookPageRepository.cs | 13 +- .../Repositories/Library/BookRepository.cs | 101 ++- .../Library/IssueArticleRepository.cs | 504 +++++++++++++ .../Library/IssuePageRepository.cs | 6 +- .../Repositories/Library/IssueRepository.cs | 6 +- .../Adapters/IGenerateToken.cs | 13 + .../Library/IArticleRepository.cs | 40 +- .../Repositories/Library/IBookRepository.cs | 9 +- .../Library/IIssueArticleRepository.cs | 35 + .../Common/RandomGenerator.cs | 4 +- .../Inshapardaz.Domain.csproj | 7 +- .../Models/ArticleFilter.cs | 18 + .../Models/ArticleSortByType.cs | 8 + .../Models/BookAssignmentStatus.cs | 10 + src/Inshapardaz.Domain/Models/BookFilter.cs | 22 +- .../Models/EditingStatus.cs | 12 +- src/Inshapardaz.Domain/Models/IssueFilter.cs | 14 + .../Models/Library/ArticleContentModel.cs | 8 +- .../Models/Library/ArticleModel.cs | 28 +- .../Models/Library/ArticleType.cs | 14 + .../Models/Library/AuthorModel.cs | 1 + .../Models/Library/BookContentModel.cs | 2 + .../Models/Library/BookModel.cs | 3 +- .../Library/IssueArticleContentModel.cs | 17 + .../Models/Library/IssueArticleModel.cs | 33 + .../Models/{BookStatuses.cs => StatusType.cs} | 7 +- .../Handlers/DownloadRekhtaBookRequest.cs | 4 +- .../Article/AddArticleContentRequest.cs | 65 ++ .../Library/Article/AddArticleRequest.cs | 77 ++ .../Article/AddArticleToFavoriteRequest.cs | 44 ++ .../AssignIssueArticleToUserRequest.cs | 74 ++ .../Article/DeleteArticleContentRequest.cs | 43 ++ .../Library/Article/DeleteArticleRequest.cs | 36 + .../Library/Article/GetArticleByIdQuery.cs | 37 + .../Library/Article/GetArticleContentQuery.cs | 52 ++ .../Library/Article/GetArticlesQuery.cs | 60 ++ .../RemoveArticleFromFavoriteRequest.cs | 39 + .../Article/UpdateArticleContentRequest.cs | 83 ++ .../Article/UpdateArticleImageRequest.cs | 105 +++ .../Library/Article/UpdateArticleRequest.cs | 93 +++ .../Library/Book/AddBookContentRequest.cs | 4 +- .../Library/Book/DeleteBookContentRequest.cs | 12 +- ...st.cs => DeleteBookFromFavoriteRequest.cs} | 13 +- .../Library/Book/GetUserBooksQuery.cs | 2 +- .../Book/Page/UpdateBookPageImageRequest.cs | 4 +- .../Library/Book/Page/UploadBookPages.cs | 27 +- .../Library/Book/UpdateBookContentRequest.cs | 14 +- .../Ports/Handlers/Library/LibraryCheck.cs | 47 ++ .../Article/AddIssueArticleContentRequest.cs | 2 +- .../Article/GetIssueArticleContentQuery.cs | 6 +- .../UpdateIssueArticleContentRequest.cs | 2 +- .../Inshapardaz.LibraryMigrator.csproj | 2 +- src/Inshapardaz.LibraryMigrator/Migrator.cs | 96 ++- .../FileSystemStorage.cs | 19 +- .../Inshapardaz.Storage.S3.csproj | 2 +- 358 files changed, 11761 insertions(+), 1312 deletions(-) create mode 100644 src/Inshapardaz.Api.Tests/Asserts/IssueArticleAssert.cs create mode 100644 src/Inshapardaz.Api.Tests/Asserts/IssueArticleContentAssert.cs create mode 100644 src/Inshapardaz.Api.Tests/DataBuilders/ArticlesDataBuilder.cs create mode 100644 src/Inshapardaz.Api.Tests/DataHelpers/IssueArticleDataHelper.cs create mode 100644 src/Inshapardaz.Api.Tests/Dto/IssueArticleDto.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticle.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleAsUnauthorized.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithInvalidData.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithMultipleAuthors.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithPermissions.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentAsUnauthorized.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentForNonExistingArticle.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentWithPermission.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteAlreadyInFavorite.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteAsUnauthorized.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteThatDoesNotExist.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteWithPermissions.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToSelfForReviewing.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToSelfForWriting.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserAsUnauthorised.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserForReviewing.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserForWriting.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleAsAnonymous.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleWithPermission.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingNonExistinArticle.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentThatDoesNotExists.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentsAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentsAsUnauthorized.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticlesContentsWithPermission.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdAsAnonymous.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdThatDoesNotExist.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdWithMultipleAuthrosAndCategories.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdWithPermission.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentLanguageNotExisting.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWhenArtcileDoesNotExists.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWhenNoContent.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWithoutLanguage.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentAsUnauthorised.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentWithPermission.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentAsUnauthorised.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentWithPermission.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesAsAnonymous.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesByAuthorAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesFirstPage.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesLastPage.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByLastModified.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByLastModifiedDescending.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByTitleDescending.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesPageInMiddle.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesPageThatDoesNotExist.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesReadbyMultipleUsers.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesSinglePage.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithAssignedToReview.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithAssignedToWrite.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithMultipleAuthorsAndCategories.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithWritePermissions.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingFavoriteArticles.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingReadArticles.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingingArticlesByStatus.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingingArticlesByType.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchinArticlesWithMultipleAuthorsAndCategories.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByStatus.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitle.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAndAuthor.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAndType.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAuthorAndType.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingFavoriteArticles.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingReadArticles.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenAddBookToFavoriteThatDoesNotExist.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveArticleFromFavoriteAsUnauthorized.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveArticleFromFavoriteWithPermissions.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveNonFavoriteArticleFromFavorite.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleAsUnauthorized.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleThatDoesNotExist.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithAdditionalCategories.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithInvalidData.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithMultipleAuthors.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithPermissions.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsAsUnauthorized.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWhereContentNotPresent.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWithDifferentLanguage.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWithPermission.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageAsReader.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageAsUnauthorized.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageWhenNoExistingImage.cs create mode 100644 src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageWithPermissions.cs rename src/Inshapardaz.Api.Tests/Library/Book/AddBook/{WhenAddingBookUsingAuthorProperties.cs => WhenAddingBook.cs} (91%) rename src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/{WhenAddBookToFavoriteAsUnauthorized.cs => WhenRemoveBookFromFavoriteAsUnauthorized.cs} (92%) rename src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/{WhenAddBookToFavoriteThatDoesNotExist.cs => WhenRemoveBookFromFavoriteThatDoesNotExist.cs} (88%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticle/WhenAddingArticleAsUnauthorizedUser.cs => IssueArticle/AddIssueArticle/WhenAddingIssueArticleAsUnauthorizedUser.cs} (87%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticle/WhenAddingArticleForIssueInOtherLibrary.cs => IssueArticle/AddIssueArticle/WhenAddingIssueArticleForIssueInOtherLibrary.cs} (86%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticle/WhenAddingArticleForNonExistingIssue.cs => IssueArticle/AddIssueArticle/WhenAddingIssueArticleForNonExistingIssue.cs} (83%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticle/WhenAddingArticleWithPermission.cs => IssueArticle/AddIssueArticle/WhenAddingIssueArticleWithPermission.cs} (91%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticle/WhenAddingArticleAsReader.cs => IssueArticle/AddIssueArticle/WhenIssueAddingArticleAsReader.cs} (85%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticleContents/WhenAddingArticleContentsAsReader.cs => IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsAsReader.cs} (84%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticleContents/WhenAddingArticleContentsAsUnauthorized.cs => IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsAsUnauthorized.cs} (86%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticleContents/WhenAddingArticleContentsForMissingArticle.cs => IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingArticle.cs} (83%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticleContents/WhenAddingArticleContentsForMissingIssue.cs => IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingIssue.cs} (83%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticleContents/WhenAddingArticleContentsForMissingPeriodical.cs => IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingPeriodical.cs} (82%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticleContents/WhenAddingIssueContentsForWrongLibrary.cs => IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForWrongLibrary.cs} (83%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticleContents/WhenAddingArticleContentsWithPermission.cs => IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsWithPermission.cs} (84%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/AddArticleContents/WhenAddingArticleContentsWithoutLanguage.cs => IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsWithoutLanguage.cs} (76%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/DeleteArticle/WhenDeletingArticleAsReader.cs => IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleAsReader.cs} (84%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/DeleteArticle/WhenDeletingArticleAsUnauthorized.cs => IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleAsUnauthorized.cs} (87%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/DeleteArticle/WhenDeletingArticleWithPermission.cs => IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleWithPermission.cs} (85%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/DeleteArticle/WhenDeletingNonExistingArticle.cs => IssueArticle/DeleteIssueArticle/WhenDeletingNonExistingIssueArticle.cs} (84%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/DeleteArticleContents/WhenDeletingArticleContentThatDoesNotExists.cs => IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentThatDoesNotExists.cs} (81%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/DeleteArticleContents/WhenDeletingArticleContentsAsReader.cs => IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsAsReader.cs} (84%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/DeleteArticleContents/WhenDeletingArticleContentsAsUnauthorized.cs => IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsAsUnauthorized.cs} (87%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/DeleteArticleContents/WhenDeletingArticleContentsWithPermission.cs => IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsWithPermission.cs} (76%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/GetArticleByIssue/WhenGettingArticlesByIssueAsReader.cs (100%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/GetArticleByIssue/WhenGettingArticlesByIssueAsUnauthorized.cs (100%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/GetArticleByIssue/WhenGettingArticlesByIssueWithNoArticles.cs (100%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/GetArticleByIssue/WhenGettingArticlesByIssueWithWritePermissions.cs (100%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/GetArticleByIssue/WhenGettingArticlesForNonExistingIssue.cs (96%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleById => IssueArticle/GetIssueArticleById}/WhenGettingArticleFromMiddleOfIssue.cs (93%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleById => IssueArticle/GetIssueArticleById}/WhenGettingFirstArticleOfIssue.cs (93%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleById/WhenGettingArticleByIdAsAnonymous.cs => IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdAsAnonymous.cs} (90%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleById/WhenGettingArticleByIdAsReader.cs => IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdAsReader.cs} (89%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleById/WhenGettingArticleByIdThatDoesNotExist.cs => IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdThatDoesNotExist.cs} (86%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleById/WhenGettingArticleByIdWithWritePermissions.cs => IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdWithWritePermissions.cs} (87%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleById => IssueArticle/GetIssueArticleById}/WhenGettingLastArticleOfIssue.cs (93%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleContents/WhenGettingArticleContentAsReader.cs => IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentAsReader.cs} (83%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleContents/WhenGettingArticleContentAsUnauthorised.cs => IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentAsUnauthorised.cs} (87%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleContents/WhenGettingArticleContentLanguageNotExisting.cs => IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentLanguageNotExisting.cs} (83%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleContents/WhenGettingArticleContentWhenNoChapterNotExists.cs => IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWhenNoChapterNotExists.cs} (79%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleContents/WhenGettingArticleContentWhenNoContent.cs => IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWhenNoContent.cs} (82%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleContents/WhenGettingArticleContentWithPermission.cs => IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWithPermission.cs} (83%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/GetArticleContents/WhenGettingArticleContentWithoutLanguage.cs => IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWithoutLanguage.cs} (83%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/UpdateArticleContents/WhenUpdatingArticleContentsAsReader.cs (93%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/UpdateArticleContents/WhenUpdatingArticleContentsAsUnauthorised.cs (93%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/UpdateArticleContents/WhenUpdatingArticleContentsWhereContentNotPresent.cs (92%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/UpdateArticleContents/WhenUpdatingArticleContentsWithDifferentLanguage.cs (92%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article => IssueArticle}/UpdateArticleContents/WhenUpdatingArticleContentsWithPermission.cs (92%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/UpdateArticle/WhenUpdatingArticleAsReader.cs => IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleAsReader.cs} (86%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/UpdateArticle/WhenUpdatingArticleAsUnauthorized.cs => IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleAsUnauthorized.cs} (88%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/UpdateArticle/WhenUpdatingArticleThatDoesNotExist.cs => IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleThatDoesNotExist.cs} (91%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/UpdateArticle/WhenUpdatingArticleWithDifferentSequenceNumber.cs => IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleWithDifferentSequenceNumber.cs} (88%) rename src/Inshapardaz.Api.Tests/Library/Periodical/Issue/{Article/UpdateArticle/WhenUpdatingArticleWithPermission.cs => IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleWithPermission.cs} (91%) create mode 100644 src/Inshapardaz.Api/Controllers/ArticleController.cs create mode 100644 src/Inshapardaz.Api/Converters/ArticleRenderer.cs rename src/{Inshapardaz.Domain/Adapters => Inshapardaz.Api/Infrastructure}/TokenGenerator.cs (85%) create mode 100644 src/Inshapardaz.Api/Mappings/ArticleMapper.cs rename src/Inshapardaz.Api/Views/Library/{ChapterAssignmentView.cs => AssignmentView.cs} (64%) create mode 100644 src/Inshapardaz.Api/Views/Library/IssueArticleContentView.cs create mode 100644 src/Inshapardaz.Api/Views/Library/IssueArticleView.cs rename src/Inshapardaz.Api/Views/Library/{ArticleSequenceView.cs => SequenceView.cs} (73%) create mode 100644 src/Inshapardaz.Database.SqlServer/Repositories/Library/IssueArticleRepository.cs create mode 100644 src/Inshapardaz.Domain/Adapters/IGenerateToken.cs create mode 100644 src/Inshapardaz.Domain/Adapters/Repositories/Library/IIssueArticleRepository.cs create mode 100644 src/Inshapardaz.Domain/Models/ArticleFilter.cs create mode 100644 src/Inshapardaz.Domain/Models/ArticleSortByType.cs create mode 100644 src/Inshapardaz.Domain/Models/BookAssignmentStatus.cs create mode 100644 src/Inshapardaz.Domain/Models/IssueFilter.cs create mode 100644 src/Inshapardaz.Domain/Models/Library/ArticleType.cs create mode 100644 src/Inshapardaz.Domain/Models/Library/IssueArticleContentModel.cs create mode 100644 src/Inshapardaz.Domain/Models/Library/IssueArticleModel.cs rename src/Inshapardaz.Domain/Models/{BookStatuses.cs => StatusType.cs} (78%) create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleContentRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleToFavoriteRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AssignIssueArticleToUserRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/DeleteArticleContentRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/DeleteArticleRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticleByIdQuery.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticleContentQuery.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticlesQuery.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/RemoveArticleFromFavoriteRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleContentRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleImageRequest.cs create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleRequest.cs rename src/Inshapardaz.Domain/Ports/Handlers/Library/Book/{DeleteBookToFavoriteRequest.cs => DeleteBookFromFavoriteRequest.cs} (52%) create mode 100644 src/Inshapardaz.Domain/Ports/Handlers/Library/LibraryCheck.cs diff --git a/src/Inshapardaz.Api.Tests/Accounts/ChangePassword/WhenChangingPassword.cs b/src/Inshapardaz.Api.Tests/Accounts/ChangePassword/WhenChangingPassword.cs index 39a90f9f..0a056c2f 100644 --- a/src/Inshapardaz.Api.Tests/Accounts/ChangePassword/WhenChangingPassword.cs +++ b/src/Inshapardaz.Api.Tests/Accounts/ChangePassword/WhenChangingPassword.cs @@ -1,5 +1,4 @@ -using Inshapardaz.Api.Entities; -using Inshapardaz.Api.Models.Accounts; +using Inshapardaz.Api.Models.Accounts; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; diff --git a/src/Inshapardaz.Api.Tests/Accounts/ChangePassword/WhenOldPasswordIsIncorrect.cs b/src/Inshapardaz.Api.Tests/Accounts/ChangePassword/WhenOldPasswordIsIncorrect.cs index 7630a3ba..5d101c70 100644 --- a/src/Inshapardaz.Api.Tests/Accounts/ChangePassword/WhenOldPasswordIsIncorrect.cs +++ b/src/Inshapardaz.Api.Tests/Accounts/ChangePassword/WhenOldPasswordIsIncorrect.cs @@ -1,5 +1,4 @@ -using Inshapardaz.Api.Entities; -using Inshapardaz.Api.Models.Accounts; +using Inshapardaz.Api.Models.Accounts; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; diff --git a/src/Inshapardaz.Api.Tests/Asserts/ArticleAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/ArticleAssert.cs index 2dcc424d..3b49f79f 100644 --- a/src/Inshapardaz.Api.Tests/Asserts/ArticleAssert.cs +++ b/src/Inshapardaz.Api.Tests/Asserts/ArticleAssert.cs @@ -2,55 +2,56 @@ using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Repositories; using System; +using System.Collections.Generic; using System.Data; using System.Linq; using System.Net.Http; +using System.Threading; namespace Inshapardaz.Api.Tests.Asserts { - internal class IssueArticleAssert + public class ArticleAssert { private HttpResponseMessage _response; private readonly int _libraryId; - private readonly IssueDto _issue; - private IssueArticleView _article; + private ArticleView _article; - public IssueArticleAssert(IssueArticleView view, int libraryId, IssueDto issue) + public ArticleAssert(ArticleView view, int libraryId) { _libraryId = libraryId; - _issue = issue; _article = view; } - public IssueArticleAssert(HttpResponseMessage response, int libraryId, IssueDto issue) + public ArticleAssert(HttpResponseMessage response, int libraryId) { _response = response; _libraryId = libraryId; - _issue = issue; - _article = response.GetContent().Result; + _article = response.GetContent().Result; } - internal static IssueArticleAssert FromResponse(HttpResponseMessage response, int libraryId, IssueDto issue) + internal static ArticleAssert FromResponse(HttpResponseMessage response, int libraryId) { - return new IssueArticleAssert(response, libraryId, issue); + return new ArticleAssert(response, libraryId); } - internal static IssueArticleAssert FromObject(IssueArticleView view, int libraryId, IssueDto issue) + internal static ArticleAssert FromObject(ArticleView view, int libraryId) { - return new IssueArticleAssert(view, libraryId, issue); + return new ArticleAssert(view, libraryId); } - internal IssueArticleAssert ShouldHaveCorrectLocationHeader() + internal ArticleAssert ShouldHaveCorrectLocationHeader() { var location = _response.Headers.Location.AbsoluteUri; location.Should().NotBeNull(); - location.Should().EndWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}"); + location.Should().EndWith($"libraries/{_libraryId}/articles/{_article.Id}"); return this; } - internal IssueArticleAssert ShouldBeAssignedToUserForWriting(AccountDto account) + internal ArticleAssert ShouldBeAssignedToUserForWriting(AccountDto account) { _article.WriterAccountId.Should().Be(account.Id); _article.WriterAccountName.Should().Be(account.Name); @@ -58,7 +59,7 @@ internal IssueArticleAssert ShouldBeAssignedToUserForWriting(AccountDto account) return this; } - internal IssueArticleAssert ShouldNotBeAssignedForWriting() + internal ArticleAssert ShouldNotBeAssignedForWriting() { _article.WriterAccountId.Should().BeNull(); _article.WriterAccountName.Should().BeNull(); @@ -66,23 +67,23 @@ internal IssueArticleAssert ShouldNotBeAssignedForWriting() return this; } - internal IssueArticleAssert ShouldBeSavedAssignmentForWriting(IDbConnection dbConnection, AccountDto account) + internal ArticleAssert ShouldBeSavedAssignmentForWriting(IDbConnection dbConnection, AccountDto account) { var dbArticle = dbConnection.GetArticleById(_article.Id); dbArticle.WriterAccountId.Should().Be(account.Id); - dbArticle.WriterAssignTimestamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2)); + dbArticle.WriterAssignTimeStamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2)); return this; } - internal IssueArticleAssert ShouldBeSavedNoAssignmentForWriting(IDbConnection dbConnection) + internal ArticleAssert ShouldBeSavedNoAssignmentForWriting(IDbConnection dbConnection) { var dbArticle = dbConnection.GetArticleById(_article.Id); dbArticle.WriterAccountId.Should().BeNull(); - dbArticle.WriterAssignTimestamp.Should().BeNull(); + dbArticle.WriterAssignTimeStamp.Should().BeNull(); return this; } - internal IssueArticleAssert ShouldBeAssignedToUserForReviewing(AccountDto account) + internal ArticleAssert ShouldBeAssignedToUserForReviewing(AccountDto account) { _article.ReviewerAccountId.Should().Be(account.Id); _article.ReviewerAccountName.Should().Be(account.Name); @@ -90,7 +91,7 @@ internal IssueArticleAssert ShouldBeAssignedToUserForReviewing(AccountDto accoun return this; } - internal IssueArticleAssert ShouldNotBeAssignedForReviewing() + internal ArticleAssert ShouldNotBeAssignedForReviewing() { _article.ReviewerAccountId.Should().BeNull(); _article.ReviewerAccountName.Should().BeNull(); @@ -98,23 +99,23 @@ internal IssueArticleAssert ShouldNotBeAssignedForReviewing() return this; } - internal IssueArticleAssert ShouldBeSavedAssignmentForReviewing(IDbConnection dbConnection, AccountDto account) + internal ArticleAssert ShouldBeSavedAssignmentForReviewing(IDbConnection dbConnection, AccountDto account) { var dbArticle = dbConnection.GetArticleById(_article.Id); dbArticle.ReviewerAccountId.Should().Be(account.Id); - dbArticle.ReviewerAssignTimestamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2)); + dbArticle.ReviewerAssignTimeStamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2)); return this; } - internal IssueArticleAssert ShouldBeSavedNoAssignmentForReviewing(IDbConnection dbConnection) + internal ArticleAssert ShouldBeSavedNoAssignmentForReviewing(IDbConnection dbConnection) { var dbArticle = dbConnection.GetArticleById(_article.Id); dbArticle.ReviewerAccountId.Should().BeNull(); - dbArticle.ReviewerAssignTimestamp.Should().BeNull(); + dbArticle.ReviewerAssignTimeStamp.Should().BeNull(); return this; } - internal IssueArticleAssert ShouldHaveSavedArticle(IDbConnection dbConnection) + internal ArticleAssert ShouldHaveSavedArticle(IDbConnection dbConnection) { var dbArticle = dbConnection.GetArticleById(_article.Id); dbArticle.Should().NotBeNull(); @@ -122,32 +123,75 @@ internal IssueArticleAssert ShouldHaveSavedArticle(IDbConnection dbConnection) return this; } - internal static void ShouldHaveDeletedArticle(int articleId, IDbConnection databaseConnection) + internal static void ShouldHaveDeletedArticle(long articleId, IDbConnection databaseConnection) { var article = databaseConnection.GetArticleById(articleId); article.Should().BeNull(); } - internal static void ThatContentsAreDeletedForArticle(int articleId, IDbConnection databaseConnection) + internal static void ThatContentsAreDeletedForArticle(long articleId, IDbConnection databaseConnection) { var contents = databaseConnection.GetContentByArticle(articleId); contents.Should().BeNullOrEmpty(); } - internal IssueArticleAssert ShouldHaveSelfLink() + public static void ShouldBeAddedToFavorite(long articleId, int accountId, IDbConnection dbConnection) + { + dbConnection.DoesArticleExistsInFavorites(articleId, accountId).Should().BeTrue(); + } + + public static void ShouldNotBeInFavorites(long articleId, int accountId, IDbConnection dbConnection) + { + dbConnection.DoesArticleExistsInFavorites(articleId, accountId).Should().BeFalse(); + } + + internal static void ShouldHaveDeletedArticleFromRecentReads(long articleId, IDbConnection dbConnection) + { + dbConnection.DoesArticleExistsInRecent(articleId).Should().BeFalse(); + } + + internal static void ShouldHaveDeletedArticleImage(long articleId, IDbConnection databaseConnection) + { + var image = databaseConnection.GetArticleImage(articleId); + image.Should().BeNull(); + } + + internal static void ShouldNotHaveUpdatedArticleImage(long articleId, byte[] oldImage, IDbConnection dbConnection, IFileStorage fileStorage) + { + var imageUrl = dbConnection.GetArticleImageUrl(articleId); + imageUrl.Should().NotBeNull(); + var image = fileStorage.GetFile(imageUrl, CancellationToken.None).Result; + image.Should().Equal(oldImage); + } + + internal static void ShouldHaveAddedArticleImage(long articleId, IDbConnection dbConnection, IFileStorage fileStorage) + { + var imageUrl = dbConnection.GetArticleImageUrl(articleId); + imageUrl.Should().NotBeNull(); + var image = fileStorage.GetFile(imageUrl, CancellationToken.None).Result; + image.Should().NotBeNullOrEmpty(); + } + + internal static void ShouldHaveUpdatedArticleImage(long articleId, byte[] newImage, IDbConnection dbConnection, IFileStorage fileStorage) + { + var imageUrl = dbConnection.GetArticleImageUrl(articleId); + imageUrl.Should().NotBeNull(); + var image = fileStorage.GetFile(imageUrl, CancellationToken.None).Result; + image.Should().NotBeNull().And.Equal(newImage); + } + + internal ArticleAssert ShouldHaveSelfLink() { _article.SelfLink() .ShouldBeGet() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}"); + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}"); return this; } - internal IssueArticleAssert WithReadOnlyLinks() + internal ArticleAssert WithReadOnlyLinks() { ShouldHaveSelfLink() - .ShouldHavePeriodicalLink() - .ShouldHaveIssueLink() .ShouldNotHaveAddArticleContentLink() .ShouldNotHaveUpdateLink() .ShouldNotHaveDeleteLink() @@ -155,177 +199,213 @@ internal IssueArticleAssert WithReadOnlyLinks() return this; } - internal IssueArticleAssert WithWriteableLinks() + internal ArticleAssert WithWriteableLinks() { - ShouldHaveAddIssueContentLink() + ShouldHaveAddContentLink() .ShouldHaveUpdateLink() .ShouldHaveDeleteLink() .ShouldHaveAssignmentLink(); return this; } - internal void ShouldHaveContentLink(ChapterContentDto content) - { - var actual = _article.Contents.Single(x => x.Id == content.Id); - actual.SelfLink() - .ShouldBeGet() - .ShouldHaveAcceptLanguage(content.Language); - } - internal void ShouldHaveNoCorrectContents() { _article.Link("content").Should().BeNull(); } - internal IssueArticleAssert ShouldHaveIssueLink() - { - _article.Link("issue") - .ShouldBeGet() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}"); - - return this; - } - - internal IssueArticleAssert ShouldHavePeriodicalLink() - { - _article.Link("periodical") - .ShouldBeGet() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}"); - - return this; - } - internal IssueArticleAssert ShouldHaveAssignmentLink() + internal ArticleAssert ShouldHaveAssignmentLink() { _article.Link("assign") .ShouldBePost() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/assign"); + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}/assign"); return this; } - internal IssueArticleAssert ShouldNotHaveAssignmentLink() + internal ArticleAssert ShouldNotHaveAssignmentLink() { _article.Link("assign") .Should().BeNull(); return this; } - internal void ShouldHaveCorrectContents(IDbConnection db) - { - var contents = db.GetContentByChapter(_article.Id); - - contents.Should().HaveSameCount(_article.Contents); - - foreach (var content in contents) - { - ShouldHaveContentLink(content); - } - } - - internal IssueArticleAssert ShouldHaveUpdateLink() + internal ArticleAssert ShouldHaveUpdateLink() { _article.UpdateLink() .ShouldBePut() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}"); + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}"); return this; } - internal IssueArticleAssert ShouldNotHaveUpdateLink() + internal ArticleAssert ShouldNotHaveUpdateLink() { _article.UpdateLink().Should().BeNull(); return this; } - internal IssueArticleAssert ShouldHaveDeleteLink() + internal ArticleAssert ShouldHaveDeleteLink() { _article.DeleteLink() .ShouldBeDelete() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}"); + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}"); return this; } - internal IssueArticleAssert ShouldNotHaveDeleteLink() + internal ArticleAssert ShouldNotHaveDeleteLink() { _article.DeleteLink().Should().BeNull(); return this; } - internal IssueArticleAssert ShouldHaveAddIssueContentLink() - { - _article.Link("add-content") - .ShouldBePost() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents"); - - return this; - } - - internal IssueArticleAssert ShouldNotHaveAddArticleContentLink() + internal ArticleAssert ShouldNotHaveAddArticleContentLink() { _article.Link("add-content").Should().BeNull(); return this; } - internal IssueArticleAssert ShouldHaveUpdateArticleContentLink(IssueContentDto content) + internal ArticleAssert ShouldHaveUpdateContentLink(IssueContentDto content) { var actual = _article.Contents.Single(x => x.Id == content.Id); actual.UpdateLink() .ShouldBePut() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents") + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}") .ShouldHaveAcceptLanguage(content.Language); return this; } - internal IssueArticleAssert ShouldHaveDeleteIssueContentLink(IssueContentDto content) + internal ArticleAssert ShouldHaveDeleteContentLink(IssueContentDto content) { var actual = _article.Contents.Single(x => x.Id == content.Id); actual.DeleteLink() .ShouldBeDelete() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents") + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}") .ShouldHaveAcceptLanguage(actual.Language); return this; } - internal IssueArticleAssert ShouldNotHaveContentsLink() + internal ArticleAssert ShouldNotHaveContentsLink() { _article.Link("content").Should().BeNull(); return this; } - internal IssueArticleAssert ShouldHaveNotNextLink() + internal ArticleAssert ShouldHavePublicImageLink() { - _article.Link("next").Should().BeNull(); + _article.Link("image") + .ShouldBeGet(); + //.Href.Should().StartWith(Settings.CDNAddress); + return this; } - internal IssueArticleAssert ShouldHaveNextLink(int sequenceNumber) + internal ArticleAssert ShouldNotHaveImageUpdateLink() { - _article.Link("next") - .ShouldBeGet() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{sequenceNumber}"); + _article.Link("image-upload").Should().BeNull(); + return this; + } + + internal ArticleAssert ShouldHaveImageUpdateLink() + { + _article.Link("image-upload") + .ShouldBePut() + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}/image"); + return this; + } + + public ArticleAssert ShouldHaveAddFavoriteLink() + { + _article.Link(RelTypes.CreateFavorite) + .ShouldBePost() + .EndingWith($"libraries/{_libraryId}/favorites/articles/{_article.Id}"); + + return this; + } + + public ArticleAssert ShouldNotHaveAddFavoriteLink() + { + _article.Link(RelTypes.CreateFavorite).Should().BeNull(); + return this; + } + + public ArticleAssert ShouldHaveRemoveFavoriteLink() + { + _article.Link(RelTypes.RemoveFavorite) + .ShouldBeDelete() + .EndingWith($"libraries/{_libraryId}/favorites/articles/{_article.Id}"); + + return this; + } + + public ArticleAssert ShouldNotHaveRemoveFavoriteLink() + { + _article.Link(RelTypes.RemoveFavorite).Should().BeNull(); return this; } - internal IssueArticleAssert ShouldHaveNotPreviousLink() + internal ArticleAssert ShouldHaveCorrectImageLocationHeader(long articleId) { - _article.Link("previous").Should().BeNull(); + _response.Headers.Location.AbsoluteUri.Should().NotBeEmpty(); return this; } - internal IssueArticleAssert ShouldHavePreviousLink(int sequenceNumber) + internal static void ShouldHavePublicImage(long articleId, IDbConnection dbConnection) { - _article.Link("previous") + var image = dbConnection.GetArticleImage(articleId); + image.Should().NotBeNull(); + image.IsPublic.Should().BeTrue(); + } + + public ArticleAssert ShouldHaveContents(List articles, bool withEditableLinks = false) + { + _article.Contents.Should().NotBeNullOrEmpty(); + foreach (var article in articles) + { + var actual = _article.Contents.SingleOrDefault(x => x.Id == article.Id); + actual.Language.Should().Be(article.Language); + actual.Text.Should().Be(article.Text); + actual.ArticleId.Should().Be(article.ArticleId); + actual.Link(RelTypes.Self) .ShouldBeGet() - .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{sequenceNumber}"); + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}/contents") + .ShouldHaveQueryParameter("language", actual.Language); + + if (withEditableLinks) + { + actual.Link(RelTypes.Update) + .ShouldBePut() + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}/contents") + .ShouldHaveQueryParameter("language", actual.Language); + + actual.Link(RelTypes.Delete) + .ShouldBeDelete() + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}/contents") + .ShouldHaveQueryParameter("language", actual.Language); + } + + } return this; } - internal void ShouldMatch(IssueArticleView view) + public ArticleAssert ShouldHaveAddContentLink() + { + _article.Link("add-content") + .ShouldBePut() + .EndingWith($"libraries/{_libraryId}/articles/{_article.Id}/contents"); + return this; + } + + public ArticleAssert ShouldNotHaveAddContentLink() + { + _article.Link("add-file").Should().BeNull(); + return this; + } + + internal void ShouldMatch(ArticleView view) { _article.Title.Should().Be(view.Title); - _article.SequenceNumber.Should().Be(view.SequenceNumber); _article.WriterAccountId.Should().Be(view.WriterAccountId); _article.WriterAccountName.Should().Be(view.WriterAccountName); if (view.WriterAssignTimeStamp.HasValue) @@ -346,54 +426,180 @@ internal void ShouldMatch(IssueArticleView view) _article.ReviewerAssignTimeStamp.Should().Be(view.ReviewerAssignTimeStamp); } _article.ReviewerAccountName.Should().Be(view.ReviewerAccountName); - _article.SeriesName.Should().Be(view.SeriesName); - _article.SeriesIndex.Should().Be(view.SeriesIndex); _article.Status.Should().Be(view.Status); } internal void ShouldMatch(ArticleDto dto) { _article.Title.Should().Be(dto.Title); - _article.SequenceNumber.Should().Be(dto.SequenceNumber); _article.WriterAccountId.Should().Be(dto.WriterAccountId); - if (dto.WriterAssignTimestamp.HasValue) + if (dto.WriterAssignTimeStamp.HasValue) { - _article.WriterAssignTimeStamp.Should().BeCloseTo(dto.WriterAssignTimestamp.Value, TimeSpan.FromSeconds(2)); + _article.WriterAssignTimeStamp.Should().BeCloseTo(dto.WriterAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); } else { - _article.WriterAssignTimeStamp.Should().Be(dto.WriterAssignTimestamp); + _article.WriterAssignTimeStamp.Should().Be(dto.WriterAssignTimeStamp); } _article.ReviewerAccountId.Should().Be(dto.ReviewerAccountId); - if (dto.ReviewerAssignTimestamp.HasValue) + if (dto.ReviewerAssignTimeStamp.HasValue) { - _article.ReviewerAssignTimeStamp.Should().BeCloseTo(dto.ReviewerAssignTimestamp.Value, TimeSpan.FromSeconds(2)); + _article.ReviewerAssignTimeStamp.Should().BeCloseTo(dto.ReviewerAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); } else { - _article.ReviewerAssignTimeStamp.Should().Be(dto.ReviewerAssignTimestamp); + _article.ReviewerAssignTimeStamp.Should().Be(dto.ReviewerAssignTimeStamp); } - _article.SeriesName.Should().Be(dto.SeriesName); - _article.SeriesIndex.Should().Be(dto.SeriesIndex); _article.Status.Should().Be(dto.Status.ToString()); } - internal IssueArticleAssert ShouldBeSameAs(ArticleDto dto) + internal ArticleAssert ShouldBeSameAs(ArticleView _expected, IDbConnection db) { - _article.Title.Should().Be(dto.Title); - _article.SequenceNumber.Should().Be(dto.SequenceNumber); - _article.WriterAccountId.Should().Be(dto.WriterAccountId); - _article.WriterAssignTimeStamp.Should().BeCloseTo(dto.WriterAssignTimestamp.Value, TimeSpan.FromSeconds(2)); - _article.ReviewerAccountId.Should().Be(dto.ReviewerAccountId); - _article.ReviewerAssignTimeStamp.Should().BeCloseTo(dto.ReviewerAssignTimestamp.Value, TimeSpan.FromSeconds(2)); - _article.SeriesName.Should().Be(dto.SeriesName); - _article.SeriesIndex.Should().Be(dto.SeriesIndex); - _article.Status.Should().Be(dto.Status.ToString()); + _article.Title.Should().Be(_expected.Title); + _article.IsPublic.Should().Be(_expected.IsPublic); + _article.WriterAccountId.Should().Be(_expected.WriterAccountId); + if (_expected.WriterAssignTimeStamp.HasValue) + { + _article.WriterAssignTimeStamp.Should().BeCloseTo(_expected.WriterAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + } + else + { + _article.WriterAssignTimeStamp.Should().BeNull(); + } + _article.ReviewerAccountId.Should().Be(_expected.ReviewerAccountId); + if (_expected.ReviewerAssignTimeStamp.HasValue) + { + _article.ReviewerAssignTimeStamp.Should().BeCloseTo(_expected.ReviewerAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + } + else + { + _article.ReviewerAssignTimeStamp.Should().BeNull(); + } + _article.Status.Should().Be(_expected.Status.ToString()); + + var authors = db.GetAuthorsByArticle(_expected.Id); + _article.Authors.Should().HaveSameCount(authors); + foreach (var author in authors) + { + var actual = _article.Authors.SingleOrDefault(a => a.Id == author.Id); + actual.Name.Should().Be(author.Name); + + actual.Link("self") + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/authors/{author.Id}"); + + return this; + } + + var categories = db.GetCategoriesByArticle(_expected.Id); + _article.Authors.Should().HaveSameCount(categories); + foreach (var category in categories) + { + var actual = _article.Categories.SingleOrDefault(a => a.Id == category.Id); + actual.Name.Should().Be(category.Name); + + actual.Link("self") + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/categories/{category.Id}"); + + return this; + } return this; } + + internal ArticleAssert ShouldBeSameAs(ArticleDto _expected, IDbConnection db) + { + _article.Title.Should().Be(_expected.Title); + _article.IsPublic.Should().Be(_expected.IsPublic); + _article.Status.Should().Be(_expected.Status.ToString()); + _article.Type.Should().Be(_expected.Type.ToString()); + _article.LastModified.Should().BeCloseTo(_expected.LastModified,TimeSpan.FromSeconds(2)); + _article.WriterAccountId.Should().Be(_expected.WriterAccountId); + if (_expected.WriterAssignTimeStamp.HasValue) + { + _article.WriterAssignTimeStamp.Should().BeCloseTo(_expected.WriterAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + } + else + { + _article.WriterAssignTimeStamp.Should().BeNull(); + } + _article.ReviewerAccountId.Should().Be(_expected.ReviewerAccountId); + if (_expected.ReviewerAssignTimeStamp.HasValue) + { + _article.ReviewerAssignTimeStamp.Should().BeCloseTo(_expected.ReviewerAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + } + else + { + _article.ReviewerAssignTimeStamp.Should().BeNull(); + } + + var authors = db.GetAuthorsByArticle(_expected.Id); + _article.Authors.Should().HaveSameCount(authors); + foreach (var author in authors) + { + var actual = _article.Authors.SingleOrDefault(a => a.Id == author.Id); + actual.Name.Should().Be(author.Name); + + actual.Link("self") + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/authors/{author.Id}"); + + return this; + } + + var categories = db.GetCategoriesByArticle(_expected.Id); + _article.Authors.Should().HaveSameCount(categories); + foreach (var category in categories) + { + var actual = _article.Categories.SingleOrDefault(a => a.Id == category.Id); + actual.Name.Should().Be(category.Name); + + actual.Link("self") + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/categories/{category.Id}"); + + return this; + } + + return this; + } + + internal ArticleAssert ShouldBeSameCategories(IEnumerable categories) + { + foreach(var category in categories) + { + var actual = _article.Categories.SingleOrDefault(x => x.Id == category.Id); + + actual.Should().BeEquivalentTo(category, config => config.ExcludingMissingMembers()); + } + return this; + } + + internal ArticleAssert ShouldHaveCategories(List categoriesToUpdate, IDbConnection databaseConnection) + { + var dbCategories = databaseConnection.GetCategoriesByArticle(_article.Id); + dbCategories.Should().HaveSameCount(categoriesToUpdate); + foreach (var category in categoriesToUpdate) + { + var actual = dbCategories.SingleOrDefault(x => x.Id == category.Id); + + actual.Should().BeEquivalentTo(category, config => config.ExcludingMissingMembers()); + } + return this; + } + } + + + public static class ArticleAssertionExtensions + { + public static ArticleAssert ShouldMatch(this ArticleView view, ArticleDto dto, IDbConnection dbConnection, int libraryId) + { + return new ArticleAssert(view, libraryId) + .ShouldBeSameAs(dto, dbConnection); + } } } diff --git a/src/Inshapardaz.Api.Tests/Asserts/ArticleContentAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/ArticleContentAssert.cs index 5d6b9256..eec35a1a 100644 --- a/src/Inshapardaz.Api.Tests/Asserts/ArticleContentAssert.cs +++ b/src/Inshapardaz.Api.Tests/Asserts/ArticleContentAssert.cs @@ -1,5 +1,4 @@ using FluentAssertions; -using FluentAssertions.Common; using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; @@ -15,23 +14,20 @@ internal class ArticleContentAssert private HttpResponseMessage _response; private readonly int _libraryId; private ArticleContentView _articleContent; - private IssueDto _issue; private LibraryDto _library; - public ArticleContentAssert(HttpResponseMessage response, int libraryId, IssueDto issue) + public ArticleContentAssert(HttpResponseMessage response, int libraryId) { _response = response; _libraryId = libraryId; - _issue = issue; _articleContent = response.GetContent().Result; } - public ArticleContentAssert(HttpResponseMessage response, LibraryDto library, IssueDto issue) + public ArticleContentAssert(HttpResponseMessage response, LibraryDto library) { _response = response; _libraryId = library.Id; _library = library; - _issue = issue; _articleContent = response.GetContent().Result; } @@ -39,7 +35,7 @@ internal ArticleContentAssert ShouldHaveSelfLink() { _articleContent.SelfLink() .ShouldBeGet() - .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}/contents") + .EndingWith($"/libraries/{_libraryId}/articles/{_articleContent.ArticleId}/contents") .ShouldHaveAcceptLanguage(_articleContent.Language); return this; @@ -63,7 +59,7 @@ internal ArticleContentAssert ShouldHaveUpdateLink() { _articleContent.UpdateLink() .ShouldBePut() - .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}/contents") + .EndingWith($"/libraries/{_libraryId}/articles/{_articleContent.ArticleId}/contents") .ShouldHaveAcceptLanguage(_articleContent.Language); return this; @@ -87,49 +83,40 @@ internal ArticleContentAssert ShouldHaveDefaultLibraryLanguage() return this; } - internal ArticleContentAssert ShouldHaveCorrectLocationHeader() + internal ArticleContentAssert ShouldHaveCorrectLocationHeader(string language) { var location = _response.Headers.Location.AbsoluteUri; location.Should().NotBeNull(); - location.Should().EndWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}/contents"); + location.Should().EndWith($"/libraries/{_libraryId}/articles/{_articleContent.ArticleId}/contents?language={language}"); return this; } internal ArticleContentAssert ShouldHaveSavedCorrectText(string expected, IDbConnection dbConnection) { - var content = dbConnection.GetArticleContentById(_issue.PeriodicalId, _issue.VolumeNumber, _issue.IssueNumber, _articleContent.SequenceNumber, _articleContent.Language); + var content = dbConnection.GetArticleContent(_articleContent.ArticleId, _articleContent.Language); content.Text.Should().NotBeNull().And.Be(expected); return this; } - internal ArticleContentAssert ShouldHaveMatechingTextForLanguage(string expected, string language, IDbConnection dbConnection) + internal ArticleContentAssert ShouldHaveMatechingTextForLanguage(string expected, string language, string newLayout, IDbConnection dbConnection) { - var content = dbConnection.GetArticleContentById(_issue.PeriodicalId, _issue.VolumeNumber, _issue.IssueNumber, _articleContent.SequenceNumber, _articleContent.Language); + var content = dbConnection.GetArticleContent(_articleContent.ArticleId, _articleContent.Language); content.Text.Should().NotBeNull().Should().NotBe(expected); content.Language.Should().Be(language); - return this; - } - - internal ArticleContentAssert ShouldHaveContentLink() - { - _articleContent.Link("contents") - .ShouldBeGet(); - + content.Layout.Should().Be(newLayout); return this; } internal ArticleContentAssert ShouldHaveSavedArticleContent(IDbConnection dbConnection) { - var dbContent = dbConnection.GetArticleContentById(_issue.PeriodicalId, _issue.VolumeNumber, _issue.IssueNumber, _articleContent.SequenceNumber, _articleContent.Language); + var dbContent = dbConnection.GetArticleContent(_articleContent.ArticleId, _articleContent.Language); dbContent.Should().NotBeNull(); var dbArticle = dbConnection.GetArticleById(dbContent.ArticleId); dbArticle.Should().NotBeNull(); - var dbIssue = dbConnection.GetIssueById(dbArticle.IssueId); - _articleContent.PeriodicalId.Should().Be(dbIssue.PeriodicalId); - _articleContent.VolumeNumber.Should().Be(dbIssue.VolumeNumber); - _articleContent.IssueNumber.Should().Be(dbIssue.IssueNumber); - _articleContent.SequenceNumber.Should().Be(dbArticle.SequenceNumber); + _articleContent.ArticleId.Should().Be(dbContent.ArticleId); _articleContent.Language.Should().Be(dbContent.Language); + _articleContent.Layout.Should().Be(dbContent.Layout); + _articleContent.Text.Should().Be(dbContent.Text); return this; } @@ -138,7 +125,7 @@ internal ArticleContentAssert ShouldHaveDeleteLink() { _articleContent.DeleteLink() .ShouldBeDelete() - .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}/contents"); + .EndingWith($"/libraries/{_libraryId}/articles/{_articleContent.ArticleId}/contents"); return this; } @@ -153,51 +140,38 @@ internal ArticleContentAssert ShouldHaveArticleLink() { _articleContent.Link("article") .ShouldBeGet() - .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}"); - - return this; - } - - internal ArticleContentAssert ShouldHaveIssueLink() - { - _articleContent.Link("issue") - .ShouldBeGet() - .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}"); + .EndingWith($"/libraries/{_libraryId}/articles/{_articleContent.ArticleId}"); return this; } - internal ArticleContentAssert ShouldHavePeriodicalLink() + internal ArticleContentAssert ShouldMatch(ArticleContentDto content, ArticleDto article) { - _articleContent.Link("periodical") - .ShouldBeGet() - .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}"); + _articleContent.ArticleId.Should().Be(article.Id); + _articleContent.Language.Should().Be(content.Language); + _articleContent.Layout.Should().Be(content.Layout); + _articleContent.Text.Should().Be(content.Text); return this; } - internal ArticleContentAssert ShouldMatch(ArticleContentDto content, IssueDto issue, ArticleDto article) + internal static void ShouldHaveDeletedContent(IDbConnection dbConnection, ArticleContentDto content) { - _articleContent.PeriodicalId.Should().Be(issue.PeriodicalId); - _articleContent.VolumeNumber.Should().Be(issue.VolumeNumber); - _articleContent.IssueNumber.Should().Be(issue.IssueNumber); - _articleContent.SequenceNumber.Should().Be(article.SequenceNumber); - _articleContent.Language.Should().Be(content.Language); - - return this; + var dbContent = dbConnection.GetArticleContent(content.ArticleId, content.Language); + dbContent.Should().BeNull("Article content should be deleted"); } - internal static void ShouldHaveDeletedContent(IDbConnection dbConnection, IssueDto issue, ArticleDto article, ArticleContentDto content) + internal static void ShouldHaveContent(IDbConnection dbConnection, long articleId, string language) { - var dbContent = dbConnection.GetArticleContentById(issue.PeriodicalId, issue.VolumeNumber, issue.IssueNumber, article.SequenceNumber, content.Language); - dbContent.Should().BeNull("Article content should be deleted"); + var dbContent = dbConnection.GetArticleContent(articleId, language); + dbContent.Should().NotBeNull("Article content should exist."); } - internal static void ShouldHaveLocationHeader(RedirectResult result, int libraryId, int periodicalId, int volumeNumber, int issueNumber, ChapterContentDto content) + internal static void ShouldHaveLocationHeader(RedirectResult result, int libraryId, ArticleContentDto content) { var response = result as RedirectResult; response.Url.Should().NotBeNull(); - response.Url.Should().EndWith($"/libraries/{libraryId}/periodicals/{periodicalId}/volumes/{volumeNumber}/issues/{issueNumber}/contents"); + response.Url.Should().EndWith($"/libraries/{libraryId}/articles/{content.ArticleId}/contents"); } } } diff --git a/src/Inshapardaz.Api.Tests/Asserts/AuthorAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/AuthorAssert.cs index c02412b7..ff03b68e 100644 --- a/src/Inshapardaz.Api.Tests/Asserts/AuthorAssert.cs +++ b/src/Inshapardaz.Api.Tests/Asserts/AuthorAssert.cs @@ -257,6 +257,7 @@ public AuthorAssert ShouldHaveCorrectAuthorRetunred(AuthorDto author, IDbConnect _author.Id.Should().Be(author.Id); _author.Name.Should().Be(author.Name); _author.BookCount.Should().Be(dbConnection.GetBookCountByAuthor(_author.Id)); + _author.ArticleCount.Should().Be(dbConnection.GetArticleCountByAuthor(_author.Id)); return this; } } @@ -269,4 +270,4 @@ public static AuthorAssert ShouldMatch(this AuthorView view, AuthorDto dto) .ShouldBeSameAs(dto); } } -} \ No newline at end of file +} diff --git a/src/Inshapardaz.Api.Tests/Asserts/BookAsserts.cs b/src/Inshapardaz.Api.Tests/Asserts/BookAsserts.cs index aeebb39b..b392181b 100644 --- a/src/Inshapardaz.Api.Tests/Asserts/BookAsserts.cs +++ b/src/Inshapardaz.Api.Tests/Asserts/BookAsserts.cs @@ -322,6 +322,8 @@ internal BookAssert ShouldBeSameAs(BookDto expected, IDbConnection db) _book.Status.Should().Be(expected.Status.ToDescription()); _book.YearPublished.Should().Be(expected.YearPublished); _book.SeriesId.Should().Be(expected.SeriesId); + _book.Source.Should().Be(expected.Source); + _book.Publisher.Should().Be(expected.Publisher); if (_book.SeriesId.HasValue) { _book.SeriesName.Should().Be(db.GetSeriesById(expected.SeriesId.Value).Name); @@ -376,6 +378,8 @@ internal BookAssert ShouldBeSameAs(BookView expected, IDbConnection db) _book.SeriesId.Should().Be(expected.SeriesId); _book.SeriesName.Should().Be(db.GetSeriesById(expected.SeriesId.Value).Name); _book.SeriesIndex.Should().Be(expected.SeriesIndex); + _book.Source.Should().Be(expected.Source); + _book.Publisher.Should().Be(expected.Publisher); var authors = db.GetAuthorsByBook(expected.Id); _book.Authors.Should().HaveSameCount(authors); diff --git a/src/Inshapardaz.Api.Tests/Asserts/BookPageAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/BookPageAssert.cs index c9b9b8b8..837ddbad 100644 --- a/src/Inshapardaz.Api.Tests/Asserts/BookPageAssert.cs +++ b/src/Inshapardaz.Api.Tests/Asserts/BookPageAssert.cs @@ -246,11 +246,11 @@ public BookPageAssert ShouldNotHaveImageDeleteLink() return this; } - public void ShouldMatch(BookPageView view) + public void ShouldMatch(BookPageView view, int pageNumber = -1) { _bookPage.Text.Should().Be(view.Text); _bookPage.BookId.Should().Be(view.BookId); - _bookPage.SequenceNumber.Should().Be(view.SequenceNumber); + _bookPage.SequenceNumber.Should().Be(pageNumber >= 0 ? pageNumber : view.SequenceNumber); } public BookPageAssert ShouldMatch(BookPageDto dto) diff --git a/src/Inshapardaz.Api.Tests/Asserts/IssueArticleAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/IssueArticleAssert.cs new file mode 100644 index 00000000..e8360009 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Asserts/IssueArticleAssert.cs @@ -0,0 +1,399 @@ +using FluentAssertions; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using System; +using System.Data; +using System.Linq; +using System.Net.Http; + +namespace Inshapardaz.Api.Tests.Asserts +{ + internal class IssueArticleAssert + { + private HttpResponseMessage _response; + private readonly int _libraryId; + private readonly IssueDto _issue; + private IssueArticleView _article; + + public IssueArticleAssert(IssueArticleView view, int libraryId, IssueDto issue) + { + _libraryId = libraryId; + _issue = issue; + _article = view; + } + + public IssueArticleAssert(HttpResponseMessage response, int libraryId, IssueDto issue) + { + _response = response; + _libraryId = libraryId; + _issue = issue; + _article = response.GetContent().Result; + } + + internal static IssueArticleAssert FromResponse(HttpResponseMessage response, int libraryId, IssueDto issue) + { + return new IssueArticleAssert(response, libraryId, issue); + } + + internal static IssueArticleAssert FromObject(IssueArticleView view, int libraryId, IssueDto issue) + { + return new IssueArticleAssert(view, libraryId, issue); + } + + internal IssueArticleAssert ShouldHaveCorrectLocationHeader() + { + var location = _response.Headers.Location.AbsoluteUri; + location.Should().NotBeNull(); + location.Should().EndWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}"); + return this; + } + + internal IssueArticleAssert ShouldBeAssignedToUserForWriting(AccountDto account) + { + _article.WriterAccountId.Should().Be(account.Id); + _article.WriterAccountName.Should().Be(account.Name); + _article.WriterAssignTimeStamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2)); + return this; + } + + internal IssueArticleAssert ShouldNotBeAssignedForWriting() + { + _article.WriterAccountId.Should().BeNull(); + _article.WriterAccountName.Should().BeNull(); + _article.WriterAssignTimeStamp.Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldBeSavedAssignmentForWriting(IDbConnection dbConnection, AccountDto account) + { + var dbArticle = dbConnection.GetIssueArticleById(_article.Id); + dbArticle.WriterAccountId.Should().Be(account.Id); + dbArticle.WriterAssignTimeStamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2)); + return this; + } + + internal IssueArticleAssert ShouldBeSavedNoAssignmentForWriting(IDbConnection dbConnection) + { + var dbArticle = dbConnection.GetIssueArticleById(_article.Id); + dbArticle.WriterAccountId.Should().BeNull(); + dbArticle.WriterAssignTimeStamp.Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldBeAssignedToUserForReviewing(AccountDto account) + { + _article.ReviewerAccountId.Should().Be(account.Id); + _article.ReviewerAccountName.Should().Be(account.Name); + _article.ReviewerAssignTimeStamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2)); + return this; + } + + internal IssueArticleAssert ShouldNotBeAssignedForReviewing() + { + _article.ReviewerAccountId.Should().BeNull(); + _article.ReviewerAccountName.Should().BeNull(); + _article.ReviewerAssignTimeStamp.Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldBeSavedAssignmentForReviewing(IDbConnection dbConnection, AccountDto account) + { + var dbArticle = dbConnection.GetIssueArticleById(_article.Id); + dbArticle.ReviewerAccountId.Should().Be(account.Id); + dbArticle.ReviewerAssignTimeStamp.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(2)); + return this; + } + + internal IssueArticleAssert ShouldBeSavedNoAssignmentForReviewing(IDbConnection dbConnection) + { + var dbArticle = dbConnection.GetIssueArticleById(_article.Id); + dbArticle.ReviewerAccountId.Should().BeNull(); + dbArticle.ReviewerAssignTimeStamp.Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldHaveSavedArticle(IDbConnection dbConnection) + { + var dbArticle = dbConnection.GetIssueArticleById(_article.Id); + dbArticle.Should().NotBeNull(); + _article.Title.Should().Be(dbArticle.Title); + return this; + } + + internal static void ShouldHaveDeletedArticle(int articleId, IDbConnection databaseConnection) + { + var article = databaseConnection.GetIssueArticleById(articleId); + article.Should().BeNull(); + } + + internal static void ThatContentsAreDeletedForArticle(int articleId, IDbConnection databaseConnection) + { + var contents = databaseConnection.GetContentByIssueArticle(articleId); + contents.Should().BeNullOrEmpty(); + } + + internal IssueArticleAssert ShouldHaveSelfLink() + { + _article.SelfLink() + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}"); + + return this; + } + + internal IssueArticleAssert WithReadOnlyLinks() + { + ShouldHaveSelfLink() + .ShouldHavePeriodicalLink() + .ShouldHaveIssueLink() + .ShouldNotHaveAddArticleContentLink() + .ShouldNotHaveUpdateLink() + .ShouldNotHaveDeleteLink() + .ShouldNotHaveAssignmentLink(); + return this; + } + + internal IssueArticleAssert WithWriteableLinks() + { + ShouldHaveAddIssueContentLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink() + .ShouldHaveAssignmentLink(); + return this; + } + + internal void ShouldHaveContentLink(ChapterContentDto content) + { + var actual = _article.Contents.Single(x => x.Id == content.Id); + actual.SelfLink() + .ShouldBeGet() + .ShouldHaveAcceptLanguage(content.Language); + } + + internal void ShouldHaveNoCorrectContents() + { + _article.Link("content").Should().BeNull(); + } + internal IssueArticleAssert ShouldHaveIssueLink() + { + _article.Link("issue") + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}"); + + return this; + } + + internal IssueArticleAssert ShouldHavePeriodicalLink() + { + _article.Link("periodical") + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}"); + + return this; + } + + internal IssueArticleAssert ShouldHaveAssignmentLink() + { + _article.Link("assign") + .ShouldBePost() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/assign"); + return this; + } + + internal IssueArticleAssert ShouldNotHaveAssignmentLink() + { + _article.Link("assign") + .Should().BeNull(); + return this; + } + + internal void ShouldHaveCorrectContents(IDbConnection db) + { + var contents = db.GetContentByChapter(_article.Id); + + contents.Should().HaveSameCount(_article.Contents); + + foreach (var content in contents) + { + ShouldHaveContentLink(content); + } + } + + internal IssueArticleAssert ShouldHaveUpdateLink() + { + _article.UpdateLink() + .ShouldBePut() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}"); + + return this; + } + + internal IssueArticleAssert ShouldNotHaveUpdateLink() + { + _article.UpdateLink().Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldHaveDeleteLink() + { + _article.DeleteLink() + .ShouldBeDelete() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}"); + + return this; + } + + internal IssueArticleAssert ShouldNotHaveDeleteLink() + { + _article.DeleteLink().Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldHaveAddIssueContentLink() + { + _article.Link("add-content") + .ShouldBePost() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents"); + + return this; + } + + internal IssueArticleAssert ShouldNotHaveAddArticleContentLink() + { + _article.Link("add-content").Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldHaveUpdateArticleContentLink(IssueContentDto content) + { + var actual = _article.Contents.Single(x => x.Id == content.Id); + actual.UpdateLink() + .ShouldBePut() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents") + .ShouldHaveAcceptLanguage(content.Language); + + return this; + } + + internal IssueArticleAssert ShouldHaveDeleteIssueContentLink(IssueContentDto content) + { + var actual = _article.Contents.Single(x => x.Id == content.Id); + actual.DeleteLink() + .ShouldBeDelete() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents") + .ShouldHaveAcceptLanguage(actual.Language); + + return this; + } + + internal IssueArticleAssert ShouldNotHaveContentsLink() + { + _article.Link("content").Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldHaveNotNextLink() + { + _article.Link("next").Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldHaveNextLink(int sequenceNumber) + { + _article.Link("next") + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{sequenceNumber}"); + return this; + } + + internal IssueArticleAssert ShouldHaveNotPreviousLink() + { + _article.Link("previous").Should().BeNull(); + return this; + } + + internal IssueArticleAssert ShouldHavePreviousLink(int sequenceNumber) + { + _article.Link("previous") + .ShouldBeGet() + .EndingWith($"libraries/{_libraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{sequenceNumber}"); + return this; + } + + internal void ShouldMatch(IssueArticleView view) + { + _article.Title.Should().Be(view.Title); + _article.SequenceNumber.Should().Be(view.SequenceNumber); + _article.WriterAccountId.Should().Be(view.WriterAccountId); + _article.WriterAccountName.Should().Be(view.WriterAccountName); + if (view.WriterAssignTimeStamp.HasValue) + { + _article.WriterAssignTimeStamp.Should().BeCloseTo(view.WriterAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + } + else + { + _article.WriterAssignTimeStamp.Should().Be(view.WriterAssignTimeStamp); + } + _article.ReviewerAccountId.Should().Be(view.ReviewerAccountId); + if (view.ReviewerAssignTimeStamp.HasValue) + { + _article.ReviewerAssignTimeStamp.Should().BeCloseTo(view.ReviewerAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + } + else + { + _article.ReviewerAssignTimeStamp.Should().Be(view.ReviewerAssignTimeStamp); + } + _article.ReviewerAccountName.Should().Be(view.ReviewerAccountName); + _article.SeriesName.Should().Be(view.SeriesName); + _article.SeriesIndex.Should().Be(view.SeriesIndex); + _article.Status.Should().Be(view.Status); + } + + internal void ShouldMatch(IssueArticleDto dto) + { + _article.Title.Should().Be(dto.Title); + _article.SequenceNumber.Should().Be(dto.SequenceNumber); + _article.WriterAccountId.Should().Be(dto.WriterAccountId); + if (dto.WriterAssignTimeStamp.HasValue) + { + _article.WriterAssignTimeStamp.Should().BeCloseTo(dto.WriterAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + } + else + { + _article.WriterAssignTimeStamp.Should().Be(dto.WriterAssignTimeStamp); + } + + _article.ReviewerAccountId.Should().Be(dto.ReviewerAccountId); + if (dto.ReviewerAssignTimeStamp.HasValue) + { + _article.ReviewerAssignTimeStamp.Should().BeCloseTo(dto.ReviewerAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + } + else + { + _article.ReviewerAssignTimeStamp.Should().Be(dto.ReviewerAssignTimeStamp); + + } + + _article.SeriesName.Should().Be(dto.SeriesName); + _article.SeriesIndex.Should().Be(dto.SeriesIndex); + _article.Status.Should().Be(dto.Status.ToString()); + } + + internal IssueArticleAssert ShouldBeSameAs(IssueArticleDto dto) + { + _article.Title.Should().Be(dto.Title); + _article.SequenceNumber.Should().Be(dto.SequenceNumber); + _article.WriterAccountId.Should().Be(dto.WriterAccountId); + _article.WriterAssignTimeStamp.Should().BeCloseTo(dto.WriterAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + _article.ReviewerAccountId.Should().Be(dto.ReviewerAccountId); + _article.ReviewerAssignTimeStamp.Should().BeCloseTo(dto.ReviewerAssignTimeStamp.Value, TimeSpan.FromSeconds(2)); + _article.SeriesName.Should().Be(dto.SeriesName); + _article.SeriesIndex.Should().Be(dto.SeriesIndex); + _article.Status.Should().Be(dto.Status.ToString()); + + return this; + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Asserts/IssueArticleContentAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/IssueArticleContentAssert.cs new file mode 100644 index 00000000..58249d4a --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Asserts/IssueArticleContentAssert.cs @@ -0,0 +1,202 @@ +using FluentAssertions; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Microsoft.AspNetCore.Mvc; +using System.Data; +using System.Net.Http; + +namespace Inshapardaz.Api.Tests.Asserts +{ + internal class IssueArticleContentAssert + { + private HttpResponseMessage _response; + private readonly int _libraryId; + private IssueArticleContentView _articleContent; + private IssueDto _issue; + private LibraryDto _library; + + public IssueArticleContentAssert(HttpResponseMessage response, int libraryId, IssueDto issue) + { + _response = response; + _libraryId = libraryId; + _issue = issue; + _articleContent = response.GetContent().Result; + } + + public IssueArticleContentAssert(HttpResponseMessage response, LibraryDto library, IssueDto issue) + { + _response = response; + _libraryId = library.Id; + _library = library; + _issue = issue; + _articleContent = response.GetContent().Result; + } + + internal IssueArticleContentAssert ShouldHaveSelfLink() + { + _articleContent.SelfLink() + .ShouldBeGet() + .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}/contents") + .ShouldHaveAcceptLanguage(_articleContent.Language); + + return this; + } + + internal IssueArticleContentAssert WithReadOnlyLinks() + { + ShouldNotHaveUpdateLink(); + ShouldNotHaveDeleteLink(); + return this; + } + + internal IssueArticleContentAssert WithWriteableLinks() + { + ShouldHaveUpdateLink(); + ShouldHaveDeleteLink(); + return this; + } + + internal IssueArticleContentAssert ShouldHaveUpdateLink() + { + _articleContent.UpdateLink() + .ShouldBePut() + .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}/contents") + .ShouldHaveAcceptLanguage(_articleContent.Language); + + return this; + } + + internal IssueArticleContentAssert ShouldHaveText(string contents) + { + _articleContent.Text.Should().Be(contents); + return this; + } + + internal IssueArticleContentAssert ShouldNotHaveUpdateLink() + { + _articleContent.UpdateLink().Should().BeNull(); + return this; + } + + internal IssueArticleContentAssert ShouldHaveDefaultLibraryLanguage() + { + _articleContent.Language.Should().Be(_library.Language); + return this; + } + + internal IssueArticleContentAssert ShouldHaveCorrectLocationHeader() + { + var location = _response.Headers.Location.AbsoluteUri; + location.Should().NotBeNull(); + location.Should().EndWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}/contents"); + return this; + } + + internal IssueArticleContentAssert ShouldHaveSavedCorrectText(string expected, IDbConnection dbConnection) + { + var content = dbConnection.GetIssueArticleContent(_issue.PeriodicalId, _issue.VolumeNumber, _issue.IssueNumber, _articleContent.SequenceNumber, _articleContent.Language); + content.Text.Should().NotBeNull().And.Be(expected); + return this; + } + + internal IssueArticleContentAssert ShouldHaveMatechingTextForLanguage(string expected, string language, IDbConnection dbConnection) + { + var content = dbConnection.GetIssueArticleContent(_issue.PeriodicalId, _issue.VolumeNumber, _issue.IssueNumber, _articleContent.SequenceNumber, _articleContent.Language); + content.Text.Should().NotBeNull().Should().NotBe(expected); + content.Language.Should().Be(language); + return this; + } + + internal IssueArticleContentAssert ShouldHaveContentLink() + { + _articleContent.Link("contents") + .ShouldBeGet(); + + return this; + } + + internal IssueArticleContentAssert ShouldHaveSavedArticleContent(IDbConnection dbConnection) + { + var dbContent = dbConnection.GetIssueArticleContent(_issue.PeriodicalId, _issue.VolumeNumber, _issue.IssueNumber, _articleContent.SequenceNumber, _articleContent.Language); + dbContent.Should().NotBeNull(); + var dbArticle = dbConnection.GetIssueArticleById(dbContent.ArticleId); + dbArticle.Should().NotBeNull(); + var dbIssue = dbConnection.GetIssueById(dbArticle.IssueId); + _articleContent.PeriodicalId.Should().Be(dbIssue.PeriodicalId); + _articleContent.VolumeNumber.Should().Be(dbIssue.VolumeNumber); + _articleContent.IssueNumber.Should().Be(dbIssue.IssueNumber); + _articleContent.SequenceNumber.Should().Be(dbArticle.SequenceNumber); + _articleContent.Language.Should().Be(dbContent.Language); + + return this; + } + + internal IssueArticleContentAssert ShouldHaveDeleteLink() + { + _articleContent.DeleteLink() + .ShouldBeDelete() + .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}/contents"); + + return this; + } + + internal IssueArticleContentAssert ShouldNotHaveDeleteLink() + { + _articleContent.DeleteLink().Should().BeNull(); + return this; + } + + internal IssueArticleContentAssert ShouldHaveArticleLink() + { + _articleContent.Link("article") + .ShouldBeGet() + .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}/articles/{_articleContent.SequenceNumber}"); + + return this; + } + + internal IssueArticleContentAssert ShouldHaveIssueLink() + { + _articleContent.Link("issue") + .ShouldBeGet() + .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}/volumes/{_articleContent.VolumeNumber}/issues/{_articleContent.IssueNumber}"); + + return this; + } + + internal IssueArticleContentAssert ShouldHavePeriodicalLink() + { + _articleContent.Link("periodical") + .ShouldBeGet() + .EndingWith($"/libraries/{_libraryId}/periodicals/{_articleContent.PeriodicalId}"); + + return this; + } + + internal IssueArticleContentAssert ShouldMatch(IssueArticleContentDto content, IssueDto issue, IssueArticleDto article) + { + _articleContent.PeriodicalId.Should().Be(issue.PeriodicalId); + _articleContent.VolumeNumber.Should().Be(issue.VolumeNumber); + _articleContent.IssueNumber.Should().Be(issue.IssueNumber); + _articleContent.SequenceNumber.Should().Be(article.SequenceNumber); + _articleContent.Language.Should().Be(content.Language); + + return this; + } + + internal static void ShouldHaveDeletedContent(IDbConnection dbConnection, IssueDto issue, IssueArticleDto article, IssueArticleContentDto content) + { + var dbContent = dbConnection.GetIssueArticleContent(issue.PeriodicalId, issue.VolumeNumber, issue.IssueNumber, article.SequenceNumber, content.Language); + dbContent.Should().BeNull("Article content should be deleted"); + } + + internal static void ShouldHaveLocationHeader(RedirectResult result, int libraryId, int periodicalId, int volumeNumber, int issueNumber, ChapterContentDto content) + { + var response = result as RedirectResult; + response.Url.Should().NotBeNull(); + response.Url.Should().EndWith($"/libraries/{libraryId}/periodicals/{periodicalId}/volumes/{volumeNumber}/issues/{issueNumber}/contents"); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Asserts/IssueAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/IssueAssert.cs index 7f00ed6f..e4943f44 100644 --- a/src/Inshapardaz.Api.Tests/Asserts/IssueAssert.cs +++ b/src/Inshapardaz.Api.Tests/Asserts/IssueAssert.cs @@ -5,7 +5,6 @@ using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Repositories; using System; -using System.Collections.Generic; using System.Data; using System.Linq; using System.Net.Http; @@ -290,7 +289,7 @@ internal static void ShouldHaveDeletedIssueImage(IDbConnection dbConnection, int internal static void ShouldHaveDeletedArticlesForIssue(IDbConnection dbConnection, int issueId) { - var articles = dbConnection.GetArticlesByIssue(issueId); + var articles = dbConnection.GetIssueArticlesByIssue(issueId); articles.Should().BeNullOrEmpty(); } diff --git a/src/Inshapardaz.Api.Tests/Asserts/LibraryAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/LibraryAssert.cs index 4695d568..ca7cf0f7 100644 --- a/src/Inshapardaz.Api.Tests/Asserts/LibraryAssert.cs +++ b/src/Inshapardaz.Api.Tests/Asserts/LibraryAssert.cs @@ -6,7 +6,6 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views; using Inshapardaz.Domain.Adapters; -using System; using System.Data; using System.Net.Http; using System.Threading; diff --git a/src/Inshapardaz.Api.Tests/Asserts/PeriodicalAssert.cs b/src/Inshapardaz.Api.Tests/Asserts/PeriodicalAssert.cs index 2f54073a..dece19e1 100644 --- a/src/Inshapardaz.Api.Tests/Asserts/PeriodicalAssert.cs +++ b/src/Inshapardaz.Api.Tests/Asserts/PeriodicalAssert.cs @@ -5,7 +5,6 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Repositories; -using System; using System.Collections.Generic; using System.Data; using System.Linq; diff --git a/src/Inshapardaz.Api.Tests/DataBuilders/AccountDataBuilder.cs b/src/Inshapardaz.Api.Tests/DataBuilders/AccountDataBuilder.cs index d621a2d0..ac757d7b 100644 --- a/src/Inshapardaz.Api.Tests/DataBuilders/AccountDataBuilder.cs +++ b/src/Inshapardaz.Api.Tests/DataBuilders/AccountDataBuilder.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Data; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; using AutoFixture; diff --git a/src/Inshapardaz.Api.Tests/DataBuilders/ArticlesDataBuilder.cs b/src/Inshapardaz.Api.Tests/DataBuilders/ArticlesDataBuilder.cs new file mode 100644 index 00000000..b2350a17 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/DataBuilders/ArticlesDataBuilder.cs @@ -0,0 +1,349 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using AutoFixture; +using Inshapardaz.Domain.Repositories; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Fakes; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Database.SqlServer; +using RandomData = Inshapardaz.Api.Tests.Helpers.RandomData; +using Inshapardaz.Domain.Models; +using Bogus; +using Inshapardaz.Domain.Models.Library; + +namespace Inshapardaz.Api.Tests.DataBuilders +{ + + public class ArticlesDataBuilder + { + private class AccountItemCountSpec + { + public int AccountId { get; set; } + public int? Count { get; set; } + } + + private readonly IDbConnection _connection; + private readonly AuthorsDataBuilder _authorBuilder; + private readonly CategoriesDataBuilder _categoriesBuilder; + private readonly FakeFileStorage _fileStorage; + + private List _articles = new(); + private readonly List _files = new(); + private List _authors = new(); + + private bool _hasImage = true; + private bool? _isPublic = null; + private int _categoriesCount, _contentCount; + private string _contentMimeType; + + public AuthorDto Author { get; set; } + private List _categories = new(); + private int _libraryId; + private List _favoriteArticlesSpec = new(); + private List _readArticlesSpec = new(); + private List _contents = new(); + private string _language = null; + private int _numberOfAuthors; + private List _recentArticles = new(); + private List _favoriteArticles = new(); + private int? _assignedWriterId, _assignedReviewerId; + private EditingStatus? _status; + private ArticleType? _articleType; + + public IEnumerable Authors => _authors; + public IEnumerable Articles => _articles; + public IEnumerable FavoriteArticles => _favoriteArticles; + public IEnumerable Contents => _contents; + public IEnumerable RecentReads => _recentArticles; + + public ArticlesDataBuilder(IProvideConnection connectionProvider, IFileStorage fileStorage, + AuthorsDataBuilder authorBuilder, CategoriesDataBuilder categoriesBuilder) + { + _connection = connectionProvider.GetConnection(); + _fileStorage = fileStorage as FakeFileStorage; + _authorBuilder = authorBuilder; + _categoriesBuilder = categoriesBuilder; + } + + internal ArticlesDataBuilder IsPublic(bool isPublic = true) + { + _isPublic = isPublic; + return this; + } + + public ArticlesDataBuilder WithCategories(int categoriesCount) + { + _categoriesCount = categoriesCount; + return this; + } + + public ArticlesDataBuilder WithCategory(CategoryDto category) + { + _categories.Add(category); + return this; + } + + public ArticlesDataBuilder WithCategories(IEnumerable categories) + { + _categories = categories.ToList(); + return this; + } + + public ArticlesDataBuilder WithNoImage() + { + _hasImage = false; + return this; + } + + public ArticlesDataBuilder WithAuthor(AuthorDto author) + { + Author = author; + return this; + } + + public ArticlesDataBuilder WithAuthors(IEnumerable authors) + { + _authors = authors.ToList(); + return this; + } + + public ArticlesDataBuilder WithAuthors(int numberOfAuthors) + { + _numberOfAuthors = numberOfAuthors; + return this; + } + + internal ArticlesDataBuilder WithLibrary(int libraryId) + { + _libraryId = libraryId; + return this; + } + + public ArticlesDataBuilder WithStatus(EditingStatus statuses) + { + _status = statuses; + return this; + } + + internal ArticlesDataBuilder WithContentLanguage(string language) + { + _language = language; + return this; + } + + public ArticlesDataBuilder AddToFavorites(int accountId, int? countOfArticlesToAddToFavorite = null) + { + _favoriteArticlesSpec.Add(new AccountItemCountSpec() { AccountId = accountId, Count = countOfArticlesToAddToFavorite }); + return this; + } + + public ArticlesDataBuilder AddToRecentReads(int accountId, int? countOfArticlesToAddToRecent = null) + { + _readArticlesSpec.Add(new AccountItemCountSpec() { AccountId = accountId, Count = countOfArticlesToAddToRecent }); + + return this; + } + + public ArticlesDataBuilder WithContent() + { + _contentCount = 1; + return this; + } + + public ArticlesDataBuilder WithContents(int contentCount, string mimeType = null) + { + _contentCount = contentCount; + _contentMimeType = mimeType; + return this; + } + + + internal ArticlesDataBuilder WithType(ArticleType type) + { + _articleType = type; + return this; + } + + internal ArticlesDataBuilder WithWtiterAssignment(int accountId) + { + _assignedWriterId = accountId; + return this; + } + + internal ArticlesDataBuilder WithReviewerAssignment(int accountId) + { + _assignedReviewerId = accountId; + return this; + } + + internal ArticleView BuildView() + { + var fixture = new Fixture(); + + if (Author == null) + { + Author = _authorBuilder.WithLibrary(_libraryId).Build(1).Single(); + } + + return fixture.Build() + .With(a => a.Authors, new List { new AuthorView { Id = Author.Id } }) + .With(a => a.Categories, _categories.Any() ? _categories.Select(c => c.ToView()) : new CategoryView[0]) + .Create(); + } + + public ArticleDto Build() + { + return Build(1).Single(); + } + + public IEnumerable Build(int numberOfArticles) + { + var fixture = new Fixture(); + + if (Author == null && !_authors.Any()) + { + _authors = _authorBuilder.WithLibrary(_libraryId) + .Build(_numberOfAuthors > 0 ? _numberOfAuthors : numberOfArticles) + .ToList(); + } + + Func isPublic = () => _isPublic ?? RandomData.Bool; + + var articles = fixture.Build() + .With(b => b.LibraryId, _libraryId) + .With(b => b.ImageId, () => _hasImage ? RandomData.Number : 0) + .With(b => b.IsPublic, isPublic) + .With(b => b.LastModified, () => RandomData.Date) + .With(b => b.Status, _status ?? EditingStatus.Completed) + .With(b => b.Type, _articleType ?? new Faker().PickRandom(ArticleType.Writing, ArticleType.Poetry)) + .With(b => b.WriterAccountId, _assignedWriterId) + .With(b => b.WriterAssignTimeStamp, _assignedWriterId.HasValue ? DateTime.Now : null) + .With(b => b.ReviewerAccountId, _assignedReviewerId) + .With(b => b.ReviewerAssignTimeStamp, _assignedReviewerId.HasValue ? DateTime.Now : null) + .CreateMany(numberOfArticles) + .ToList(); + + IEnumerable categories; + + if (_categoriesCount > 0 && !_categories.Any()) + { + categories = _categoriesBuilder + .WithLibrary(_libraryId) + .Build(_categoriesCount); + } + else + { + categories = _categories; + } + + foreach (var article in articles) + { + FileDto articleImage = null; + if (_hasImage) + { + articleImage = fixture.Build() + .With(a => a.FilePath, RandomData.BlobUrl) + .With(a => a.IsPublic, true) + .Create(); + _connection.AddFile(articleImage); + + _files.Add(articleImage); + _fileStorage.SetupFileContents(articleImage.FilePath, RandomData.Bytes); + _connection.AddFile(articleImage); + + article.ImageId = articleImage.Id; + } + else + { + article.ImageId = null; + } + + _connection.AddArticle(article); + + if (Author != null) + { + _connection.AddArticleAuthor(article.Id, Author.Id); + } + else + { + foreach (var author in _authors) + { + _connection.AddArticleAuthor(article.Id, author.Id); + } + } + + if (categories != null && categories.Any()) + { + _connection.AddArticleToCategories(article.Id, categories); + } + + if (_contentCount > 0) + { + var contents = Enumerable.Range(1, _contentCount).Select(f => new ArticleContentDto + { + ArticleId = article.Id, + Language = _language ?? RandomData.NextLocale(), + Text = RandomData.Words(100), + Layout = RandomData.String + }).ToList(); + contents.ForEach(f => { + f.Id = _connection.AddArticleContents(f); + }); + _contents.AddRange(contents); + } + + + + } + + if (_favoriteArticlesSpec.Any()) + { + foreach (var f in _favoriteArticlesSpec) + { + var articlessToAddToFavorite = f.Count.HasValue ? articles.PickRandom(f.Count.Value) : articles; + foreach (var fav in articlessToAddToFavorite) + { + if (f.AccountId != 0) + { + var favorite = new FavoriteArticleDto { AccountId = f.AccountId, ArticleId = fav.Id, LibraryId = _libraryId, DateAdded = RandomData.Date }; + _connection.AddArticleToFavorites(_libraryId, favorite.ArticleId, favorite.AccountId, favorite.DateAdded); + + _favoriteArticles.Add(favorite); + } + } + } + } + + if (_readArticlesSpec.Any()) + { + foreach (var r in _readArticlesSpec) + { + var articlesToAddToRecent = r.Count.HasValue ? articles.PickRandom(r.Count.Value) : articles; + foreach (var recentArticle in articlesToAddToRecent) + { + if (r.AccountId != 0) + { + RecentArticleDto recent = new RecentArticleDto { LibraryId = _libraryId, ArticleId = recentArticle.Id, AccountId = r.AccountId, DateRead = RandomData.Date }; + _connection.AddArticleToRecentReads(recent); + _recentArticles.Add(recent); + } + } + } + } + + _articles.AddRange(articles); + return _articles; + } + + public void CleanUp() + { + _connection.DeleteArticles(_articles); + _connection.DeleteFiles(_files); + _authorBuilder.CleanUp(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/DataBuilders/AuthorsDataBuilder.cs b/src/Inshapardaz.Api.Tests/DataBuilders/AuthorsDataBuilder.cs index fa969f3b..2c9cf162 100644 --- a/src/Inshapardaz.Api.Tests/DataBuilders/AuthorsDataBuilder.cs +++ b/src/Inshapardaz.Api.Tests/DataBuilders/AuthorsDataBuilder.cs @@ -8,6 +8,7 @@ using Inshapardaz.Api.Tests.Fakes; using Inshapardaz.Database.SqlServer; using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; namespace Inshapardaz.Api.Tests.DataBuilders { @@ -16,12 +17,14 @@ public class AuthorsDataBuilder private List _authors = new List(); private List _books = new List(); private List _files = new List(); + private List _articles = new(); private readonly IDbConnection _connection; private readonly FakeFileStorage _fileStorage; private int _libraryId; private int _bookCount; private bool _withImage = true; private string _namePattern = ""; + private int _articleCount; internal IEnumerable Books => _books; @@ -57,6 +60,13 @@ public AuthorsDataBuilder WithoutImage() return this; } + + internal AuthorsDataBuilder WithArticles(int count) + { + _articleCount = count; + return this; + } + public AuthorDto Build() { return Build(1).Single(); @@ -74,7 +84,7 @@ public IEnumerable Build(int count) if (_withImage) { authorImage = fixture.Build() - .With(a => a.FilePath, Helpers.RandomData.BlobUrl) + .With(a => a.FilePath, RandomData.BlobUrl) .With(a => a.IsPublic, true) .Create(); _connection.AddFile(authorImage); @@ -86,7 +96,6 @@ public IEnumerable Build(int count) var author = fixture.Build() .With(a => a.Name, () => fixture.Create(_namePattern)) - //.With(a => a.Name, Random.Name) .With(a => a.LibraryId, _libraryId) .With(a => a.ImageId, authorImage?.Id) .Create(); @@ -97,7 +106,7 @@ public IEnumerable Build(int count) var books = fixture.Build() .With(b => b.LibraryId, _libraryId) .With(b => b.Language, RandomData.Locale) - .With(b => b.Status, Domain.Models.BookStatuses.Published) + .With(b => b.Status, Domain.Models.StatusType.Published) .Without(b => b.ImageId) .Without(b => b.SeriesId) .CreateMany(_bookCount); @@ -107,6 +116,27 @@ public IEnumerable Build(int count) _books.AddRange(books); + var articles = fixture.Build() + .With(b => b.LibraryId, _libraryId) + .Without(b => b.ImageId) + .With(b => b.IsPublic, true) + .With(b => b.LastModified, RandomData.Date) + .With(b => b.Status, EditingStatus.Completed) + .Without(b => b.WriterAccountId) + .Without(b => b.WriterAssignTimeStamp) + .Without(b => b.ReviewerAccountId) + .Without(b => b.ReviewerAssignTimeStamp) + .CreateMany(_articleCount); + + _connection.AddArticles(articles); + + _articles.AddRange(articles); + + foreach(var article in articles) + { + _connection.AddArticleAuthor(article.Id, author.Id); + } + authors.Add(author); } @@ -118,5 +148,6 @@ public void CleanUp() _connection.DeleteAuthors(_authors); _connection.DeleteFiles(_files); } + } } diff --git a/src/Inshapardaz.Api.Tests/DataBuilders/BooksDataBuilder.cs b/src/Inshapardaz.Api.Tests/DataBuilders/BooksDataBuilder.cs index 41dbdefd..9adf623b 100644 --- a/src/Inshapardaz.Api.Tests/DataBuilders/BooksDataBuilder.cs +++ b/src/Inshapardaz.Api.Tests/DataBuilders/BooksDataBuilder.cs @@ -15,7 +15,7 @@ namespace Inshapardaz.Api.Tests.DataBuilders { - + public class BooksDataBuilder { private class AccountItemCountSpec @@ -253,7 +253,7 @@ public IEnumerable Build(int numberOfBooks) .With(b => b.SeriesIndex, _hasSeries ? RandomData.Number : (int?)null) .With(b => b.DateAdded, RandomData.Date) .With(b => b.DateUpdated, RandomData.Date) - .With(b => b.Status, Domain.Models.BookStatuses.Published) + .With(b => b.Status, Domain.Models.StatusType.Published) .CreateMany(numberOfBooks) .ToList(); @@ -436,7 +436,7 @@ public IEnumerable Build(int numberOfBooks) { var booksToAddToFavorite = f.Count.HasValue ? _books.PickRandom(f.Count.Value) : _books; if (f.AccountId != 0) - _connection.AddBooksToFavorites(_libraryId, booksToAddToFavorite.Select(b => b.Id), f.AccountId); + _connection.AddBooksToFavorites(_libraryId, booksToAddToFavorite.Select(b => b.Id), f.AccountId); } } @@ -454,7 +454,7 @@ public IEnumerable Build(int numberOfBooks) _recentBooks.Add(recent); } } - } + } } return _books; diff --git a/src/Inshapardaz.Api.Tests/DataBuilders/CategoriesDataBuilder.cs b/src/Inshapardaz.Api.Tests/DataBuilders/CategoriesDataBuilder.cs index eb5b9c6a..e585016a 100644 --- a/src/Inshapardaz.Api.Tests/DataBuilders/CategoriesDataBuilder.cs +++ b/src/Inshapardaz.Api.Tests/DataBuilders/CategoriesDataBuilder.cs @@ -68,7 +68,7 @@ public IEnumerable Build(int count) _books = fixture.Build() .With(b => b.LibraryId, _libraryId) - .With(b => b.Language, RandomData.Locale) + .With(b => b.Language, RandomData.Locale) .Without(b => b.ImageId) .Without(b => b.SeriesId) .CreateMany(_bookCount); diff --git a/src/Inshapardaz.Api.Tests/DataBuilders/IssueDataBuilder.cs b/src/Inshapardaz.Api.Tests/DataBuilders/IssueDataBuilder.cs index bc994b1a..b9c9551e 100644 --- a/src/Inshapardaz.Api.Tests/DataBuilders/IssueDataBuilder.cs +++ b/src/Inshapardaz.Api.Tests/DataBuilders/IssueDataBuilder.cs @@ -32,10 +32,10 @@ private class AccountItemCountSpec private readonly List _files = new List(); private List _pages = new List(); private List _authors = new List(); - private List _articles = new List(); + private List _articles = new List(); internal IEnumerable GetPages(int issuesId) => _pages.Where(p => p.IssueId == issuesId); - internal IEnumerable GetArticles(int issuesId) => _articles.Where(a => a.IssueId == issuesId); + internal IEnumerable GetArticles(int issuesId) => _articles.Where(a => a.IssueId == issuesId); private bool _hasImage = true; private bool? _isPublic = null; @@ -49,7 +49,7 @@ private class AccountItemCountSpec private List _favoriteBooks = new List(); private List _readBooks = new List(); private List _contents = new List(); - private List _articleContents = new List(); + private List _articleContents = new List(); private List _recentBooks = new List(); private int _pageCount; private int? _periodicalId; @@ -63,7 +63,7 @@ private class AccountItemCountSpec public IEnumerable Issues => _issues; public IEnumerable Contents => _contents; - public IEnumerable ArticleContents => _articleContents; + public IEnumerable ArticleContents => _articleContents; public IssueDataBuilder(IProvideConnection connectionProvider, IFileStorage fileStorage, AuthorsDataBuilder authorBuilder) { @@ -379,11 +379,11 @@ public IEnumerable Build(int numberOfIssues) _authors = _authorBuilder.WithLibrary(_libraryId).Build(_numberOfAuthors > 0 ? _numberOfAuthors : 1).ToList(); } - var articles = new List(); + var articles = new List(); for (int i = 0; i < _articleCount; i++) { - var article = fixture.Build() + var article = fixture.Build() .With(p => p.IssueId, issue.Id) .With(p => p.SequenceNumber, i + 1) .With(p => p.WriterAccountId, (int?)null) @@ -392,29 +392,29 @@ public IEnumerable Build(int numberOfIssues) .Create(); articles.Add(article); - _connection.AddArticle(article); + _connection.AddIssueArticle(article); if (Author != null) { - _connection.AddArticleAuthor(article.Id, Author.Id); + _connection.AddIssueArticleAuthor(article.Id, Author.Id); } else { foreach (var author in _authors) { - _connection.AddArticleAuthor(article.Id, author.Id); + _connection.AddIssueArticleAuthor(article.Id, author.Id); } } if (_articleContentCount > 0) { - var articleContent = fixture.Build() + var articleContent = fixture.Build() .With(x => x.ArticleId, article.Id) .With(x => x.Language, () => _articleContentLanguage ?? RandomData.String) .With(x => x.Text, RandomData.String) .CreateMany(_articleContentCount); - _connection.AddArticleContents(articleContent); + _connection.AddIssueArticleContents(articleContent); _articleContents.AddRange(articleContent); } } @@ -451,7 +451,7 @@ public IEnumerable Build(int numberOfIssues) public void CleanUp() { - _connection.DeleteArticles(_articles); + _connection.DeleteIssueArticles(_articles); _connection.DeleteIssuePages(_pages); _connection.DeleteIssues(_issues); _connection.DeleteFiles(_files); diff --git a/src/Inshapardaz.Api.Tests/DataBuilders/LibraryDataBuilder.cs b/src/Inshapardaz.Api.Tests/DataBuilders/LibraryDataBuilder.cs index def49b0e..57c9c4c1 100644 --- a/src/Inshapardaz.Api.Tests/DataBuilders/LibraryDataBuilder.cs +++ b/src/Inshapardaz.Api.Tests/DataBuilders/LibraryDataBuilder.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Data; using System.Linq; diff --git a/src/Inshapardaz.Api.Tests/DataBuilders/PeriodicalsDataBuilder.cs b/src/Inshapardaz.Api.Tests/DataBuilders/PeriodicalsDataBuilder.cs index 8ef65309..c8015a0a 100644 --- a/src/Inshapardaz.Api.Tests/DataBuilders/PeriodicalsDataBuilder.cs +++ b/src/Inshapardaz.Api.Tests/DataBuilders/PeriodicalsDataBuilder.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -7,17 +6,15 @@ using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Fakes; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views.Library; using Inshapardaz.Database.SqlServer; using RandomData = Inshapardaz.Api.Tests.Helpers.RandomData; -using Inshapardaz.Domain.Models; using Inshapardaz.Domain.Models.Library; using Bogus; namespace Inshapardaz.Api.Tests.DataBuilders { - + public class PeriodicalsDataBuilder { private readonly IDbConnection _connection; diff --git a/src/Inshapardaz.Api.Tests/DataHelpers/ArticleDataHelper.cs b/src/Inshapardaz.Api.Tests/DataHelpers/ArticleDataHelper.cs index f49e44e3..5f72d2dd 100644 --- a/src/Inshapardaz.Api.Tests/DataHelpers/ArticleDataHelper.cs +++ b/src/Inshapardaz.Api.Tests/DataHelpers/ArticleDataHelper.cs @@ -10,101 +10,138 @@ namespace Inshapardaz.Api.Tests.DataHelpers { public static class ArticleDataHelper { - public static void AddArticle(this IDbConnection connection, ArticleDto issue) + public static void AddArticle(this IDbConnection connection, ArticleDto article) { - var sql = @"Insert Into Article (Title, IssueId, SequenceNumber, Status, WriterAccountId, WriterAssignTimeStamp, ReviewerAccountId, ReviewerAssignTimeStamp, SeriesName, SeriesIndex) + var sql = @"Insert Into Article (LibraryId, Title, IsPublic, ImageId, Type, Status, WriterAccountId, WriterAssignTimeStamp, ReviewerAccountId, ReviewerAssignTimeStamp, SourceId, SourceType, LastModified) Output Inserted.Id - Values (@Title, @IssueId, @SequenceNumber, @Status, @WriterAccountId, @WriterAssignTimeStamp, @ReviewerAccountId, @ReviewerAssignTimeStamp, @SeriesName, @SeriesIndex)"; - var id = connection.ExecuteScalar(sql, issue); - issue.Id = id; + Values (@LibraryId, @Title, @IsPublic, @ImageId, @Type, @Status, @WriterAccountId, @WriterAssignTimeStamp, @ReviewerAccountId, @ReviewerAssignTimeStamp, @SourceId, @SourceType, @LastModified)"; + var id = connection.ExecuteScalar(sql, article); + article.Id = id; } - public static void AddArticles(this IDbConnection connection, IEnumerable issues) + public static void AddArticles(this IDbConnection connection, IEnumerable articles) { - foreach (var issue in issues) + foreach (var article in articles) { - AddArticle(connection, issue); + AddArticle(connection, article); } } - public static ArticleDto GetArticleById(this IDbConnection connection, int articleId) + public static ArticleDto GetArticleById(this IDbConnection connection, long articleId) { var sql = @"SELECT * FROM Article WHERE Id = @Id"; return connection.QuerySingleOrDefault(sql, new { Id = articleId }); } - public static ArticleDto GetArticlesByIssue(this IDbConnection connection, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber) - { - var sql = @"SELECT a.* FROM Article a - INNER JOIN Issue i on i.Id = a.IssueId - WHERE i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber"; - return connection.QuerySingleOrDefault(sql, new { - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber - }); - } - public static void DeleteArticles(this IDbConnection connection, IEnumerable articles) { var sql = "Delete From Article Where Id IN @Ids"; connection.Execute(sql, new { Ids = articles.Select(f => f.Id) }); } - public static IEnumerable GetArticlesByIssue(this IDbConnection connection, int issueId) + public static void AddArticleAuthor(this IDbConnection connection, long articleId, int authorId) { - var sql = @"SELECT a.* FROM Article a - INNER JOIN Issue i on i.Id = a.IssueId - WHERE i.Id = @IssueId"; - return connection.Query(sql, new { IssueId = issueId }); + var sql = "INSERT INTO ArticleAuthor VALUES (@ArticleId, @AuthorId)"; + connection.Execute(sql, new { ArticleId = articleId, AuthorId = authorId }); } - public static void AddArticleAuthor(this IDbConnection connection, int issueId, int authorId) - { - var sql = "INSERT INTO ArticleAuthor VALUES (@IssueId, @AuthorId)"; - connection.Execute(sql, new { IssueId = issueId, AuthorId = authorId }); - } - - public static ArticleContentDto GetArticleContentById(this IDbConnection connection, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language) + public static ArticleContentDto GetArticleContent(this IDbConnection connection, long articleId, string language) { return connection.QuerySingleOrDefault(@"select ac.* FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - INNER JOIN Periodical p ON p.Id = i.Periodicalid LEFT OUTER JOIN ArticleContent ac ON a.Id = ac.ArticleId - WHERE i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber - AND ac.Language = @Language", - new { - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber, + WHERE a.Id = @ArticleId + AND ac.Language = @Language", + new + { + ArticleId = articleId, Language = language }); } - public static IEnumerable GetContentByArticle(this IDbConnection connection, int articleId) + public static IEnumerable GetArticleContents(this IDbConnection connection, long articleId) + { + return connection.Query(@"select * + FROM ArticleContent + WHERE ArticleId = @Id", + new + { + Id = articleId + }); + } + + public static IEnumerable GetContentByArticle(this IDbConnection connection, long articleId) + { + return connection.Query("Select * From ArticleContent Where ArticleId = @Id", new { Id = articleId }); + } + + public static int AddArticleContents(this IDbConnection connection, ArticleContentDto content) + { + var sql = @"INSERT INTO ArticleContent (ArticleId, Language, Text, Layout) + OUTPUT Inserted.ID + VALUES (@ArticleId, @Language, @Text, @Layout)"; + return connection.ExecuteScalar(sql, content); + } + public static void AddArticlesToFavorites(this IDbConnection connection, int libraryId, IEnumerable articleIds, int accountId) + { + articleIds.ForEach(id => connection.AddArticleToFavorites(libraryId, id, accountId)); + } + + public static void AddArticleToFavorites(this IDbConnection connection, int libraryId, long articleId, int accountId, DateTime? timestamp = null) + { + var sql = @"Insert into ArticleFavorite (LibraryId, ArticleId, AccountId) + Values (@LibraryId, @ArticleId, @AccountId)"; + connection.ExecuteScalar(sql, new { LibraryId = libraryId, ArticleId = articleId, AccountId = accountId }); + } + + + public static bool DoesArticleExistsInFavorites(this IDbConnection connection, long articleId, int accountId) => + connection.QuerySingle(@"Select Count(1) From ArticleFavorite Where ArticleId = @ArticleId And AccountId = @AccountId", new + { + ArticleId = articleId, + AccountId = accountId + }); + + + public static void AddArticlesToRecentReads(this IDbConnection connection, int libraryId, IEnumerable articleIds, int accountId) + { + articleIds.ForEach(id => connection.AddArticleToRecentReads(new RecentArticleDto { LibraryId = libraryId, ArticleId = id, AccountId = accountId, DateRead = DateTime.UtcNow })); + } + + public static void AddArticleToRecentReads(this IDbConnection connection, RecentArticleDto dto) + { + var sql = @"Insert into ArticleRead (LibraryId, ArticleId, AccountId, DateRead) + Values (@LibraryId, @ArticleId, @AccountId, @DateRead)"; + connection.ExecuteScalar(sql, dto); + } + + + public static bool DoesArticleExistsInRecent(this IDbConnection connection, long articleId) => + connection.QuerySingle(@"Select Count(1) From ArticleRead Where ArticleId = @ArticleId", new + { + ArticleId = articleId + }); + + public static string GetArticleImageUrl(this IDbConnection connection, long articleId) { - return connection.Query("Select * From ArticleContent Where ArticleId = @Id", new { Id = articleId }); + var sql = @"SELECT f.FilePath FROM [File] f + INNER JOIN Article a ON f.Id = a.ImageId + WHERE a.Id = @Id"; + return connection.QuerySingleOrDefault(sql, new { Id = articleId }); } - public static void AddArticleContents(this IDbConnection connection, IEnumerable contents) + public static FileDto GetArticleImage(this IDbConnection connection, long articleId) { - var sql = "INSERT INTO ArticleContent (ArticleId, Language, Text) VALUES (@ArticleId, @Language, @Text)"; - connection.Execute(sql, contents); + var sql = @"Select f.* from [File] f + Inner Join Article a ON f.Id = a.ImageId + Where a.Id = @Id"; + return connection.QuerySingleOrDefault(sql, new { Id = articleId }); } - public static void AddArticleContents(this IDbConnection connection, ArticleContentDto content) + public static int GetArticleCountByAuthor(this IDbConnection connection, int id) { - var sql = "INSERT INTO ArticleContent (ArticleId, Language, Text) VALUES (@ArticleId, @Language, @Text)"; - connection.Execute(sql, content); + var sql = @"SELECT Count(*) FROM ArticleAuthor WHERE AuthorId = @Id"; + return connection.ExecuteScalar(sql, new { Id = id }); } } diff --git a/src/Inshapardaz.Api.Tests/DataHelpers/AuthorDataHelper.cs b/src/Inshapardaz.Api.Tests/DataHelpers/AuthorDataHelper.cs index 76e4aa10..e7100158 100644 --- a/src/Inshapardaz.Api.Tests/DataHelpers/AuthorDataHelper.cs +++ b/src/Inshapardaz.Api.Tests/DataHelpers/AuthorDataHelper.cs @@ -62,5 +62,13 @@ public static IEnumerable GetAuthorsByBook(this IDbConnection connect WHERE ba.BookId = @Id"; return connection.Query(query, new { Id = bookId }); } + + public static IEnumerable GetAuthorsByArticle(this IDbConnection connection, long articleId) + { + var query = @"Select a.* From ArticleAuthor + INNER JOIN Author a ON a.Id = ArticleAuthor.AuthorId + WHERE ArticleAuthor.ArticleId = @Id"; + return connection.Query(query, new { Id = articleId }); + } } } diff --git a/src/Inshapardaz.Api.Tests/DataHelpers/BookDataHelper.cs b/src/Inshapardaz.Api.Tests/DataHelpers/BookDataHelper.cs index 0e85c4f5..c66a12e9 100644 --- a/src/Inshapardaz.Api.Tests/DataHelpers/BookDataHelper.cs +++ b/src/Inshapardaz.Api.Tests/DataHelpers/BookDataHelper.cs @@ -75,7 +75,7 @@ public static int GetBookCountByAuthor(this IDbConnection connection, int id) var sql = @"SELECT Count(*) FROM Book b INNER JOIN BookAuthor ba ON ba.BookId = b.Id - WHERE ba.AuthorId = @Id AND b.Status = 0"; + WHERE ba.AuthorId = @Id"; return connection.ExecuteScalar(sql, new { Id = id }); } diff --git a/src/Inshapardaz.Api.Tests/DataHelpers/BookShelfDataHelper.cs b/src/Inshapardaz.Api.Tests/DataHelpers/BookShelfDataHelper.cs index c0b4f137..b79abb6f 100644 --- a/src/Inshapardaz.Api.Tests/DataHelpers/BookShelfDataHelper.cs +++ b/src/Inshapardaz.Api.Tests/DataHelpers/BookShelfDataHelper.cs @@ -1,6 +1,5 @@ using Dapper; using Inshapardaz.Api.Tests.Dto; -using System; using System.Collections.Generic; using System.Data; using System.Linq; diff --git a/src/Inshapardaz.Api.Tests/DataHelpers/CategoryDataHelper.cs b/src/Inshapardaz.Api.Tests/DataHelpers/CategoryDataHelper.cs index 815c3c67..22d7e44c 100644 --- a/src/Inshapardaz.Api.Tests/DataHelpers/CategoryDataHelper.cs +++ b/src/Inshapardaz.Api.Tests/DataHelpers/CategoryDataHelper.cs @@ -54,6 +54,13 @@ public static IEnumerable GetCategoriesByPeriodical(this IDbConnect Where pc.PeriodicalId = @PeriodicalId", new { PeriodicalId = id }); } + public static IEnumerable GetCategoriesByArticle(this IDbConnection connection, long id) + { + return connection.Query(@"Select c.* From Category c + Inner Join ArticleCategory bc ON c.Id = bc.CategoryId + Where bc.ArticleId = @ArticleId ", new { ArticleId = id }); + } + public static void AddBooksToCategory(this IDbConnection connection, IEnumerable books, CategoryDto category) { foreach (var book in books) @@ -89,5 +96,14 @@ public static void AddPeriodicalToCategories(this IDbConnection connection, int new { PeriodicalId = periodicalId, CategoryId = category.Id }); } } + + public static void AddArticleToCategories(this IDbConnection connection, long articleId, IEnumerable categories) + { + foreach (var category in categories) + { + connection.Execute("Insert Into ArticleCategory (ArticleId, CategoryId) Values(@ArticleId, @CategoryId)", + new { ArticleId = articleId, CategoryId = category.Id }); + } + } } } diff --git a/src/Inshapardaz.Api.Tests/DataHelpers/FileDataHelper.cs b/src/Inshapardaz.Api.Tests/DataHelpers/FileDataHelper.cs index 7784aec0..20e9409e 100644 --- a/src/Inshapardaz.Api.Tests/DataHelpers/FileDataHelper.cs +++ b/src/Inshapardaz.Api.Tests/DataHelpers/FileDataHelper.cs @@ -21,10 +21,10 @@ Output Inserted.Id file.Id = id; } - public static void DeleteFiles(this IDbConnection connection, IEnumerable file) + public static void DeleteFiles(this IDbConnection connection, IEnumerable files) { var sql = "Delete From [File] Where Id IN @Ids"; - connection.Execute(sql, new { Ids = file.Select(f => f.Id) }); + connection.Execute(sql, new { Ids = files.Select(f => f.Id) }); } public static FileDto GetFileById(this IDbConnection connection, int fileId) diff --git a/src/Inshapardaz.Api.Tests/DataHelpers/IssueArticleDataHelper.cs b/src/Inshapardaz.Api.Tests/DataHelpers/IssueArticleDataHelper.cs new file mode 100644 index 00000000..7e0a35f9 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/DataHelpers/IssueArticleDataHelper.cs @@ -0,0 +1,131 @@ +using Dapper; +using Inshapardaz.Api.Tests.Dto; +using System.Collections.Generic; +using System.Data; +using System.Linq; + +namespace Inshapardaz.Api.Tests.DataHelpers +{ + public static class IssueArticleDataHelper + { + public static void AddIssueArticle(this IDbConnection connection, IssueArticleDto issue) + { + var sql = @"Insert Into IssueArticle (Title, IssueId, SequenceNumber, Status, WriterAccountId, WriterAssignTimeStamp, ReviewerAccountId, ReviewerAssignTimeStamp, SeriesName, SeriesIndex) + Output Inserted.Id + Values (@Title, @IssueId, @SequenceNumber, @Status, @WriterAccountId, @WriterAssignTimeStamp, @ReviewerAccountId, @ReviewerAssignTimeStamp, @SeriesName, @SeriesIndex)"; + var id = connection.ExecuteScalar(sql, issue); + issue.Id = id; + } + + public static void AddIssueArticles(this IDbConnection connection, IEnumerable issues) + { + foreach (var issue in issues) + { + AddIssueArticle(connection, issue); + } + } + + public static IssueArticleDto GetIssueArticleById(this IDbConnection connection, int articleId) + { + var sql = @"SELECT * FROM IssueArticle WHERE Id = @Id"; + return connection.QuerySingleOrDefault(sql, new { Id = articleId }); + } + + public static IssueArticleDto GetIssueArticleById(this IDbConnection connection, long articleId) + { + var sql = @"SELECT * FROM IssueArticle WHERE Id = @Id"; + return connection.QuerySingleOrDefault(sql, new { Id = articleId }); + } + + public static IssueArticleDto GetIssueArticlesByIssue(this IDbConnection connection, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber) + { + var sql = @"SELECT a.* FROM IssueArticle a + INNER JOIN Issue i on i.Id = a.IssueId + WHERE i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber"; + return connection.QuerySingleOrDefault(sql, new { + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber + }); + } + + public static void DeleteIssueArticles(this IDbConnection connection, IEnumerable articles) + { + var sql = "Delete From IssueArticle Where Id IN @Ids"; + connection.Execute(sql, new { Ids = articles.Select(f => f.Id) }); + } + + public static IEnumerable GetIssueArticlesByIssue(this IDbConnection connection, int issueId) + { + var sql = @"SELECT a.* FROM IssueArticle a + INNER JOIN Issue i on i.Id = a.IssueId + WHERE i.Id = @IssueId"; + return connection.Query(sql, new { IssueId = issueId }); + } + + public static void AddIssueArticleAuthor(this IDbConnection connection, int issueId, int authorId) + { + var sql = "INSERT INTO IssueArticleAuthor VALUES (@IssueId, @AuthorId)"; + connection.Execute(sql, new { IssueId = issueId, AuthorId = authorId }); + } + + public static IssueArticleContentDto GetIssueArticleContent(this IDbConnection connection, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language) + { + return connection.QuerySingleOrDefault(@"select ac.* + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + INNER JOIN Periodical p ON p.Id = i.Periodicalid + LEFT OUTER JOIN IssueArticleContent ac ON a.Id = ac.ArticleId + WHERE i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber + AND ac.Language = @Language", + new { + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber, + Language = language + }); + } + + public static IEnumerable GetIssueArticleContents(this IDbConnection connection, long articleId) + { + return connection.Query(@"select * + FROM IssueArticleContent + WHERE ArticleId = @Id", + new + { + Id = articleId + }); + } + + public static IEnumerable GetContentByIssueArticle(this IDbConnection connection, int articleId) + { + return connection.Query("Select * From IssueArticleContent Where ArticleId = @Id", new { Id = articleId }); + } + + public static IEnumerable GetIssueContentByArticle(this IDbConnection connection, long articleId) + { + return connection.Query("Select * From IssueArticleContent Where ArticleId = @Id", new { Id = articleId }); + } + + public static void AddIssueArticleContents(this IDbConnection connection, IEnumerable contents) + { + var sql = "INSERT INTO IssueArticleContent (ArticleId, Language, Text) VALUES (@ArticleId, @Language, @Text)"; + connection.Execute(sql, contents); + } + + public static void AddIssueArticleContents(this IDbConnection connection, IssueArticleContentDto content) + { + var sql = "INSERT INTO ArticleContent (ArticleId, Language, Text) VALUES (@ArticleId, @Language, @Text)"; + connection.Execute(sql, content); + } + + } +} diff --git a/src/Inshapardaz.Api.Tests/DataHelpers/IssueDataHelper.cs b/src/Inshapardaz.Api.Tests/DataHelpers/IssueDataHelper.cs index 3d7a69ba..207411f4 100644 --- a/src/Inshapardaz.Api.Tests/DataHelpers/IssueDataHelper.cs +++ b/src/Inshapardaz.Api.Tests/DataHelpers/IssueDataHelper.cs @@ -1,7 +1,6 @@ using Dapper; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using System; using System.Collections.Generic; using System.Data; using System.Linq; diff --git a/src/Inshapardaz.Api.Tests/Dto/AccountDto.cs b/src/Inshapardaz.Api.Tests/Dto/AccountDto.cs index 9a4545f6..606954ec 100644 --- a/src/Inshapardaz.Api.Tests/Dto/AccountDto.cs +++ b/src/Inshapardaz.Api.Tests/Dto/AccountDto.cs @@ -1,5 +1,4 @@ -using Inshapardaz.Domain.Models; -using System; +using System; namespace Inshapardaz.Api.Tests.Dto { diff --git a/src/Inshapardaz.Api.Tests/Dto/ArticleDto.cs b/src/Inshapardaz.Api.Tests/Dto/ArticleDto.cs index 3237c4b3..b2c6bff8 100644 --- a/src/Inshapardaz.Api.Tests/Dto/ArticleDto.cs +++ b/src/Inshapardaz.Api.Tests/Dto/ArticleDto.cs @@ -1,4 +1,5 @@ using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; using System; namespace Inshapardaz.Api.Tests.Dto @@ -12,33 +13,35 @@ public ArticleDto() public ArticleDto(ArticleDto source) { Id = source.Id; - IssueId = source.IssueId; Title = source.Title; - SequenceNumber = source.SequenceNumber; - SeriesName = source.SeriesName; - SeriesIndex = source.SeriesIndex; Status = source.Status; WriterAccountId = source.WriterAccountId; - WriterAssignTimestamp = source.WriterAssignTimestamp; + WriterAssignTimeStamp = source.WriterAssignTimeStamp; ReviewerAccountId = source.ReviewerAccountId; - ReviewerAssignTimestamp = source.ReviewerAssignTimestamp; + ReviewerAssignTimeStamp = source.ReviewerAssignTimeStamp; } - public int Id { get; set; } + public long Id { get; set; } - public int IssueId { get; set; } + public int LibraryId { get; set; } + public int? ImageId { get; set; } public string Title { get; set; } + public bool IsPublic{ get; set; } - public int SequenceNumber { get; set; } - public string SeriesName { get; set; } - public int SeriesIndex { get; set; } - + public ArticleType Type { get; set; } public EditingStatus Status { get; set; } public int? WriterAccountId { get; set; } - public DateTime? WriterAssignTimestamp { get; set; } + public DateTime? WriterAssignTimeStamp { get; set; } public int? ReviewerAccountId { get; set; } - public DateTime? ReviewerAssignTimestamp { get; set; } + public DateTime? ReviewerAssignTimeStamp { get; set; } + + public int SourceType { get; set; } + + public int SourceId { get; set; } + + public DateTime LastModified { get; set; } + } @@ -46,10 +49,34 @@ public class ArticleContentDto { public int Id { get; set; } - public int ArticleId { get; set; } + public long ArticleId { get; set; } public string Language { get; set; } public string Text { get; set; } + + public string Layout { get; set; } + } + + public class RecentArticleDto + { + public long ArticleId { get; set; } + + public int AccountId { get; set; } + + public DateTime DateRead { get; set; } + + public int LibraryId { get; set; } + } + + public class FavoriteArticleDto + { + public long ArticleId { get; set; } + + public int AccountId { get; set; } + + public DateTime DateAdded { get; set; } + + public int LibraryId { get; set; } } } diff --git a/src/Inshapardaz.Api.Tests/Dto/BookDto.cs b/src/Inshapardaz.Api.Tests/Dto/BookDto.cs index 32905f43..7df351ad 100644 --- a/src/Inshapardaz.Api.Tests/Dto/BookDto.cs +++ b/src/Inshapardaz.Api.Tests/Dto/BookDto.cs @@ -14,7 +14,7 @@ public class BookDto public bool IsPublic { get; set; } public string Language { get; set; } - public BookStatuses Status { get; set; } + public StatusType Status { get; set; } public int LibraryId { get; set; } @@ -33,5 +33,7 @@ public class BookDto public DateTime DateAdded { get; set; } public DateTime DateUpdated { get; set; } + public string Source { get; internal set; } + public string Publisher { get; internal set; } } } diff --git a/src/Inshapardaz.Api.Tests/Dto/IssueArticleDto.cs b/src/Inshapardaz.Api.Tests/Dto/IssueArticleDto.cs new file mode 100644 index 00000000..f70939f7 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Dto/IssueArticleDto.cs @@ -0,0 +1,55 @@ +using Inshapardaz.Domain.Models; +using System; + +namespace Inshapardaz.Api.Tests.Dto +{ + public class IssueArticleDto + { + public IssueArticleDto() + { + } + + public IssueArticleDto(IssueArticleDto source) + { + Id = source.Id; + IssueId = source.IssueId; + Title = source.Title; + SequenceNumber = source.SequenceNumber; + SeriesName = source.SeriesName; + SeriesIndex = source.SeriesIndex; + Status = source.Status; + WriterAccountId = source.WriterAccountId; + WriterAssignTimeStamp = source.WriterAssignTimeStamp; + ReviewerAccountId = source.ReviewerAccountId; + ReviewerAssignTimeStamp = source.ReviewerAssignTimeStamp; + } + + public int Id { get; set; } + + public int IssueId { get; set; } + + public string Title { get; set; } + + public int SequenceNumber { get; set; } + public string SeriesName { get; set; } + public int SeriesIndex { get; set; } + + public EditingStatus Status { get; set; } + public int? WriterAccountId { get; set; } + public DateTime? WriterAssignTimeStamp { get; set; } + public int? ReviewerAccountId { get; set; } + public DateTime? ReviewerAssignTimeStamp { get; set; } + + } + + public class IssueArticleContentDto + { + public int Id { get; set; } + + public int ArticleId { get; set; } + + public string Language { get; set; } + + public string Text { get; set; } + } +} diff --git a/src/Inshapardaz.Api.Tests/Dto/IssueDto.cs b/src/Inshapardaz.Api.Tests/Dto/IssueDto.cs index 0ce3b228..1b69e92b 100644 --- a/src/Inshapardaz.Api.Tests/Dto/IssueDto.cs +++ b/src/Inshapardaz.Api.Tests/Dto/IssueDto.cs @@ -1,5 +1,4 @@ -using Inshapardaz.Domain.Models; -using System; +using System; namespace Inshapardaz.Api.Tests.Dto { diff --git a/src/Inshapardaz.Api.Tests/Dto/IssueFileDto.cs b/src/Inshapardaz.Api.Tests/Dto/IssueFileDto.cs index 015c7f5b..177db9c0 100644 --- a/src/Inshapardaz.Api.Tests/Dto/IssueFileDto.cs +++ b/src/Inshapardaz.Api.Tests/Dto/IssueFileDto.cs @@ -1,6 +1,4 @@ -using System; - -namespace Inshapardaz.Api.Tests.Dto +namespace Inshapardaz.Api.Tests.Dto { public class IssueFileDto { diff --git a/src/Inshapardaz.Api.Tests/Helpers/HttpExtensions.cs b/src/Inshapardaz.Api.Tests/Helpers/HttpExtensions.cs index 1678d8a9..a81e5297 100644 --- a/src/Inshapardaz.Api.Tests/Helpers/HttpExtensions.cs +++ b/src/Inshapardaz.Api.Tests/Helpers/HttpExtensions.cs @@ -2,7 +2,6 @@ using System.IO; using System.Net.Http; using System.Net.Http.Headers; -using System.Resources; using System.Text; using System.Threading.Tasks; diff --git a/src/Inshapardaz.Api.Tests/Helpers/LinkAssertions.cs b/src/Inshapardaz.Api.Tests/Helpers/LinkAssertions.cs index 033a75dd..d1972e6c 100644 --- a/src/Inshapardaz.Api.Tests/Helpers/LinkAssertions.cs +++ b/src/Inshapardaz.Api.Tests/Helpers/LinkAssertions.cs @@ -45,7 +45,7 @@ public static LinkView ShouldGetMatching(this LinkView link, string regEx) public static LinkView EndingWith(this LinkView link, string endingWith) { Uri uri = new Uri(link.Href); - uri.AbsolutePath.Should().EndWith(endingWith, $"Link {uri.AbsoluteUri} reltype '{link.Rel}' not ending with `{endingWith}`."); + uri.AbsolutePath.Should().EndWith(endingWith, $"Link {uri.AbsolutePath} reltype '{link.Rel}' not ending with `{endingWith}`."); return link; } @@ -61,6 +61,7 @@ public static LinkView ShouldPut(this LinkView link, string url) public static LinkView ShouldPost(this LinkView link, string url) { + url.Should().NotBeNull(); Assert.That(link.Method.ToLower(), Is.EqualTo("post"), $"Link with reltype '{link.Rel}' should have method 'POST' but found '{link.Method}'"); Uri uri = new Uri(link.Href); Assert.That(uri.AbsolutePath.ToLower(), Is.EqualTo(url.ToLower()), $"Link with reltype '{link.Rel}' not matching."); @@ -85,7 +86,7 @@ public static LinkView ShouldBeGet(this LinkView link) public static LinkView ShouldBePost(this LinkView link) { - Assert.That(link.Method.ToLower(), Is.EqualTo("post"), $"Link with reltype '{link.Rel}' should have method 'POST' but found '{link.Method}'"); + Assert.That(link?.Method.ToLower(), Is.EqualTo("post"), $"Link with reltype '{link.Rel}' should have method 'POST' but found '{link.Method}'"); return link; } diff --git a/src/Inshapardaz.Api.Tests/Helpers/Random.cs b/src/Inshapardaz.Api.Tests/Helpers/Random.cs index 9ea803e9..bde8acc7 100644 --- a/src/Inshapardaz.Api.Tests/Helpers/Random.cs +++ b/src/Inshapardaz.Api.Tests/Helpers/Random.cs @@ -20,7 +20,6 @@ public static class RandomData public static string BlobUrl => new Faker().Internet.Url(); - public static T PickRandom() => new Faker().PickRandom(); public static T PickRandom(this IEnumerable source) => new Faker().PickRandom(source); diff --git a/src/Inshapardaz.Api.Tests/Inshapardaz.Api.Tests.csproj b/src/Inshapardaz.Api.Tests/Inshapardaz.Api.Tests.csproj index b07fbc4e..d3cee60c 100644 --- a/src/Inshapardaz.Api.Tests/Inshapardaz.Api.Tests.csproj +++ b/src/Inshapardaz.Api.Tests/Inshapardaz.Api.Tests.csproj @@ -20,18 +20,22 @@ - - + + - - + + - - + + + + + + diff --git a/src/Inshapardaz.Api.Tests/Library/AddLibrary/WhenAddingLibraryForUserAlreadyExisting.cs b/src/Inshapardaz.Api.Tests/Library/AddLibrary/WhenAddingLibraryForUserAlreadyExisting.cs index 5cfd9850..ed411233 100644 --- a/src/Inshapardaz.Api.Tests/Library/AddLibrary/WhenAddingLibraryForUserAlreadyExisting.cs +++ b/src/Inshapardaz.Api.Tests/Library/AddLibrary/WhenAddingLibraryForUserAlreadyExisting.cs @@ -4,7 +4,6 @@ using Inshapardaz.Api.Views; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System; using System.Net.Http; using System.Threading.Tasks; diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticle.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticle.cs new file mode 100644 index 00000000..9e38fbca --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticle.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticle +{ + [TestFixture] + public class WhenAddingArticle : TestBase + { + private ArticleAssert _articleAssert; + private HttpResponseMessage _response; + + public WhenAddingArticle() : base(Role.LibraryAdmin) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var author = AuthorBuilder.WithLibrary(LibraryId).Build(); + var article = new ArticleView + { + Title = RandomData.Name, + Authors = new List { new AuthorView { Id = author.Id } }, + }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + _articleAssert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveCreatedResult() + { + _response.ShouldBeCreated(); + } + + [Test] + public void ShouldHaveLocationHeader() + { + _articleAssert.ShouldHaveCorrectLocationHeader(); + } + + [Test] + public void ShouldSaveTheArticle() + { + _articleAssert.ShouldHaveSavedArticle(DatabaseConnection); + } + + [Test] + public void ShouldHaveLinks() + { + _articleAssert.ShouldHaveSelfLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleAsReader.cs new file mode 100644 index 00000000..abdb74c4 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleAsReader.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticle +{ + [TestFixture] + public class WhenAddingArticleAsReader : TestBase + { + private HttpResponseMessage _response; + + public WhenAddingArticleAsReader() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var author = AuthorBuilder.WithLibrary(LibraryId).Build(); + var article = new ArticleView { Title = RandomData.Name, Authors = new List { new AuthorView { Id = author.Id } } }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveForbiddenResult() + { + _response.ShouldBeForbidden(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleAsUnauthorized.cs new file mode 100644 index 00000000..a9dd173d --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleAsUnauthorized.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticle +{ + [TestFixture] + public class WhenAddingArticleAsUnauthorized : TestBase + { + private HttpResponseMessage _response; + + [OneTimeSetUp] + public async Task Setup() + { + var author = AuthorBuilder.WithLibrary(LibraryId).Build(); + var article = new ArticleView { Title = RandomData.Name, Authors = new List { new AuthorView { Id = author.Id } } }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveForbiddenResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithInvalidData.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithInvalidData.cs new file mode 100644 index 00000000..d3d46904 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithInvalidData.cs @@ -0,0 +1,191 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.DataBuilders; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticle +{ + [TestFixture] + public partial class WhenAddingArticleWithInvalidData + { + [TestFixture] + public class AndUsingNonExistingLibrary : TestBase + { + private HttpResponseMessage _response; + + public AndUsingNonExistingLibrary() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var author = AuthorBuilder.WithLibrary(LibraryId).Build(); + var article = new ArticleView { Title = RandomData.Name, Authors = new List { new AuthorView { Id = author.Id } } }; + + _response = await Client.PostObject($"/libraries/{-RandomData.Number}/articles", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnBadRequest() + { + _response.ShouldBeBadRequest(); + } + } + + [TestFixture] + public class AndUsingAuthorFromOtherLibrary : TestBase + { + private HttpResponseMessage _response; + private LibraryDataBuilder _library2Builder; + + public AndUsingAuthorFromOtherLibrary() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _library2Builder = Services.GetService(); + var library2 = _library2Builder.Build(); + var author = AuthorBuilder.WithLibrary(library2.Id).Build(); + + var article = new ArticleView { Title = RandomData.Name, Authors = new List { new AuthorView { Id = author.Id } } }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + } + + [OneTimeTearDown] + public void Teardown() + { + _library2Builder.CleanUp(); + Cleanup(); + } + + [Test] + public void ShouldHaveBadReqestResult() + { + _response.ShouldBeBadRequest(); + } + } + + [TestFixture] + public class AndUsingNonExistingAuthor : TestBase + { + private HttpResponseMessage _response; + + public AndUsingNonExistingAuthor() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = new ArticleView { Title = RandomData.Name, Authors = new List { new AuthorView { Id = -RandomData.Number } } }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveBadReqestResult() + { + _response.ShouldBeBadRequest(); + } + } + + [TestFixture] + public class AndUsingCategoryFromOtherLibrary : TestBase + { + private HttpResponseMessage _response; + private LibraryDataBuilder _library2Builder; + + public AndUsingCategoryFromOtherLibrary() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _library2Builder = Services.GetService(); + var library2 = _library2Builder.Build(); + var author = AuthorBuilder.WithLibrary(Library.Id).Build(); + var categories = CategoryBuilder.WithLibrary(library2.Id).Build(); + + var article = new ArticleView { + Title = RandomData.Name, + Authors = new List { new AuthorView { Id = author.Id } }, + Categories = new List { new CategoryView { Id = categories.Id } } + }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + } + + [OneTimeTearDown] + public void Teardown() + { + _library2Builder.CleanUp(); + Cleanup(); + } + + [Test] + public void ShouldHaveBadReqestResult() + { + _response.ShouldBeBadRequest(); + } + } + + [TestFixture] + public class AndUsingNonExistingCategories : TestBase + { + private HttpResponseMessage _response; + + public AndUsingNonExistingCategories() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var author = AuthorBuilder.WithLibrary(Library.Id).Build(); + + var article = new ArticleView { + Title = RandomData.Name, + Authors = new List { new AuthorView { Id = author.Id } }, + Categories = new List { new CategoryView { Id = -RandomData.Number } } + }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveBadReqestResult() + { + _response.ShouldBeBadRequest(); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithMultipleAuthors.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithMultipleAuthors.cs new file mode 100644 index 00000000..04135de3 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithMultipleAuthors.cs @@ -0,0 +1,81 @@ +using System; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticle +{ + [TestFixture(Role.LibraryAdmin)] + public class WhenAddingArticleWithMultipleAuthors : TestBase + { + private ArticleAssert _articleAssert; + private HttpResponseMessage _response; + + public WhenAddingArticleWithMultipleAuthors(Role role) : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var reviewer = AccountBuilder.As(Role.Writer).Build(); + var writer = AccountBuilder.As(Role.Writer).Build(); + var authors = AuthorBuilder.WithLibrary(LibraryId).Build(3); + var categories = CategoryBuilder.WithLibrary(LibraryId).Build(3); + var article = new ArticleView + { + Title = RandomData.Name, + Authors = authors.PickRandom(2).Select(c => new AuthorView { Id = c.Id }), + Categories = categories.PickRandom(2).Select(c => new CategoryView { Id = c.Id }), + IsPublic = true, + WriterAccountId = writer.Id, + WriterAccountName = writer.Name, + WriterAssignTimeStamp = DateTime.UtcNow, + ReviewerAccountId = reviewer.Id, + ReviewerAccountName = reviewer.Name, + ReviewerAssignTimeStamp = DateTime.UtcNow, + Status = EditingStatus.Available.ToString() + }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + _articleAssert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveCreatedResult() + { + _response.ShouldBeCreated(); + } + + [Test] + public void ShouldHaveLocationHeader() + { + _articleAssert.ShouldHaveCorrectLocationHeader(); + } + + [Test] + public void ShouldSaveArticle() + { + _articleAssert.ShouldHaveSavedArticle(DatabaseConnection); + } + + [Test] + public void ShouldHaveLinks() + { + _articleAssert.ShouldHaveSelfLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithPermissions.cs new file mode 100644 index 00000000..4d9ab98b --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticle/WhenAddingArticleWithPermissions.cs @@ -0,0 +1,84 @@ +using System; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticle +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenAddingArticleWithPermissions : TestBase + { + private ArticleAssert _articleAssert; + private HttpResponseMessage _response; + + public WhenAddingArticleWithPermissions(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var reviewer = AccountBuilder.As(Role.Writer).Build(); + var writer = AccountBuilder.As(Role.Writer).Build(); + var authors = AuthorBuilder.WithLibrary(LibraryId).Build(3); + var categories = CategoryBuilder.WithLibrary(LibraryId).Build(3); + var article = new ArticleView + { + Title = RandomData.Name, + Authors = authors.PickRandom(2).Select(c => new AuthorView { Id = c.Id }), + Categories = categories.PickRandom(2).Select(c => new CategoryView { Id = c.Id }), + IsPublic = true, + WriterAccountId = writer.Id, + WriterAccountName = writer.Name, + WriterAssignTimeStamp = DateTime.UtcNow, + ReviewerAccountId = reviewer.Id, + ReviewerAccountName = reviewer.Name, + ReviewerAssignTimeStamp = DateTime.UtcNow, + Status = EditingStatus.Available.ToString() + }; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles", article); + _articleAssert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveCreatedResult() + { + _response.ShouldBeCreated(); + } + + [Test] + public void ShouldHaveLocationHeader() + { + _articleAssert.ShouldHaveCorrectLocationHeader(); + } + + [Test] + public void ShouldSaveTheArticle() + { + _articleAssert.ShouldHaveSavedArticle(DatabaseConnection); + } + + [Test] + public void ShouldHaveLinks() + { + _articleAssert.ShouldHaveSelfLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentAsReader.cs new file mode 100644 index 00000000..5391afc8 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentAsReader.cs @@ -0,0 +1,48 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticleContent +{ + [TestFixture] + public class WhenAddingArticleContentAsReader + : TestBase + { + private HttpResponseMessage _response; + + public WhenAddingArticleContentAsReader() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/{-RandomData.Number}/contents", + new ArticleContentView + { + Text = RandomData.Text, + Language = "hi", + Layout = RandomData.String + }); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveForbidResult() + { + _response.ShouldBeForbidden(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentAsUnauthorized.cs new file mode 100644 index 00000000..0bbf01ef --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentAsUnauthorized.cs @@ -0,0 +1,42 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticleContent +{ + [TestFixture] + public class WhenAddingArticleContentAsUnauthorized + : TestBase + { + private HttpResponseMessage _response; + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/{article.Id}/contents", + new ArticleContentView + { + Text = RandomData.Text, + Language = "hi", + Layout = RandomData.String + }); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorizedResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentForNonExistingArticle.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentForNonExistingArticle.cs new file mode 100644 index 00000000..0dca2c1a --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentForNonExistingArticle.cs @@ -0,0 +1,46 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticleContent +{ + [TestFixture] + public class WhenAddingArticleContentForNonExistingArticle + : TestBase + { + private HttpResponseMessage _response; + + public WhenAddingArticleContentForNonExistingArticle() + : base(Role.LibraryAdmin) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/{-RandomData.Number}/contents", + new ArticleContentView + { + Text = RandomData.Text, + Language = "hi", + Layout = RandomData.String + }); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveBadRequestResult() + { + _response.ShouldBeBadRequest(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentWithPermission.cs new file mode 100644 index 00000000..cc59bd83 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleContent/WhenAddingArticleContentWithPermission.cs @@ -0,0 +1,73 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticleContent +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenAddingArticleContentWithPermission + : TestBase + { + private HttpResponseMessage _response; + private string _locale, _contents, _layout; + private ArticleContentAssert _assert; + + public WhenAddingArticleContentWithPermission(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _locale = RandomData.Locale; + + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + _contents = RandomData.Text; + _layout = RandomData.String; + + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/{article.Id}/contents", + new ArticleContentView + { + Text = _contents, + Language = _locale, + Layout = _layout + }); + + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveCreatedResult() + { + _response.ShouldBeCreated(); + } + + [Test] + public void ShouldHaveCorrectLink() + { + _assert.ShouldHaveSelfLink() + .ShouldHaveArticleLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink(); + } + + [Test] + public void ShouldHaceCorrectContentSaved() + { + _assert.ShouldHaveSavedArticleContent(DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteAlreadyInFavorite.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteAlreadyInFavorite.cs new file mode 100644 index 00000000..44642635 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteAlreadyInFavorite.cs @@ -0,0 +1,53 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticleToFavorite +{ + [TestFixture] + public class WhenAddArticleToFavoriteAlreadyInFavorite : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + + public WhenAddArticleToFavoriteAlreadyInFavorite() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var articles = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(1) + .AddToFavorites(AccountId) + .Build(2); + + _article = articles.PickRandom(); + + _response = await Client.PostObject($"/libraries/{LibraryId}/favorites/articles/{_article.Id}", new object()); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOKResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldBeAddedToFavorites() + { + ArticleAssert.ShouldBeAddedToFavorite(_article.Id, AccountId, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteAsUnauthorized.cs new file mode 100644 index 00000000..522acb85 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteAsUnauthorized.cs @@ -0,0 +1,35 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticleToFavorite +{ + [TestFixture] + public class WhenAddArticleToFavoriteAsUnauthorized : TestBase + { + private HttpResponseMessage _response; + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + article.Title = RandomData.Name; + + _response = await Client.PostObject($"/libraries/{LibraryId}/favorites/articles/{article.Id}", new object()); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorizedResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteThatDoesNotExist.cs new file mode 100644 index 00000000..79a625b1 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteThatDoesNotExist.cs @@ -0,0 +1,38 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticleToFavorite +{ + [TestFixture] + public class WhenAddArticleToFavoriteThatDoesNotExist : TestBase + { + private HttpResponseMessage _response; + + public WhenAddArticleToFavoriteThatDoesNotExist() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _response = await Client.PostObject($"/libraries/{LibraryId}/favorites/articles/{-RandomData.Number}", new object()); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldBeOk() + { + _response.ShouldBeOk(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteWithPermissions.cs new file mode 100644 index 00000000..d9bf4e83 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AddArticleToFavorite/WhenAddArticleToFavoriteWithPermissions.cs @@ -0,0 +1,54 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.AddArticleToFavorite +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + [TestFixture(Role.Reader)] + public class WhenAddArticleToFavoriteWithPermissions : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + + public WhenAddArticleToFavoriteWithPermissions(Role role) : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var articles = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(1) + .Build(2); + + _article = articles.PickRandom(); + + _response = await Client.PostObject($"/libraries/{LibraryId}/favorites/articles/{_article.Id}", new object()); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOKResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldBeAddedToFavorites() + { + ArticleAssert.ShouldBeAddedToFavorite(_article.Id, AccountId, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToReader.cs new file mode 100644 index 00000000..d289eefd --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToReader.cs @@ -0,0 +1,43 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AssignArticleToUser +{ + [TestFixture] + public class WhenAssignArticleToReader + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + + public WhenAssignArticleToReader() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var reader = AccountBuilder.InLibrary(LibraryId).As(Role.Reader).Build(); + _article = ArticleBuilder.WithLibrary(LibraryId).WithContent().Build(); + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/{_article.Id}/assign", new { AccountId = reader.Id, Type = "write" }); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveBadRequestResult() + { + _response.ShouldBeBadRequest(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToSelfForReviewing.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToSelfForReviewing.cs new file mode 100644 index 00000000..7e78eae6 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToSelfForReviewing.cs @@ -0,0 +1,65 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AssignArticleToUser +{ + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenAssignArticleToSelfForReviewing + : TestBase + { + private HttpResponseMessage _response; + private ArticleAssert _assert; + private ArticleDto _article; + + public WhenAssignArticleToSelfForReviewing(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder + .WithLibrary(LibraryId) + .WithContent() + .WithStatus(EditingStatus.InReview) + .Build(); + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/ {_article.Id}/assign", new { Type = "review" }); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOkResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldAssignArticleToUser() + { + _assert + .ShouldNotBeAssignedForWriting() + .ShouldBeAssignedToUserForReviewing(Account); + } + + [Test] + public void ShouldUpdateDatabaseWithAssignment() + { + _assert + .ShouldBeSavedNoAssignmentForWriting(DatabaseConnection) + .ShouldBeSavedAssignmentForReviewing(DatabaseConnection, Account); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToSelfForWriting.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToSelfForWriting.cs new file mode 100644 index 00000000..b89a2ed1 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToSelfForWriting.cs @@ -0,0 +1,61 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AssignArticleToUser +{ + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenAssignArticleToSelfForWriting + : TestBase + { + private HttpResponseMessage _response; + private ArticleAssert _assert; + private ArticleDto _article; + + public WhenAssignArticleToSelfForWriting(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).WithContent().WithStatus(EditingStatus.Typing).Build(); + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/{_article.Id}/assign", new { Type = "write" }); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOkResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldAssignArticleToUser() + { + _assert + .ShouldBeAssignedToUserForWriting(Account) + .ShouldNotBeAssignedForReviewing(); + } + + [Test] + public void ShouldUpdateDatabaseWithAssignment() + { + _assert + .ShouldBeSavedAssignmentForWriting(DatabaseConnection, Account) + .ShouldBeSavedNoAssignmentForReviewing(DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserAsReader.cs new file mode 100644 index 00000000..91d9f74a --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserAsReader.cs @@ -0,0 +1,42 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AssignArticleToUser +{ + [TestFixture] + public class WhenAssignArticleToUserAsReader + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + + public WhenAssignArticleToUserAsReader() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).WithContent().Build(); + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/{_article.Id}/assign", new { AccountId = AccountId, Type = "write" }); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveForbiddenResult() + { + _response.ShouldBeForbidden(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserAsUnauthorised.cs new file mode 100644 index 00000000..154c1a66 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserAsUnauthorised.cs @@ -0,0 +1,36 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AssignArticleToUser +{ + [TestFixture] + public class WhenAssignArticleToUserAsUnauthorised + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).WithContent().Build(); + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/ {_article.Id}/assign", new { Type = "write" }); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorisedResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserForReviewing.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserForReviewing.cs new file mode 100644 index 00000000..ec6bba35 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserForReviewing.cs @@ -0,0 +1,63 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AssignArticleToUser +{ + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenAssignArticleToUserForReviewing + : TestBase + { + private HttpResponseMessage _response; + private ArticleAssert _assert; + private ArticleDto _article; + private AccountDto _reviewer; + + public WhenAssignArticleToUserForReviewing(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _reviewer = AccountBuilder.InLibrary(LibraryId).As(Role.Writer).Build(); + _article = ArticleBuilder.WithLibrary(LibraryId).WithContent().WithStatus(EditingStatus.InReview).Build(); + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/ {_article.Id}/assign", new { AccountId = _reviewer.Id, Type = "review" }); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOkResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldAssignArticleToUser() + { + _assert + .ShouldNotBeAssignedForWriting() + .ShouldBeAssignedToUserForReviewing(_reviewer); + } + + [Test] + public void ShouldUpdateDatabaseWithAssignment() + { + _assert + .ShouldBeSavedNoAssignmentForWriting(DatabaseConnection) + .ShouldBeSavedAssignmentForReviewing(DatabaseConnection, _reviewer); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserForWriting.cs b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserForWriting.cs new file mode 100644 index 00000000..9b6b237c --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/AssignArticleToUser/WhenAssignArticleToUserForWriting.cs @@ -0,0 +1,63 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.AssignArticleToUser +{ + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenAssignArticleToUserForWriting + : TestBase + { + private HttpResponseMessage _response; + private ArticleAssert _assert; + private ArticleDto _article; + private AccountDto _writer; + + public WhenAssignArticleToUserForWriting(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _writer = AccountBuilder.InLibrary(LibraryId).As(Role.Writer).Build(); + _article = ArticleBuilder.WithLibrary(LibraryId).WithContent().WithStatus(EditingStatus.Typing).Build(); + _response = await Client.PostObject($"/libraries/{LibraryId}/articles/{_article.Id}/assign", new { AccountId = _writer.Id, Type = "write" }); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOkResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldAssignArticleToUser() + { + _assert + .ShouldBeAssignedToUserForWriting(_writer) + .ShouldNotBeAssignedForReviewing(); + } + + [Test] + public void ShouldUpdateDatabaseWithAssignment() + { + _assert + .ShouldBeSavedAssignmentForWriting(DatabaseConnection, _writer) + .ShouldBeSavedNoAssignmentForReviewing(DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleAsAnonymous.cs b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleAsAnonymous.cs new file mode 100644 index 00000000..accdea5e --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleAsAnonymous.cs @@ -0,0 +1,35 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.DeleteArticle +{ + [TestFixture] + public class WhenDeletingArticleAsAnonymous : TestBase + { + private HttpResponseMessage _response; + + [OneTimeSetUp] + public async Task Setup() + { + var articles = ArticleBuilder.WithLibrary(LibraryId).Build(4); + var expected = articles.PickRandom(); + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/articles/{expected.Id}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorizedResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleAsReader.cs new file mode 100644 index 00000000..03340135 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleAsReader.cs @@ -0,0 +1,40 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.DeleteArticle +{ + [TestFixture] + public class WhenDeletingArticleAsReader : TestBase + { + private HttpResponseMessage _response; + + public WhenDeletingArticleAsReader() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var articles = ArticleBuilder.WithLibrary(LibraryId).Build(4); + var expected = articles.First(); + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/articles/{expected.Id}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveForbiddenResult() + { + _response.ShouldBeForbidden(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleWithPermission.cs new file mode 100644 index 00000000..2a3de23c --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingArticleWithPermission.cs @@ -0,0 +1,86 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.DeleteArticle +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenDeletingArticleWithPermission : TestBase + { + private HttpResponseMessage _response; + + private ArticleDto _expected; + + private int _authorId; + + public WhenDeletingArticleWithPermission(Role role) : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _expected = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(1) + .AddToFavorites(AccountId) + .AddToRecentReads(AccountId) + .Build(1) + .Single(); + + _authorId = ArticleBuilder.Authors.First().Id; + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/articles/{_expected.Id}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnNoContent() + { + _response.ShouldBeNoContent(); + } + + [Test] + public void ShouldHaveDeletedArticle() + { + ArticleAssert.ShouldHaveDeletedArticle(_expected.Id, DatabaseConnection); + } + + [Test] + public void ShouldNotHaveDeletedTheAuthor() + { + AuthorAssert.ShouldNotHaveDeletedAuthor(_authorId, DatabaseConnection); + } + + [Test] + public void ShouldNotHaveDeletedTheCategory() + { + var cats = DatabaseConnection.GetCategoriesByArticle(_expected.Id); + cats.ForEach(cat => CategoryAssert.ShouldNotHaveDeletedCategory(LibraryId, cat.Id, DatabaseConnection)); + } + + [Test] + public void ShouldBeDeletedFromTheFavoritesOfAllUsers() + { + ArticleAssert.ShouldNotBeInFavorites(_expected.Id, AccountId, DatabaseConnection); + } + + [Test] + public void ShouldBeDeletedFromTheRecentReadArticles() + { + ArticleAssert.ShouldHaveDeletedArticleFromRecentReads(_expected.Id, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingNonExistinArticle.cs b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingNonExistinArticle.cs new file mode 100644 index 00000000..4f6eb5f5 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticle/WhenDeletingNonExistinArticle.cs @@ -0,0 +1,37 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.DeleteArticle +{ + [TestFixture] + public class WhenDeletingNonExistinArticle : TestBase + { + private HttpResponseMessage _response; + + public WhenDeletingNonExistinArticle() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/articles/{-RandomData.Number}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnNoContent() + { + _response.ShouldBeNoContent(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentThatDoesNotExists.cs b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentThatDoesNotExists.cs new file mode 100644 index 00000000..2f6de158 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentThatDoesNotExists.cs @@ -0,0 +1,41 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.DeleteArticleContent +{ + [TestFixture] + public class WhenDeletingArticleContentThatDoesNotExists + : TestBase + { + private HttpResponseMessage _response; + + public WhenDeletingArticleContentThatDoesNotExists() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/articles/{article.Id}/contents?language={RandomData.Locale}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnNoContentResult() + { + _response.ShouldBeNoContent(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentsAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentsAsReader.cs new file mode 100644 index 00000000..ff003976 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentsAsReader.cs @@ -0,0 +1,42 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.DeleteArticleContent +{ + [TestFixture] + public class WhenDeletingArticleContentsAsReader + : TestBase + { + private HttpResponseMessage _response; + + public WhenDeletingArticleContentsAsReader() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).WithContent().Build(); + var content = ArticleBuilder.Contents.Single(x => x.ArticleId == article.Id); + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/articles/{article.Id}/contents?language={content.Language}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveForbiddenResult() + { + _response.ShouldBeForbidden(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentsAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentsAsUnauthorized.cs new file mode 100644 index 00000000..404fc76d --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticleContentsAsUnauthorized.cs @@ -0,0 +1,36 @@ +using Inshapardaz.Api.Tests.Asserts; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.DeleteArticleContent +{ + [TestFixture] + public class WhenDeletingArticleContentsAsUnauthorized + : TestBase + { + private HttpResponseMessage _response; + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).WithContent().Build(); + var content = ArticleBuilder.Contents.Single(x => x.ArticleId == article.Id); + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/articles/{article.Id}/contents?language={content.Language}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorizedResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticlesContentsWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticlesContentsWithPermission.cs new file mode 100644 index 00000000..e702975d --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/DeleteArticleContent/WhenDeletingArticlesContentsWithPermission.cs @@ -0,0 +1,52 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.DeleteArticleContent +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenDeletingArticlesContentsWithPermission + : TestBase + { + private HttpResponseMessage _response; + private ArticleContentDto _content; + + public WhenDeletingArticlesContentsWithPermission(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == article.Id); + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/articles/{article.Id}/contents?language={_content.Language}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveNoContentResult() + { + _response.ShouldBeNoContent(); + } + + [Test] + public void ShouldHaveDeletedArticleContent() + { + ArticleContentAssert.ShouldHaveDeletedContent(DatabaseConnection, _content); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdAsAnonymous.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdAsAnonymous.cs new file mode 100644 index 00000000..6ed43419 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdAsAnonymous.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleById +{ + [TestFixture] + public class WhenGettingArticleByIdAsAnonymous : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _expected; + private ArticleAssert _assert; + private IEnumerable _categories; + + [OneTimeSetUp] + public async Task Setup() + { + _categories = CategoryBuilder.WithLibrary(LibraryId).Build(2); + var articles = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(_categories) + .WithContent() + .Build(4); + _expected = articles.PickRandom(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_expected.Id}"); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + + [Test] + public void ShouldNotHaveContentsLink() + { + _assert.ShouldNotHaveContentsLink(); + } + + [Test] + public void ShouldHaveImageLink() + { + _assert.ShouldHavePublicImageLink(); + } + + [Test] + public void ShouldNotHaveFavoriteLinks() + { + _assert.ShouldNotHaveAddFavoriteLink() + .ShouldNotHaveRemoveFavoriteLink(); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldBeSameAs(_expected, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdAsReader.cs new file mode 100644 index 00000000..36fd6278 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdAsReader.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleById +{ + [TestFixture] + public class WhenGettingArticleByIdAsReader : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _expected; + private ArticleAssert _assert; + private IEnumerable _categories; + + public WhenGettingArticleByIdAsReader() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _categories = CategoryBuilder.WithLibrary(LibraryId).Build(2); + var articles = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(_categories) + .WithContent() + .Build(4); + _expected = articles.PickRandom(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_expected.Id}"); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + [Test] + public void ShouldHaveImageLink() + { + _assert.ShouldHavePublicImageLink(); + } + + [Test] + public void ShouldHaveContents() + { + _assert.ShouldHaveContents(ArticleBuilder.Contents.Where(x => x.ArticleId == _expected.Id).ToList()); + } + + [Test] + public void ShouldHaveAddFavoriteLinks() + { + _assert.ShouldHaveAddFavoriteLink(); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldBeSameAs(_expected, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdThatDoesNotExist.cs new file mode 100644 index 00000000..a56a474c --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdThatDoesNotExist.cs @@ -0,0 +1,32 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleById +{ + [TestFixture] + public class WhenGettingArticleByIdThatDoesNotExist : TestBase + { + private HttpResponseMessage _response; + + [OneTimeSetUp] + public async Task Setup() + { + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{RandomData.Number}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveNotFoundResult() + { + _response.ShouldBeNotFound(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdWithMultipleAuthrosAndCategories.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdWithMultipleAuthrosAndCategories.cs new file mode 100644 index 00000000..8e9bf30a --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdWithMultipleAuthrosAndCategories.cs @@ -0,0 +1,103 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleById +{ + [TestFixture] + public class WhenGettingArticleByIdWithMultipleAuthrosAndCategories : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _expected; + private ArticleAssert _assert; + private IEnumerable _categories; + private IEnumerable _authors; + + public WhenGettingArticleByIdWithMultipleAuthrosAndCategories() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _authors = AuthorBuilder.WithLibrary(LibraryId).Build(3); + _categories = CategoryBuilder.WithLibrary(LibraryId).Build(3); + var article = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(_categories) + .WithAuthors(_authors) + .WithContent() + .Build(4); + _expected = article.PickRandom(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_expected.Id}"); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + + [Test] + public void ShouldHaveContents() + { + _assert.ShouldHaveContents(ArticleBuilder.Contents.Where(x => x.ArticleId == _expected.Id).ToList()); + } + + [Test] + public void ShouldHaveImageLink() + { + _assert.ShouldHavePublicImageLink(); + } + + [Test] + public void ShouldHaveUpdateLink() + { + _assert.ShouldHaveUpdateLink(); + } + + [Test] + public void ShouldHaveDeleteLink() + { + _assert.ShouldHaveDeleteLink(); + } + + [Test] + public void ShouldHaveAddContentLink() + { + _assert.ShouldHaveAddContentLink(); + } + + [Test] + public void ShouldHaveAddFavoriteLinks() + { + _assert.ShouldHaveAddFavoriteLink(); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldBeSameAs(_expected, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdWithPermission.cs new file mode 100644 index 00000000..7ff98d6f --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleById/WhenGettingArticleByIdWithPermission.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleById +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenGettingArticleByIdWithPermission : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _expected; + private ArticleAssert _assert; + private IEnumerable _categories; + + public WhenGettingArticleByIdWithPermission(Role role) : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _categories = CategoryBuilder.WithLibrary(LibraryId).Build(2); + var articles = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(_categories) + .WithContent() + .Build(4); + _expected = articles.PickRandom(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_expected.Id}"); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + [Test] + public void ShouldHaveContents() + { + _assert.ShouldHaveContents(ArticleBuilder.Contents.Where(x => x.ArticleId == _expected.Id).ToList(), true); + } + + [Test] + public void ShouldHaveImageLink() + { + _assert.ShouldHavePublicImageLink(); + } + + [Test] + public void ShouldHaveUpdateLink() + { + _assert.ShouldHaveUpdateLink(); + } + + [Test] + public void ShouldHaveDeleteLink() + { + _assert.ShouldHaveDeleteLink(); + } + + [Test] + public void ShouldHaveAddContentLink() + { + _assert.ShouldHaveAddContentLink(); + } + + [Test] + public void ShouldHaveAddFavoriteLinks() + { + _assert.ShouldHaveAddFavoriteLink(); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldBeSameAs(_expected, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentLanguageNotExisting.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentLanguageNotExisting.cs new file mode 100644 index 00000000..0138094b --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentLanguageNotExisting.cs @@ -0,0 +1,42 @@ +using Inshapardaz.Api.Tests.Asserts; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Domain.Models; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture] + public class WhenGettingArticleContentLanguageNotExisting + : TestBase + { + private HttpResponseMessage _response; + + public WhenGettingArticleContentLanguageNotExisting() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().WithContent().Build(); + var content = ArticleBuilder.Contents.Single(x => x.ArticleId == article.Id); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{article.Id}/contents?language=babel"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnNotFound() + { + _response.ShouldBeNotFound(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWhenArtcileDoesNotExists.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWhenArtcileDoesNotExists.cs new file mode 100644 index 00000000..d7e32208 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWhenArtcileDoesNotExists.cs @@ -0,0 +1,41 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture] + public class WhenGettingArticleContentWhenArtcileDoesNotExists + : TestBase + { + private HttpResponseMessage _response; + + public WhenGettingArticleContentWhenArtcileDoesNotExists() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{-RandomData.Number}/contents?language={RandomData.Locale}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveNotFoundResult() + { + _response.ShouldBeNotFound(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWhenNoContent.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWhenNoContent.cs new file mode 100644 index 00000000..17624a26 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWhenNoContent.cs @@ -0,0 +1,41 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture] + public class WhenGettingArticleContentWhenNoContent + : TestBase + { + private HttpResponseMessage _response; + + public WhenGettingArticleContentWhenNoContent() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{article.Id}/contents?language={RandomData.Locale}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveNotFoundResult() + { + _response.ShouldBeNotFound(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWithoutLanguage.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWithoutLanguage.cs new file mode 100644 index 00000000..2ecffede --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingArticleContentWithoutLanguage.cs @@ -0,0 +1,77 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture] + public class WhenGettingArticleContentWithoutLanguage + : TestBase + { + private HttpResponseMessage _response; + private ArticleContentAssert _assert; + private ArticleDto _article; + private ArticleContentDto _content; + + public WhenGettingArticleContentWithoutLanguage() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).WithContent().WithContentLanguage(Library.Language).Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_article.Id}/contents"); + _assert = new ArticleContentAssert(_response, Library); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + [Test] + public void ShouldHaveArticleLink() + { + _assert.ShouldHaveArticleLink(); + } + + [Test] + public void ShouldReturnCorrectLanguage() + { + _assert.ShouldHaveDefaultLibraryLanguage(); + } + + [Test] + public void ShouldHaveTextReturened() + { + _assert.ShouldHaveText(_content.Text); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldMatch(_content, _article); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentAsReader.cs new file mode 100644 index 00000000..e1721e86 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentAsReader.cs @@ -0,0 +1,71 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Domain.Models; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture] + public class WhenGettingPrivateArticleContentAsReader + : TestBase + { + private HttpResponseMessage _response; + private ArticleContentAssert _assert; + private ArticleDto _article; + private ArticleContentDto _content; + + public WhenGettingPrivateArticleContentAsReader() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic(false).WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_article.Id}/contents?language={_content.Language}"); + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + [Test] + public void ShouldHaveArticleLink() + { + _assert.ShouldHaveArticleLink(); + } + + [Test] + public void ShouldHaveTextReturened() + { + _assert.ShouldHaveText(_content.Text); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldMatch(_content, _article); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentAsUnauthorised.cs new file mode 100644 index 00000000..d5edf893 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentAsUnauthorised.cs @@ -0,0 +1,38 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture] + public class WhenGettingPrivateArticleContentAsUnauthorised + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic(false).WithContent().Build(); + var content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_article.Id}/contents?language={content.Language}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnUnathorised() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentWithPermission.cs new file mode 100644 index 00000000..054bf524 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPrivateArticleContentWithPermission.cs @@ -0,0 +1,80 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenGettingPrivateArticleContentWithPermission + : TestBase + { + private HttpResponseMessage _response; + private ArticleContentAssert _assert; + private ArticleDto _article; + private ArticleContentDto _content; + + public WhenGettingPrivateArticleContentWithPermission(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic(false).WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_article.Id}/contents?language={_content.Language}"); + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + [Test] + public void ShouldHaveArticleLink() + { + _assert.ShouldHaveArticleLink(); + } + + [Test] + public void ShouldHaveTextReturened() + { + _assert.ShouldHaveText(_content.Text); + } + + [Test] + public void ShouldHaveEditLinks() + { + _assert.ShouldHaveUpdateLink(); + _assert.ShouldHaveDeleteLink(); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldMatch(_content, _article); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentAsReader.cs new file mode 100644 index 00000000..5f955b39 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentAsReader.cs @@ -0,0 +1,71 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture] + public class WhenGettingPublicArticleContentAsReader + : TestBase + { + private HttpResponseMessage _response; + private ArticleContentAssert _assert; + private ArticleDto _article; + private ArticleContentDto _content; + + public WhenGettingPublicArticleContentAsReader() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_article.Id}/contents?language={_content.Language}"); + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + [Test] + public void ShouldHaveArticleLink() + { + _assert.ShouldHaveArticleLink(); + } + + [Test] + public void ShouldHaveTextReturened() + { + _assert.ShouldHaveText(_content.Text); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldMatch(_content, _article); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentAsUnauthorised.cs new file mode 100644 index 00000000..b8673e85 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentAsUnauthorised.cs @@ -0,0 +1,41 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture] + public class WhenGettingPublicArticleContentAsUnauthorised + : TestBase + { + private HttpResponseMessage _response; + private ArticleContentAssert _assert; + private ArticleDto _article; + private ArticleContentDto _content; + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_article.Id}/contents?language={_content.Language}"); + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnUnauthorised() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentWithPermission.cs new file mode 100644 index 00000000..8aca398b --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticleContent/WhenGettingPublicArticleContentWithPermission.cs @@ -0,0 +1,83 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Security.Claims; +using System.Threading.Tasks; +using Inshapardaz.Domain.Models; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticleContent +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenGettingPublicArticleContentWithPermission + : TestBase + { + private HttpResponseMessage _response; + private ArticleContentAssert _assert; + private ArticleDto _article; + private ArticleContentDto _content; + private ClaimsPrincipal _claim; + + public WhenGettingPublicArticleContentWithPermission(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles/{_article.Id}/contents?language={_content.Language}"); + + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink(); + } + + [Test] + public void ShouldHaveArticleLink() + { + _assert.ShouldHaveArticleLink(); + } + + [Test] + public void ShouldHaveEditLinks() + { + _assert.ShouldHaveUpdateLink(); + _assert.ShouldHaveDeleteLink(); + } + + [Test] + public void ShouldHaveTextReturened() + { + _assert.ShouldHaveText(_content.Text); + } + + [Test] + public void ShouldReturnCorrectArticleData() + { + _assert.ShouldMatch(_content, _article); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesAsAnonymous.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesAsAnonymous.cs new file mode 100644 index 00000000..798f365c --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesAsAnonymous.cs @@ -0,0 +1,102 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Views.Library; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesAsAnonymous : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + private IEnumerable _categories; + + + [OneTimeSetUp] + public async Task Setup() + { + _categories = CategoryBuilder.WithLibrary(LibraryId).Build(2); + + ArticleBuilder.WithLibrary(LibraryId) + .IsPublic() + .WithCategories(_categories) + .WithContents(2) + .Build(4); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles"); + } + + [Test] + public void ShouldNotHaveCreateLink() + { + _assert.ShouldNotHaveCreateLink(); + } + + [Test] + public void ShouldNotHaveNavigationLinks() + { + _assert.ShouldNotHaveNextLink(); + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldHaveCorrectPagination() + { + _assert.ShouldHavePageCount(1) + .ShouldHavePageSize(10) + .ShouldHavePage(1) + .ShouldHaveTotalCount(4); + } + + [Test] + public void ShouldReturnExpectedArticle() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldBeSameCategories(_categories) + .ShouldHavePublicImageLink() + .ShouldNotHaveAddFavoriteLink() + .ShouldNotHaveRemoveFavoriteLink() + .ShouldHaveContents( + ArticleBuilder.Contents.Where(c => c.ArticleId == actual.Id).ToList(), + false) + .ShouldBeSameAs(expected, DatabaseConnection); + }; + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesAsReader.cs new file mode 100644 index 00000000..21573685 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesAsReader.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesAsReader : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + private IEnumerable _categories; + + public WhenGettingArticlesAsReader() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _categories = CategoryBuilder.WithLibrary(LibraryId).Build(2); + + ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(_categories) + .WithContents(2) + .Build(4); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles"); + } + + [Test] + public void ShouldNotHaveCreateLink() + { + _assert.ShouldNotHaveCreateLink(); + } + + [Test] + public void ShouldNotHaveNavigationLinks() + { + _assert.ShouldNotHaveNextLink(); + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldHaveCorrectPagination() + { + _assert.ShouldHavePageCount(1) + .ShouldHavePageSize(10) + .ShouldHavePage(1) + .ShouldHaveTotalCount(4); + } + + [Test] + public void ShouldReturnExpectedArticle() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldBeSameCategories(_categories) + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldHaveContents( + ArticleBuilder.Contents.Where(c => c.ArticleId == actual.Id).ToList(), + false) + .ShouldBeSameAs(expected, DatabaseConnection); + }; + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesByAuthorAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesByAuthorAsReader.cs new file mode 100644 index 00000000..5dffeeb8 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesByAuthorAsReader.cs @@ -0,0 +1,113 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesByAuthorAsReader : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + private AuthorDto _author; + private IEnumerable _authorArticles; + + public WhenGettingArticlesByAuthorAsReader() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _author = AuthorBuilder.WithLibrary(LibraryId).Build(); + _authorArticles = ArticleBuilder.WithLibrary(LibraryId).WithAuthor(_author).IsPublic().Build(5); + AuthorBuilder.WithLibrary(LibraryId).Build(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=10&authorId={_author.Id}"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("authorId", _author.Id.ToString())); + } + + [Test] + public void ShouldNotHaveNextLink() + { + _assert.ShouldNotHaveNextLink(); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldNotHaveCreateLink() + { + _assert.ShouldNotHaveCreateLink(); + } + + [Test] + public void ShouldHaveCorrectPagination() + { + _assert.ShouldHavePageCount(1) + .ShouldHavePageSize(10) + .ShouldHavePage(1) + .ShouldHaveTotalCount(5); + } + + [Test] + public void ShouldReturnCorrectPage() + { + _assert.ShouldHavePage(1) + .ShouldHavePageSize(10) + .ShouldHaveTotalCount(_authorArticles.Count()) + .ShouldHaveItems(5); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = _authorArticles.OrderBy(a => a.Title).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesFirstPage.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesFirstPage.cs new file mode 100644 index 00000000..3bf056ed --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesFirstPage.cs @@ -0,0 +1,92 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesFirstPage : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesFirstPage() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(20); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=10"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 1, 10); + } + + [Test] + public void ShouldHaveCorrectPaginationData() + { + _assert.ShouldHavePageCount(2) + .ShouldHavePageSize(10) + .ShouldHavePage(1) + .ShouldHaveTotalCount(20); + + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 2); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHaveAddFavoriteLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesLastPage.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesLastPage.cs new file mode 100644 index 00000000..d5d2b92c --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesLastPage.cs @@ -0,0 +1,92 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesLastPage : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesLastPage() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(30); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=3&pageSize=10"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 3, 10); + } + + [Test] + public void ShouldHaveCorrectPaginationData() + { + _assert.ShouldHavePageCount(3) + .ShouldHavePageSize(10) + .ShouldHavePage(3) + .ShouldHaveTotalCount(30); + + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldNotHaveNextLink(); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 2); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).Skip(20).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHaveAddFavoriteLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByLastModified.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByLastModified.cs new file mode 100644 index 00000000..e395436c --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByLastModified.cs @@ -0,0 +1,95 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesOrderByLastModified : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesOrderByLastModified() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(10); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=12&sortBy=lastmodified"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 1, 12, + new KeyValuePair("sortBy", "lastModified")); + } + + [Test] + public void ShouldHaveCorrectPaginationData() + { + _assert.ShouldHavePageCount(1) + .ShouldHavePageSize(12) + .ShouldHavePage(1) + .ShouldHaveTotalCount(10); + + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldNotHaveNextLink(); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.LastModified).ThenBy(x => x.Title).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + ; + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHaveAddFavoriteLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByLastModifiedDescending.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByLastModifiedDescending.cs new file mode 100644 index 00000000..19c588e6 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByLastModifiedDescending.cs @@ -0,0 +1,97 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesOrderByLastModifiedDescending : TestBase + { + private IEnumerable _expected; + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesOrderByLastModifiedDescending() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _expected = ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(10); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=12&sortBy=lastmodified&sortDirection=descending"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 1, 12, + new KeyValuePair("sortBy", "lastModified"), + new KeyValuePair("sortDirection", "descending")); + } + + [Test] + public void ShouldHaveCorrectPaginationData() + { + _assert.ShouldHavePageCount(1) + .ShouldHavePageSize(12) + .ShouldHavePage(1) + .ShouldHaveTotalCount(10); + + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldNotHaveNextLink(); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = _expected.OrderByDescending(a => a.LastModified).ThenBy(x => x.Title).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHaveAddFavoriteLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByTitleDescending.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByTitleDescending.cs new file mode 100644 index 00000000..92aee414 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesOrderByTitleDescending.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesOrderByTitleDescending : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesOrderByTitleDescending() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(10); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=12&sortDirection=descending"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 1, 12, + new KeyValuePair("sortDirection", "descending")); + } + + [Test] + public void ShouldHaveCorrectPaginationData() + { + _assert.ShouldHavePageCount(1) + .ShouldHavePageSize(12) + .ShouldHavePage(1) + .ShouldHaveTotalCount(10); + + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldNotHaveNextLink(); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderByDescending(a => a.Title).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHaveAddFavoriteLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesPageInMiddle.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesPageInMiddle.cs new file mode 100644 index 00000000..08eca641 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesPageInMiddle.cs @@ -0,0 +1,92 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesPageInMiddle : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesPageInMiddle() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(30); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 2, 10); + } + + [Test] + public void ShouldHaveCorrectPaginationData() + { + _assert.ShouldHavePageCount(3) + .ShouldHavePageSize(10) + .ShouldHavePage(2) + .ShouldHaveTotalCount(30); + + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).Skip(10).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHaveAddFavoriteLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesPageThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesPageThatDoesNotExist.cs new file mode 100644 index 00000000..81bb323b --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesPageThatDoesNotExist.cs @@ -0,0 +1,76 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesPageThatDoesNotExist : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesPageThatDoesNotExist() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(20); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=5&pageSize=10"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 5, 10); + } + + [Test] + public void ShouldHaveCorrectPaginationData() + { + _assert.ShouldHavePageCount(2) + .ShouldHavePageSize(10) + .ShouldHavePage(5) + .ShouldHaveTotalCount(20); + + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldNotHaveNextLink(); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + _assert.ShouldHaveNoData(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesReadbyMultipleUsers.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesReadbyMultipleUsers.cs new file mode 100644 index 00000000..bfa99965 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesReadbyMultipleUsers.cs @@ -0,0 +1,96 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesReadbyMultipleUsers : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesReadbyMultipleUsers() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var account2 = AccountBuilder.As(Role.Reader).Build(); + ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(2) + .WithAuthors(2) + .AddToFavorites(AccountId) + .AddToRecentReads(AccountId) + .AddToFavorites(account2.Id) + .AddToRecentReads(account2.Id) + .WithContent() + .IsPublic() + .Build(20); + + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=12"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 1, 12); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 2, 12); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).Take(12).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveRemoveFavoriteLink() + .ShouldHaveContents( + ArticleBuilder.Contents.Where(c => c.ArticleId == actual.Id).ToList(), + false) + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesSinglePage.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesSinglePage.cs new file mode 100644 index 00000000..70ad564a --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesSinglePage.cs @@ -0,0 +1,92 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesSinglePage : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesSinglePage() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(10); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=12"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 1, 12); + } + + [Test] + public void ShouldHaveCorrectPaginationData() + { + _assert.ShouldHavePageCount(1) + .ShouldHavePageSize(12) + .ShouldHavePage(1) + .ShouldHaveTotalCount(10); + + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldNotHaveNextLink(); + } + + [Test] + public void ShouldNotHavePreviousLink() + { + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHaveAddFavoriteLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithAssignedToReview.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithAssignedToReview.cs new file mode 100644 index 00000000..a7471b99 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithAssignedToReview.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesWithAssignedToReview : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesWithAssignedToReview() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(2) + .WithContents(2) + .WithReviewerAssignment(AccountId) + .Build(4); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?assignedfor=reviewer"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("assignedfor", "reviewer")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles + .Where(x => x.ReviewerAccountId == AccountId) + .OrderBy(a => a.Title).Take(10).ToArray(); + + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveContents(ArticleBuilder.Contents.Where(c => c.ArticleId == actual.Id).ToList(), true) + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithAssignedToWrite.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithAssignedToWrite.cs new file mode 100644 index 00000000..f39380cc --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithAssignedToWrite.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesWithAssignedToWrite : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesWithAssignedToWrite() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(2) + .WithContents(2) + .WithWtiterAssignment(AccountId) + .Build(4); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?assignedfor=writer"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("assignedfor", "writer")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles + .Where(x => x.WriterAccountId == AccountId) + .OrderBy(a => a.Title).Take(10).ToArray(); + + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveContents(ArticleBuilder.Contents.Where(c => c.ArticleId == actual.Id).ToList(), true) + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithMultipleAuthorsAndCategories.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithMultipleAuthorsAndCategories.cs new file mode 100644 index 00000000..33264cb7 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithMultipleAuthorsAndCategories.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingArticlesWithMultipleAuthorsAndCategories : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + private IEnumerable _categories; + private IEnumerable _authors; + + public WhenGettingArticlesWithMultipleAuthorsAndCategories() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _categories = CategoryBuilder.WithLibrary(LibraryId).Build(2); + _authors = AuthorBuilder.WithLibrary(LibraryId).Build(2); + + ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(_categories) + .WithAuthors(_authors) + .WithContents(2) + .Build(40); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles"); + } + + [Test] + public void ShouldNotHaveCreateLink() + { + _assert.ShouldNotHaveCreateLink(); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).Skip(10).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHaveAddFavoriteLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithWritePermissions.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithWritePermissions.cs new file mode 100644 index 00000000..8f1d0dc7 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingArticlesWithWritePermissions.cs @@ -0,0 +1,89 @@ +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenGettingArticlesWithWritePermissions : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingArticlesWithWritePermissions(Role role) : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(2) + .WithContents(2) + .Build(4); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles"); + } + + [Test] + public void ShouldHaveCreateLink() + { + _assert.ShouldHaveCreateLink($"/libraries/{LibraryId}/articles"); + } + + [Test] + public void ShouldNotHaveNavigationLinks() + { + _assert.ShouldNotHaveNextLink(); + _assert.ShouldNotHavePreviousLink(); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.OrderBy(a => a.Title).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldHaveContents(ArticleBuilder.Contents.Where(c => c.ArticleId == actual.Id).ToList(), true) + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingFavoriteArticles.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingFavoriteArticles.cs new file mode 100644 index 00000000..9f5ad15c --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingFavoriteArticles.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingFavoriteArticles : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingFavoriteArticles() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).AddToFavorites(AccountId, 25).Build(40); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&favorite=true"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("favorite", "true")); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("favorite", "true")); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("favorite", "true")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles + .Where(b => ArticleBuilder.FavoriteArticles.Any(f => f.ArticleId == b.Id )) + .OrderBy(a => a.Title).Skip(10).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveRemoveFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingReadArticles.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingReadArticles.cs new file mode 100644 index 00000000..cd570432 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingReadArticles.cs @@ -0,0 +1,89 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingReadArticles : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingReadArticles() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).AddToRecentReads(AccountId, 25).Build(40); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&read=true"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 2, 10, + new KeyValuePair("read", "true")); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("read", "true")); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("read", "true")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.Where(b => ArticleBuilder.RecentReads.Any(f => f.ArticleId == b.Id )) + .OrderBy(a => a.Title).Skip(10).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingingArticlesByStatus.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingingArticlesByStatus.cs new file mode 100644 index 00000000..ddce7a48 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingingArticlesByStatus.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingingArticlesByStatus : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingingArticlesByStatus() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).WithStatus(EditingStatus.InReview).Build(30); + ArticleBuilder.WithLibrary(LibraryId).WithStatus(EditingStatus.Completed).Build(10); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&status=inreview"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("status", "inreview")); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("status", "inreview")); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("status", "inreview")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.Where(b => b.Status == EditingStatus.InReview) + .OrderBy(a => a.Title).Skip(10).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingingArticlesByType.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingingArticlesByType.cs new file mode 100644 index 00000000..b88c14b8 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenGettingingArticlesByType.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenGettingingArticlesByType : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenGettingingArticlesByType() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).WithType(Domain.Models.Library.ArticleType.Poetry).Build(30); + ArticleBuilder.WithLibrary(LibraryId).WithType(Domain.Models.Library.ArticleType.Writing).Build(10); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&type=poetry"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("type", "poetry")); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("type", "poetry")); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("type", "poetry")); + } + + [Test] + public void ShouldHaveCorrectPagination() + { + _assert.ShouldHavePageCount(3) + .ShouldHavePageSize(10) + .ShouldHavePage(2) + .ShouldHaveTotalCount(30); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.Where(b => b.Type == Domain.Models.Library.ArticleType.Poetry) + .OrderBy(a => a.Title).Skip(10).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchinArticlesWithMultipleAuthorsAndCategories.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchinArticlesWithMultipleAuthorsAndCategories.cs new file mode 100644 index 00000000..fcfc59c0 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchinArticlesWithMultipleAuthorsAndCategories.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenSearchinArticlesWithMultipleAuthorsAndCategories : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + private IEnumerable _categories; + private IEnumerable _authors; + + public WhenSearchinArticlesWithMultipleAuthorsAndCategories() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _categories = CategoryBuilder.WithLibrary(LibraryId).Build(2); + _authors = AuthorBuilder.WithLibrary(LibraryId).Build(2); + + ArticleBuilder.WithLibrary(LibraryId).WithCategories(_categories).WithAuthors(_authors).IsPublic().Build(30); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&query=itle"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 2, 10); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.Where(b => b.Title.Contains("itle")) + .OrderBy(a => a.Title).Skip(10).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByStatus.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByStatus.cs new file mode 100644 index 00000000..47b302a1 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByStatus.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenSearchingArticlesByStatus : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenSearchingArticlesByStatus() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).WithStatus(EditingStatus.InReview).Build(30); + ArticleBuilder.WithLibrary(LibraryId).WithStatus(EditingStatus.Completed).Build(10); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&query=itle&status=inreview"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("query", "itle"), + new KeyValuePair("status", "inreview")); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("status", "inreview")); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("status", "inreview")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.Where(b => b.Status == EditingStatus.InReview) + .OrderBy(a => a.Title).Skip(10).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitle.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitle.cs new file mode 100644 index 00000000..158a7b45 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitle.cs @@ -0,0 +1,89 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenSearchingArticlesByTitle : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenSearchingArticlesByTitle() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(30); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&query=itle"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("query", "itle")); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("query", "itle")); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("query", "itle")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.Where(b => b.Title.Contains("itle")) + .OrderBy(a => a.Title).Skip(10).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAndAuthor.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAndAuthor.cs new file mode 100644 index 00000000..2ecfc99e --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAndAuthor.cs @@ -0,0 +1,96 @@ +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenSearchingArticlesByTitleAndAuthor + : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + private AuthorDto _author; + private IEnumerable _authorArticles; + + public WhenSearchingArticlesByTitleAndAuthor() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _author = AuthorBuilder.WithLibrary(LibraryId).Build(); + _authorArticles = ArticleBuilder.WithLibrary(LibraryId).WithAuthor(_author).IsPublic().Build(25); + AuthorBuilder.WithLibrary(LibraryId).WithArticles(3).Build(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&authorId={_author.Id}&query=itle"); + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("query", "itle"), + new KeyValuePair("authorid", _author.Id.ToString())); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("authorid", _author.Id.ToString())); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("authorid", _author.Id.ToString())); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = _authorArticles.Where(b => b.Title.Contains("itle")) + .OrderBy(a => a.Title).Skip(10).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.Authors.Should().Contain(x => x.Id == _author.Id); + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAndType.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAndType.cs new file mode 100644 index 00000000..6df6c3f9 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAndType.cs @@ -0,0 +1,103 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenSearchingArticlesByTitleAndType : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenSearchingArticlesByTitleAndType() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).WithType(ArticleType.Writing).Build(30); + ArticleBuilder.WithLibrary(LibraryId).WithType(ArticleType.Poetry).Build(10); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&query=itle&type=writing"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("query", "itle"), + new KeyValuePair("type", "writing")); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("type", "writing")); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("type", "writing")); + } + + [Test] + public void ShouldHaveCorrectPagination() + { + _assert.ShouldHavePageCount(3) + .ShouldHavePageSize(10) + .ShouldHavePage(2) + .ShouldHaveTotalCount(30); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.Where(b => b.Title.Contains("itle") && b.Type == ArticleType.Writing) + .OrderBy(a => a.Title).Skip(10).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAuthorAndType.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAuthorAndType.cs new file mode 100644 index 00000000..50c8fc33 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingArticlesByTitleAuthorAndType.cs @@ -0,0 +1,102 @@ +using FluentAssertions; +using Inshapardaz.Api.Extensions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; +using NUnit.Framework; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenSearchingArticlesByTitleAuthorAndType + : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + private AuthorDto _author; + private IEnumerable _authorArticles; + + public WhenSearchingArticlesByTitleAuthorAndType() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _author = AuthorBuilder.WithLibrary(LibraryId).Build(); + _authorArticles = ArticleBuilder.WithLibrary(LibraryId).WithType(ArticleType.Poetry).WithAuthor(_author).IsPublic().Build(25); + ArticleBuilder.WithLibrary(LibraryId).WithType(ArticleType.Writing).WithAuthor(_author).IsPublic().Build(30); + AuthorBuilder.WithLibrary(LibraryId).WithArticles(3).Build(); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=2&pageSize=10&authorId={_author.Id}&query=itle&type=poetry"); + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 2, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("authorid", _author.Id.ToString()), + new KeyValuePair("type", ArticleType.Poetry.ToDescription())); + } + + [Test] + public void ShouldHaveNextLink() + { + _assert.ShouldHaveNextLink($"/libraries/{LibraryId}/articles", 3, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("authorid", _author.Id.ToString()), + new KeyValuePair("type", ArticleType.Poetry.ToDescription())); + } + + [Test] + public void ShouldHavePreviousLink() + { + _assert.ShouldHavePreviousLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("authorid", _author.Id.ToString()), + new KeyValuePair("type", ArticleType.Poetry.ToDescription())); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = _authorArticles.Where(b => b.Title.Contains("itle") && b.Type == ArticleType.Poetry) + .OrderBy(a => a.Title).Skip(10).Take(10).ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.Type.Should().Be(ArticleType.Poetry.ToDescription()); + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithReadOnlyLinks() + .ShouldNotHaveImageUpdateLink() + .ShouldNotHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingFavoriteArticles.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingFavoriteArticles.cs new file mode 100644 index 00000000..c2be04cb --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingFavoriteArticles.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenSearchingFavoriteArticles : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenSearchingFavoriteArticles() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).AddToFavorites(AccountId, 25).Build(40); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=10&favorite=true&query=itle"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", + new KeyValuePair("query", "itle"), + new KeyValuePair("favorite", "true")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles + .Where(b => ArticleBuilder.FavoriteArticles.Any(f => f.ArticleId == b.Id )) + .Where(b => b.Title.Contains("itle")) + .OrderBy(a => a.Title).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveRemoveFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingReadArticles.cs b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingReadArticles.cs new file mode 100644 index 00000000..fa264031 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/GetArticles/WhenSearchingReadArticles.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.GetArticles +{ + [TestFixture] + public class WhenSearchingReadArticles : TestBase + { + private HttpResponseMessage _response; + private PagingAssert _assert; + + public WhenSearchingReadArticles() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + ArticleBuilder.WithLibrary(LibraryId).AddToRecentReads(AccountId, 25).Build(40); + + _response = await Client.GetAsync($"/libraries/{LibraryId}/articles?pageNumber=1&pageSize=10&read=true&query=itle"); + + _assert = new PagingAssert(_response); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveSelfLink() + { + _assert.ShouldHaveSelfLink($"/libraries/{LibraryId}/articles", 1, 10, + new KeyValuePair("query", "itle"), + new KeyValuePair("read", "true")); + } + + [Test] + public void ShouldReturnExpectedArticles() + { + var expectedItems = ArticleBuilder.Articles.Where(b => ArticleBuilder.RecentReads.Any(f => f.ArticleId == b.Id )) + .Where(a => a.Title.Contains("itle")) + .OrderBy(a => a.Title).Take(10) + .ToArray(); + _assert.Data.Count().Should().Be(expectedItems.Length); + for (int i = 0; i < _assert.Data.Count(); i++) + { + var actual = _assert.Data.ElementAt(i); + var expected = expectedItems[i]; + actual.ShouldMatch(expected, DatabaseConnection, LibraryId) + .ShouldHaveSelfLink() + .WithWriteableLinks() + .ShouldHaveImageUpdateLink() + .ShouldHaveAddContentLink() + .ShouldHavePublicImageLink() + .ShouldHaveAddFavoriteLink() + .ShouldBeSameAs(expected, DatabaseConnection); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenAddBookToFavoriteThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenAddBookToFavoriteThatDoesNotExist.cs new file mode 100644 index 00000000..83b23326 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenAddBookToFavoriteThatDoesNotExist.cs @@ -0,0 +1,45 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.RemoveArtiucleFromFavorites +{ + [TestFixture] + public class WhenRemoveArticleFromFavoriteThatDoesNotExist : TestBase + { + private HttpResponseMessage _response; + private int _articleId = -RandomData.Number; + + public WhenRemoveArticleFromFavoriteThatDoesNotExist() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/favorites/articles/{_articleId}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOkResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldNotBeInFavorites() + { + ArticleAssert.ShouldNotBeInFavorites(_articleId, AccountId, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveArticleFromFavoriteAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveArticleFromFavoriteAsUnauthorized.cs new file mode 100644 index 00000000..b5b9151d --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveArticleFromFavoriteAsUnauthorized.cs @@ -0,0 +1,32 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.RemoveArtiucleFromFavorites +{ + [TestFixture] + public class WhenRemoveArticleFromFavoriteAsUnauthorized : TestBase + { + private HttpResponseMessage _response; + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).AddToFavorites(AccountId).Build(); + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/favorites/articles/{article.Id}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorisedResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveArticleFromFavoriteWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveArticleFromFavoriteWithPermissions.cs new file mode 100644 index 00000000..f29bc906 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveArticleFromFavoriteWithPermissions.cs @@ -0,0 +1,55 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.RemoveArtiucleFromFavorites +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + [TestFixture(Role.Reader)] + public class WhenRemoveArticleFromFavoriteWithPermissions : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + + public WhenRemoveArticleFromFavoriteWithPermissions(Role role) : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var articles = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(1) + .AddToFavorites(AccountId) + .Build(2); + + _article = articles.PickRandom(); + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/favorites/articles/{_article.Id}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOKResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldBeRemovedFromFavorites() + { + ArticleAssert.ShouldNotBeInFavorites(_article.Id, AccountId, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveNonFavoriteArticleFromFavorite.cs b/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveNonFavoriteArticleFromFavorite.cs new file mode 100644 index 00000000..a3be4d9d --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/RemoveArtiucleFromFavorites/WhenRemoveNonFavoriteArticleFromFavorite.cs @@ -0,0 +1,52 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.RemoveArtiucleFromFavorites +{ + [TestFixture] + public class WhenRemoveNonFavoriteArticleFromFavorite : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + + public WhenRemoveNonFavoriteArticleFromFavorite() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var articles = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(1) + .Build(2); + + _article = articles.PickRandom(); + + _response = await Client.DeleteAsync($"/libraries/{LibraryId}/favorites/articles/{_article.Id}"); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOKResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldBeRemovedFromFavorites() + { + ArticleAssert.ShouldNotBeInFavorites(_article.Id, AccountId, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleAsReader.cs new file mode 100644 index 00000000..76c636a8 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleAsReader.cs @@ -0,0 +1,40 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticle +{ + [TestFixture] + public class WhenUpdatingArticleAsReader : TestBase + { + private HttpResponseMessage _response; + + public WhenUpdatingArticleAsReader() : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + article.Title = RandomData.Name; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{article.Id}", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveForbiddenResult() + { + _response.ShouldBeForbidden(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleAsUnauthorized.cs new file mode 100644 index 00000000..384383d0 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleAsUnauthorized.cs @@ -0,0 +1,35 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticle +{ + [TestFixture] + public class WhenUpdatingArticleAsUnauthorized : TestBase + { + private HttpResponseMessage _response; + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + article.Title = RandomData.Name; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{article.Id}", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorizedResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleThatDoesNotExist.cs new file mode 100644 index 00000000..3347609b --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleThatDoesNotExist.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticle +{ + [TestFixture] + public class WhenUpdatingArticleThatDoesNotExist : TestBase + { + private HttpResponseMessage _response; + private ArticleView _expected; + private ArticleAssert _assert; + + public WhenUpdatingArticleThatDoesNotExist() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var author = AuthorBuilder.WithLibrary(LibraryId).Build(); + + _expected = new ArticleView + { + Title = RandomData.Name, + Authors = new List { new AuthorView { Id = author.Id } }, + }; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_expected.Id}", _expected); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveCreatedResult() + { + _response.ShouldBeCreated(); + } + + [Test] + public void ShouldHaveLocationHeader() + { + _assert.ShouldHaveCorrectLocationHeader(); + } + + [Test] + public void ShouldSaveTheArticle() + { + _assert.ShouldHaveSavedArticle(DatabaseConnection); + } + + [Test] + public void ShouldHaveLinks() + { + _assert.ShouldHaveSelfLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink() + .ShouldHaveUpdateLink(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithAdditionalCategories.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithAdditionalCategories.cs new file mode 100644 index 00000000..e355fa78 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithAdditionalCategories.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Bogus; +using Inshapardaz.Api.Extensions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticle +{ + [TestFixture] + public class WhenUpdatingArticleWithAdditionalCategories : TestBase + { + private HttpResponseMessage _response; + private ArticleView _expected; + private ArticleAssert _assert; + private List _categoriesToUpdate; + + public WhenUpdatingArticleWithAdditionalCategories() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var otherAuthor = AuthorBuilder.WithLibrary(LibraryId).Build(); + var newCategories = CategoryBuilder.WithLibrary(LibraryId).Build(3); + var otherSeries = SeriesBuilder.WithLibrary(LibraryId).Build(); + var articles = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(3) + .AddToFavorites(AccountId) + .AddToRecentReads(AccountId) + .Build(2); + + var selectedArticle = articles.PickRandom(); + + _categoriesToUpdate = DatabaseConnection.GetCategoriesByArticle(selectedArticle.Id).ToList(); + _categoriesToUpdate.AddRange(newCategories); + + var fake = new Faker(); + _expected = new ArticleView + { + Id = selectedArticle.Id, + Title = fake.Name.FullName(), + Status = fake.PickRandom().ToDescription(), + IsPublic = fake.Random.Bool(), + Authors = new List { new AuthorView { Id = otherAuthor.Id, Name = otherAuthor.Name } }, + Categories = _categoriesToUpdate.Select(c => new CategoryView { Id = c.Id }) + }; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{selectedArticle.Id}", _expected); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOKResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveUpdatedTheArticle() + { + _assert.ShouldBeSameAs(_expected, DatabaseConnection); + } + + [Test] + public void ShouldReturnCorrectCategories() + { + _assert.ShouldBeSameCategories(_categoriesToUpdate); + } + + [Test] + public void ShouldSaveCorrectCategories() + { + _assert.ShouldHaveCategories(_categoriesToUpdate, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithInvalidData.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithInvalidData.cs new file mode 100644 index 00000000..a5c61b3c --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithInvalidData.cs @@ -0,0 +1,242 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.DataBuilders; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticle +{ + [TestFixture] + public class WhenUpdatingArticleWithInvalidData + { + [TestFixture] + public class AndUsingNonExistingLibrary : TestBase + { + private HttpResponseMessage _response; + + public AndUsingNonExistingLibrary() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var author = AuthorBuilder.WithLibrary(LibraryId).Build(); + + var article = new ArticleView { Title = RandomData.Name, Authors = new List { new AuthorView { Id = author.Id } } }; + + _response = await Client.PutObject($"/libraries/{-RandomData.Number}/articles/{article.Id}", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + public void ShouldReturnBadRequest() + { + _response.ShouldBeBadRequest(); + } + } + + [TestFixture] + public class AndUpdatingWithNonExistingAuthor : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _articleToUpdate; + private AuthorDto _author; + + public AndUpdatingWithNonExistingAuthor() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _author = AuthorBuilder.WithLibrary(LibraryId).Build(); + + var articles = ArticleBuilder.WithLibrary(LibraryId).WithAuthor(_author).Build(1); + _articleToUpdate = articles.PickRandom(); + + var article = new ArticleView { Title = RandomData.Text, Authors = new List { new AuthorView { Id = -RandomData.Number } } }; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_articleToUpdate.Id}", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveBadReqestResult() + { + _response.ShouldBeBadRequest(); + } + + [Test] + public void ShouldNotUpdateTheAuthor() + { + var authors = DatabaseConnection.GetAuthorsByArticle(_articleToUpdate.Id); + authors.Should().Contain(a => a.Id == _author.Id); + } + } + + [TestFixture] + public class AndUpdatingWithAuthorFromOtherLibrary : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _articleToUpdate; + private AuthorDto _author; + private LibraryDataBuilder _library2Builder; + + public AndUpdatingWithAuthorFromOtherLibrary() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _library2Builder = Services.GetService(); + var library2 = _library2Builder.Build(); + var author2 = AuthorBuilder.WithLibrary(library2.Id).Build(); + + _author = AuthorBuilder.WithLibrary(LibraryId).Build(); + + var articles = ArticleBuilder.WithLibrary(LibraryId).WithAuthor(_author).Build(1); + _articleToUpdate = articles.PickRandom(); + + var arricle = new ArticleView { Title = RandomData.Text, Authors = new List { new AuthorView { Id = author2.Id } } }; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_articleToUpdate.Id}", arricle); + } + + [OneTimeTearDown] + public void Teardown() + { + _library2Builder.CleanUp(); + Cleanup(); + } + + [Test] + public void ShouldHaveBadReqestResult() + { + _response.ShouldBeBadRequest(); + } + + [Test] + public void ShouldNotUpdateTheAuthor() + { + var authors = DatabaseConnection.GetAuthorsByArticle(_articleToUpdate.Id); + authors.Should().Contain(a => a.Id == _author.Id); + } + } + + [TestFixture] + public class AndUpdatingWithNonExistingCategory : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _articleToUpdate; + private CategoryDto _category; + + public AndUpdatingWithNonExistingCategory() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _category = CategoryBuilder.WithLibrary(LibraryId).Build(); + + var articles = ArticleBuilder.WithLibrary(LibraryId).WithCategory(_category).Build(1); + _articleToUpdate = articles.PickRandom(); + + var article = new ArticleView { Title = RandomData.Text, Categories = new[] { new CategoryView { Id = -RandomData.Number } } }; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_articleToUpdate.Id}", article); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveBadReqestResult() + { + _response.ShouldBeBadRequest(); + } + + [Test] + public void ShouldNotUpdateTheAuthor() + { + var categories = DatabaseConnection.GetCategoriesByArticle(_articleToUpdate.Id); + categories.Should().HaveCount(1); + categories.First().Id.Should().Be(_category.Id); + } + } + + [TestFixture] + public class AndUpdatingWithCategoryFromOtherLibrary : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _articleToUpdate; + private CategoryDto _category; + private LibraryDataBuilder _library2Builder; + + public AndUpdatingWithCategoryFromOtherLibrary() : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _library2Builder = Services.GetService(); + var library2 = _library2Builder.Build(); + var series2 = CategoryBuilder.WithLibrary(library2.Id).Build(); + + _category = CategoryBuilder.WithLibrary(LibraryId).Build(); + + var articles = ArticleBuilder.WithLibrary(LibraryId).WithCategory(_category).Build(1); + _articleToUpdate = articles.PickRandom(); + + var article = new ArticleView { Title = RandomData.Text, Categories = new[] { new CategoryView { Id = _category.Id } } }; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_articleToUpdate.Id}", article); + } + + [OneTimeTearDown] + public void Teardown() + { + _library2Builder.CleanUp(); + Cleanup(); + } + + [Test] + public void ShouldHaveBadReqestResult() + { + _response.ShouldBeBadRequest(); + } + + [Test] + public void ShouldNotUpdateTheAuthor() + { + var categories = DatabaseConnection.GetCategoriesByArticle(_articleToUpdate.Id); + categories.Should().HaveCount(1); + categories.First().Id.Should().Be(_category.Id); + } + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithMultipleAuthors.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithMultipleAuthors.cs new file mode 100644 index 00000000..bc879b6a --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithMultipleAuthors.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Bogus; +using Inshapardaz.Api.Extensions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticle +{ + [TestFixture] + public class WhenUpdatingArticleWithMultipleAuthors : TestBase + { + private HttpResponseMessage _response; + private ArticleView _expected; + private ArticleAssert _assert; + private IEnumerable _otherCategories; + + public WhenUpdatingArticleWithMultipleAuthors() + : base(Role.LibraryAdmin) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var otherAuthors = AuthorBuilder.WithLibrary(LibraryId).Build(2); + _otherCategories = CategoryBuilder.WithLibrary(LibraryId).Build(3); + var article = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(1) + .AddToFavorites(AccountId) + .AddToRecentReads(AccountId) + .Build(1) + .First(); + + var fake = new Faker(); + _expected = new ArticleView + { + Id = article.Id, + Title = fake.Name.FullName(), + Status = fake.PickRandom().ToDescription(), + IsPublic = fake.Random.Bool(), + Authors = otherAuthors.Select(x => new AuthorView { Id = x.Id, Name = x.Name }), + Categories = _otherCategories.Select(c => new CategoryView { Id = c.Id }), + WriterAccountId = AccountId, + WriterAssignTimeStamp = DateTime.UtcNow, + ReviewerAccountId = AccountId, + ReviewerAssignTimeStamp = DateTime.UtcNow, + }; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{article.Id}", _expected); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOKResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveUpdatedTheArticle() + { + _expected.Authors.ElementAt(0).Links = new List { new Views.LinkView { + Rel = RelTypes.Self, + Method = "GET", + Href = $"http://localhost/libraries/{LibraryId}/authors/{_expected.Authors.ElementAt(0).Id}" + } }; + _assert.ShouldBeSameAs(_expected, DatabaseConnection); + } + + [Test] + public void ShouldReturnCorrectCategories() + { + _assert.ShouldBeSameCategories(_otherCategories.ToList()); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithPermissions.cs new file mode 100644 index 00000000..d3a06d82 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticle/WhenUpdatingArticleWithPermissions.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Bogus; +using Inshapardaz.Api.Extensions; +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticle +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenUpdatingArticleWithPermissions : TestBase + { + private HttpResponseMessage _response; + private ArticleView _expected; + private ArticleAssert _assert; + private IEnumerable _otherCategories; + + public WhenUpdatingArticleWithPermissions(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var otherAuthors = AuthorBuilder.WithLibrary(LibraryId).Build(2); + _otherCategories = CategoryBuilder.WithLibrary(LibraryId).Build(3); + var article = ArticleBuilder.WithLibrary(LibraryId) + .WithCategories(1) + .AddToFavorites(AccountId) + .AddToRecentReads(AccountId) + .Build(1) + .Single(); + + var fake = new Faker(); + _expected = new ArticleView + { + Id = article.Id, + Title = fake.Name.FullName(), + Status = fake.PickRandom().ToDescription(), + IsPublic = fake.Random.Bool(), + Authors = otherAuthors.Select(x => new AuthorView { Id = x.Id, Name = x.Name }), + Categories = _otherCategories.Select(c => new CategoryView { Id = c.Id }), + WriterAccountId = AccountId, + WriterAssignTimeStamp = DateTime.UtcNow, + ReviewerAccountId = AccountId, + ReviewerAssignTimeStamp = DateTime.UtcNow, + }; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{article.Id}", _expected); + _assert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOKResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveUpdatedTheArticle() + { + _expected.Authors.ElementAt(0).Links = new List { new Views.LinkView { + Rel = RelTypes.Self, + Method = "GET", + Href = $"http://localhost/libraries/{LibraryId}/authors/{_expected.Authors.ElementAt(0).Id}" + } }; + _assert.ShouldBeSameAs(_expected, DatabaseConnection); + } + + [Test] + public void ShouldReturnCorrectCategories() + { + _assert.ShouldBeSameCategories(_otherCategories.ToList()); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsAsReader.cs new file mode 100644 index 00000000..c50754c7 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsAsReader.cs @@ -0,0 +1,57 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleContent +{ + [TestFixture] + public class WhenUpdatingArticleContentsAsReader + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + private ArticleContentDto _content; + + private string _newContents, _newLayout; + + public WhenUpdatingArticleContentsAsReader() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _newContents = RandomData.String; + _newLayout = RandomData.String; + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_article.Id}/contents", + new ArticleContentView + { + Text = _newContents, + Language = _content.Language, + Layout = _newLayout + }); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveForbiddenResult() + { + _response.ShouldBeForbidden(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsAsUnauthorized.cs new file mode 100644 index 00000000..0f0af7aa --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsAsUnauthorized.cs @@ -0,0 +1,52 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleContent +{ + [TestFixture] + public class WhenUpdatingArticleContentsAsUnauthorised + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + private ArticleContentDto _content; + + private string _newContents, _newLayout; + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _newContents = RandomData.String; + _newLayout = RandomData.String; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_article.Id}/contents", + new ArticleContentView + { + Text = _newContents, + Language = _content.Language, + Layout = _newLayout + }); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorizedResult() + { + _response.ShouldBeUnauthorized(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWhereContentNotPresent.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWhereContentNotPresent.cs new file mode 100644 index 00000000..11e52009 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWhereContentNotPresent.cs @@ -0,0 +1,91 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleContent +{ + [TestFixture] + public class WhenUpdatingArticleContentsWhereContentNotPresent + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + private ArticleContentAssert _assert; + private string _language = RandomData.Locale; + private string _newContents, _newLayout; + + public WhenUpdatingArticleContentsWhereContentNotPresent() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().Build(); + + _newContents = RandomData.String; + _newLayout = RandomData.String; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_article.Id}/contents", + new ArticleContentView + { + Text = _newContents, + Language = _language, + Layout = _newLayout + }); + + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveCreatedResult() + { + _response.ShouldBeCreated(); + } + + [Test] + public void ShouldHaveLocationHeader() + { + _assert.ShouldHaveCorrectLocationHeader(_language); + } + + [Test] + public void ShouldSaveTheArticleContent() + { + _assert.ShouldHaveSavedArticleContent(DatabaseConnection); + } + + [Test] + public void ShouldHaveTextReturened() + { + _assert.ShouldHaveText(_newContents); + } + + [Test] + public void ShouldHaveCorrectContentSaved() + { + _assert.ShouldHaveSavedCorrectText(_newContents, DatabaseConnection); + } + + [Test] + public void ShouldHaveLinks() + { + _assert.ShouldHaveSelfLink() + .ShouldHaveArticleLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink(); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWithDifferentLanguage.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWithDifferentLanguage.cs new file mode 100644 index 00000000..9b801e70 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWithDifferentLanguage.cs @@ -0,0 +1,88 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleContent +{ + [TestFixture] + public class WhenUpdatingArticleContentsWithDifferentLanguage + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + private ArticleContentDto _content; + private ArticleContentAssert _assert; + + private string _newContents, _newLayout, _newLanguge; + + public WhenUpdatingArticleContentsWithDifferentLanguage() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().WithContent().WithContentLanguage("de").Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _newContents = RandomData.String; + _newLayout = RandomData.String; + _newLanguge = "en"; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_article.Id}/contents", + new ArticleContentView + { + Text = _newContents, + Language = _newLanguge, + Layout = _newLayout + }); + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveCreatedResult() + { + _response.ShouldBeCreated(); + } + + [Test] + public void ShouldHaveLinks() + { + _assert.ShouldHaveSelfLink() + .ShouldHaveArticleLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink(); + } + + [Test] + public void ShouldHaveTextReturened() + { + _assert.ShouldHaveText(_newContents); + } + + [Test] + public void ShouldHaveCreatedCorrectContents() + { + _assert.ShouldHaveMatechingTextForLanguage(_newContents, _newLanguge, _newLayout, DatabaseConnection); + } + + [Test] + public void ShouldHaveOtherLanguageContents() + { + ArticleContentAssert.ShouldHaveContent(DatabaseConnection, _article.Id, _content.Language); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWithPermission.cs new file mode 100644 index 00000000..ed5cc473 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleContent/WhenUpdatingArticleContentsWithPermission.cs @@ -0,0 +1,84 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleContent +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenUpdatingArticleContentsWithPermission + : TestBase + { + private HttpResponseMessage _response; + private ArticleDto _article; + private ArticleContentDto _content; + private ArticleContentAssert _assert; + + private string _newContents, _newLayout; + + public WhenUpdatingArticleContentsWithPermission(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + _article = ArticleBuilder.WithLibrary(LibraryId).IsPublic().WithContent().Build(); + _content = ArticleBuilder.Contents.Single(x => x.ArticleId == _article.Id); + + _newContents = RandomData.String; + _newLayout = RandomData.String; + + _response = await Client.PutObject($"/libraries/{LibraryId}/articles/{_article.Id}/contents", + new ArticleContentView + { + Text = _newContents, + Language = _content.Language, + Layout = _newLayout + }); + + _assert = new ArticleContentAssert(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldHaveOkResult() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveLinks() + { + _assert.ShouldHaveSelfLink() + .ShouldHaveArticleLink() + .ShouldHaveUpdateLink() + .ShouldHaveDeleteLink(); + } + + [Test] + public void ShouldHaveTextReturened() + { + _assert.ShouldHaveText(_newContents); + } + + [Test] + public void ShouldHaveUpdatedContents() + { + _assert.ShouldHaveSavedCorrectText(_newContents, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageAsReader.cs new file mode 100644 index 00000000..ca1c8ec0 --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageAsReader.cs @@ -0,0 +1,54 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleImage +{ + [TestFixture] + public class WhenUploadingArticleImageAsReader : TestBase + { + private HttpResponseMessage _response; + private long _articleId; + private byte[] _oldImage; + + public WhenUploadingArticleImageAsReader() + : base(Role.Reader) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + _articleId = article.Id; + var imageUrl = DatabaseConnection.GetArticleImageUrl(_articleId); + _oldImage = await FileStore.GetFile(imageUrl, CancellationToken.None); + + _response = await Client.PutFile($"/libraries/{LibraryId}/articles/{_articleId}/image", RandomData.Bytes); + } + + [OneTimeTearDown] + public void Teardown() + { + ArticleBuilder.CleanUp(); + Cleanup(); + } + + [Test] + public void ShouldHaveForbidResult() + { + _response.ShouldBeForbidden(); + } + + [Test] + public void ShouldNotHaveUpdatedArticleImage() + { + ArticleAssert.ShouldNotHaveUpdatedArticleImage(_articleId, _oldImage, DatabaseConnection, FileStore); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageAsUnauthorized.cs new file mode 100644 index 00000000..1c1c275d --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageAsUnauthorized.cs @@ -0,0 +1,48 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Helpers; +using NUnit.Framework; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleImage +{ + [TestFixture] + public class WhenUploadingArticleImageAsUnauthorized : TestBase + { + private HttpResponseMessage _response; + private long _articleId; + private byte[] _oldImage; + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + _articleId = article.Id; + var imageUrl = DatabaseConnection.GetArticleImageUrl(_articleId); + _oldImage = await FileStore.GetFile(imageUrl, CancellationToken.None); + + _response = await Client.PutFile($"/libraries/{LibraryId}/articles/{_articleId}/image", RandomData.Bytes); + } + + [OneTimeTearDown] + public void Teardown() + { + ArticleBuilder.CleanUp(); + Cleanup(); + } + + [Test] + public void ShouldHaveUnauthorisedResult() + { + _response.ShouldBeUnauthorized(); + } + + [Test] + public void ShouldNotHaveUpdatedArticleImage() + { + ArticleAssert.ShouldNotHaveUpdatedArticleImage(_articleId, _oldImage, DatabaseConnection, FileStore); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageWhenNoExistingImage.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageWhenNoExistingImage.cs new file mode 100644 index 00000000..9ce733de --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageWhenNoExistingImage.cs @@ -0,0 +1,63 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleImage +{ + [TestFixture] + public class WhenUploadingArticleImageWhenNoExistingImage : TestBase + { + private HttpResponseMessage _response; + private ArticleAssert _articleAssert; + private long _articleId; + + public WhenUploadingArticleImageWhenNoExistingImage() + : base(Role.Writer) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).WithNoImage().Build(); + _articleId = article.Id; + + _response = await Client.PutFile($"/libraries/{LibraryId}/articles/{_articleId}/image", RandomData.Bytes); + _articleAssert = ArticleAssert.FromResponse(_response, LibraryId); + } + + [OneTimeTearDown] + public void Teardown() + { + ArticleBuilder.CleanUp(); + Cleanup(); + } + + [Test] + public void ShouldHaveHttpResponseMessage() + { + _response.ShouldBeCreated(); + } + + [Test] + public void ShouldHaveLocationHeader() + { + _articleAssert.ShouldHaveCorrectImageLocationHeader(_articleId); + } + + [Test] + public void ShouldHaveAddedImageToArticle() + { + ArticleAssert.ShouldHaveAddedArticleImage(_articleId, DatabaseConnection, FileStore); + } + + [Test] + public void ShouldHavePublicImage() + { + ArticleAssert.ShouldHavePublicImage(_articleId, DatabaseConnection); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageWithPermissions.cs new file mode 100644 index 00000000..ada22dfe --- /dev/null +++ b/src/Inshapardaz.Api.Tests/Library/Articles/UpdateArticleImage/WhenUploadingArticleImageWithPermissions.cs @@ -0,0 +1,54 @@ +using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.DataHelpers; +using Inshapardaz.Api.Tests.Helpers; +using Inshapardaz.Domain.Models; +using NUnit.Framework; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Inshapardaz.Api.Tests.Library.Articles.UpdateArticleImage +{ + [TestFixture(Role.Admin)] + [TestFixture(Role.LibraryAdmin)] + [TestFixture(Role.Writer)] + public class WhenUploadingArticleImageWithPermissions : TestBase + { + private HttpResponseMessage _response; + private long _articleId; + private byte[] _newImage = RandomData.Bytes; + + public WhenUploadingArticleImageWithPermissions(Role role) + : base(role) + { + } + + [OneTimeSetUp] + public async Task Setup() + { + var article = ArticleBuilder.WithLibrary(LibraryId).Build(); + _articleId = article.Id; + + var imageUrl = DatabaseConnection.GetArticleImageUrl(_articleId); + + _response = await Client.PutFile($"/libraries/{LibraryId}/articles/{_articleId}/image", _newImage); + } + + [OneTimeTearDown] + public void Teardown() + { + Cleanup(); + } + + [Test] + public void ShouldReturnOk() + { + _response.ShouldBeOk(); + } + + [Test] + public void ShouldHaveUpdatedArticleImage() + { + ArticleAssert.ShouldHaveUpdatedArticleImage(_articleId, _newImage, DatabaseConnection, FileStore); + } + } +} diff --git a/src/Inshapardaz.Api.Tests/Library/Author/GetAuthorById/WhenGettingAuthorWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Author/GetAuthorById/WhenGettingAuthorWithPermission.cs index beff8fc0..9bd9f8ef 100644 --- a/src/Inshapardaz.Api.Tests/Library/Author/GetAuthorById/WhenGettingAuthorWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Author/GetAuthorById/WhenGettingAuthorWithPermission.cs @@ -25,7 +25,7 @@ public WhenGettingAuthorWithPermission(Role Role) [OneTimeSetUp] public async Task Setup() { - var authors = AuthorBuilder.WithLibrary(LibraryId).Build(4); + var authors = AuthorBuilder.WithLibrary(LibraryId).WithBooks(20).WithArticles(13).Build(4); _expected = authors.PickRandom(); _response = await Client.GetAsync($"/libraries/{LibraryId}/authors/{_expected.Id}"); diff --git a/src/Inshapardaz.Api.Tests/Library/Author/GetAuthors/WhenGettingAuthorsWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Author/GetAuthors/WhenGettingAuthorsWithPermission.cs index 22ac3b1f..4328aef0 100644 --- a/src/Inshapardaz.Api.Tests/Library/Author/GetAuthors/WhenGettingAuthorsWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Author/GetAuthors/WhenGettingAuthorsWithPermission.cs @@ -24,7 +24,7 @@ public WhenGettingAuthorsWithPermission(Role Role) [OneTimeSetUp] public async Task Setup() { - AuthorBuilder.WithLibrary(LibraryId).WithBooks(3).Build(4); + AuthorBuilder.WithLibrary(LibraryId).WithBooks(3).WithArticles(5).Build(4); _response = await Client.GetAsync($"/libraries/{LibraryId}/authors?pageNumber={1}&pageSize={10}"); _assert = new PagingAssert(_response); diff --git a/src/Inshapardaz.Api.Tests/Library/Author/GetAuthors/WhenSearchingAuthors.cs b/src/Inshapardaz.Api.Tests/Library/Author/GetAuthors/WhenSearchingAuthors.cs index d69deaa3..24d52b20 100644 --- a/src/Inshapardaz.Api.Tests/Library/Author/GetAuthors/WhenSearchingAuthors.cs +++ b/src/Inshapardaz.Api.Tests/Library/Author/GetAuthors/WhenSearchingAuthors.cs @@ -20,7 +20,7 @@ public class WhenSearchingAuthors : TestBase [OneTimeSetUp] public async Task Setup() { - var authors = AuthorBuilder.WithLibrary(LibraryId).WithBooks(3).WithoutImage().Build(20); + var authors = AuthorBuilder.WithLibrary(LibraryId).WithBooks(3).WithArticles(4).WithoutImage().Build(20); _searchedAuthor = authors.PickRandom(); diff --git a/src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBookUsingAuthorProperties.cs b/src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBook.cs similarity index 91% rename from src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBookUsingAuthorProperties.cs rename to src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBook.cs index 6fd4c4be..30062d07 100644 --- a/src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBookUsingAuthorProperties.cs +++ b/src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBook.cs @@ -11,12 +11,12 @@ namespace Inshapardaz.Api.Tests.Library.Book.AddBook { [TestFixture] - public class WhenAddingBookUsingAuthorProperties : TestBase + public class WhenAddingBook : TestBase { private BookAssert _bookAssert; private HttpResponseMessage _response; - public WhenAddingBookUsingAuthorProperties() : base(Role.LibraryAdmin) + public WhenAddingBook() : base(Role.LibraryAdmin) { } @@ -33,6 +33,8 @@ public async Task Setup() SeriesId = series.Id, SeriesIndex = 1, SeriesName = series.Name, + Source = RandomData.String, + Publisher = RandomData.String, Language = RandomData.Locale, Categories = RandomData.PickRandom(categories, 2).Select(c => new CategoryView { Id = c.Id }) }; diff --git a/src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBookWithInvalidData.cs b/src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBookWithInvalidData.cs index ae0c43b1..7252cf40 100644 --- a/src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBookWithInvalidData.cs +++ b/src/Inshapardaz.Api.Tests/Library/Book/AddBook/WhenAddingBookWithInvalidData.cs @@ -40,9 +40,9 @@ public void Teardown() } [Test] - public void ShouldHaveForbiddenResult() + public void ShouldHaveBadRequestResult() { - _response.ShouldBeForbidden(); + _response.ShouldBeBadRequest(); } } diff --git a/src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenAddBookToFavoriteAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenRemoveBookFromFavoriteAsUnauthorized.cs similarity index 92% rename from src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenAddBookToFavoriteAsUnauthorized.cs rename to src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenRemoveBookFromFavoriteAsUnauthorized.cs index 5899a025..ce464b40 100644 --- a/src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenAddBookToFavoriteAsUnauthorized.cs +++ b/src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenRemoveBookFromFavoriteAsUnauthorized.cs @@ -7,7 +7,7 @@ namespace Inshapardaz.Api.Tests.Library.Book.RemoveBookFromFavorite { [TestFixture] - public class WhenAddBookToFavoriteAsUnauthorized : TestBase + public class WhenRemoveBookFromFavoriteAsUnauthorized : TestBase { private HttpResponseMessage _response; diff --git a/src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenAddBookToFavoriteThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenRemoveBookFromFavoriteThatDoesNotExist.cs similarity index 88% rename from src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenAddBookToFavoriteThatDoesNotExist.cs rename to src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenRemoveBookFromFavoriteThatDoesNotExist.cs index 0904f04e..03a5ae8f 100644 --- a/src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenAddBookToFavoriteThatDoesNotExist.cs +++ b/src/Inshapardaz.Api.Tests/Library/Book/RemoveBookFromFavorite/WhenRemoveBookFromFavoriteThatDoesNotExist.cs @@ -8,12 +8,12 @@ namespace Inshapardaz.Api.Tests.Library.Book.RemoveBookFromFavorite { [TestFixture] - public class WhenAddBookToFavoriteThatDoesNotExist : TestBase + public class WhenRemoveBookFromFavoriteThatDoesNotExist : TestBase { private HttpResponseMessage _response; private int _bookId = -RandomData.Number; - public WhenAddBookToFavoriteThatDoesNotExist() + public WhenRemoveBookFromFavoriteThatDoesNotExist() : base(Role.Writer) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithAdditionalCategories.cs b/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithAdditionalCategories.cs index 6386448f..075219cd 100644 --- a/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithAdditionalCategories.cs +++ b/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithAdditionalCategories.cs @@ -54,7 +54,7 @@ public async Task Setup() Copyrights = fake.PickRandom().ToDescription(), Language = Helpers.RandomData.Locale, YearPublished = fake.Date.Past().Year, - Status = fake.PickRandom().ToDescription(), + Status = fake.PickRandom().ToDescription(), IsPublic = fake.Random.Bool(), Authors = new List { new AuthorView { Id = otherAuthor.Id, Name = otherAuthor.Name } }, SeriesId = otherSeries.Id, diff --git a/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithInvalidData.cs b/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithInvalidData.cs index f1a63ad5..51a404e9 100644 --- a/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithInvalidData.cs +++ b/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithInvalidData.cs @@ -44,9 +44,9 @@ public void Teardown() } [Test] - public void ShouldHaveForbiddenResult() + public void ShouldHaveBadRequestResult() { - _response.ShouldBeForbidden(); + _response.ShouldBeBadRequest(); } } diff --git a/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithMultipleAuthors.cs b/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithMultipleAuthors.cs index 6c1f6214..bd998307 100644 --- a/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithMultipleAuthors.cs +++ b/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithMultipleAuthors.cs @@ -51,7 +51,7 @@ public async Task Setup() Copyrights = fake.PickRandom().ToDescription(), Language = Helpers.RandomData.Locale, YearPublished = fake.Date.Past().Year, - Status = fake.PickRandom().ToDescription(), + Status = fake.PickRandom().ToDescription(), IsPublic = fake.Random.Bool(), Authors = new List { new AuthorView { Id = otherAuthor.Id, Name = otherAuthor.Name } }, SeriesId = otherSeries.Id, diff --git a/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithPermissions.cs index 8d8b2fba..5dbcfbb1 100644 --- a/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithPermissions.cs +++ b/src/Inshapardaz.Api.Tests/Library/Book/UpdateBook/WhenUpdatingBookWithPermissions.cs @@ -53,11 +53,13 @@ public async Task Setup() Copyrights = fake.PickRandom().ToDescription(), Language = Helpers.RandomData.Locale, YearPublished = fake.Date.Past().Year, - Status = fake.PickRandom().ToDescription(), + Status = fake.PickRandom().ToDescription(), IsPublic = fake.Random.Bool(), Authors = new List { new AuthorView { Id = otherAuthor.Id, Name = otherAuthor.Name } }, SeriesId = otherSeries.Id, IsPublished = fake.Random.Bool(), + Source = RandomData.String, + Publisher = RandomData.String, Categories = _otherCategories.Select(c => new CategoryView { Id = c.Id }) }; diff --git a/src/Inshapardaz.Api.Tests/Library/BookPage/UpdatePage/WhenUpdatingBookPageWhenPageDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/BookPage/UpdatePage/WhenUpdatingBookPageWhenPageDoesNotExist.cs index 015d6876..d29c15e7 100644 --- a/src/Inshapardaz.Api.Tests/Library/BookPage/UpdatePage/WhenUpdatingBookPageWhenPageDoesNotExist.cs +++ b/src/Inshapardaz.Api.Tests/Library/BookPage/UpdatePage/WhenUpdatingBookPageWhenPageDoesNotExist.cs @@ -59,7 +59,7 @@ public void ShouldHaveLocationHeader() [Test] public void ShouldHaveReturnCorrectObject() { - _assert.ShouldMatch(_page); + _assert.ShouldMatch(_page, 1); } [Test] diff --git a/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookFromBookShelf/WhenDeletingBookFromBookShelf.cs b/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookFromBookShelf/WhenDeletingBookFromBookShelf.cs index 0234f572..ec9cace3 100644 --- a/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookFromBookShelf/WhenDeletingBookFromBookShelf.cs +++ b/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookFromBookShelf/WhenDeletingBookFromBookShelf.cs @@ -5,7 +5,6 @@ using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; using NUnit.Framework; namespace Inshapardaz.Api.Tests.Library.BookShelf.DeleteBookFromBookShelf diff --git a/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookFromBookShelf/WhenDeletingBookFromBookShelfAsAnonymousUser.cs b/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookFromBookShelf/WhenDeletingBookFromBookShelfAsAnonymousUser.cs index a96e5aca..a4910f77 100644 --- a/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookFromBookShelf/WhenDeletingBookFromBookShelfAsAnonymousUser.cs +++ b/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookFromBookShelf/WhenDeletingBookFromBookShelfAsAnonymousUser.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; using NUnit.Framework; namespace Inshapardaz.Api.Tests.Library.BookShelf.DeleteBookFromBookShelf diff --git a/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookShelf/WhenDeletingBookShelfAsAnonymous.cs b/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookShelf/WhenDeletingBookShelfAsAnonymous.cs index c37bd683..67479d38 100644 --- a/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookShelf/WhenDeletingBookShelfAsAnonymous.cs +++ b/src/Inshapardaz.Api.Tests/Library/BookShelf/DeleteBookShelf/WhenDeletingBookShelfAsAnonymous.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Helpers; -using Microsoft.EntityFrameworkCore.Migrations.Operations; using NUnit.Framework; namespace Inshapardaz.Api.Tests.Library.BookShelf.DeleteBookShelf diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/AddChapter/WhenAddingChapterWithoutChapterNumber.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/AddChapter/WhenAddingChapterWithoutChapterNumber.cs index a049652b..286a2eb9 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/AddChapter/WhenAddingChapterWithoutChapterNumber.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/AddChapter/WhenAddingChapterWithoutChapterNumber.cs @@ -5,7 +5,6 @@ using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; -using System.Security.Claims; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.AddChapter diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToReader.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToReader.cs index b289d020..5450f1e8 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToReader.cs @@ -1,7 +1,6 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToSelfForWriting.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToSelfForWriting.cs index ed4fe7ae..af9870a1 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToSelfForWriting.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToSelfForWriting.cs @@ -1,7 +1,6 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserAsReader.cs index 9df21c99..463affb5 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserAsReader.cs @@ -1,7 +1,6 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserAsUnauthorised.cs index 4da669e8..c041c4a6 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserAsUnauthorised.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserAsUnauthorised.cs @@ -1,8 +1,6 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; -using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; using System.Threading.Tasks; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserForReviewing.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserForReviewing.cs index e256bd60..d7832489 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserForReviewing.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserForReviewing.cs @@ -1,7 +1,6 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserForWriting.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserForWriting.cs index cddb8e57..a26bc312 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserForWriting.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/AssignChapterToUser/WhenAssignChapterToUserForWriting.cs @@ -1,7 +1,6 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsAsReader.cs index 03def9f4..a87357f7 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsAsReader.cs @@ -1,5 +1,4 @@ using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Linq; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsAsUnauthorized.cs index 9e409409..fbbb3ea3 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsAsUnauthorized.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsAsUnauthorized.cs @@ -1,5 +1,4 @@ using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Helpers; using NUnit.Framework; using System.Linq; using System.Net.Http; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsWithPermission.cs index bec76f6d..72b583ca 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/DeleteChapterContents/WhenDeletingChapterContentsWithPermission.cs @@ -1,6 +1,5 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Linq; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingChapterContentLanguageNotExisting.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingChapterContentLanguageNotExisting.cs index a510610a..960edd44 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingChapterContentLanguageNotExisting.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingChapterContentLanguageNotExisting.cs @@ -1,9 +1,7 @@ -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Tests.Asserts; +using Inshapardaz.Api.Tests.Asserts; using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; using Inshapardaz.Domain.Models; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingChapterContentWithoutLanguage.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingChapterContentWithoutLanguage.cs index 0ddb348c..18c17a15 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingChapterContentWithoutLanguage.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingChapterContentWithoutLanguage.cs @@ -1,11 +1,9 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.Contents.GetChapterContents diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentAsReader.cs index 405b6db8..05125be7 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentAsReader.cs @@ -1,10 +1,8 @@ using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Tests.Dto; using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; using Inshapardaz.Domain.Models; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentAsUnauthorised.cs index b1fee131..ee589f94 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentAsUnauthorised.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentAsUnauthorised.cs @@ -1,10 +1,8 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.Contents.GetChapterContents diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentWithPermission.cs index 82b0f3ce..80ae2afa 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPrivateChapterContentWithPermission.cs @@ -1,11 +1,9 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.Contents.GetChapterContents diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentAsReader.cs index 535e712d..13c5119f 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentAsReader.cs @@ -1,11 +1,9 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.Contents.GetChapterContents diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentAsUnauthorised.cs index 7f63fc9e..b2eba46a 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentAsUnauthorised.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentAsUnauthorised.cs @@ -1,10 +1,8 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.Contents.GetChapterContents diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentWithPermission.cs index 8f3e6ea2..2d64555d 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/GetChapterContents/WhenGettingPublicChapterContentWithPermission.cs @@ -1,11 +1,9 @@ using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Tests.Dto; using NUnit.Framework; using System.Linq; using System.Net.Http; using System.Security.Claims; -using System.Threading; using System.Threading.Tasks; using Inshapardaz.Domain.Models; diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsAsReader.cs index f21fa08f..65725e43 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsAsReader.cs @@ -5,7 +5,6 @@ using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.Contents.UpdateChapterContents diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsAsUnauthorized.cs index d4af2ab9..aec555cb 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsAsUnauthorized.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsAsUnauthorized.cs @@ -4,7 +4,6 @@ using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.Contents.UpdateChapterContents diff --git a/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsWithDifferentLanguage.cs b/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsWithDifferentLanguage.cs index 0f6d6146..3e854ee9 100644 --- a/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsWithDifferentLanguage.cs +++ b/src/Inshapardaz.Api.Tests/Library/Chapter/UpdateChapterContents/WhenUpdatingChapterContentsWithDifferentLanguage.cs @@ -5,7 +5,6 @@ using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Chapter.Contents.UpdateChapterContents diff --git a/src/Inshapardaz.Api.Tests/Library/DeleteLibrary/WhenDeletingLibraryWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/DeleteLibrary/WhenDeletingLibraryWithPermission.cs index 014de8cd..19bac2a2 100644 --- a/src/Inshapardaz.Api.Tests/Library/DeleteLibrary/WhenDeletingLibraryWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/DeleteLibrary/WhenDeletingLibraryWithPermission.cs @@ -1,5 +1,4 @@ using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; diff --git a/src/Inshapardaz.Api.Tests/Library/GetLibraries/WhenGettingLibrariesAs.cs b/src/Inshapardaz.Api.Tests/Library/GetLibraries/WhenGettingLibrariesAs.cs index c0e580b2..8b21656f 100644 --- a/src/Inshapardaz.Api.Tests/Library/GetLibraries/WhenGettingLibrariesAs.cs +++ b/src/Inshapardaz.Api.Tests/Library/GetLibraries/WhenGettingLibrariesAs.cs @@ -1,5 +1,4 @@ -using System.Linq; -using System.Net.Http; +using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Views; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/AddPeriodical/WhenAddingPeriodicalWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/AddPeriodical/WhenAddingPeriodicalWithPermissions.cs index d3b61701..6a76587e 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/AddPeriodical/WhenAddingPeriodicalWithPermissions.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/AddPeriodical/WhenAddingPeriodicalWithPermissions.cs @@ -1,7 +1,10 @@ -using Inshapardaz.Api.Tests.Asserts; +using Bogus; +using Inshapardaz.Api.Extensions; +using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; using NUnit.Framework; using System.Net.Http; using System.Threading.Tasks; @@ -25,7 +28,13 @@ public WhenAddingPeriodicalWithPermissions(Role role) [OneTimeSetUp] public async Task Setup() { - var periodical = new PeriodicalView { Title = RandomData.Name, Description = RandomData.Words(20) }; + var periodical = new PeriodicalView + { + Title = RandomData.Name, + Description = RandomData.Words(20), + Language = RandomData.Locale, + Frequency = new Faker().PickRandom().ToDescription() + }; _response = await Client.PostObject($"/libraries/{LibraryId}/periodicals", periodical); diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/DeletePeriodical/WhenDeletingPeriodicalWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/DeletePeriodical/WhenDeletingPeriodicalWithPermission.cs index 543301f1..054cfe9c 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/DeletePeriodical/WhenDeletingPeriodicalWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/DeletePeriodical/WhenDeletingPeriodicalWithPermission.cs @@ -1,5 +1,4 @@ -using System.Linq; -using System.Net.Http; +using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.DataHelpers; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdAsAnonymous.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdAsAnonymous.cs index 7732769b..43582fff 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdAsAnonymous.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdAsAnonymous.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Net.Http; +using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdAsReader.cs index c5fefe07..c98b198e 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdAsReader.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Net.Http; +using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdWithMultipleCategories.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdWithMultipleCategories.cs index 5625e509..a484d59e 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdWithMultipleCategories.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdWithMultipleCategories.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Net.Http; +using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdWithPermission.cs index 097e2028..7fbe9273 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicalById/WhenGettingPeriodicalByIdWithPermission.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Net.Http; +using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsAsReader.cs index 9a34fda5..dbf80acd 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsAsReader.cs @@ -1,9 +1,7 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsAsUnauthorised.cs index d748e0e9..0597066b 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsAsUnauthorised.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsAsUnauthorised.cs @@ -1,9 +1,6 @@ -using FluentAssertions; -using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Dto; +using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Views.Library; using NUnit.Framework; -using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsWithMultipleCategories.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsWithMultipleCategories.cs index 0bea43c9..a16f4ae3 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsWithMultipleCategories.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsWithMultipleCategories.cs @@ -1,9 +1,7 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsWithWritePermissions.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsWithWritePermissions.cs index 8ad4e6cf..29141356 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsWithWritePermissions.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/GetPeriodicals/WhenGettingPeriodicalsWithWritePermissions.cs @@ -1,9 +1,7 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/AddIssue/WhenAddingIssueThatAlreadyExists.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/AddIssue/WhenAddingIssueThatAlreadyExists.cs index 4fe4244c..68dc26ba 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/AddIssue/WhenAddingIssueThatAlreadyExists.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/AddIssue/WhenAddingIssueThatAlreadyExists.cs @@ -1,10 +1,6 @@ -using Bogus; -using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataBuilders; +using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; -using Microsoft.Extensions.DependencyInjection; using NUnit.Framework; using System.Net.Http; using System.Threading.Tasks; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/AddIssue/WhenAddingIssueWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/AddIssue/WhenAddingIssueWithPermission.cs index 6783c72a..04ea366a 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/AddIssue/WhenAddingIssueWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/AddIssue/WhenAddingIssueWithPermission.cs @@ -5,7 +5,6 @@ using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; -using System.Security.Claims; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.AddIssue diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssueById/WhenGettingIssueByIdHavingContentsWithWritePermissions.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssueById/WhenGettingIssueByIdHavingContentsWithWritePermissions.cs index 989c04e8..855eeaf1 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssueById/WhenGettingIssueByIdHavingContentsWithWritePermissions.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssueById/WhenGettingIssueByIdHavingContentsWithWritePermissions.cs @@ -1,6 +1,5 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Linq; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssueContent/WhenGettingIssueContentWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssueContent/WhenGettingIssueContentWithPermissions.cs index 318a0f9a..3910e00c 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssueContent/WhenGettingIssueContentWithPermissions.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssueContent/WhenGettingIssueContentWithPermissions.cs @@ -4,7 +4,6 @@ using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; -using System.Security.Claims; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.GetIssueContent diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalAsReader.cs index d59bb30a..08eb8966 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalAsReader.cs @@ -1,6 +1,5 @@ using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalAsUnauthorized.cs index 7cdaf179..5fe61a5f 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalAsUnauthorized.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalAsUnauthorized.cs @@ -1,6 +1,5 @@ using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalFirstPage.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalFirstPage.cs index ab85cd60..a42db292 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalFirstPage.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalFirstPage.cs @@ -1,9 +1,5 @@ -using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalForYear.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalForYear.cs index 3e072858..53a63741 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalForYear.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalForYear.cs @@ -1,9 +1,6 @@ using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalLastPage.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalLastPage.cs index dff5b8ff..2c48cac4 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalLastPage.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalLastPage.cs @@ -1,9 +1,5 @@ -using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalMiddlePage.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalMiddlePage.cs index f7e6c2e4..5f9d29c8 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalMiddlePage.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalMiddlePage.cs @@ -1,9 +1,5 @@ -using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByIssueDateDescending.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByIssueDateDescending.cs index 27274768..3807b878 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByIssueDateDescending.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByIssueDateDescending.cs @@ -1,9 +1,5 @@ -using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByVolumeAndIssueNumber.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByVolumeAndIssueNumber.cs index 46113fec..a6a1dacd 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByVolumeAndIssueNumber.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByVolumeAndIssueNumber.cs @@ -1,9 +1,5 @@ -using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByVolumeNumberDescending.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByVolumeNumberDescending.cs index 651d877c..c5529867 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByVolumeNumberDescending.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalSortedByVolumeNumberDescending.cs @@ -1,9 +1,5 @@ -using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalWithCustomPageSize.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalWithCustomPageSize.cs index 81c476da..035cb65e 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalWithCustomPageSize.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalWithCustomPageSize.cs @@ -1,9 +1,5 @@ -using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalWithWritePermissions.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalWithWritePermissions.cs index 0bb26ef8..90bc48f9 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalWithWritePermissions.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/GetIssuesByPeriodical/WhenGettingIssuesByPeriodicalWithWritePermissions.cs @@ -1,6 +1,5 @@ using FluentAssertions; using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleAsUnauthorizedUser.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleAsUnauthorizedUser.cs similarity index 87% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleAsUnauthorizedUser.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleAsUnauthorizedUser.cs index e3813aba..6f5e87d9 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleAsUnauthorizedUser.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleAsUnauthorizedUser.cs @@ -6,10 +6,10 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticle { [TestFixture] - public class WhenAddingArticleAsUnauthorizedUser + public class WhenAddingIssueArticleAsUnauthorizedUser : TestBase { private HttpResponseMessage _response; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleForIssueInOtherLibrary.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleForIssueInOtherLibrary.cs similarity index 86% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleForIssueInOtherLibrary.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleForIssueInOtherLibrary.cs index 17494761..7a13363b 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleForIssueInOtherLibrary.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleForIssueInOtherLibrary.cs @@ -9,16 +9,16 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticle { [TestFixture] - public class WhenAddingArticleForIssueInOtherLibrary + public class WhenAddingIssueArticleForIssueInOtherLibrary : TestBase { private HttpResponseMessage _response; private LibraryDataBuilder _libBuilder; - public WhenAddingArticleForIssueInOtherLibrary() + public WhenAddingIssueArticleForIssueInOtherLibrary() : base(Role.Writer) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleForNonExistingIssue.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleForNonExistingIssue.cs similarity index 83% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleForNonExistingIssue.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleForNonExistingIssue.cs index 6a6fa23e..f81acd80 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleForNonExistingIssue.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleForNonExistingIssue.cs @@ -7,15 +7,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticle { [TestFixture] - public class WhenAddingArticleForNonExistingIssue + public class WhenAddingIssueArticleForNonExistingIssue : TestBase { private HttpResponseMessage _response; - public WhenAddingArticleForNonExistingIssue() + public WhenAddingIssueArticleForNonExistingIssue() : base(Role.Writer) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleWithPermission.cs similarity index 91% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleWithPermission.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleWithPermission.cs index de7e26be..3632dc32 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenAddingIssueArticleWithPermission.cs @@ -8,12 +8,12 @@ using System.Security.Claims; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticle { [TestFixture(Role.Admin)] [TestFixture(Role.LibraryAdmin)] [TestFixture(Role.Writer)] - public class WhenAddingArticleWithPermission + public class WhenAddingIssueArticleWithPermission : TestBase { private IssueArticleView _article; @@ -21,7 +21,7 @@ public class WhenAddingArticleWithPermission private IssueArticleAssert _assert; private ClaimsPrincipal _claim; - public WhenAddingArticleWithPermission(Role role) + public WhenAddingIssueArticleWithPermission(Role role) : base(role) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenIssueAddingArticleAsReader.cs similarity index 85% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenIssueAddingArticleAsReader.cs index a503585b..8e552255 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticle/WhenAddingArticleAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticle/WhenIssueAddingArticleAsReader.cs @@ -7,15 +7,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticle { [TestFixture] - public class WhenAddingArticleAsReader + public class WhenIssueAddingArticleAsReader : TestBase { private HttpResponseMessage _response; - public WhenAddingArticleAsReader() + public WhenIssueAddingArticleAsReader() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsAsReader.cs similarity index 84% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsAsReader.cs index 6dd68beb..24fc8d3c 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsAsReader.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticleContents { [TestFixture] - public class WhenAddingArticleContentsAsReader + public class WhenAddingIssueArticleContentsAsReader : TestBase { private HttpResponseMessage _response; - public WhenAddingArticleContentsAsReader() + public WhenAddingIssueArticleContentsAsReader() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsAsUnauthorized.cs similarity index 86% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsAsUnauthorized.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsAsUnauthorized.cs index 460c9a3b..5d0d46a5 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsAsUnauthorized.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsAsUnauthorized.cs @@ -4,10 +4,10 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticleContents { [TestFixture] - public class WhenAddingArticleContentsAsUnauthorized + public class WhenAddingIssueArticleContentsAsUnauthorized : TestBase { private HttpResponseMessage _response; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingArticle.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingArticle.cs similarity index 83% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingArticle.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingArticle.cs index 1ca4744d..0a055ae7 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingArticle.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingArticle.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticleContents { [TestFixture] - public class WhenAddingArticleContentsForMissingArticle + public class WhenAddingIssueArticleContentsForMissingArticle : TestBase { private HttpResponseMessage _response; - public WhenAddingArticleContentsForMissingArticle() + public WhenAddingIssueArticleContentsForMissingArticle() : base(Role.LibraryAdmin) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingIssue.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingIssue.cs similarity index 83% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingIssue.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingIssue.cs index 6a5b7961..defedd1e 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingIssue.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingIssue.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticleContents { [TestFixture] - public class WhenAddingArticleContentsForMissingIssue + public class WhenAddingIssueArticleContentsForMissingIssue : TestBase { private HttpResponseMessage _response; - public WhenAddingArticleContentsForMissingIssue() + public WhenAddingIssueArticleContentsForMissingIssue() : base(Role.LibraryAdmin) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingPeriodical.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingPeriodical.cs similarity index 82% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingPeriodical.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingPeriodical.cs index f591b5a5..aeaaf0c1 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsForMissingPeriodical.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForMissingPeriodical.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticleContents { [TestFixture] - public class WhenAddingArticleContentsForMissingPeriodical + public class WhenAddingIssueArticleContentsForMissingPeriodical : TestBase { private HttpResponseMessage _response; - public WhenAddingArticleContentsForMissingPeriodical() + public WhenAddingIssueArticleContentsForMissingPeriodical() : base(Role.LibraryAdmin) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingIssueContentsForWrongLibrary.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForWrongLibrary.cs similarity index 83% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingIssueContentsForWrongLibrary.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForWrongLibrary.cs index 30c5ba26..38b32ec4 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingIssueContentsForWrongLibrary.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsForWrongLibrary.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticleContents { [TestFixture] - public class WhenAddingIssueContentsForWrongLibrary + public class WhenAddingIssueArticleContentsForWrongLibrary : TestBase { private HttpResponseMessage _response; - public WhenAddingIssueContentsForWrongLibrary() + public WhenAddingIssueArticleContentsForWrongLibrary() : base(Role.Writer) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsWithPermission.cs similarity index 84% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsWithPermission.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsWithPermission.cs index d83516c7..69854c30 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsWithPermission.cs @@ -3,24 +3,23 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticleContents { [TestFixture(Role.Admin)] [TestFixture(Role.LibraryAdmin)] [TestFixture(Role.Writer)] - public class WhenAddingArticleContentsWithPermission + public class WhenAddingIssueArticleContentsWithPermission : TestBase { private HttpResponseMessage _response; private string _contents; - private ArticleDto _article; - private ArticleContentAssert _assert; + private IssueArticleDto _article; + private IssueArticleContentAssert _assert; - public WhenAddingArticleContentsWithPermission(Role role) + public WhenAddingIssueArticleContentsWithPermission(Role role) : base(role) { } @@ -35,7 +34,7 @@ public async Task Setup() _contents = RandomData.String; _response = await Client.PostString($"/libraries/{LibraryId}/periodicals/{issue.PeriodicalId}/volumes/{issue.VolumeNumber}/issues/{issue.IssueNumber}/articles/{_article.SequenceNumber}/contents", _contents, RandomData.Locale); - _assert = new ArticleContentAssert(_response, Library, issue); + _assert = new IssueArticleContentAssert(_response, Library, issue); } [OneTimeTearDown] diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsWithoutLanguage.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsWithoutLanguage.cs similarity index 76% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsWithoutLanguage.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsWithoutLanguage.cs index d6cc50f6..8ed41ade 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/AddArticleContents/WhenAddingArticleContentsWithoutLanguage.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/AddIssueArticleContents/WhenAddingIssueArticleContentsWithoutLanguage.cs @@ -6,17 +6,17 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.AddArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.AddIssueArticleContents { [TestFixture] - public class WhenAddingArticleContentsWithoutLanguage + public class WhenAddingIssueArticleContentsWithoutLanguage : TestBase { private HttpResponseMessage _response; - private ArticleDto _article; - private ArticleContentAssert _assert; + private IssueArticleDto _article; + private IssueArticleContentAssert _assert; - public WhenAddingArticleContentsWithoutLanguage() + public WhenAddingIssueArticleContentsWithoutLanguage() : base(Role.Writer) { } @@ -29,7 +29,7 @@ public async Task Setup() _article = RandomData.PickRandom(articles); _response = await Client.PostString($"/libraries/{LibraryId}/periodicals/{issue.PeriodicalId}/volumes/{issue.VolumeNumber}/issues/{issue.IssueNumber}/articles/{_article.SequenceNumber}/contents", RandomData.String, null); - _assert = new ArticleContentAssert(_response, Library, issue); + _assert = new IssueArticleContentAssert(_response, Library, issue); } [OneTimeTearDown] diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleAsReader.cs similarity index 84% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleAsReader.cs index 53347883..73e937b6 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleAsReader.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.DeleteArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.DeleteIssueArticle { [TestFixture] - public class WhenDeletingArticleAsReader + public class WhenDeletingIssueArticleAsReader : TestBase { private HttpResponseMessage _response; - public WhenDeletingArticleAsReader() + public WhenDeletingIssueArticleAsReader() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleAsUnauthorized.cs similarity index 87% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleAsUnauthorized.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleAsUnauthorized.cs index aa763493..21a156b8 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleAsUnauthorized.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleAsUnauthorized.cs @@ -4,10 +4,10 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.DeleteArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.DeleteIssueArticle { [TestFixture] - public class WhenDeletingArticleAsUnauthorized + public class WhenDeletingIssueArticleAsUnauthorized : TestBase { private HttpResponseMessage _response; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleWithPermission.cs similarity index 85% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleWithPermission.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleWithPermission.cs index 63355039..85d3a550 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingArticleWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingIssueArticleWithPermission.cs @@ -6,18 +6,18 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.DeleteArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.DeleteIssueArticle { [TestFixture(Role.Admin)] [TestFixture(Role.LibraryAdmin)] [TestFixture(Role.Writer)] - public class WhenDeletingArticleWithPermission + public class WhenDeletingIssueArticleWithPermission : TestBase { private HttpResponseMessage _response; - private ArticleDto _expected; + private IssueArticleDto _expected; - public WhenDeletingArticleWithPermission(Role role) + public WhenDeletingIssueArticleWithPermission(Role role) : base(role) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingNonExistingArticle.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingNonExistingIssueArticle.cs similarity index 84% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingNonExistingArticle.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingNonExistingIssueArticle.cs index 0a070e78..7605cec1 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticle/WhenDeletingNonExistingArticle.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticle/WhenDeletingNonExistingIssueArticle.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.DeleteArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.DeleteIssueArticle { [TestFixture] - public class WhenDeletingNonExistingArticle + public class WhenDeletingNonExistingIssueArticle : TestBase { private HttpResponseMessage _response; - public WhenDeletingNonExistingArticle() + public WhenDeletingNonExistingIssueArticle() : base(Role.Writer) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentThatDoesNotExists.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentThatDoesNotExists.cs similarity index 81% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentThatDoesNotExists.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentThatDoesNotExists.cs index dfdb2108..3c61750e 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentThatDoesNotExists.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentThatDoesNotExists.cs @@ -2,19 +2,18 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.DeleteArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.DeleteIssueArticleContents { [TestFixture] - public class WhenDeletingArticleContentThatDoesNotExists + public class WhenDeletingIssueArticleContentThatDoesNotExists : TestBase { private HttpResponseMessage _response; - public WhenDeletingArticleContentThatDoesNotExists() + public WhenDeletingIssueArticleContentThatDoesNotExists() : base(Role.Writer) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsAsReader.cs similarity index 84% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsAsReader.cs index e398e222..aaf79e14 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsAsReader.cs @@ -6,15 +6,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.DeleteArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.DeleteIssueArticleContents { [TestFixture] - public class WhenDeletingArticleContentsAsReader + public class WhenDeletingIssueArticleContentsAsReader : TestBase { private HttpResponseMessage _response; - public WhenDeletingArticleContentsAsReader() + public WhenDeletingIssueArticleContentsAsReader() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsAsUnauthorized.cs similarity index 87% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsAsUnauthorized.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsAsUnauthorized.cs index ae34096e..f51ea1c7 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsAsUnauthorized.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsAsUnauthorized.cs @@ -5,10 +5,10 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.DeleteArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.DeleteIssueArticleContents { [TestFixture] - public class WhenDeletingArticleContentsAsUnauthorized + public class WhenDeletingIssueArticleContentsAsUnauthorized : TestBase { private HttpResponseMessage _response; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsWithPermission.cs similarity index 76% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsWithPermission.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsWithPermission.cs index 5fc26644..22809caa 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/DeleteArticleContents/WhenDeletingArticleContentsWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/DeleteIssueArticleContents/WhenDeletingIssueArticleContentsWithPermission.cs @@ -7,20 +7,20 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.DeleteArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.DeleteIssueArticleContents { [TestFixture(Role.Admin)] [TestFixture(Role.LibraryAdmin)] [TestFixture(Role.Writer)] - public class WhenDeletingArticleContentsWithPermission + public class WhenDeletingIssueArticleContentsWithPermission : TestBase { private HttpResponseMessage _response; private IssueDto _issue; - private ArticleDto _article; - private ArticleContentDto _content; + private IssueArticleDto _article; + private IssueArticleContentDto _content; - public WhenDeletingArticleContentsWithPermission(Role role) + public WhenDeletingIssueArticleContentsWithPermission(Role role) : base(role) { } @@ -50,7 +50,7 @@ public void ShouldHaveNoContentResult() [Test] public void ShouldHaveDeletedArticleContent() { - ArticleContentAssert.ShouldHaveDeletedContent(DatabaseConnection, _issue, _article, _content); + IssueArticleContentAssert.ShouldHaveDeletedContent(DatabaseConnection, _issue, _article, _content); } } } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesByIssueAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesByIssueAsReader.cs similarity index 100% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesByIssueAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesByIssueAsReader.cs diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesByIssueAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesByIssueAsUnauthorized.cs similarity index 100% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesByIssueAsUnauthorized.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesByIssueAsUnauthorized.cs diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesByIssueWithNoArticles.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesByIssueWithNoArticles.cs similarity index 100% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesByIssueWithNoArticles.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesByIssueWithNoArticles.cs diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesByIssueWithWritePermissions.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesByIssueWithWritePermissions.cs similarity index 100% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesByIssueWithWritePermissions.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesByIssueWithWritePermissions.cs diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesForNonExistingIssue.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesForNonExistingIssue.cs similarity index 96% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesForNonExistingIssue.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesForNonExistingIssue.cs index 7ef5d27f..878af7e3 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleByIssue/WhenGettingArticlesForNonExistingIssue.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetArticleByIssue/WhenGettingArticlesForNonExistingIssue.cs @@ -1,5 +1,4 @@ using Inshapardaz.Api.Tests.Asserts; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; using System.Net.Http; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleFromMiddleOfIssue.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingArticleFromMiddleOfIssue.cs similarity index 93% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleFromMiddleOfIssue.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingArticleFromMiddleOfIssue.cs index 0ceb7146..f96e665d 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleFromMiddleOfIssue.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingArticleFromMiddleOfIssue.cs @@ -6,14 +6,14 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleById +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleById { [TestFixture] public class WhenGettingArticleFromMiddleOfIssue : TestBase { private HttpResponseMessage _response; - private ArticleDto _expected; + private IssueArticleDto _expected; private IssueArticleAssert _assert; public WhenGettingArticleFromMiddleOfIssue() diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingFirstArticleOfIssue.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingFirstArticleOfIssue.cs similarity index 93% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingFirstArticleOfIssue.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingFirstArticleOfIssue.cs index 4dfece9b..32a1d512 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingFirstArticleOfIssue.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingFirstArticleOfIssue.cs @@ -6,14 +6,14 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleById +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleById { [TestFixture] public class WhenGettingFirstArticleOfIssue : TestBase { private HttpResponseMessage _response; - private ArticleDto _expected; + private IssueArticleDto _expected; private IssueArticleAssert _assert; public WhenGettingFirstArticleOfIssue() diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdAsAnonymous.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdAsAnonymous.cs similarity index 90% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdAsAnonymous.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdAsAnonymous.cs index ceeae88e..f8a78802 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdAsAnonymous.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdAsAnonymous.cs @@ -2,19 +2,18 @@ using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleById +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleById { [TestFixture] - public class WhenGettingArticleByIdAsAnonymous + public class WhenGettingIssueArticleByIdAsAnonymous : TestBase { private HttpResponseMessage _response; - private ArticleDto _expected; + private IssueArticleDto _expected; private IssueArticleAssert _assert; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdAsReader.cs similarity index 89% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdAsReader.cs index 00997bda..df295298 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdAsReader.cs @@ -3,21 +3,20 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleById +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleById { [TestFixture] - public class WhenGettingArticleByIdAsReader + public class WhenGettingIssueArticleByIdAsReader : TestBase { private HttpResponseMessage _response; - private ArticleDto _expected; + private IssueArticleDto _expected; private IssueArticleAssert _assert; - public WhenGettingArticleByIdAsReader() + public WhenGettingIssueArticleByIdAsReader() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdThatDoesNotExist.cs similarity index 86% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdThatDoesNotExist.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdThatDoesNotExist.cs index ab6d08d0..a7af6b0f 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdThatDoesNotExist.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdThatDoesNotExist.cs @@ -4,10 +4,10 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleById +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleById { [TestFixture] - public class WhenGettingArticleByIdThatDoesNotExist + public class WhenGettingIssueArticleByIdThatDoesNotExist : TestBase { private HttpResponseMessage _response; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdWithWritePermissions.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdWithWritePermissions.cs similarity index 87% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdWithWritePermissions.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdWithWritePermissions.cs index d0e6aecd..b8e347d0 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingArticleByIdWithWritePermissions.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingIssueArticleByIdWithWritePermissions.cs @@ -3,23 +3,22 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleById +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleById { [TestFixture(Role.Admin)] [TestFixture(Role.LibraryAdmin)] [TestFixture(Role.Writer)] - public class WhenGettingArticleByIdWithWritePermissions + public class WhenGettingIssueArticleByIdWithWritePermissions : TestBase { private HttpResponseMessage _response; - private ArticleDto _expected; + private IssueArticleDto _expected; private IssueArticleAssert _assert; - public WhenGettingArticleByIdWithWritePermissions(Role role) + public WhenGettingIssueArticleByIdWithWritePermissions(Role role) : base(role) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingLastArticleOfIssue.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingLastArticleOfIssue.cs similarity index 93% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingLastArticleOfIssue.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingLastArticleOfIssue.cs index aeba3309..386f62c5 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleById/WhenGettingLastArticleOfIssue.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleById/WhenGettingLastArticleOfIssue.cs @@ -6,14 +6,14 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleById +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleById { [TestFixture] public class WhenGettingLastArticleOfIssue : TestBase { private HttpResponseMessage _response; - private ArticleDto _expected; + private IssueArticleDto _expected; private IssueArticleAssert _assert; public WhenGettingLastArticleOfIssue() diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentAsReader.cs similarity index 83% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentAsReader.cs index e30ccc0f..fd529800 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentAsReader.cs @@ -4,23 +4,22 @@ using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; using Inshapardaz.Domain.Models; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleContents { [TestFixture] - public class WhenGettingArticleContentAsReader + public class WhenGettingIssueArticleContentAsReader : TestBase { private HttpResponseMessage _response; - private ArticleContentAssert _assert; + private IssueArticleContentAssert _assert; private IssueDto _issue; - private ArticleDto _article; - private ArticleContentDto _content; + private IssueArticleDto _article; + private IssueArticleContentDto _content; - public WhenGettingArticleContentAsReader() + public WhenGettingIssueArticleContentAsReader() : base(Role.Reader) { } @@ -33,7 +32,7 @@ public async Task Setup() _content = IssueBuilder.ArticleContents.Where(x => x.ArticleId == _article.Id).PickRandom(); _response = await Client.GetAsync($"/libraries/{LibraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents", _content.Language); - _assert = new ArticleContentAssert(_response, Library, _issue); + _assert = new IssueArticleContentAssert(_response, Library, _issue); } [OneTimeTearDown] diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentAsUnauthorised.cs similarity index 87% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentAsUnauthorised.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentAsUnauthorised.cs index 3b1a4329..c9a66e94 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentAsUnauthorised.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentAsUnauthorised.cs @@ -5,10 +5,10 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleContents { [TestFixture] - public class WhenGettingArticleContentAsUnauthorised + public class WhenGettingIssueArticleContentAsUnauthorised : TestBase { private HttpResponseMessage _response; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentLanguageNotExisting.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentLanguageNotExisting.cs similarity index 83% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentLanguageNotExisting.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentLanguageNotExisting.cs index a1dbd033..d16e856e 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentLanguageNotExisting.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentLanguageNotExisting.cs @@ -6,15 +6,15 @@ using System.Threading.Tasks; using Inshapardaz.Domain.Models; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleContents { [TestFixture] - public class WhenGettingArticleContentLanguageNotExisting + public class WhenGettingIssueArticleContentLanguageNotExisting : TestBase { private HttpResponseMessage _response; - public WhenGettingArticleContentLanguageNotExisting() + public WhenGettingIssueArticleContentLanguageNotExisting() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWhenNoChapterNotExists.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWhenNoChapterNotExists.cs similarity index 79% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWhenNoChapterNotExists.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWhenNoChapterNotExists.cs index 523e83c2..268c3634 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWhenNoChapterNotExists.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWhenNoChapterNotExists.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleContents { [TestFixture] - public class WhenGettingArticleContentWhenNoChapterNotExists + public class WhenGettingIssueArticleContentWhenNoChapterNotExists : TestBase { private HttpResponseMessage _response; - public WhenGettingArticleContentWhenNoChapterNotExists() + public WhenGettingIssueArticleContentWhenNoChapterNotExists() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWhenNoContent.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWhenNoContent.cs similarity index 82% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWhenNoContent.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWhenNoContent.cs index a9da4807..05005ed7 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWhenNoContent.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWhenNoContent.cs @@ -2,19 +2,18 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleContents { [TestFixture] - public class WhenGettingArticleContentWhenNoContent + public class WhenGettingIssueArticleContentWhenNoContent : TestBase { private HttpResponseMessage _response; - public WhenGettingArticleContentWhenNoContent() + public WhenGettingIssueArticleContentWhenNoContent() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWithPermission.cs similarity index 83% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWithPermission.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWithPermission.cs index ea7cec34..061b24a4 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWithPermission.cs @@ -7,21 +7,21 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleContents { [TestFixture(Role.Admin)] [TestFixture(Role.LibraryAdmin)] [TestFixture(Role.Writer)] - public class WhenGettingArticleContentWithPermission + public class WhenGettingIssueArticleContentWithPermission : TestBase { private HttpResponseMessage _response; - private ArticleContentAssert _assert; + private IssueArticleContentAssert _assert; private IssueDto _issue; - private ArticleDto _article; - private ArticleContentDto _content; + private IssueArticleDto _article; + private IssueArticleContentDto _content; - public WhenGettingArticleContentWithPermission(Role role) + public WhenGettingIssueArticleContentWithPermission(Role role) : base(role) { } @@ -34,7 +34,7 @@ public async Task Setup() _content = IssueBuilder.ArticleContents.Where(x => x.ArticleId == _article.Id).PickRandom(); _response = await Client.GetAsync($"/libraries/{LibraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents", _content.Language); - _assert = new ArticleContentAssert(_response, Library, _issue); + _assert = new IssueArticleContentAssert(_response, Library, _issue); } [OneTimeTearDown] diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWithoutLanguage.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWithoutLanguage.cs similarity index 83% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWithoutLanguage.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWithoutLanguage.cs index 34d1d247..9c470d86 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/GetArticleContents/WhenGettingArticleContentWithoutLanguage.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/GetIssueArticleContents/WhenGettingIssueArticleContentWithoutLanguage.cs @@ -5,22 +5,21 @@ using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.GetArticleContents +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.GetIssueArticleContents { [TestFixture] - public class WhenGettingArticleContentWithoutLanguage + public class WhenGettingIssueArticleContentWithoutLanguage : TestBase { private HttpResponseMessage _response; - private ArticleContentAssert _assert; + private IssueArticleContentAssert _assert; private IssueDto _issue; - private ArticleDto _article; - private ArticleContentDto _content; + private IssueArticleDto _article; + private IssueArticleContentDto _content; - public WhenGettingArticleContentWithoutLanguage() + public WhenGettingIssueArticleContentWithoutLanguage() : base(Role.Reader) { } @@ -33,7 +32,7 @@ public async Task Setup() _content = IssueBuilder.ArticleContents.Where(x => x.ArticleId == _article.Id).PickRandom(); _response = await Client.GetAsync($"/libraries/{LibraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents"); - _assert = new ArticleContentAssert(_response, Library, _issue); + _assert = new IssueArticleContentAssert(_response, Library, _issue); } [OneTimeTearDown] diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsAsReader.cs similarity index 93% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsAsReader.cs index db37d682..0429d68a 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsAsReader.cs @@ -5,7 +5,6 @@ using NUnit.Framework; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.UpdateArticleContents @@ -16,8 +15,8 @@ public class WhenUpdatingArticleContentsAsReader { private HttpResponseMessage _response; private IssueDto _issue; - private ArticleDto _article; - private ArticleContentDto _content; + private IssueArticleDto _article; + private IssueArticleContentDto _content; private string _newContents; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsAsUnauthorised.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsAsUnauthorised.cs similarity index 93% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsAsUnauthorised.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsAsUnauthorised.cs index 2170100b..9b3c060a 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsAsUnauthorised.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsAsUnauthorised.cs @@ -14,8 +14,8 @@ public class WhenUpdatingArticleContentsAsUnauthorised { private HttpResponseMessage _response; private IssueDto _issue; - private ArticleDto _article; - private ArticleContentDto _content; + private IssueArticleDto _article; + private IssueArticleContentDto _content; private string _newContents; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWhereContentNotPresent.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWhereContentNotPresent.cs similarity index 92% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWhereContentNotPresent.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWhereContentNotPresent.cs index ee98730a..f88ca7b3 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWhereContentNotPresent.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWhereContentNotPresent.cs @@ -3,7 +3,6 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; @@ -14,9 +13,9 @@ public class WhenUpdatingArticleContentsWhereContentNotPresent : TestBase { private HttpResponseMessage _response; - private ArticleContentAssert _assert; + private IssueArticleContentAssert _assert; private IssueDto _issue; - private ArticleDto _article; + private IssueArticleDto _article; private string _newContents; public WhenUpdatingArticleContentsWhereContentNotPresent() @@ -34,7 +33,7 @@ public async Task Setup() _response = await Client.PutString($"/libraries/{LibraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents", _newContents, RandomData.Locale); - _assert = new ArticleContentAssert(_response, LibraryId, _issue); + _assert = new IssueArticleContentAssert(_response, LibraryId, _issue); } [OneTimeTearDown] diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWithDifferentLanguage.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWithDifferentLanguage.cs similarity index 92% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWithDifferentLanguage.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWithDifferentLanguage.cs index 5492143b..6cbe7d4d 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWithDifferentLanguage.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWithDifferentLanguage.cs @@ -3,7 +3,6 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; @@ -14,9 +13,9 @@ public class WhenUpdatingArticleContentsWithDifferentLanguage : TestBase { private HttpResponseMessage _response; - private ArticleContentAssert _assert; + private IssueArticleContentAssert _assert; private IssueDto _issue; - private ArticleDto _article; + private IssueArticleDto _article; private string _newArticleContentLanguage; private string _newContents; @@ -36,7 +35,7 @@ public async Task Setup() _response = await Client.PutString($"/libraries/{LibraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents", _newContents, _newArticleContentLanguage); - _assert = new ArticleContentAssert(_response, LibraryId, _issue); + _assert = new IssueArticleContentAssert(_response, LibraryId, _issue); } [OneTimeTearDown] diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWithPermission.cs similarity index 92% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWithPermission.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWithPermission.cs index 2df01ece..9fa22751 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticleContents/WhenUpdatingArticleContentsWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateArticleContents/WhenUpdatingArticleContentsWithPermission.cs @@ -3,7 +3,6 @@ using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; @@ -16,9 +15,9 @@ public class WhenUpdatingArticleContentsWithPermission : TestBase { private HttpResponseMessage _response; - private ArticleContentAssert _assert; + private IssueArticleContentAssert _assert; private IssueDto _issue; - private ArticleDto _article; + private IssueArticleDto _article; private string _newContents; public WhenUpdatingArticleContentsWithPermission(Role role) @@ -36,7 +35,7 @@ public async Task Setup() _response = await Client.PutString($"/libraries/{LibraryId}/periodicals/{_issue.PeriodicalId}/volumes/{_issue.VolumeNumber}/issues/{_issue.IssueNumber}/articles/{_article.SequenceNumber}/contents", _newContents, "en"); - _assert = new ArticleContentAssert(_response, LibraryId, _issue); + _assert = new IssueArticleContentAssert(_response, LibraryId, _issue); } [OneTimeTearDown] diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleAsReader.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleAsReader.cs similarity index 86% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleAsReader.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleAsReader.cs index 65ca8f5b..c4c22ab5 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleAsReader.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleAsReader.cs @@ -6,15 +6,15 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.UpdateArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.UpdateIssueArticle { [TestFixture] - public class WhenUpdatingArticleAsReader + public class WhenUpdatingIssueArticleAsReader : TestBase { private HttpResponseMessage _response; - public WhenUpdatingArticleAsReader() + public WhenUpdatingIssueArticleAsReader() : base(Role.Reader) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleAsUnauthorized.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleAsUnauthorized.cs similarity index 88% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleAsUnauthorized.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleAsUnauthorized.cs index 09f34403..ced67e2b 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleAsUnauthorized.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleAsUnauthorized.cs @@ -5,10 +5,10 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.UpdateArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.UpdateIssueArticle { [TestFixture] - public class WhenUpdatingArticleAsUnauthorized + public class WhenUpdatingIssueArticleAsUnauthorized : TestBase { private HttpResponseMessage _response; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleThatDoesNotExist.cs similarity index 91% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleThatDoesNotExist.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleThatDoesNotExist.cs index ca7040a6..aa3cfdce 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleThatDoesNotExist.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleThatDoesNotExist.cs @@ -6,17 +6,17 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.UpdateArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.UpdateIssueArticle { [TestFixture] - public class WhenUpdatingArticleThatDoesNotExist + public class WhenUpdatingIssueArticleThatDoesNotExist : TestBase { private HttpResponseMessage _response; private IssueArticleAssert _articleAssert; private IssueArticleView _newArticle; - public WhenUpdatingArticleThatDoesNotExist() + public WhenUpdatingIssueArticleThatDoesNotExist() : base(Role.Writer) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleWithDifferentSequenceNumber.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleWithDifferentSequenceNumber.cs similarity index 88% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleWithDifferentSequenceNumber.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleWithDifferentSequenceNumber.cs index 0fbace53..fc6616cc 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleWithDifferentSequenceNumber.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleWithDifferentSequenceNumber.cs @@ -6,16 +6,16 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.UpdateArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.UpdateIssueArticle { - public class WhenUpdatingArticleWithDifferentSequenceNumber + public class WhenUpdatingIssueArticleWithDifferentSequenceNumber : TestBase { private HttpResponseMessage _response; private IssueArticleAssert _articleAssert; private IssueArticleView _newArticle; - public WhenUpdatingArticleWithDifferentSequenceNumber() + public WhenUpdatingIssueArticleWithDifferentSequenceNumber() : base(Role.Writer) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleWithPermission.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleWithPermission.cs similarity index 91% rename from src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleWithPermission.cs rename to src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleWithPermission.cs index edafef77..35ba7ab8 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/Article/UpdateArticle/WhenUpdatingArticleWithPermission.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/IssueArticle/UpdateIssueArticle/WhenUpdatingIssueArticleWithPermission.cs @@ -6,19 +6,19 @@ using System.Net.Http; using System.Threading.Tasks; -namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.Article.UpdateArticle +namespace Inshapardaz.Api.Tests.Library.Periodical.Issue.IssueArticle.UpdateIssueArticle { [TestFixture(Role.Admin)] [TestFixture(Role.LibraryAdmin)] [TestFixture(Role.Writer)] - public class WhenUpdatingArticleWithPermission + public class WhenUpdatingIssueArticleWithPermission : TestBase { private HttpResponseMessage _response; private IssueArticleAssert _articleAssert; private IssueArticleView _newArticle; - public WhenUpdatingArticleWithPermission(Role role) + public WhenUpdatingIssueArticleWithPermission(Role role) : base(role) { } diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/UpdateIssue/WhenUpdatingIssueThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/UpdateIssue/WhenUpdatingIssueThatDoesNotExist.cs index bd328f23..e309ec3e 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/UpdateIssue/WhenUpdatingIssueThatDoesNotExist.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/Issue/UpdateIssue/WhenUpdatingIssueThatDoesNotExist.cs @@ -4,7 +4,6 @@ using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using NUnit.Framework; -using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/IssuePage/GetIssuePages/WhenGettingAllIssuePages.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/IssuePage/GetIssuePages/WhenGettingAllIssuePages.cs index 80dc734b..1375c4e8 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/IssuePage/GetIssuePages/WhenGettingAllIssuePages.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/IssuePage/GetIssuePages/WhenGettingAllIssuePages.cs @@ -1,8 +1,6 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; -using Inshapardaz.Api.Extensions; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Views.Library; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalThatDoesNotExist.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalThatDoesNotExist.cs index 9476d341..fadc69b8 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalThatDoesNotExist.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalThatDoesNotExist.cs @@ -1,10 +1,12 @@ -using System.Collections.Generic; -using System.Net.Http; +using System.Net.Http; using System.Threading.Tasks; +using Bogus; +using Inshapardaz.Api.Extensions; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; using NUnit.Framework; namespace Inshapardaz.Api.Tests.Library.Periodical.UpdatePeriodical @@ -28,7 +30,8 @@ public async Task Setup() { Title = RandomData.Name, Description = RandomData.Words(10), - Language = RandomData.Locale + Language = RandomData.Locale, + Frequency = new Faker().PickRandom().ToDescription() }; _response = await Client.PutObject($"/libraries/{LibraryId}/periodicals/{_expected.Id}", _expected); diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithAdditionalCategories.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithAdditionalCategories.cs index 7d2c11f8..14e98a19 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithAdditionalCategories.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithAdditionalCategories.cs @@ -8,9 +8,9 @@ using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; using NUnit.Framework; namespace Inshapardaz.Api.Tests.Library.Periodical.UpdatePeriodical @@ -48,6 +48,7 @@ public async Task Setup() Title = fake.Name.FullName(), Description = fake.Random.Words(5), Language = Helpers.RandomData.Locale, + Frequency = new Faker().PickRandom().ToDescription(), Categories = _categoriesToUpdate.Select(c => new CategoryView { Id = c.Id }) }; diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithInvalidData.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithInvalidData.cs index af266c5e..6791e2ed 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithInvalidData.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithInvalidData.cs @@ -1,15 +1,15 @@ using System.Collections.Generic; -using System.Linq; using System.Net.Http; using System.Threading.Tasks; -using FluentAssertions; +using Bogus; +using Inshapardaz.Api.Extensions; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.DataBuilders; -using Inshapardaz.Api.Tests.DataHelpers; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; using Microsoft.Extensions.DependencyInjection; using NUnit.Framework; @@ -69,9 +69,14 @@ public async Task Setup() var periodicals = PeriodicalBuilder.WithLibrary(LibraryId).WithCategory(_category).Build(1); _periodicalToUpdate = periodicals.PickRandom(); - var book = new BookView { Title = RandomData.Text, Categories = new[] { new CategoryView { Id = -RandomData.Number } } }; + var periodical = new PeriodicalView { + Title = RandomData.Text, + Language = RandomData.Locale, + Frequency = new Faker().PickRandom().ToDescription(), + Categories = new[] { new CategoryView { Id = -RandomData.Number } } + }; - _response = await Client.PutObject($"/libraries/{LibraryId}/periodicals/{_periodicalToUpdate.Id}", book); + _response = await Client.PutObject($"/libraries/{LibraryId}/periodicals/{_periodicalToUpdate.Id}", periodical); _assert = PeriodicalAssert.WithResponse(_response); } @@ -119,7 +124,11 @@ public async Task Setup() var periodicals = PeriodicalBuilder.WithLibrary(LibraryId).WithCategory(_category).Build(1); _periodicalToUpdate = periodicals.PickRandom(); - var periodical = new PeriodicalView { Title = RandomData.Text, Language = RandomData.Locale, Categories = new[] { new CategoryView { Id = category.Id } } }; + var periodical = new PeriodicalView { + Title = RandomData.Text, + Language = RandomData.Locale, + Frequency = new Faker().PickRandom().ToDescription(), + Categories = new[] { new CategoryView { Id = category.Id } } }; _response = await Client.PutObject($"/libraries/{LibraryId}/periodicals/{_periodicalToUpdate.Id}", periodical); _assert = PeriodicalAssert.WithResponse(_response); diff --git a/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithPermissions.cs b/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithPermissions.cs index 2c00c468..2ed4cd1a 100644 --- a/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithPermissions.cs +++ b/src/Inshapardaz.Api.Tests/Library/Periodical/UpdatePeriodical/WhenUpdatingPeriodicalWithPermissions.cs @@ -7,7 +7,6 @@ using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; -using Inshapardaz.Api.Views; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; using Inshapardaz.Domain.Models.Library; diff --git a/src/Inshapardaz.Api.Tests/TestBase.cs b/src/Inshapardaz.Api.Tests/TestBase.cs index 4bf5333a..adf0ee07 100644 --- a/src/Inshapardaz.Api.Tests/TestBase.cs +++ b/src/Inshapardaz.Api.Tests/TestBase.cs @@ -108,7 +108,8 @@ private void ConfigureServices(IServiceCollection services) .AddTransient() .AddTransient() .AddTransient() - .AddTransient(); + .AddTransient() + .AddTransient(); } protected void AuthenticateClientWithToken(string token) @@ -143,6 +144,7 @@ protected void AuthenticateClientWithToken(string token) private PeriodicalsDataBuilder _periodicalBuilder; protected CorrectionBuilder _correctionBuilder; private BookShelfDataBuilder _bookshelfDataBuilder; + private ArticlesDataBuilder _articleBuilder; protected Role? CurrentAuthenticationLevel => _role; @@ -213,6 +215,19 @@ protected BooksDataBuilder BookBuilder } } + protected ArticlesDataBuilder ArticleBuilder + { + get + { + if (_articleBuilder == null) + { + _articleBuilder = _factory.Services.GetService(); + } + + return _articleBuilder; + } + } + protected BookShelfDataBuilder BookShelfBuilder { get @@ -279,15 +294,15 @@ protected CorrectionBuilder CorrectionBuilder } protected virtual void Cleanup() { - _accountBuilder?.CleanUp(); - _authorBuilder?.CleanUp(); - _seriesDataBuilder?.CleanUp(); - _categoriesDataBuilder?.CleanUp(); _booksDataBuilder?.CleanUp(); + _seriesDataBuilder?.CleanUp(); _chapterDataBuilder?.CleanUp(); _periodicalBuilder?.CleanUp(); _issueDataBuilder?.CleanUp(); + _articleBuilder?.CleanUp(); _accountBuilder?.CleanUp(); + _authorBuilder?.CleanUp(); + _categoriesDataBuilder?.CleanUp(); _bookshelfDataBuilder?.CleanUp(); _libraryBuilder?.CleanUp(); _correctionBuilder?.Cleanup(); diff --git a/src/Inshapardaz.Api.Tests/Tools/Corrections/AddCorrection/WhenAddingCorrectionAsAdmin.cs b/src/Inshapardaz.Api.Tests/Tools/Corrections/AddCorrection/WhenAddingCorrectionAsAdmin.cs index feb40ba6..79ad0b7f 100644 --- a/src/Inshapardaz.Api.Tests/Tools/Corrections/AddCorrection/WhenAddingCorrectionAsAdmin.cs +++ b/src/Inshapardaz.Api.Tests/Tools/Corrections/AddCorrection/WhenAddingCorrectionAsAdmin.cs @@ -1,7 +1,6 @@ using Inshapardaz.Api.Tests; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.DataBuilders; -using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views; using Inshapardaz.Domain.Models; diff --git a/src/Inshapardaz.Api.Tests/Tools/Corrections/DeleteCorrection/WhenDeletingCorrectionAsAdmin.cs b/src/Inshapardaz.Api.Tests/Tools/Corrections/DeleteCorrection/WhenDeletingCorrectionAsAdmin.cs index 61938b90..0f1c66d9 100644 --- a/src/Inshapardaz.Api.Tests/Tools/Corrections/DeleteCorrection/WhenDeletingCorrectionAsAdmin.cs +++ b/src/Inshapardaz.Api.Tests/Tools/Corrections/DeleteCorrection/WhenDeletingCorrectionAsAdmin.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Domain.Models; using NUnit.Framework; diff --git a/src/Inshapardaz.Api.Tests/Tools/Corrections/DeleteCorrection/WhenDeletingCorrectionAsAnonymous.cs b/src/Inshapardaz.Api.Tests/Tools/Corrections/DeleteCorrection/WhenDeletingCorrectionAsAnonymous.cs index e6edc95e..4f471eb8 100644 --- a/src/Inshapardaz.Api.Tests/Tools/Corrections/DeleteCorrection/WhenDeletingCorrectionAsAnonymous.cs +++ b/src/Inshapardaz.Api.Tests/Tools/Corrections/DeleteCorrection/WhenDeletingCorrectionAsAnonymous.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using Inshapardaz.Api.Tests.Asserts; using Inshapardaz.Api.Tests.Dto; -using Inshapardaz.Domain.Models; using NUnit.Framework; namespace Inshapardaz.Api.Tests.Tools.Corrections.DeleteCorrection diff --git a/src/Inshapardaz.Api.Tests/Tools/Corrections/UpdateCorrection/WhenUpdatingCorrectionAsAnonymous.cs b/src/Inshapardaz.Api.Tests/Tools/Corrections/UpdateCorrection/WhenUpdatingCorrectionAsAnonymous.cs index 31b60b29..989acebc 100644 --- a/src/Inshapardaz.Api.Tests/Tools/Corrections/UpdateCorrection/WhenUpdatingCorrectionAsAnonymous.cs +++ b/src/Inshapardaz.Api.Tests/Tools/Corrections/UpdateCorrection/WhenUpdatingCorrectionAsAnonymous.cs @@ -4,7 +4,6 @@ using Inshapardaz.Api.Tests.Dto; using Inshapardaz.Api.Tests.Helpers; using Inshapardaz.Api.Views; -using Inshapardaz.Domain.Models; using NUnit.Framework; namespace Inshapardaz.Api.Tests.Tools.Corrections.UpdateCorrection diff --git a/src/Inshapardaz.Api/Configuration/DatabaseConfiguration.cs b/src/Inshapardaz.Api/Configuration/DatabaseConfiguration.cs index 5dbd0de1..5d2f5349 100644 --- a/src/Inshapardaz.Api/Configuration/DatabaseConfiguration.cs +++ b/src/Inshapardaz.Api/Configuration/DatabaseConfiguration.cs @@ -25,6 +25,7 @@ public static IServiceCollection AddDatabase(this IServiceCollection services) services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -32,7 +33,7 @@ public static IServiceCollection AddDatabase(this IServiceCollection services) services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/src/Inshapardaz.Api/Controllers/ArticleController.cs b/src/Inshapardaz.Api/Controllers/ArticleController.cs new file mode 100644 index 00000000..616d1552 --- /dev/null +++ b/src/Inshapardaz.Api/Controllers/ArticleController.cs @@ -0,0 +1,316 @@ +using System; +using System.IO; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using DocumentFormat.OpenXml.Bibliography; +using Inshapardaz.Api.Converters; +using Inshapardaz.Api.Extensions; +using Inshapardaz.Api.Helpers; +using Inshapardaz.Api.Mappings; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Domain.Ports.Handlers.Library.Article; +using Inshapardaz.Domain.Ports.Handlers.Library.Book; +using Inshapardaz.Domain.Ports.Handlers.Library.Book.Chapter; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Paramore.Brighter; +using Paramore.Darker; + +namespace Inshapardaz.Api.Controllers +{ + public class ArticleController : Controller + { + private readonly IAmACommandProcessor _commandProcessor; + private readonly IQueryProcessor _queryProcessor; + private readonly IRenderArticle _articleRenderer; + private readonly IUserHelper _userHelper; + private readonly IRenderFile _fileRenderer; + + public ArticleController(IAmACommandProcessor commandProcessor, + IQueryProcessor queryProcessor, + IRenderArticle articleRenderer, + IUserHelper userHelper, + IRenderFile fileRenderer) + { + _commandProcessor = commandProcessor; + _queryProcessor = queryProcessor; + _articleRenderer = articleRenderer; + _userHelper = userHelper; + _fileRenderer = fileRenderer; + + } + + [HttpGet("libraries/{libraryId}/articles", Name = nameof(ArticleController.GetArticles))] + public async Task GetArticles(int libraryId, string query, + int pageNumber = 1, + int pageSize = 10, + [FromQuery] int? authorId = null, + [FromQuery] int? categoryId = null, + [FromQuery] bool? favorite = null, + [FromQuery] bool? read = null, + [FromQuery] EditingStatus status = EditingStatus.All, + [FromQuery] ArticleType type = ArticleType.Unknown, + [FromQuery] AssignmentStatus assignedFor = AssignmentStatus.None, + [FromQuery] ArticleSortByType sortBy = ArticleSortByType.Title, + [FromQuery] SortDirection sortDirection = SortDirection.Ascending, + CancellationToken token = default(CancellationToken)) + { + var filter = new ArticleFilter + { + AuthorId = authorId, + CategoryId = categoryId, + Favorite = favorite, + Read = read, + Status = status, + Type = type, + AssignmentStatus = assignedFor + }; + var articlesQuery = new GetArticlesQuery(libraryId, pageNumber, pageSize, _userHelper.Account?.Id) + { + Query = query, + Filter = filter, + SortBy = sortBy, + SortDirection = sortDirection + }; + var articles = await _queryProcessor.ExecuteAsync(articlesQuery, cancellationToken: token); + + var args = new PageRendererArgs + { + Page = articles, + RouteArguments = new PagedRouteArgs + { + PageNumber = pageNumber, + PageSize = pageSize, + Query = query, + SortBy = sortBy, + SortDirection = sortDirection + }, + Filters = filter, + }; + + return new OkObjectResult(_articleRenderer.Render(args, libraryId)); + } + + [HttpGet("libraries/{libraryId}/articles/{articleId}", Name = nameof(ArticleController.GetArticle))] + public async Task GetArticle(int libraryId, int articleId, CancellationToken token = default(CancellationToken)) + { + var query = new GetArticleByIdQuery(libraryId, articleId); + var article = await _queryProcessor.ExecuteAsync(query, cancellationToken: token); + + if (article != null) + { + return new OkObjectResult(_articleRenderer.Render(article, libraryId)); + } + + return new NotFoundResult(); + } + + [HttpPost("libraries/{libraryId}/articles", Name = nameof(ArticleController.CreateArticle))] + [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] + public async Task CreateArticle(int libraryId, [FromBody] ArticleView article, CancellationToken token = default(CancellationToken)) + { + if (!ModelState.IsValid) + { + return new BadRequestObjectResult(ModelState); + } + + var request = new AddArticleRequest(libraryId, article.Map()) + { + AccountId = _userHelper.Account.Id + }; + + await _commandProcessor.SendAsync(request, cancellationToken: token); + + if (request.Result != null) + { + var renderResult = _articleRenderer.Render(request.Result, libraryId); + return new CreatedResult(renderResult.Links.Self(), renderResult); + } + + return new BadRequestResult(); + } + + [HttpPut("libraries/{libraryId}/articles/{articleId}", Name = nameof(ArticleController.UpdateArticle))] + [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] + public async Task UpdateArticle(int libraryId, int articleId, [FromBody] ArticleView article, CancellationToken token = default(CancellationToken)) + { + if (!ModelState.IsValid) + { + return new BadRequestObjectResult(ModelState); + } + + var articleToUpdate = article.Map(); + articleToUpdate.Id = articleId; + var request = new UpdateArticleRequest(libraryId, articleToUpdate) + { + AccountId = _userHelper.Account.Id + }; + await _commandProcessor.SendAsync(request, cancellationToken: token); + + var renderResult = _articleRenderer.Render(request.Result.Article, libraryId); + + if (request.Result.HasAddedNew) + { + return new CreatedResult(renderResult.Links.Self(), renderResult); + } + + return new OkObjectResult(renderResult); + } + + [HttpDelete("libraries/{libraryId}/articles/{articleId}", Name = nameof(ArticleController.DeleteArticle))] + [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] + public async Task DeleteArticle(int libraryId, int articleId, CancellationToken token = default(CancellationToken)) + { + var request = new DeleteArticleRequest(libraryId, articleId); + await _commandProcessor.SendAsync(request, cancellationToken: token); + return new NoContentResult(); + } + + [HttpPut("libraries/{libraryId}/articles/{articleId}/image", Name = nameof(ArticleController.UpdateArticleImage))] + [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] + public async Task UpdateArticleImage(int libraryId, long articleId, IFormFile file, CancellationToken token = default(CancellationToken)) + { + var content = new byte[file.Length]; + using (var stream = new MemoryStream(content)) + { + await file.CopyToAsync(stream); + } + + var request = new UpdateArticleImageRequest(libraryId, articleId, _userHelper.Account?.Id) + { + Image = new FileModel + { + FileName = file.FileName, + MimeType = file.ContentType, + Contents = content + } + }; + + await _commandProcessor.SendAsync(request, cancellationToken: token); + + if (request.Result.HasAddedNew) + { + var response = _fileRenderer.Render(libraryId, request.Result.File); + + return new CreatedResult(response.Links.Self(), response); + } + + return new OkResult(); + } + + [HttpGet("libraries/{libraryId}/articles/{articleId}/contents", Name = nameof(ArticleController.GetArticleContent))] + [Authorize()] + public async Task GetArticleContent(int libraryId, int articleId, string language, CancellationToken token = default(CancellationToken)) + { + var parsedLanguage = Request.Headers["Accept-Language"]; // default to "" + + var query = new GetArticleContentQuery(libraryId, articleId, language ?? parsedLanguage); + + var articleContents = await _queryProcessor.ExecuteAsync(query, cancellationToken: token); + + if (articleContents != null) + { + return new OkObjectResult(_articleRenderer.Render(articleContents, libraryId, articleId)); + } + + return new NotFoundResult(); + } + + [HttpPost("libraries/{libraryId}/articles/{articleId}/contents", Name = nameof(CreateArticleContent))] + [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] + public async Task CreateArticleContent(int libraryId, long articleId, [FromBody] ArticleContentView content, CancellationToken token = default(CancellationToken)) + { + var contentPayload = content.Map(); + contentPayload.ArticleId = articleId; + + var request = new AddArticleContentRequest(libraryId) + { + Content = contentPayload + }; + await _commandProcessor.SendAsync(request, cancellationToken: token); + + if (request.Result != null) + { + var renderResult = _articleRenderer.Render(request.Result, libraryId, articleId); + return new CreatedResult(renderResult.Links.Self(), renderResult); + } + + return new BadRequestResult(); + } + + [HttpPut("libraries/{libraryId}/articles/{articleId}/contents", Name = nameof(ArticleController.UpdateArticleContent))] + [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] + public async Task UpdateArticleContent(int libraryId, int articleId, [FromBody] ArticleContentView content, CancellationToken token = default(CancellationToken)) + { + var contentPayload = content.Map(); + contentPayload.ArticleId = articleId; + + var request = new UpdateArticleContentRequest(libraryId) + { + Content = contentPayload + }; + await _commandProcessor.SendAsync(request, cancellationToken: token); + + var renderResult = _articleRenderer.Render(request.Result.Content, libraryId, articleId); + if (request.Result != null && request.Result.HasAddedNew) + { + return new CreatedResult(renderResult.Links.Self(), renderResult); + } + + return Ok(renderResult); + } + + [HttpDelete("libraries/{libraryId}/articles/{articleId}/contents", Name = nameof(ArticleController.DeleteArticleContent))] + [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] + public async Task DeleteArticleContent(int libraryId, int articleId, string language, CancellationToken token = default(CancellationToken)) + { + var parsedLanguage = Request.Headers["Accept-Language"]; + + var request = new DeleteArticleContentRequest(libraryId, articleId, language ?? parsedLanguage); + await _commandProcessor.SendAsync(request, cancellationToken: token); + return new NoContentResult(); + } + + [HttpPost("libraries/{libraryId}/articles/{articleId}/assign", Name = nameof(ArticleController.AssignArticleToUser))] + [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] + [Produces(typeof(IssueArticleView))] + public async Task AssignArticleToUser(int libraryId, int articleId, [FromBody] AssignmentView assignment, CancellationToken token = default(CancellationToken)) + { + if (!ModelState.IsValid) + { + return new BadRequestObjectResult(ModelState); + } + + var request = new AssignArticleToUserRequest(libraryId, articleId, assignment.AccountId ?? _userHelper.Account.Id, _userHelper.IsAdmin); + + await _commandProcessor.SendAsync(request, cancellationToken: token); + + var renderResult = _articleRenderer.Render(request.Result, libraryId); + + return Ok(renderResult); + } + + [HttpPost("libraries/{libraryId}/favorites/articles/{articleId}", Name = nameof(ArticleController.AddArticleToFavorites))] + [Authorize] + public async Task AddArticleToFavorites(int libraryId, int articleId, CancellationToken token) + { + var request = new AddArticleToFavoriteRequest(libraryId, articleId, _userHelper.Account?.Id); + await _commandProcessor.SendAsync(request, cancellationToken: token); + + return new OkResult(); + } + + [HttpDelete("libraries/{libraryId}/favorites/articles/{articleId}", Name = nameof(ArticleController.RemoveArtiucleFromFavorites))] + [Authorize] + public async Task RemoveArtiucleFromFavorites(int libraryId, int articleId, CancellationToken token) + { + var request = new RemoveArticleFromFavoriteRequest(libraryId, articleId, _userHelper.Account?.Id); + await _commandProcessor.SendAsync(request, cancellationToken: token); + + return new OkResult(); + } + } +} diff --git a/src/Inshapardaz.Api/Controllers/AuthorController.cs b/src/Inshapardaz.Api/Controllers/AuthorController.cs index 940f69c6..cf0774fe 100644 --- a/src/Inshapardaz.Api/Controllers/AuthorController.cs +++ b/src/Inshapardaz.Api/Controllers/AuthorController.cs @@ -34,6 +34,7 @@ public AuthorController(IAmACommandProcessor commandProcessor, _fileRenderer = fileRenderer; } + // TODO : Add sorting [HttpGet("libraries/{libraryId}/authors", Name = nameof(AuthorController.GetAuthors))] public async Task GetAuthors(int libraryId, string query, AuthorTypes? authorType = null, int pageNumber = 1, int pageSize = 10, CancellationToken token = default(CancellationToken)) { @@ -88,7 +89,9 @@ public AuthorController(IAmACommandProcessor commandProcessor, return new BadRequestObjectResult(ModelState); } - var request = new UpdateAuthorRequest(libraryId, author.Map()); + var authorModel = author.Map(); + authorModel.Id = authorId; + var request = new UpdateAuthorRequest(libraryId, authorModel); await _commandProcessor.SendAsync(request, cancellationToken: token); var renderResult = _authorRenderer.Render(request.Result.Author, libraryId); @@ -135,7 +138,7 @@ public AuthorController(IAmACommandProcessor commandProcessor, if (request.Result.HasAddedNew) { - var response = _fileRenderer.Render(request.Result.File); + var response = _fileRenderer.Render(libraryId, request.Result.File); return new CreatedResult(response.Links.Self(), response); } diff --git a/src/Inshapardaz.Api/Controllers/BookController.cs b/src/Inshapardaz.Api/Controllers/BookController.cs index d17a3b6d..c5a5b9d8 100644 --- a/src/Inshapardaz.Api/Controllers/BookController.cs +++ b/src/Inshapardaz.Api/Controllers/BookController.cs @@ -49,10 +49,10 @@ public async Task GetBooks(int libraryId, [FromQuery] int? bookShelfId = null, [FromQuery] bool? favorite = null, [FromQuery] bool? read = null, - [FromQuery] BookStatuses status = BookStatuses.Published, + [FromQuery] StatusType status = StatusType.Published, [FromQuery] BookSortByType sortBy = BookSortByType.Title, [FromQuery] SortDirection sortDirection = SortDirection.Ascending, - [FromQuery] BookAssignmentStatus assignedFor = BookAssignmentStatus.None, + [FromQuery] AssignmentStatus assignedFor = AssignmentStatus.None, CancellationToken token = default(CancellationToken)) { var filter = new BookFilter @@ -182,7 +182,7 @@ public async Task DeleteBook(int libraryId, int bookId, Cancellat if (request.Result.HasAddedNew) { - var response = _fileRenderer.Render(request.Result.File); + var response = _fileRenderer.Render(libraryId, request.Result.File); return new CreatedResult(response.Links.Self(), response); } @@ -240,9 +240,9 @@ public async Task DeleteBook(int libraryId, int bookId, Cancellat return new BadRequestResult(); } - [HttpPut("libraries/{libraryId}/books/{bookId}/contents", Name = nameof(BookController.UpdateBookContent))] + [HttpPut("libraries/{libraryId}/books/{bookId}/contents/{contentId}", Name = nameof(BookController.UpdateBookContent))] [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] - public async Task UpdateBookContent(int libraryId, int bookId, IFormFile file, CancellationToken token = default(CancellationToken)) + public async Task UpdateBookContent(int libraryId, int bookId, int contentId, IFormFile file, CancellationToken token = default(CancellationToken)) { var content = new byte[file.Length]; using (var stream = new MemoryStream(content)) @@ -252,7 +252,7 @@ public async Task DeleteBook(int libraryId, int bookId, Cancellat var language = Request.Headers["Accept-Language"]; var mimeType = file.ContentType; - var request = new UpdateBookContentRequest(libraryId, bookId, language, mimeType, _userHelper.Account?.Id) + var request = new UpdateBookContentRequest(libraryId, bookId, contentId, language, mimeType, _userHelper.Account?.Id) { Content = new FileModel { @@ -282,14 +282,11 @@ public async Task DeleteBook(int libraryId, int bookId, Cancellat return new BadRequestResult(); } - [HttpDelete("libraries/{libraryId}/books/{bookId}/contents", Name = nameof(BookController.DeleteBookContent))] + [HttpDelete("libraries/{libraryId}/books/{bookId}/contents/{contentId}", Name = nameof(BookController.DeleteBookContent))] [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] - public async Task DeleteBookContent(int libraryId, int bookId, CancellationToken token = default(CancellationToken)) + public async Task DeleteBookContent(int libraryId, int bookId, int contentId, CancellationToken token = default(CancellationToken)) { - var mimeType = Request.Headers["Accept"]; - var language = Request.Headers["Accept-Language"]; - - var request = new DeleteBookContentRequest(libraryId, bookId, language, mimeType); + var request = new DeleteBookContentRequest(libraryId, bookId, contentId); await _commandProcessor.SendAsync(request, cancellationToken: token); return new NoContentResult(); } @@ -308,7 +305,7 @@ public async Task AddBookToFavorites(int libraryId, int bookId, C [Authorize] public async Task RemoveBookFromFavorites(int libraryId, int bookId, CancellationToken token) { - var request = new DeleteBookToFavoriteRequest(libraryId, bookId, _userHelper.Account?.Id); + var request = new DeleteBookFromFavoriteRequest(libraryId, bookId, _userHelper.Account?.Id); await _commandProcessor.SendAsync(request, cancellationToken: token); return new OkResult(); diff --git a/src/Inshapardaz.Api/Controllers/BookPageController.cs b/src/Inshapardaz.Api/Controllers/BookPageController.cs index 2e3816e9..4af5e4e0 100644 --- a/src/Inshapardaz.Api/Controllers/BookPageController.cs +++ b/src/Inshapardaz.Api/Controllers/BookPageController.cs @@ -154,7 +154,7 @@ public async Task GetPagesByBook(int libraryId, }); } - var request = new UploadBookPages(libraryId, bookId) + var request = new UploadBookPagesRequest(libraryId, bookId) { Files = fileModels }; @@ -233,7 +233,7 @@ public async Task GetPagesByBook(int libraryId, await _commandProcessor.SendAsync(request, cancellationToken: token); - var imageLink = _bookPageRenderer.RenderImageLink(request.Result.File); + var imageLink = _bookPageRenderer.RenderImageLink(libraryId, request.Result.File); if (request.Result.HasAddedNew) { diff --git a/src/Inshapardaz.Api/Controllers/BookShelfController.cs b/src/Inshapardaz.Api/Controllers/BookShelfController.cs index 9e776a2b..87337483 100644 --- a/src/Inshapardaz.Api/Controllers/BookShelfController.cs +++ b/src/Inshapardaz.Api/Controllers/BookShelfController.cs @@ -143,7 +143,7 @@ public async Task UpdateBookShelfImage(int libraryId, int bookShe if (request.Result.HasAddedNew) { - var response = _fileRenderer.Render(request.Result.File); + var response = _fileRenderer.Render(libraryId, request.Result.File); return new CreatedResult(response.Links.Self(), response); } diff --git a/src/Inshapardaz.Api/Controllers/ChapterController.cs b/src/Inshapardaz.Api/Controllers/ChapterController.cs index 91c627cb..e961871e 100644 --- a/src/Inshapardaz.Api/Controllers/ChapterController.cs +++ b/src/Inshapardaz.Api/Controllers/ChapterController.cs @@ -135,14 +135,14 @@ public ChapterController(IAmACommandProcessor commandProcessor, [HttpPost("libraries/{libraryId}/books/{bookId}/chapters/{chapterNumber}/assign", Name = nameof(ChapterController.AssignChapterToUser))] [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] [Produces(typeof(BookPageView))] - public async Task AssignChapterToUser(int libraryId, int bookId, int chapterNumber, [FromBody] ChapterAssignmentView assignment, CancellationToken token = default(CancellationToken)) + public async Task AssignChapterToUser(int libraryId, int bookId, int chapterNumber, [FromBody] AssignmentView assignment, CancellationToken token = default(CancellationToken)) { if (!ModelState.IsValid) { return new BadRequestObjectResult(ModelState); } - var request = new AssignChapterToUserRequest(libraryId, bookId, chapterNumber, assignment.AccountId ?? _userHelper.Account.Id, _userHelper.IsAdmin); + var request = new AssignChapterToUserRequest(libraryId, bookId, chapterNumber, assignment.Unassign ? null : assignment.AccountId ?? _userHelper.Account.Id, _userHelper.IsAdmin); await _commandProcessor.SendAsync(request, cancellationToken: token); diff --git a/src/Inshapardaz.Api/Controllers/FileController.cs b/src/Inshapardaz.Api/Controllers/FileController.cs index 724147ed..fa64cf4e 100644 --- a/src/Inshapardaz.Api/Controllers/FileController.cs +++ b/src/Inshapardaz.Api/Controllers/FileController.cs @@ -34,6 +34,20 @@ public FileController(IAmACommandProcessor commandProcessor, IQueryProcessor que return File(file.Contents, file.MimeType); } + [HttpGet("libraries/{libraryId}/files/{fileId}", Name = nameof(FileController.GetLibraryFile))] + public async Task GetLibraryFile(int libraryId, int fileId, CancellationToken token = default(CancellationToken)) + { + var query = new GetFileQuery(fileId, 200, 200); + var file = await _queryProcessor.ExecuteAsync(query, token); + + if (file == null) + { + return new NotFoundResult(); + } + + return File(file.Contents, file.MimeType); + } + [HttpDelete("files/{fileId}", Name = nameof(FileController.DeleteFile))] [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] public async Task DeleteFile(int fileId, CancellationToken token = default(CancellationToken)) diff --git a/src/Inshapardaz.Api/Controllers/IssueArticleController.cs b/src/Inshapardaz.Api/Controllers/IssueArticleController.cs index 61af490c..325051ed 100644 --- a/src/Inshapardaz.Api/Controllers/IssueArticleController.cs +++ b/src/Inshapardaz.Api/Controllers/IssueArticleController.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; using Inshapardaz.Api.Converters; @@ -10,10 +8,8 @@ using Inshapardaz.Api.Mappings; using Inshapardaz.Api.Views.Library; using Inshapardaz.Domain.Models; -using Inshapardaz.Domain.Models.Library; using Inshapardaz.Domain.Ports.Handlers.Library.Periodical.Issue; using Inshapardaz.Domain.Ports.Handlers.Library.Periodical.Issue.Article; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Paramore.Brighter; using Paramore.Darker; @@ -120,7 +116,7 @@ public IssueArticleController(IAmACommandProcessor commandProcessor, [HttpPost("libraries/{libraryId}/periodicals/{periodicalId}/volumes/{volumeNumber}/issues/{issueNumber}/articles/sequence", Name = nameof(IssueArticleController.UpdateIssueArticleSequence))] [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] - public async Task UpdateIssueArticleSequence(int libraryId, int periodicalId, int volumeNumber, int issueNumber, [FromBody] IEnumerable articles, CancellationToken token = default(CancellationToken)) + public async Task UpdateIssueArticleSequence(int libraryId, int periodicalId, int volumeNumber, int issueNumber, [FromBody] IEnumerable articles, CancellationToken token = default(CancellationToken)) { if (!ModelState.IsValid) { @@ -201,7 +197,7 @@ public IssueArticleController(IAmACommandProcessor commandProcessor, [HttpPost("libraries/{libraryId}/periodicals/{periodicalId}/volumes/{volumeNumber}/issues/{issueNumber}/articles/{sequenceNumber}/assign", Name = nameof(IssueArticleController.AssignIssueArticleToUser))] [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] [Produces(typeof(IssueArticleView))] - public async Task AssignIssueArticleToUser(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, [FromBody] ChapterAssignmentView assignment, CancellationToken token = default(CancellationToken)) + public async Task AssignIssueArticleToUser(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, [FromBody] AssignmentView assignment, CancellationToken token = default(CancellationToken)) { if (!ModelState.IsValid) { diff --git a/src/Inshapardaz.Api/Controllers/IssueController.cs b/src/Inshapardaz.Api/Controllers/IssueController.cs index f06bcbbb..2c589e10 100644 --- a/src/Inshapardaz.Api/Controllers/IssueController.cs +++ b/src/Inshapardaz.Api/Controllers/IssueController.cs @@ -46,7 +46,7 @@ public async Task GetIssues(int libraryId, int periodicalId, [FromQuery] int? volumeNumber = null, [FromQuery] IssueSortByType sortBy = IssueSortByType.IssueDate, [FromQuery] SortDirection sortDirection = SortDirection.Ascending, - [FromQuery] BookAssignmentStatus assignedFor = BookAssignmentStatus.None, + [FromQuery] AssignmentStatus assignedFor = AssignmentStatus.None, CancellationToken token = default(CancellationToken)) { var filter = new IssueFilter @@ -55,7 +55,8 @@ public async Task GetIssues(int libraryId, int periodicalId, VolumeNumber = volumeNumber, AssignmentStatus = assignedFor }; - var issuesQuery = new GetIssuesQuery(libraryId, periodicalId, pageNumber, pageSize) { + var issuesQuery = new GetIssuesQuery(libraryId, periodicalId, pageNumber, pageSize) + { Filter = filter, SortBy = sortBy, SortDirection = sortDirection @@ -68,8 +69,9 @@ public async Task GetIssues(int libraryId, int periodicalId, var args = new PageRendererArgs { Page = result, - RouteArguments = new PagedRouteArgs { - PageNumber = pageNumber, + RouteArguments = new PagedRouteArgs + { + PageNumber = pageNumber, PageSize = pageSize, SortBy = sortBy, SortDirection = sortDirection @@ -100,7 +102,7 @@ public async Task GetIssues(int libraryId, int periodicalId, [HttpPost("libraries/{libraryId}/periodicals/{periodicalId}/issues", Name = nameof(IssueController.CreateIssue))] [Authorize(Role.Admin, Role.LibraryAdmin, Role.Writer)] - public async Task CreateIssue(int libraryId, int periodicalId, [FromBody]IssueView issue, CancellationToken token = default(CancellationToken)) + public async Task CreateIssue(int libraryId, int periodicalId, [FromBody] IssueView issue, CancellationToken token = default(CancellationToken)) { if (!ModelState.IsValid) { @@ -170,7 +172,7 @@ public async Task GetIssues(int libraryId, int periodicalId, if (request.Result.HasAddedNew) { - var response = _fileRenderer.Render(request.Result.File); + var response = _fileRenderer.Render(libraryId, request.Result.File); return new CreatedResult(response.Links.Self(), response); } diff --git a/src/Inshapardaz.Api/Controllers/IssuePageController.cs b/src/Inshapardaz.Api/Controllers/IssuePageController.cs index 6fa4fb9c..ae92aaf3 100644 --- a/src/Inshapardaz.Api/Controllers/IssuePageController.cs +++ b/src/Inshapardaz.Api/Controllers/IssuePageController.cs @@ -278,7 +278,7 @@ public async Task UpdateIssuePageImage(int libraryId, await _commandProcessor.SendAsync(request, cancellationToken: token); - var imageLink = _issuePageRenderer.RenderImageLink(request.Result.File); + var imageLink = _issuePageRenderer.RenderImageLink(libraryId, request.Result.File); if (request.Result.HasAddedNew) { diff --git a/src/Inshapardaz.Api/Controllers/LibraryController.cs b/src/Inshapardaz.Api/Controllers/LibraryController.cs index 2f694521..11c1c377 100644 --- a/src/Inshapardaz.Api/Controllers/LibraryController.cs +++ b/src/Inshapardaz.Api/Controllers/LibraryController.cs @@ -182,7 +182,7 @@ public async Task RemoveLibraryFromAccount(int accountId, int lib if (request.Result.HasAddedNew) { - var response = _fileRenderer.Render(request.Result.File); + var response = _fileRenderer.Render(libraryId, request.Result.File); return new CreatedResult(response.Links.Self(), response); } diff --git a/src/Inshapardaz.Api/Controllers/PeriodicalController.cs b/src/Inshapardaz.Api/Controllers/PeriodicalController.cs index 61a9a29b..fdb588a4 100644 --- a/src/Inshapardaz.Api/Controllers/PeriodicalController.cs +++ b/src/Inshapardaz.Api/Controllers/PeriodicalController.cs @@ -163,7 +163,7 @@ public async Task GetPeriodicals(int libraryId, if (request.Result.HasAddedNew) { - var response = _fileRenderer.Render(request.Result.File); + var response = _fileRenderer.Render(libraryId, request.Result.File); return new CreatedResult(response.Links.Self(), response); } diff --git a/src/Inshapardaz.Api/Controllers/SeriesController.cs b/src/Inshapardaz.Api/Controllers/SeriesController.cs index 464e71a3..f28285c1 100644 --- a/src/Inshapardaz.Api/Controllers/SeriesController.cs +++ b/src/Inshapardaz.Api/Controllers/SeriesController.cs @@ -137,7 +137,7 @@ public SeriesController(IAmACommandProcessor commandProcessor, if (request.Result.HasAddedNew) { - var response = _fileRenderer.Render(request.Result.File); + var response = _fileRenderer.Render(libraryId, request.Result.File); return new CreatedResult(response.Links.Self(), response); } diff --git a/src/Inshapardaz.Api/Controllers/UserController.cs b/src/Inshapardaz.Api/Controllers/UserController.cs index 1157b920..ebe6ba8f 100644 --- a/src/Inshapardaz.Api/Controllers/UserController.cs +++ b/src/Inshapardaz.Api/Controllers/UserController.cs @@ -114,7 +114,7 @@ public async Task GetIssuePagesByUser(int libraryId, public async Task GetBooksByUser(int libraryId, int pageNumber = 1, int pageSize = 10, - [FromQuery] BookStatuses status = BookStatuses.BeingTyped, + [FromQuery] StatusType status = StatusType.BeingTyped, CancellationToken token = default(CancellationToken)) { var accountId = _userHelper.Account.Id; diff --git a/src/Inshapardaz.Api/Converters/ArticleRenderer.cs b/src/Inshapardaz.Api/Converters/ArticleRenderer.cs new file mode 100644 index 00000000..aa6573da --- /dev/null +++ b/src/Inshapardaz.Api/Converters/ArticleRenderer.cs @@ -0,0 +1,359 @@ +using DocumentFormat.OpenXml.Wordprocessing; +using Inshapardaz.Api.Controllers; +using Inshapardaz.Api.Extensions; +using Inshapardaz.Api.Helpers; +using Inshapardaz.Api.Mappings; +using Inshapardaz.Api.Views; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Domain.Models.Library; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +using System.Collections.Generic; +using System.Linq; + +namespace Inshapardaz.Api.Converters +{ + public interface IRenderArticle + { + ArticleContentView Render(ArticleContentModel source, int libraryId, long articleId); + + ArticleView Render(ArticleModel source, int libraryId); + + PageView Render(PageRendererArgs source, int libraryId); + } + + public class ArticleRenderer : IRenderArticle + { + private readonly IRenderLink _linkRenderer; + private readonly IRenderAuthor _authorRenderer; + private readonly IRenderCategory _categoryRenderer; + private readonly IUserHelper _userHelper; + + public ArticleRenderer(IRenderLink linkRenderer, IRenderAuthor authorRenderer, IRenderCategory categoryRenderer, IUserHelper userHelper) + { + _linkRenderer = linkRenderer; + _authorRenderer = authorRenderer; + _categoryRenderer = categoryRenderer; + _userHelper = userHelper; + } + + public PageView Render(PageRendererArgs source, int libraryId) + { + var page = new PageView(source.Page.TotalCount, source.Page.PageSize, source.Page.PageNumber) + { + Data = source.Page.Data?.Select(x => Render(x, libraryId)) + }; + + Dictionary query = CreateQueryString(source, page); + query.Add("pageNumber", (page.CurrentPageIndex).ToString()); + + page.Links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.GetArticles), + Method = HttpMethod.Get, + Rel = RelTypes.Self, + Parameters = new { libraryId = libraryId }, + QueryString = query + })); + + if (_userHelper.IsWriter(libraryId) || _userHelper.IsAdmin || _userHelper.IsLibraryAdmin(libraryId)) + { + page.Links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.CreateArticle), + Method = HttpMethod.Post, + Rel = RelTypes.Create, + Parameters = new { libraryId = libraryId } + })); + } + + if (page.CurrentPageIndex < page.PageCount) + { + var pageQuery = CreateQueryString(source, page); + pageQuery.Add("pageNumber", (page.CurrentPageIndex + 1).ToString()); + + page.Links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.GetArticles), + Method = HttpMethod.Get, + Rel = RelTypes.Next, + Parameters = new { libraryId = libraryId }, + QueryString = pageQuery + })); + } + + if (page.PageCount > 1 && page.CurrentPageIndex > 1 && page.CurrentPageIndex <= page.PageCount) + { + var pageQuery = CreateQueryString(source, page); + pageQuery.Add("pageNumber", (page.CurrentPageIndex - 1).ToString()); + + page.Links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.GetArticles), + Method = HttpMethod.Get, + Rel = RelTypes.Previous, + Parameters = new { libraryId = libraryId }, + QueryString = pageQuery + })); + } + + return page; + } + + public ArticleView Render(ArticleModel source, int libraryId) + { + var result = source.Map(); + var links = new List + { + _linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.GetArticle), + Method = HttpMethod.Get, + Rel = RelTypes.Self, + Parameters = new { libraryId = libraryId, articleId = source.Id} + }) + }; + + + if (source.ImageId.HasValue) + { + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(FileController.GetLibraryFile), + Method = HttpMethod.Get, + Rel = RelTypes.Image, + Parameters = new { libraryId = libraryId, fileId = source.ImageId.Value } + })); + } + + if (source.Contents != null && source.Contents.Any()) + { + var contents = new List(); + foreach (var content in source.Contents) + { + contents.Add(Render(content, libraryId, source.Id)); + } + + result.Contents = contents; + } + + if (source.PreviousArticle != null) + { + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.GetArticle), + Method = HttpMethod.Get, + Rel = RelTypes.Previous, + Parameters = new { libraryId = libraryId, articleId = source.PreviousArticle.Id } + })); + } + + if (source.NextArticle != null) + { + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.GetArticle), + Method = HttpMethod.Get, + Rel = RelTypes.Next, + Parameters = new { libraryId = libraryId, articleId = source.NextArticle.Id } + })); + } + + if (_userHelper.IsWriter(libraryId)) + { + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.UpdateArticle), + Method = HttpMethod.Put, + Rel = RelTypes.Update, + Parameters = new { libraryId = libraryId, articleId = source.Id } + })); + + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.DeleteArticle), + Method = HttpMethod.Delete, + Rel = RelTypes.Delete, + Parameters = new { libraryId = libraryId, articleId = source.Id } + })); + + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.UpdateArticleContent), + Method = HttpMethod.Put, + Rel = RelTypes.AddContent, + Parameters = new { libraryId = libraryId, articleId = source.Id } + })); + + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.UpdateArticleImage), + Method = HttpMethod.Put, + Rel = RelTypes.ImageUpload, + Parameters = new { libraryId = libraryId, articleId = source.Id } + })); + + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.AssignArticleToUser), + Method = HttpMethod.Post, + Rel = RelTypes.Assign, + Parameters = new { libraryId = libraryId, articleId = source.Id } + })); + } + + if (_userHelper.IsAuthenticated) + { + if (source.Contents != null && source.Contents.Any()) + { + var contents = new List(); + foreach (var content in source.Contents) + { + contents.Add(Render(content, libraryId, source.Id)); + } + + result.Contents = contents; + } + + if (source.IsFavorite) + { + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.RemoveArtiucleFromFavorites), + Method = HttpMethod.Delete, + Rel = RelTypes.RemoveFavorite, + Parameters = new { libraryId = libraryId, articleId = source.Id } + })); + } + else + { + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.AddArticleToFavorites), + Method = HttpMethod.Post, + Rel = RelTypes.CreateFavorite, + Parameters = new { libraryId = libraryId, articleId = source.Id } + })); + } + } + + if (source.Authors.Any()) + { + var authors = new List(); + foreach (var author in source.Authors) + { + authors.Add(_authorRenderer.Render(author, libraryId)); + } + + result.Authors = authors; + } + + if (source.Categories != null) + { + var categories = new List(); + foreach (var category in source.Categories) + { + categories.Add(_categoryRenderer.Render(category, libraryId)); + } + + result.Categories = categories; + } + + result.Links = links; + return result; + } + + public ArticleContentView Render(ArticleContentModel source, int libraryId, long articleId) + { + var result = source.Map(); + + var links = new List + { + _linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.GetArticleContent), + Method = HttpMethod.Get, + Rel = RelTypes.Self, + Language = source.Language, + Parameters = new { libraryId = libraryId, articleId = articleId }, + QueryString = new Dictionary{{ "language", source.Language}} + }), + _linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.GetArticle), + Method = HttpMethod.Get, + Rel = RelTypes.Article, + Parameters = new { libraryId = libraryId, articleId = articleId } + }) + }; + + if (_userHelper.IsWriter(libraryId)) + { + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.UpdateArticleContent), + Method = HttpMethod.Put, + Rel = RelTypes.Update, + Language = source.Language, + Parameters = new { libraryId = libraryId, articleId = articleId }, + QueryString = new Dictionary { { "language", source.Language } } + })); + + links.Add(_linkRenderer.Render(new Link + { + ActionName = nameof(ArticleController.DeleteArticleContent), + Method = HttpMethod.Delete, + Rel = RelTypes.Delete, + Language = source.Language, + Parameters = new { libraryId = libraryId, articleId = articleId }, + QueryString = new Dictionary { { "language", source.Language } } + })); + } + + result.Links = links; + return result; + } + + private static Dictionary CreateQueryString(PageRendererArgs source, PageView page) + { + Dictionary queryString = new Dictionary { + { "pageSize", page.PageSize.ToString() } + }; + + if (!string.IsNullOrWhiteSpace(source.RouteArguments.Query)) + { + queryString.Add("query", source.RouteArguments.Query); + } + + if (source.Filters != null) + { + if (source.Filters.AuthorId.HasValue) + queryString.Add("authorid", source.Filters.AuthorId.Value.ToString()); + + if (source.Filters.CategoryId.HasValue) + queryString.Add("categoryid", source.Filters.CategoryId.Value.ToString()); + + if (source.Filters.Favorite.HasValue) + queryString.Add("favorite", bool.TrueString); + + if (source.Filters.Read.HasValue) + queryString.Add("read", bool.TrueString); + + if (source.Filters.Status != Domain.Models.EditingStatus.Completed) + queryString.Add("status", source.Filters.Status.ToDescription()); + + if (source.Filters.Type != ArticleType.Unknown) + queryString.Add("type", source.Filters.Type.ToDescription()); + + if (source.Filters.AssignmentStatus != AssignmentStatus.None) + queryString.Add("assignedfor", source.Filters.AssignmentStatus.ToDescription()); + } + + if (source.RouteArguments.SortBy != ArticleSortByType.Title) + queryString.Add("sortby", source.RouteArguments.SortBy.ToDescription()); + + if (source.RouteArguments.SortDirection != SortDirection.Ascending) + queryString.Add("sortDirection", source.RouteArguments.SortDirection.ToDescription()); + return queryString; + } + } +} diff --git a/src/Inshapardaz.Api/Converters/AuthorRenderer.cs b/src/Inshapardaz.Api/Converters/AuthorRenderer.cs index 0d3b7aeb..89ab96ba 100644 --- a/src/Inshapardaz.Api/Converters/AuthorRenderer.cs +++ b/src/Inshapardaz.Api/Converters/AuthorRenderer.cs @@ -145,10 +145,10 @@ public AuthorView Render(AuthorModel source, int libraryId) { links.Add(_linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = source.ImageId.Value } + Parameters = new { libraryId = libraryId, fileId = source.ImageId.Value } })); } diff --git a/src/Inshapardaz.Api/Converters/BookPageRenderer.cs b/src/Inshapardaz.Api/Converters/BookPageRenderer.cs index d5fc5fb0..ba888988 100644 --- a/src/Inshapardaz.Api/Converters/BookPageRenderer.cs +++ b/src/Inshapardaz.Api/Converters/BookPageRenderer.cs @@ -20,7 +20,7 @@ public interface IRenderBookPage PageView Render(PageRendererArgs source, int libraryId, int bookId); PageView RenderUserPages(PageRendererArgs source, int libraryId); - LinkView RenderImageLink(FileModel file); + LinkView RenderImageLink(int libraryId, FileModel file); } public class BookPageRenderer : IRenderBookPage @@ -198,10 +198,10 @@ public BookPageView Render(BookPageModel source, int libraryId) { links.Add(_linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = source.ImageId.Value } + Parameters = new { libraryId = libraryId, fileId = source.ImageId.Value } })); } @@ -322,7 +322,7 @@ public BookPageView Render(BookPageModel source, int libraryId) return result; } - public LinkView RenderImageLink(FileModel file) + public LinkView RenderImageLink(int libraryId, FileModel file) { if (!string.IsNullOrWhiteSpace(file.FilePath) && _fileStorage.SupportsPublicLink) { @@ -337,10 +337,10 @@ public LinkView RenderImageLink(FileModel file) return _linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = file.Id } + Parameters = new { libraryId = libraryId, fileId = file.Id } }); } diff --git a/src/Inshapardaz.Api/Converters/BookRenderer.cs b/src/Inshapardaz.Api/Converters/BookRenderer.cs index 317bb9cb..cd9b5ac4 100644 --- a/src/Inshapardaz.Api/Converters/BookRenderer.cs +++ b/src/Inshapardaz.Api/Converters/BookRenderer.cs @@ -125,7 +125,7 @@ private static Dictionary CreateQueryString(PageRendererArgs CreateQueryString(PageRendererArgs { _linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Self, - Parameters = new { fileId = source.Id }, + Parameters = new { libraryId = libraryId, fileId = source.Id }, }) }; diff --git a/src/Inshapardaz.Api/Converters/IssueArticleRenderer.cs b/src/Inshapardaz.Api/Converters/IssueArticleRenderer.cs index 079dfaa9..ef4d3cc9 100644 --- a/src/Inshapardaz.Api/Converters/IssueArticleRenderer.cs +++ b/src/Inshapardaz.Api/Converters/IssueArticleRenderer.cs @@ -12,7 +12,7 @@ namespace Inshapardaz.Api.Converters { public interface IRenderIssueArticle { - ArticleContentView Render(ArticleContentModel source, int libraryId); + IssueArticleContentView Render(IssueArticleContentModel source, int libraryId); IssueArticleView Render(IssueArticleModel source, int libraryId, int periodicalId, int volumeNumber, int issueNumber); @@ -152,7 +152,7 @@ public IssueArticleView Render(IssueArticleModel source, int libraryId, int peri if (_userHelper.IsAuthenticated) { - var contents = new List(); + var contents = new List(); foreach (var content in source.Contents) { contents.Add(Render(content, libraryId)); @@ -165,7 +165,7 @@ public IssueArticleView Render(IssueArticleModel source, int libraryId, int peri return result; } - public ArticleContentView Render(ArticleContentModel source, int libraryId) + public IssueArticleContentView Render(IssueArticleContentModel source, int libraryId) { var result = source.Map(); @@ -210,7 +210,7 @@ public ArticleContentView Render(ArticleContentModel source, int libraryId) Method = HttpMethod.Put, Rel = RelTypes.Update, Language = source.Language, - Parameters = new { libraryId = libraryId, periodicalId = source.PeriodicalId, volumeNumber = source.VolumeNumber, issueNumber = source.IssueNumber, sequenceNumber = source.SequenceNumber } + Parameters = new { libraryId = libraryId, periodicalId = source.PeriodicalId, volumeNumber = source.VolumeNumber, issueNumber = source.IssueNumber, sequenceNumber = source.SequenceNumber } })); links.Add(_linkRenderer.Render(new Link @@ -219,7 +219,7 @@ public ArticleContentView Render(ArticleContentModel source, int libraryId) Method = HttpMethod.Delete, Rel = RelTypes.Delete, Language = source.Language, - Parameters = new { libraryId = libraryId, periodicalId = source.PeriodicalId, volumeNumber = source.VolumeNumber, issueNumber = source.IssueNumber, sequenceNumber = source.SequenceNumber } + Parameters = new { libraryId = libraryId, periodicalId = source.PeriodicalId, volumeNumber = source.VolumeNumber, issueNumber = source.IssueNumber, sequenceNumber = source.SequenceNumber } })); } diff --git a/src/Inshapardaz.Api/Converters/IssuePageRenderer.cs b/src/Inshapardaz.Api/Converters/IssuePageRenderer.cs index b1c5c258..0fb4f14b 100644 --- a/src/Inshapardaz.Api/Converters/IssuePageRenderer.cs +++ b/src/Inshapardaz.Api/Converters/IssuePageRenderer.cs @@ -20,7 +20,7 @@ public interface IRenderIssuePage PageView Render(PageRendererArgs source, int libraryId, int periodicalId, int volumeNumber, int issueNumber); PageView RenderUserPages(PageRendererArgs source, int libraryId); - LinkView RenderImageLink(FileModel file); + LinkView RenderImageLink(int libraryId, FileModel file); } public class IssuePageRenderer : IRenderIssuePage @@ -219,10 +219,10 @@ public IssuePageView Render(IssuePageModel source, int libraryId) { links.Add(_linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = source.ImageId.Value } + Parameters = new { libraryId = libraryId, fileId = source.ImageId.Value } })); } @@ -409,7 +409,7 @@ public IssuePageView Render(IssuePageModel source, int libraryId) return result; } - public LinkView RenderImageLink(FileModel file) + public LinkView RenderImageLink(int libraryId, FileModel file) { if (!string.IsNullOrWhiteSpace(file.FilePath) && _fileStorage.SupportsPublicLink) { @@ -424,10 +424,10 @@ public LinkView RenderImageLink(FileModel file) return _linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = file.Id } + Parameters = new { libraryId = libraryId, fileId = file.Id } }); } diff --git a/src/Inshapardaz.Api/Converters/IssueRenderer.cs b/src/Inshapardaz.Api/Converters/IssueRenderer.cs index 9c38a6fa..cefcca05 100644 --- a/src/Inshapardaz.Api/Converters/IssueRenderer.cs +++ b/src/Inshapardaz.Api/Converters/IssueRenderer.cs @@ -153,10 +153,10 @@ public IssueView Render(IssueModel source, int libraryId) { links.Add(_linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = source.ImageId.Value } + Parameters = new { libraryId = libraryId, fileId = source.ImageId.Value } })); } @@ -288,12 +288,12 @@ public IssueContentView Render(IssueContentModel source, int libraryId) { links.Add(_linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Download, Language = source.Language, MimeType = source.MimeType, - Parameters = new { fileId = source.FileId } + Parameters = new { libraryId = libraryId, fileId = source.FileId } })); } diff --git a/src/Inshapardaz.Api/Converters/LibraryRenderer.cs b/src/Inshapardaz.Api/Converters/LibraryRenderer.cs index ff623a98..4c095eff 100644 --- a/src/Inshapardaz.Api/Converters/LibraryRenderer.cs +++ b/src/Inshapardaz.Api/Converters/LibraryRenderer.cs @@ -8,6 +8,7 @@ using Inshapardaz.Api.Extensions; using Inshapardaz.Domain.Models; using Inshapardaz.Domain.Repositories; +using Microsoft.Extensions.DependencyModel; namespace Inshapardaz.Api.Converters { @@ -189,10 +190,10 @@ public LibraryView Render(LibraryModel model) { links.Add(_linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = model.ImageId.Value } + Parameters = new { libraryId = model.Id, fileId = model.ImageId.Value } })); } diff --git a/src/Inshapardaz.Api/Converters/PeriodicalRenderer.cs b/src/Inshapardaz.Api/Converters/PeriodicalRenderer.cs index c0f084b5..26473e2a 100644 --- a/src/Inshapardaz.Api/Converters/PeriodicalRenderer.cs +++ b/src/Inshapardaz.Api/Converters/PeriodicalRenderer.cs @@ -139,10 +139,10 @@ public PeriodicalView Render(PeriodicalModel source, int libraryId) { links.Add(_linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = source.ImageId.Value } + Parameters = new { libraryId = libraryId, fileId = source.ImageId.Value } })); } diff --git a/src/Inshapardaz.Api/Converters/SeriesRenderer.cs b/src/Inshapardaz.Api/Converters/SeriesRenderer.cs index 1df00175..b2204884 100644 --- a/src/Inshapardaz.Api/Converters/SeriesRenderer.cs +++ b/src/Inshapardaz.Api/Converters/SeriesRenderer.cs @@ -142,10 +142,10 @@ public SeriesView Render(SeriesModel series, int libraryId) { view.Links.Add(_linkRenderer.Render(new Link { - ActionName = nameof(FileController.GetFile), + ActionName = nameof(FileController.GetLibraryFile), Method = HttpMethod.Get, Rel = RelTypes.Image, - Parameters = new { fileId = series.ImageId.Value } + Parameters = new { libraryId = libraryId, fileId = series.ImageId.Value } })); } diff --git a/src/Inshapardaz.Api/Helpers/AuthorizeAttribute.cs b/src/Inshapardaz.Api/Helpers/AuthorizeAttribute.cs index 671f8cc4..61cb541a 100644 --- a/src/Inshapardaz.Api/Helpers/AuthorizeAttribute.cs +++ b/src/Inshapardaz.Api/Helpers/AuthorizeAttribute.cs @@ -50,7 +50,8 @@ public void OnAuthorization(AuthorizationFilterContext context) { var library = libraries.SingleOrDefault(l => l.Id == libraryId); - if (library != null && _roles.Contains(library.Role)) + if (library == null) return; + if (_roles.Contains(library.Role)) { return; } diff --git a/src/Inshapardaz.Domain/Adapters/TokenGenerator.cs b/src/Inshapardaz.Api/Infrastructure/TokenGenerator.cs similarity index 85% rename from src/Inshapardaz.Domain/Adapters/TokenGenerator.cs rename to src/Inshapardaz.Api/Infrastructure/TokenGenerator.cs index f022637f..81196521 100644 --- a/src/Inshapardaz.Domain/Adapters/TokenGenerator.cs +++ b/src/Inshapardaz.Api/Infrastructure/TokenGenerator.cs @@ -1,4 +1,5 @@ -using Inshapardaz.Domain.Common; +using Inshapardaz.Domain.Adapters; +using Inshapardaz.Domain.Common; using Inshapardaz.Domain.Models; using Microsoft.IdentityModel.Tokens; using System; @@ -7,16 +8,8 @@ using System.Security.Claims; using System.Text; -namespace Inshapardaz.Domain.Adapters +namespace Inshapardaz.Api.Infrastructure { - public interface IGenerateToken - { - string GenerateAccessToken(AccountModel account); - - RefreshTokenModel GenerateRefreshToken(string ipAddress); - - string GenerateResetToken(); - } public class TokenGenerator : IGenerateToken { diff --git a/src/Inshapardaz.Api/Inshapardaz.Api.csproj b/src/Inshapardaz.Api/Inshapardaz.Api.csproj index 19f64f5b..449a2d81 100644 --- a/src/Inshapardaz.Api/Inshapardaz.Api.csproj +++ b/src/Inshapardaz.Api/Inshapardaz.Api.csproj @@ -4,22 +4,22 @@ false - + - + - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + - + - + diff --git a/src/Inshapardaz.Api/Mappings/ArticleMapper.cs b/src/Inshapardaz.Api/Mappings/ArticleMapper.cs new file mode 100644 index 00000000..e5822edb --- /dev/null +++ b/src/Inshapardaz.Api/Mappings/ArticleMapper.cs @@ -0,0 +1,71 @@ +using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Api.Views.Library; +using Inshapardaz.Api.Extensions; +using Inshapardaz.Domain.Models; +using System.Linq; + +namespace Inshapardaz.Api.Mappings +{ + public static class ArticleMapper + { + public static ArticleView Map(this ArticleModel source) + => source == null ? null : new ArticleView + { + Id = source.Id, + Title = source.Title, + IsPublic = source.IsPublic, + Status = source.Status.ToDescription(), + Type = source.Type.ToDescription(), + WriterAccountId = source.WriterAccountId, + WriterAccountName = source.WriterAccountName, + WriterAssignTimeStamp = source.WriterAssignTimeStamp, + ReviewerAccountId = source.ReviewerAccountId, + ReviewerAccountName = source.ReviewerAccountName, + ReviewerAssignTimeStamp = source.ReviewerAssignTimeStamp, + Authors = source.Authors?.Select(a => a.Map()), + Categories = source.Categories?.Select(c => c.Map()), + Contents = source?.Contents?.Select(c => c.Map()).ToList(), + LastModified = source?.LastModified + }; + + public static ArticleModel Map(this ArticleView source) + => source == null ? null : new ArticleModel + { + Id = source.Id, + Title = source.Title, + IsPublic = source.IsPublic, + Status = source.Status.ToEnum(EditingStatus.Available), + Type = source.Type.ToEnum(ArticleType.Unknown), + WriterAccountId = source.WriterAccountId, + WriterAccountName = source.WriterAccountName, + WriterAssignTimeStamp = source.WriterAssignTimeStamp, + ReviewerAccountId = source.ReviewerAccountId, + ReviewerAccountName = source.ReviewerAccountName, + ReviewerAssignTimeStamp = source.ReviewerAssignTimeStamp, + Authors = source.Authors?.Select(x => x.Map()).ToList(), + Categories = source.Categories?.Select(x => x.Map()).ToList(), + Contents = source?.Contents?.Select(c => c.Map()).ToList(), + LastModified = source?.LastModified + }; + + public static ArticleContentView Map(this ArticleContentModel source) + => new ArticleContentView + { + Id = source.Id, + ArticleId = source.ArticleId, + Language = source.Language, + Text = source.Text, + Layout = source.Layout + }; + + public static ArticleContentModel Map(this ArticleContentView source) + => new ArticleContentModel + { + Id = source.Id, + ArticleId = source.ArticleId, + Language = source.Language, + Text = source.Text, + Layout = source.Layout + }; + } +} diff --git a/src/Inshapardaz.Api/Mappings/AuthorMapper.cs b/src/Inshapardaz.Api/Mappings/AuthorMapper.cs index f23399a9..bde628ee 100644 --- a/src/Inshapardaz.Api/Mappings/AuthorMapper.cs +++ b/src/Inshapardaz.Api/Mappings/AuthorMapper.cs @@ -13,6 +13,7 @@ public static AuthorView Map(this AuthorModel source) Name = source.Name, Description = source.Description, BookCount = source.BookCount, + ArticleCount = source.ArticleCount, AuthorType = source.AuthorType.ToDescription() }; diff --git a/src/Inshapardaz.Api/Mappings/BookMapper.cs b/src/Inshapardaz.Api/Mappings/BookMapper.cs index beb06c6b..8011c5b0 100644 --- a/src/Inshapardaz.Api/Mappings/BookMapper.cs +++ b/src/Inshapardaz.Api/Mappings/BookMapper.cs @@ -28,6 +28,8 @@ public static class BookMapper Categories = source.Categories?.Select(c => c.Map()), PageCount = source.PageCount, ChapterCount = source.ChapterCount, + Source = source.Source, + Publisher = source.Publisher, PageStatus = source.PageStatus?.Select(ps => ps.Map()), Authors = source.Authors?.Select(c => c.Map()), }; @@ -44,9 +46,11 @@ public static class BookMapper SeriesId = source.SeriesId, SeriesIndex = source.SeriesIndex, Copyrights = source.Copyrights.ToEnum(CopyrightStatuses.Copyright), - Status = source.Status.ToEnum(BookStatuses.AvailableForTyping), + Status = source.Status.ToEnum(StatusType.AvailableForTyping), YearPublished = source.YearPublished, IsPublished = source.IsPublished, + Source = source.Source, + Publisher = source.Publisher, Progress = source.Progress, Categories = source.Categories?.Select(c => c.Map()).ToList(), PageCount = source.PageCount, @@ -61,7 +65,8 @@ public static BookContentView Map(this BookContentModel source) Id = source.Id, BookId = source.BookId, Language = source.Language, - MimeType = source.MimeType + MimeType = source.MimeType, + FileName = source.FileName, }; public static BookContentModel Map(this BookContentView source) diff --git a/src/Inshapardaz.Api/Mappings/PeriodicalMapper.cs b/src/Inshapardaz.Api/Mappings/PeriodicalMapper.cs index 4cb4ffe8..33facff6 100644 --- a/src/Inshapardaz.Api/Mappings/PeriodicalMapper.cs +++ b/src/Inshapardaz.Api/Mappings/PeriodicalMapper.cs @@ -114,15 +114,15 @@ public static IssueArticleModel Map(this IssueArticleView source) ReviewerAssignTimeStamp = source.ReviewerAssignTimeStamp }; - public static IssueArticleModel Map(this ArticleSequenceView source) + public static IssueArticleModel Map(this SequenceView source) => source == null ? null : new IssueArticleModel { Id = source.Id, SequenceNumber = source.SequenceNumber, }; - public static ArticleContentView Map(this ArticleContentModel source) - => new ArticleContentView + public static IssueArticleContentView Map(this IssueArticleContentModel source) + => new IssueArticleContentView { Id = source.Id, PeriodicalId = source.PeriodicalId, @@ -133,8 +133,8 @@ public static ArticleContentView Map(this ArticleContentModel source) Text = source.Text }; - public static ArticleContentModel Map(this ArticleContentView source) - => new ArticleContentModel + public static IssueArticleContentModel Map(this IssueArticleContentView source) + => new IssueArticleContentModel { Id = source.Id, PeriodicalId = source.PeriodicalId, diff --git a/src/Inshapardaz.Api/Startup.cs b/src/Inshapardaz.Api/Startup.cs index ebd31aa5..c38156a2 100644 --- a/src/Inshapardaz.Api/Startup.cs +++ b/src/Inshapardaz.Api/Startup.cs @@ -79,6 +79,7 @@ public void ConfigureServices(IServiceCollection services) services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/src/Inshapardaz.Api/Views/Library/ArticleContentView.cs b/src/Inshapardaz.Api/Views/Library/ArticleContentView.cs index 150edd20..5ba5bea3 100644 --- a/src/Inshapardaz.Api/Views/Library/ArticleContentView.cs +++ b/src/Inshapardaz.Api/Views/Library/ArticleContentView.cs @@ -4,16 +4,13 @@ public class ArticleContentView : ViewWithLinks { public int Id { get; set; } - public int PeriodicalId { get; set; } - - public int VolumeNumber { get; set; } - - public int IssueNumber { get; set; } - - public int SequenceNumber { get; set; } + public long ArticleId { get; set; } public string Language { get; set; } public string Text { get; set; } + + public string Layout { get; set; } + } } diff --git a/src/Inshapardaz.Api/Views/Library/ArticleView.cs b/src/Inshapardaz.Api/Views/Library/ArticleView.cs index cd5a5e12..aefac2e2 100644 --- a/src/Inshapardaz.Api/Views/Library/ArticleView.cs +++ b/src/Inshapardaz.Api/Views/Library/ArticleView.cs @@ -1,23 +1,21 @@ -using System; +using Inshapardaz.Domain.Models.Library; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace Inshapardaz.Api.Views.Library { - public class IssueArticleView : ViewWithLinks + public class ArticleView : ViewWithLinks { - public int Id { get; set; } + public long Id { get; set; } [Required] public string Title { get; set; } - public int SequenceNumber { get; set; } - - public string SeriesName { get; set; } - - public int? SeriesIndex { get; set; } + public bool IsPublic { get; set; } public IEnumerable Authors { get; set; } + public IEnumerable Categories { get; set; } public string Status { get; set; } @@ -33,6 +31,8 @@ public class IssueArticleView : ViewWithLinks public DateTime? ReviewerAssignTimeStamp { get; set; } - public List Contents { get; internal set; } + public List Contents { get; set; } + public string Type { get; set; } + public DateTime? LastModified { get; set; } } } diff --git a/src/Inshapardaz.Api/Views/Library/ChapterAssignmentView.cs b/src/Inshapardaz.Api/Views/Library/AssignmentView.cs similarity index 64% rename from src/Inshapardaz.Api/Views/Library/ChapterAssignmentView.cs rename to src/Inshapardaz.Api/Views/Library/AssignmentView.cs index cef0e2cb..43bc5a78 100644 --- a/src/Inshapardaz.Api/Views/Library/ChapterAssignmentView.cs +++ b/src/Inshapardaz.Api/Views/Library/AssignmentView.cs @@ -3,9 +3,10 @@ namespace Inshapardaz.Api.Views.Library { - public class ChapterAssignmentView : ViewWithLinks + public class AssignmentView : ViewWithLinks { - + public bool Unassign { get; set; } + public int? AccountId { get; set; } } } diff --git a/src/Inshapardaz.Api/Views/Library/AuthorView.cs b/src/Inshapardaz.Api/Views/Library/AuthorView.cs index c2a39f19..50f16abe 100644 --- a/src/Inshapardaz.Api/Views/Library/AuthorView.cs +++ b/src/Inshapardaz.Api/Views/Library/AuthorView.cs @@ -9,5 +9,6 @@ public class AuthorView : ViewWithLinks public string Description { get; set; } public int BookCount { get; set; } public string AuthorType { get; set; } + public int ArticleCount { get; set; } } } diff --git a/src/Inshapardaz.Api/Views/Library/BookContentView.cs b/src/Inshapardaz.Api/Views/Library/BookContentView.cs index 349585aa..fb141bc4 100644 --- a/src/Inshapardaz.Api/Views/Library/BookContentView.cs +++ b/src/Inshapardaz.Api/Views/Library/BookContentView.cs @@ -6,8 +6,10 @@ public class BookContentView : ViewWithLinks public int BookId { get; set; } + public string FileName { get; set; } + public string MimeType { get; set; } public string Language { get; set; } } -} \ No newline at end of file +} diff --git a/src/Inshapardaz.Api/Views/Library/BookView.cs b/src/Inshapardaz.Api/Views/Library/BookView.cs index 928886eb..21aa42ce 100644 --- a/src/Inshapardaz.Api/Views/Library/BookView.cs +++ b/src/Inshapardaz.Api/Views/Library/BookView.cs @@ -13,6 +13,8 @@ public class BookView : ViewWithLinks public string Title { get; set; } public string Description { get; set; } + public string Publisher { get; set; } + public string Source { get; set; } [Required] public IEnumerable Authors { get; set; } diff --git a/src/Inshapardaz.Api/Views/Library/IssueArticleContentView.cs b/src/Inshapardaz.Api/Views/Library/IssueArticleContentView.cs new file mode 100644 index 00000000..ff2ce667 --- /dev/null +++ b/src/Inshapardaz.Api/Views/Library/IssueArticleContentView.cs @@ -0,0 +1,19 @@ +namespace Inshapardaz.Api.Views.Library +{ + public class IssueArticleContentView : ViewWithLinks + { + public int Id { get; set; } + + public int PeriodicalId { get; set; } + + public int VolumeNumber { get; set; } + + public int IssueNumber { get; set; } + + public int SequenceNumber { get; set; } + + public string Language { get; set; } + + public string Text { get; set; } + } +} diff --git a/src/Inshapardaz.Api/Views/Library/IssueArticleView.cs b/src/Inshapardaz.Api/Views/Library/IssueArticleView.cs new file mode 100644 index 00000000..02841be3 --- /dev/null +++ b/src/Inshapardaz.Api/Views/Library/IssueArticleView.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Inshapardaz.Api.Views.Library +{ + public class IssueArticleView : ViewWithLinks + { + public int Id { get; set; } + + [Required] + public string Title { get; set; } + + public int SequenceNumber { get; set; } + + public string SeriesName { get; set; } + + public int? SeriesIndex { get; set; } + + public IEnumerable Authors { get; set; } + + public string Status { get; set; } + + public int? WriterAccountId { get; set; } + + public string WriterAccountName { get; set; } + + public DateTime? WriterAssignTimeStamp { get; set; } + + public int? ReviewerAccountId { get; set; } + + public string ReviewerAccountName { get; set; } + + public DateTime? ReviewerAssignTimeStamp { get; set; } + + public List Contents { get; internal set; } + } +} diff --git a/src/Inshapardaz.Api/Views/Library/ArticleSequenceView.cs b/src/Inshapardaz.Api/Views/Library/SequenceView.cs similarity index 73% rename from src/Inshapardaz.Api/Views/Library/ArticleSequenceView.cs rename to src/Inshapardaz.Api/Views/Library/SequenceView.cs index e9b15b05..d2d3aa4a 100644 --- a/src/Inshapardaz.Api/Views/Library/ArticleSequenceView.cs +++ b/src/Inshapardaz.Api/Views/Library/SequenceView.cs @@ -1,6 +1,6 @@ namespace Inshapardaz.Api.Views.Library { - public class ArticleSequenceView : ViewWithLinks + public class SequenceView : ViewWithLinks { public int Id { get; set; } diff --git a/src/Inshapardaz.Api/Views/LibraryView.cs b/src/Inshapardaz.Api/Views/LibraryView.cs index ce3f754d..8860cfea 100644 --- a/src/Inshapardaz.Api/Views/LibraryView.cs +++ b/src/Inshapardaz.Api/Views/LibraryView.cs @@ -19,8 +19,8 @@ public class LibraryView : ViewWithLinks public string DatabaseConnection { get; set; } [Required] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? FileStoreType { get; set; } + public string FileStoreType { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? FileStoreSource { get; set; } + public string FileStoreSource { get; set; } } } diff --git a/src/Inshapardaz.Database.SqlServer/Inshapardaz.Database.SqlServer.csproj b/src/Inshapardaz.Database.SqlServer/Inshapardaz.Database.SqlServer.csproj index d2c5bf6e..2bf39c7d 100644 --- a/src/Inshapardaz.Database.SqlServer/Inshapardaz.Database.SqlServer.csproj +++ b/src/Inshapardaz.Database.SqlServer/Inshapardaz.Database.SqlServer.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/Inshapardaz.Database.SqlServer/Repositories/Library/ArticleRepository.cs b/src/Inshapardaz.Database.SqlServer/Repositories/Library/ArticleRepository.cs index 7ea4c524..608bdfd7 100644 --- a/src/Inshapardaz.Database.SqlServer/Repositories/Library/ArticleRepository.cs +++ b/src/Inshapardaz.Database.SqlServer/Repositories/Library/ArticleRepository.cs @@ -1,18 +1,20 @@ -using Dapper; -using Inshapardaz.Domain.Adapters.Repositories.Library; -using Inshapardaz.Domain.Models; -using Inshapardaz.Domain.Models.Library; -using Polly; -using System; using System.Collections.Generic; +using System.Data; +using System.Drawing; using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; +using Dapper; +using DocumentFormat.OpenXml.Bibliography; +using DocumentFormat.OpenXml.Drawing.Diagrams; +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; namespace Inshapardaz.Database.SqlServer.Repositories.Library { - public class ArticleRepository : IIssueArticleRepository + public class ArticleRepository : IArticleRepository { private readonly IProvideConnection _connectionProvider; @@ -20,476 +22,487 @@ public ArticleRepository(IProvideConnection connectionProvider) { _connectionProvider = connectionProvider; } - - public async Task AddArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IssueArticleModel article, CancellationToken cancellationToken) + public async Task AddArticle(int libraryId, ArticleModel article, int? accountId, CancellationToken cancellationToken) { int id; using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"INSERT INTO Article (Title, IssueId, Status, SequenceNumber, SeriesName, SeriesIndex, WriterAccountId, WriterAssignTimestamp, ReviewerAccountId, ReviewerAssignTimeStamp) - OUTPUT Inserted.Id VALUES (@Title, (SELECT Id FROM Issue WHERE VolumeNumber = @VolumeNumber AND IssueNumber = @IssueNumber), @Status, @SequenceNumber, @SeriesName, @SeriesIndex, @WriterAccountId, @WriteAssignTimestamp, @ReviewerAccountId, @ReviewerAssignTimeStamp)"; + var sql = @"INSERT INTO Article (LibraryId, Title, Status, WriterAccountId, WriterAssignTimeStamp, ReviewerAccountId, ReviewerAssignTimeStamp) + OUTPUT Inserted.Id VALUES (@LibraryId, @Title, @Status, @WriterAccountId, @WriterAssignTimeStamp, @ReviewerAccountId, @ReviewerAssignTimeStamp)"; var command = new CommandDefinition(sql, new { + LibraryId = libraryId, Title = article.Title, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = article.SequenceNumber, Status = article.Status, - SeriesName = article.SeriesName, - SeriesIndex = article.SeriesIndex, WriterAccountId = article.WriterAccountId, - WriteAssignTimestamp = article.WriterAssignTimeStamp, + WriterAssignTimeStamp = article.WriterAssignTimeStamp, ReviewerAccountId = article.ReviewerAccountId, ReviewerAssignTimeStamp = article.ReviewerAssignTimeStamp }, cancellationToken: cancellationToken); id = await connection.ExecuteScalarAsync(command); - var sqlAuthor = @"Insert Into ArticleAuthor (ArticleId, AuthorId) Values (@ArticleId, @AuthorId);"; - if (article.Authors != null && article.Authors.Any()) { - var bookAuthors = article.Authors.Select(a => new { ArticleId = article.Id, AuthorId = a.Id }); - var commandCategory = new CommandDefinition(sqlAuthor, bookAuthors, cancellationToken: cancellationToken); + var sqlAuthor = @"Insert Into ArticleAuthor (ArticleId, AuthorId) Values (@ArticleId, @AuthorId);"; + var articleAuthors = article.Authors.Select(a => new { ArticleId = id, AuthorId = a.Id }); + var commandCategory = new CommandDefinition(sqlAuthor, articleAuthors, cancellationToken: cancellationToken); await connection.ExecuteAsync(commandCategory); } - } - await ReorderArticles(libraryId, periodicalId, volumeNumber, issueNumber, cancellationToken); - return await GetArticleById(id, cancellationToken); - } - - public async Task UpdateArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IssueArticleModel article, CancellationToken cancellationToken) - { - using (var connection = _connectionProvider.GetLibraryConnection()) - { - var sql = @"UPDATE a SET a.Title = @Title, - a.SequenceNumber = @SequenceNumber, - a.SeriesName = @SeriesName, - a.SeriesIndex = @SeriesIndex, - a.WriterAccountId = @WriterAccountId, - a.WriterAssignTimestamp = @WriteAssignTimestamp, - a.ReviewerAccountId = @ReviewerAccountId, - a.ReviewerAssignTimeStamp = @ReviewerAssignTimeStamp - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - INNER JOIN Periodical p ON p.Id = i.PeriodicalId - WHERE p.LibraryId = @LibraryId - AND p.Id = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber"; - var args = new + if (article.Categories != null && article.Categories.Any()) { - LibraryId = libraryId, - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - ArticleId = article.Id, - Title = article.Title, - SequenceNumber = article.SequenceNumber, - SeriesName = article.SeriesName, - SeriesIndex = article.SeriesIndex, - WriterAccountId = article.WriterAccountId, - WriteAssignTimestamp = article.WriterAssignTimeStamp, - ReviewerAccountId = article.ReviewerAccountId, - ReviewerAssignTimeStamp = article.ReviewerAssignTimeStamp - }; - var command = new CommandDefinition(sql, args, cancellationToken: cancellationToken); - await connection.ExecuteAsync(command); - - await ReorderArticles(libraryId, periodicalId, volumeNumber, issueNumber, cancellationToken); + var sqlCategory = @"Insert Into ArticleCategory (ArticleId, CategoryId) Values (@ArticleId, @CategoryId);"; + var articleCategories = article.Categories.Select(c => new { ArticleId = id, CategoryId = c.Id }); + var commandCategory = new CommandDefinition(sqlCategory, articleCategories, cancellationToken: cancellationToken); + await connection.ExecuteAsync(commandCategory); + } } + + return await GetArticleById(libraryId, id, accountId, cancellationToken); } - public async Task DeleteArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken) + public async Task AddArticleContent(int libraryId, ArticleContentModel content, CancellationToken cancellationToken) { - await DeleteArticleContent(libraryId, periodicalId, volumeNumber, issueNumber, sequenceNumber, cancellationToken); using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"DELETE a - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - WHERE i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber"; - var command = new CommandDefinition(sql, new - { - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber - }, cancellationToken: cancellationToken); + var sql = @"Insert Into ArticleContent (ArticleId, Language, Text, Layout) + Values (@ArticleId, @Language, @Text, @Layout)"; + var command = new CommandDefinition(sql, content, cancellationToken: cancellationToken); await connection.ExecuteAsync(command); - await ReorderArticles(libraryId, periodicalId, volumeNumber, issueNumber, cancellationToken); + return await GetArticleContent(libraryId, content.ArticleId, content.Language, cancellationToken); } } - public async Task GetArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken) + public async Task DeleteArticle(int libraryId, long articleId, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - IssueArticleModel article = null; - var sql = @"SELECT a.*, ac.* - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - LEFT OUTER JOIN ArticleContent ac ON a.Id = ac.ArticleId - WHERE i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber"; - var command = new CommandDefinition(sql, new { - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber - }, cancellationToken: cancellationToken); - await connection.QueryAsync(command, (a, ac) => - { - if (article == null) - { - article = a; - } - - if (ac != null) - { - var content = article.Contents.SingleOrDefault(x => x.Id == ac.Id); - if (content == null) - { - article.Contents.Add(ac); - } - } - - return article; - }); - - return article; + var sql = @"Delete From Article Where LibraryId = @LibraryId AND Id = @Id"; + var command = new CommandDefinition(sql, new { LibraryId = libraryId, Id = articleId }, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); } } - public async Task GetArticleContentById(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, CancellationToken cancellationToken) + public async Task DeleteArticleContent(int libraryId, long articleId, string language, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - ArticleContentModel articleContent = null; - var sql = @"SELECT a.*, ac.*, i.* - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - LEFT OUTER JOIN ArticleContent ac ON a.Id = ac.ArticleId - WHERE i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber - AND ac.Language = @Language"; - var command = new CommandDefinition(sql, new { - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber, - Language = language }, cancellationToken: cancellationToken); - await connection.QueryAsync(command, (a, ac, i) => + var sql = @"DELETE ac + FROM ArticleContent ac + INNER JOIN Article a ON a.Id = ac.ArticleId + WHERE a.Id= @ArticleId + AND a.LibraryId = @LibraryId + AND ac.Language = @Language"; + var command = new CommandDefinition(sql, new { - if (articleContent == null) - { - articleContent = ac; - articleContent.PeriodicalId = i.PeriodicalId; - articleContent.VolumeNumber = i.VolumeNumber; - articleContent.IssueNumber = i.IssueNumber; - articleContent.SequenceNumber = a.SequenceNumber; - } - - return articleContent; - }); - - return articleContent; + LibraryId = libraryId, + ArticleId = articleId, + Language = language + }, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); } } - public async Task> GetArticlesByIssue(int libraryId, int periodicalId, int volumeNumber, int issueNumber, CancellationToken cancellationToken) + public Task GetArticle(int libraryId, long articleId, CancellationToken cancellationToken) { - using (var connection = _connectionProvider.GetLibraryConnection()) - { - var articles = new Dictionary(); - - var sql = @"SELECT a.*, at.*, i.* - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - LEFT OUTER JOIN ArticleContent at ON a.Id = at.ArticleId - WHERE i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - ORDER BY a.SequenceNumber"; - var command = new CommandDefinition(sql, new { - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - }, cancellationToken: cancellationToken); - await connection.QueryAsync(command, (a, at, i) => - { - if (!articles.TryGetValue(a.Id, out IssueArticleModel article)) - { - articles.Add(a.Id, article = a); - } - - article = articles[a.Id]; - if (at != null) - { - at.VolumeNumber = i.VolumeNumber; - at.IssueNumber = i.IssueNumber; - - var content = article.Contents.SingleOrDefault(x => x.Id == at.Id); - if (content == null) - { - article.Contents.Add(at); - } - } - - return article; - }); - - return articles.Values; - } + return GetArticleById(libraryId, articleId, null, cancellationToken); } - public async Task GetArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, CancellationToken cancellationToken) + public async Task GetArticleContent(int libraryId, long articleId, string language, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"SELECT ac.*, a.sequenceNumber, p.Id AS PeriodicalId - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - INNER JOIN Periodical p ON p.Id = i.Periodicalid - LEFT OUTER JOIN ArticleContent ac ON a.Id = ac.ArticleId - WHERE p.LibraryId = @LibraryId - AND i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.sequenceNumber = @SequenceNumber - AND ac.Language = @Language"; + var sql = @"SELECT ac.* + FROM ArticleContent ac + INNER JOIN Article a ON a.Id = ac.ArticleId + WHERE a.LibraryId = @LibraryId AND ac.ArticleId = @ArticleId AND Language = @Language"; var command = new CommandDefinition(sql, new { LibraryId = libraryId, - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber, - Language = language + ArticleId = articleId, + Language = language }, cancellationToken: cancellationToken); return await connection.QuerySingleOrDefaultAsync(command); } } - public async Task> GetArticleContents(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken) + public async Task> GetArticleContents(int libraryId, long articleId, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"SELECT ac.*, a.SequenceNumber AS SequenceNumber, p.Id AS PeriodicalId - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - INNER JOIN Periodical p ON p.Id = i.Periodicalid - LEFT OUTER JOIN ArticleContent ac ON a.Id = ac.ArticleId - WHERE a.sequenceNumber = @SequenceNumber - AND p.LibraryId = @LibraryId - AND i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber"; - var command = new CommandDefinition(sql, new - { - LibraryId = libraryId, - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber - }, cancellationToken: cancellationToken); + var sql = @"SELECT ac.* + FROM ArticleContent ac + INNER JOIN Article a ON a.Id = ac.ArticleId + WHERE a.LibraryId = @LibraryId AND ac.ArticleId = @ArticleId"; + var command = new CommandDefinition(sql, new { LibraryId = libraryId, ArticleId = articleId }, cancellationToken: cancellationToken); return await connection.QueryAsync(command); } } - public async Task AddArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, string content, CancellationToken cancellationToken) + public async Task> GetArticles(int libraryId, string query, int pageNumber, int pageSize, int? accountId, ArticleFilter filter, ArticleSortByType sortBy, SortDirection direction, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"INSERT INTO ArticleContent (ArticleId, [Language], Text) - (SELECT TOp 1 a.Id, @Language, @Text FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - INNER JOIN Periodical p ON p.Id = i.PeriodicalId - WHERE p.LibraryId = @LibraryId - AND i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber)" - ; - var command = new CommandDefinition(sql, new { + var sortDirection = direction == SortDirection.Descending ? "DESC" : "ASC"; + var sortByQuery = GetSortByQuery(sortBy, sortDirection, "at"); + var param = new + { LibraryId = libraryId, - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber, - Language = language, - Text = content }, cancellationToken: cancellationToken); - await connection.ExecuteAsync(command); - return await GetArticleContentById(libraryId, periodicalId, volumeNumber, issueNumber, sequenceNumber, language, cancellationToken); + Query = string.IsNullOrWhiteSpace(query) ? null : $"%{query}%", + PageSize = pageSize, + PageNumber = pageNumber, + AccountId = accountId, + AuthorFilter = filter.AuthorId, + TypeFilter = filter.Type == ArticleType.Unknown ? (ArticleType?) null : filter.Type, + CategoryFilter = filter.CategoryId, + FavoriteFilter = filter.Favorite, + RecentFilter = filter.Read, + StatusFilter = filter.Status + }; + + var sql = @"SELECT at.Id + From Article at + INNER JOIN ArticleAuthor aa ON at.Id = aa.ArticleId + INNER JOIN Author a On aa.AuthorId = a.Id + LEFT JOIN ArticleCategory ac ON at.Id = ac.ArticleId + LEFT JOIN Category c ON ac.CategoryId = c.Id + LEFT JOIN ArticleFavorite f On f.ArticleId= at.Id + LEFT JOIN ArticleRead r On at.Id = r.ArticleId + Where at.LibraryId = @LibraryId + AND (at.Title Like @Query OR @Query IS NULL) + AND (@AccountId IS NOT NULL OR at.IsPublic = 1) + AND (at.[Type] = @TypeFilter OR @TypeFilter = 0 OR @TypeFilter IS NULL) + AND (at.Status = @StatusFilter OR @StatusFilter = 0 OR @StatusFilter IS NULL) + AND (aa.AuthorId = @AuthorFilter OR @AuthorFilter IS NULL) + AND (f.AccountId = @AccountId OR @FavoriteFilter IS NULL) + AND (r.AccountId = @AccountId OR @RecentFilter IS NULL) + AND (ac.CategoryId = @CategoryFilter OR @CategoryFilter IS NULL) + GROUP BY at.Id, at.Title, at.LastModified " + + $" ORDER BY {sortByQuery} " + + @"OFFSET @PageSize * (@PageNumber - 1) ROWS + FETCH NEXT @PageSize ROWS ONLY"; + + var command = new CommandDefinition(sql, param, cancellationToken: cancellationToken); + + var articleIds = await connection.QueryAsync(command); + + var sqlCount = @"SELECT Count(*) + FROM ( + SELECT at.Id + FROM Article at + INNER JOIN ArticleAuthor aa ON at.Id = aa.ArticleId + INNER JOIN Author a On aa.AuthorId = a.Id + LEFT JOIN ArticleCategory ac ON at.Id = ac.ArticleId + LEFT JOIN Category c ON ac.CategoryId = c.Id + LEFT JOIN ArticleFavorite f On f.ArticleId= at.Id + LEFT JOIN ArticleRead r On at.Id = r.ArticleId + Where at.LibraryId = @LibraryId + AND (at.Title Like @Query OR @Query IS NULL) + AND (@AccountId IS NOT NULL OR at.IsPublic = 1) + AND (at.[Type] = @TypeFilter OR @TypeFilter = 0 OR @TypeFilter IS NULL) + AND (at.Status = @StatusFilter OR @StatusFilter = 0 OR @StatusFilter IS NULL) + AND (aa.AuthorId = @AuthorFilter OR @AuthorFilter IS NULL) + AND (f.AccountId = @AccountId OR @FavoriteFilter IS NULL) + AND (r.AccountId = @AccountId OR @RecentFilter IS NULL) + AND (ac.CategoryId = @CategoryFilter OR @CategoryFilter IS NULL) + GROUP BY at.Id) as articleCounts"; + + var articleCount = await connection.QuerySingleAsync(new CommandDefinition(sqlCount, param, cancellationToken: cancellationToken)); + + var articles = await GetArticles(connection, libraryId, articleIds.Select(b => (long)b.Id).ToList(), accountId, cancellationToken); + + return new Page + { + PageNumber = pageNumber, + PageSize = pageSize, + TotalCount = articleCount, + Data = articles + }; } } - public async Task UpdateArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, string content, CancellationToken cancellationToken) + public async Task UpdateArticle(int libraryId, ArticleModel article, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"Update ac SET Text = @Text - FROM ArticleContent ac - INNER JOIN Article a ON a.Id = ac.Articleid - INNER JOIN Issue i ON i.Id = a.IssueId - INNER JOIN Periodical p ON p.Id = i.PeriodicalId - WHERE p.LibraryId = @LibraryId - AND i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber - AND ac.Language = @Language"; + var sql = @"Update Article SET + Title = @Title, + IsPublic = @IsPublic, + [Status] = @Status, + [Type] = @Type, + WriterAccountId = @WriterAccountId, + WriterAssignTimeStamp = @WriterAssignTimeStamp, + ReviewerAccountId = @ReviewerAccountId, + ReviewerAssignTimeStamp = @ReviewerAssignTimeStamp, + SourceType = @SourceType, + SourceId = @SourceId, + LastModified = GETDATE() + Where LibraryId = @LibraryId And Id = @Id"; var command = new CommandDefinition(sql, new { LibraryId = libraryId, - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber, - Language = language, - Text = content + Id = article.Id, + Title = article.Title, + IsPublic = article.IsPublic, + Status = article.Status, + Type = article.Type, + WriterAccountId = article.WriterAccountId, + WriterAssignTimeStamp = article.WriterAssignTimeStamp, + ReviewerAccountId = article.ReviewerAccountId, + ReviewerAssignTimeStamp = article.ReviewerAssignTimeStamp, + SourceType = article.SourceType, + SourceId = article.SourceId, }, cancellationToken: cancellationToken); - await connection.ExecuteAsync(command); + await connection.ExecuteScalarAsync(command); + + await connection.ExecuteAsync(new CommandDefinition( + "Delete From ArticleAuthor Where ArticleId = @ArticleId", + new { ArticleId = article.Id }, + cancellationToken: cancellationToken)); + + var sqlAuthor = @"Insert Into ArticleAuthor (ArticleId, AuthorId) Values (@ArticleId, @AuthorId);"; + + if (article.Authors != null && article.Authors.Any()) + { + var authors = article.Authors.Select(a => new { ArticleId = article.Id, AuthorId = a.Id }); + var commandCategory = new CommandDefinition(sqlAuthor, authors, cancellationToken: cancellationToken); + await connection.ExecuteAsync(commandCategory); + } + + await connection.ExecuteAsync(new CommandDefinition( + "Delete From ArticleCategory Where ArticleId = @ArticleId", + new { ArticleId = article.Id }, + cancellationToken: cancellationToken)); + + var sqlCategory = @"Insert Into ArticleCategory (ArticleId, CategoryId) Values (@ArticleId, @CategoryId);"; + + if (article.Categories != null && article.Categories.Any()) + { + var categories = article.Categories.Select(c => new { ArticleId = article.Id, CategoryId = c.Id }); + var commandCategory = new CommandDefinition(sqlCategory, categories, cancellationToken: cancellationToken); + await connection.ExecuteAsync(commandCategory); + } } - return await GetArticleContent(libraryId, periodicalId, volumeNumber, issueNumber, sequenceNumber, language, cancellationToken); + return await GetArticleById(libraryId, article.Id, null, cancellationToken); } - public async Task DeleteArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken) + public async Task UpdateArticleContent(int libraryId, ArticleContentModel content, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"Delete ac - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - INNER JOIN Periodical p ON p.Id = i.Periodicalid - LEFT OUTER JOIN ArticleContent ac ON a.Id = ac.ArticleId - WHERE a.sequenceNumber = @SequenceNumber - AND p.LibraryId = @LibraryId - AND i.PeriodicalId = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND a.SequenceNumber = @SequenceNumber"; + var sql = @"UPDATE ac SET Text = @Text, Layout = @Layout + FROM ArticleContent ac + INNER JOIN Article a ON a.Id = ac.ArticleId + WHERE a.Id= @ArticleId + AND a.LibraryId = @LibraryId + AND ac.Language = @Language"; var command = new CommandDefinition(sql, new { LibraryId = libraryId, - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - SequenceNumber = sequenceNumber + ArticleId = content.ArticleId, + Language = content.Language, + Text = content.Text, + Layout = content.Layout }, cancellationToken: cancellationToken); await connection.ExecuteAsync(command); + + return await GetArticleContent(libraryId, content.ArticleId, content.Language, cancellationToken); } } - public Task UpdateWriterAssignment(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, int? accountId, CancellationToken cancellationToken) + public async Task UpdateReviewerAssignment(int libraryId, long articleId, int? accountId, CancellationToken cancellationToken) { - throw new NotImplementedException(); - } + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"Update Article + SET ReviewerAccountId = @ReviewerAccountId, ReviewerAssignTimeStamp = GETUTCDATE() + WHERE LibraryId = @LibraryId AND Id = @ArticleId"; + var command = new CommandDefinition(sql, new { LibraryId = libraryId, + ReviewerAccountId = accountId, + ArticleId = articleId + }, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); - public Task UpdateReviewerAssignment(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, int? accountId, CancellationToken cancellationToken) - { - throw new NotImplementedException(); + return await GetArticle(libraryId, articleId, cancellationToken); + } } - private async Task GetArticleById(int articleId, CancellationToken cancellationToken) + public async Task UpdateWriterAssignment(int libraryId, long articleId, int? accountId, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - IssueArticleModel article = null; - var sql = @"SELECT a.*, ac.* - FROM Article a - INNER JOIN Issue i ON i.Id = a.IssueId - LEFT OUTER JOIN ArticleContent ac ON a.Id = ac.ArticleId - WHERE a.Id = @Id"; + var sql = @"Update Article + SET WriterAccountId = @WriterAccountId, WriterAssignTimeStamp = GETUTCDATE() + WHERE LibraryId = @LibraryId AND Id = @ArticleId"; var command = new CommandDefinition(sql, new { - Id = articleId + LibraryId = libraryId, + WriterAccountId = accountId, + ArticleId = articleId }, cancellationToken: cancellationToken); - await connection.QueryAsync(command, (a, ac) => + await connection.ExecuteAsync(command); + + return await GetArticle(libraryId, articleId, cancellationToken); + } + } + + private async Task GetArticleById(int libraryId, long articleId, int? accountId, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + ArticleModel article = null; + + var sql = @"SElect at.*, fl.FilePath AS ImageUrl, + CASE WHEN af.ArticleId IS NULL THEN 0 ELSE 1 END AS IsFavorite, + a.*, c.*, con.*, aw.*, arv.* + FROM Article at + LEFT OUTER JOIN ArticleAuthor ara ON ara.ArticleId = at.Id + LEFT OUTER JOIN Author a ON ara.AuthorId = a.Id + LEFT OUTER JOIN ArticleFavorite af ON at.Id = af.ArticleId AND (af.AccountId = @AccountId OR @AccountId Is Null) + LEFT OUTER JOIN ArticleRead ar On at.Id = ar.ArticleId AND (ar.AccountId = @AccountId OR @AccountId Is Null) + LEFT OUTER JOIN ArticleCategory ac ON at.Id = ac.ArticleId + LEFT OUTER JOIN Category c ON ac.CategoryId = c.Id + LEFT JOIN ArticleContent con ON con.ArticleId = at.Id + LEFT OUTER JOIN [Accounts] aw ON aw.Id = WriterAccountId + LEFT OUTER JOIN [Accounts] arv ON arv.Id = ReviewerAccountId + LEFT OUTER JOIN [File] fl ON fl.Id = at.ImageId + WhEre at.LibraryId = @LibraryId AND at.Id = @Id"; + await connection.QueryAsync(sql, (ar, a, c, con, writer, reviewer) => { if (article == null) { - article = a; + article = ar; + article.WriterAccountName = writer?.Name; + article.ReviewerAccountName = reviewer?.Name; } - if (ac != null) + if (a != null && !article.Authors.Any(x => x.Id == a.Id)) { - var content = article.Contents.SingleOrDefault(x => x.Id == ac.Id); - if (content == null) - { - article.Contents.Add(ac); - } + article.Authors.Add(a); + } + + if (c != null && !article.Categories.Any(x => x.Id == c.Id)) + { + article.Categories.Add(c); + } + + if (con != null && !article.Contents.Any(x => x.Id == con.Id)) + { + article.Contents.Add(con); } return article; - }); + + }, new { LibraryId = libraryId, Id = articleId, AccountId = accountId }); return article; } } - public async Task ReorderArticles(int libraryId, int periodicalId, int volumeNumber, int issueNumber, CancellationToken cancellationToken) + private async Task> GetArticles(IDbConnection connection, int libraryId, List articleIds, int? accountId = null, CancellationToken cancellationToken = default) { - using (var connection = _connectionProvider.GetLibraryConnection()) + var articles = new Dictionary(); + var sql3 = @"SELECT at.*, fl.FilePath AS ImageUrl, + CASE WHEN af.ArticleId IS NULL THEN 0 ELSE 1 END AS IsFavorite, + a.*, c.*, con.* + FROM Article at + LEFT OUTER JOIN ArticleAuthor ara ON ara.ArticleId = at.Id + LEFT OUTER JOIN Author a On ara.AuthorId = a.Id + LEFT OUTER JOIN ArticleFavorite af On at.Id = af.ArticleId + AND (af.AccountId = @AccountId OR @AccountId Is Null) + LEFT OUTER JOIN ArticleRead ar On at.Id = ar.ArticleId + AND (ar.AccountId = @AccountId OR @AccountId Is Null) + LEFT OUTER JOIN ArticleCategory ac ON at.Id = ac.ArticleId + LEFT OUTER JOIN Category c ON ac.CategoryId = c.Id + LEFT OUTER JOIN [File] fl ON fl.Id = at.ImageId + LEFT JOIN ArticleContent con ON con.ArticleId = at.Id + WHERE at.LibraryId = @LibraryId + AND at.Id IN @ArticleList"; + var command3 = new CommandDefinition(sql3, new { + LibraryId = libraryId, + ArticleList = articleIds, + AccountId = accountId + }, cancellationToken: cancellationToken); + + await connection.QueryAsync(command3, (at, a, c, con) => { - var sql = @"SELECT a.Id, row_number() OVER (ORDER BY a.SequenceNumber) as 'SequenceNumber' - From Article a - Inner Join Issue i On i.Id = a.IssueId - Inner Join Periodical p On p.Id = i.PeriodicalId - Where p.LibraryId = @LibraryId - AND p.Id = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - Order By a.SequenceNumber"; - var command = new CommandDefinition(sql, new + if (!articles.TryGetValue(at.Id, out ArticleModel article)) + articles.Add(at.Id, article = at); + + if (!article.Authors.Any(x => x.Id == a.Id)) { - LibraryId = libraryId, - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber - }, cancellationToken: cancellationToken); - var newOrder = await connection.QueryAsync(command); + article.Authors.Add(a); + } + + if (c != null && !article.Categories.Any(x => x.Id == c.Id)) + { + article.Categories.Add(c); + } + + if (con != null && !article.Contents.Any(x => x.Id == con.Id)) + { + article.Contents.Add(con); + } + + return article; + }); + + return articles.Values.OrderBy(b => articleIds.IndexOf(b.Id)).ToList(); + } + + private static string GetSortByQuery(ArticleSortByType sortBy, string sortDiretion, string prefix = "") + { + switch (sortBy) + { + case ArticleSortByType.LastModified: + return $"{prefix}.LastModified {sortDiretion}, {prefix}.Title {sortDiretion}"; + + case ArticleSortByType.Title: + default: + return $"{prefix}.Title {sortDiretion}"; + } + } + + public async Task UpdateArticleImage(int libraryId, long articleId, int imageId, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"Update Article + Set ImageId = @ImageId + Where Id = @ArticleId And LibraryId = @LibraryId;"; + var command = new CommandDefinition(sql, new { ImageId = imageId, ArticleId = articleId, LibraryId = libraryId }, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); + } + } + - var sql2 = @"UPDATE Article - SET SequenceNumber = @SequenceNumber - Where Id = @Id"; - var command2 = new CommandDefinition(sql2, newOrder, cancellationToken: cancellationToken); - await connection.ExecuteAsync(command2); + public async Task AddArticleToFavorites(int libraryId, int? accountId, long articleId, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"INSERT INTO ArticleFavorite (LibraryId, ArticleId, AccountId) VALUES (@LibraryId, @ArticleId, @AccountId)"; + var command = new CommandDefinition(sql, new { + LibraryId = libraryId, + ArticleId = articleId, + AccountId = accountId }, + cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); } } - public async Task UpdateArticleSequence(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IEnumerable articles, CancellationToken cancellationToken) + public async Task RemoveArticleFromFavorites(int libraryId, int? accountId, long articleId, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"Update A Set A.SequenceNumber = @SequenceNumber - From Article A - Inner Join Issue i On i.Id = A.IssueId - Inner Join Periodical p On p.Id = i.PeriodicalId - Where p.LibraryId = @LibraryId - AND p.Id = @PeriodicalId - AND i.VolumeNumber = @VolumeNumber - AND i.IssueNumber = @IssueNumber - AND A.Id = @Id"; - var args = articles.Select(a => new + var sql = @"DELETE FROM ArticleFavorite WHERE LibraryId = @Libraryid AND ArticleId = @ArticleId AND AccountId = @AccountId"; + var command = new CommandDefinition(sql, new { LibraryId = libraryId, - PeriodicalId = periodicalId, - VolumeNumber = volumeNumber, - IssueNumber = issueNumber, - Id = a.Id, - SequenceNumber = a.SequenceNumber - }); - var command = new CommandDefinition(sql, args, cancellationToken: cancellationToken); + ArticleId = articleId, + AccountId = accountId + }, + cancellationToken: cancellationToken); await connection.ExecuteAsync(command); } } diff --git a/src/Inshapardaz.Database.SqlServer/Repositories/Library/AuthorRepository.cs b/src/Inshapardaz.Database.SqlServer/Repositories/Library/AuthorRepository.cs index 12777bf0..4d6f3659 100644 --- a/src/Inshapardaz.Database.SqlServer/Repositories/Library/AuthorRepository.cs +++ b/src/Inshapardaz.Database.SqlServer/Repositories/Library/AuthorRepository.cs @@ -65,10 +65,8 @@ public async Task> GetAuthors(int libraryId, AuthorTypes? auth using (var connection = _connectionProvider.GetLibraryConnection()) { var sql = @"SELECT a.Id, a.Name, a.Description, a.AuthorType, f.Id As ImageId, f.FilePath AS ImageUrl, - (SELECT Count(*) - FROM Book b - INNER JOIN BookAuthor ba ON ba.BookId = b.Id - WHERE ba.AuthorId = a.Id AND b.Status = 0) AS BookCount + (SELECT Count(*) FROM BookAuthor WHERE AuthorId = a.Id) AS BookCount, + (SELECT Count(*) FROM ArticleAuthor WHERE AuthorId = a.Id) AS ArticleCount FROM Author AS a LEFT OUTER JOIN [File] f ON f.Id = a.ImageId Where a.LibraryId = @LibraryId @@ -103,10 +101,8 @@ public async Task GetAuthorById(int libraryId, int authorId, Cancel using (var connection = _connectionProvider.GetLibraryConnection()) { var sql = @"SELECT a.Id, a.Name, a.Description, a.AuthorType as AuthorType, f.Id As ImageId, f.FilePath AS ImageUrl, - (SELECT Count(*) - FROM Book b - INNER JOIN BookAuthor ba ON ba.BookId = b.Id - WHERE ba.AuthorId = a.Id AND b.Status = 0) AS BookCount + (SELECT Count(*) FROM BookAuthor WHERE AuthorId = a.Id) AS BookCount, + (SELECT Count(*) FROM ArticleAuthor WHERE AuthorId = a.Id) AS ArticleCount FROM Author AS a LEFT OUTER JOIN [File] f ON f.Id = a.ImageId Where a.LibraryId = @LibraryId @@ -124,10 +120,8 @@ public async Task> FindAuthors(int libraryId, string query, Au using (var connection = _connectionProvider.GetLibraryConnection()) { var sql = @"SELECT a.Id, a.Name, a.Description, a.AuthorType, f.Id As ImageId, f.FilePath AS ImageUrl, - (SELECT Count(*) - FROM Book b - INNER JOIN BookAuthor ba ON ba.BookId = b.Id - WHERE ba.AuthorId = a.Id AND b.Status = 0) AS BookCount + (SELECT Count(*) FROM BookAuthor WHERE AuthorId = a.Id) AS BookCount, + (SELECT Count(*) FROM ArticleAuthor WHERE AuthorId = a.Id) AS ArticleCount FROM Author AS a LEFT OUTER JOIN [File] f ON f.Id = a.ImageId Where a.LibraryId = @LibraryId @@ -160,10 +154,8 @@ public async Task> GetAuthorByIds(int libraryId, IEnume using (var connection = _connectionProvider.GetLibraryConnection()) { var sql = @"SELECT a.Id, a.Name, a.Description, a.AuthorType, f.Id As ImageId, f.FilePath AS ImageUrl, - (SELECT Count(*) - FROM Book b - INNER JOIN BookAuthor ba ON ba.BookId = b.Id - WHERE ba.AuthorId = a.Id AND b.Status = 0) AS BookCount + (SELECT Count(*) FROM BookAuthor WHERE AuthorId = a.Id) AS BookCount, + (SELECT Count(*) FROM ArticleAuthor WHERE AuthorId = a.Id) AS ArticleCount FROM Author AS a LEFT OUTER JOIN [File] f ON f.Id = a.ImageId Where a.LibraryId = @LibraryId diff --git a/src/Inshapardaz.Database.SqlServer/Repositories/Library/BookPageRepository.cs b/src/Inshapardaz.Database.SqlServer/Repositories/Library/BookPageRepository.cs index cc6a2373..358eb194 100644 --- a/src/Inshapardaz.Database.SqlServer/Repositories/Library/BookPageRepository.cs +++ b/src/Inshapardaz.Database.SqlServer/Repositories/Library/BookPageRepository.cs @@ -23,10 +23,17 @@ public async Task AddPage(int libraryId, int bookId, int sequence int pageId; using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"Insert Into BookPage(BookId, SequenceNumber, Text, ImageId, ChapterId) + var sql = @"Insert Into BookPage(BookId, SequenceNumber, Text, Status, ImageId, ChapterId) OUTPUT Inserted.Id - VALUES(@BookId, @SequenceNumber, @Text, @ImageId, @ChapterId);"; - var command = new CommandDefinition(sql, new { BookId = bookId, SequenceNumber = sequenceNumber, Text = text, ImageId = imageId, ChapterId = chapterId }, cancellationToken: cancellationToken); + VALUES(@BookId, @SequenceNumber, @Text, @Status, @ImageId, @ChapterId);"; + var command = new CommandDefinition(sql, new { + BookId = bookId, + SequenceNumber = sequenceNumber, + Text = text, + ImageId = imageId, + ChapterId = chapterId, + Status = EditingStatus.Available + }, cancellationToken: cancellationToken); pageId = await connection.ExecuteScalarAsync(command); } diff --git a/src/Inshapardaz.Database.SqlServer/Repositories/Library/BookRepository.cs b/src/Inshapardaz.Database.SqlServer/Repositories/Library/BookRepository.cs index 6817db4d..6dc13fc2 100644 --- a/src/Inshapardaz.Database.SqlServer/Repositories/Library/BookRepository.cs +++ b/src/Inshapardaz.Database.SqlServer/Repositories/Library/BookRepository.cs @@ -28,8 +28,8 @@ public async Task AddBook(int libraryId, BookModel book, int? Account { book.LibraryId = libraryId; var sql = @"Insert Into Book - (Title, [Description], ImageId, LibraryId, IsPublic, IsPublished, [Language], [Status], SeriesId, SeriesIndex, CopyRights, YearPublished, Source, DateAdded, DateUpdated) - OUTPUT Inserted.Id VALUES(@Title, @Description, @ImageId, @LibraryId, @IsPublic, @IsPublished, @Language, @Status, @SeriesId, @SeriesIndex, @CopyRights, @YearPublished, @Source, GETDATE(), GETDATE());"; + (Title, [Description], Publisher, Source, ImageId, LibraryId, IsPublic, IsPublished, [Language], [Status], SeriesId, SeriesIndex, CopyRights, YearPublished, DateAdded, DateUpdated) + OUTPUT Inserted.Id VALUES(@Title, @Description, @Publisher, @Source, @ImageId, @LibraryId, @IsPublic, @IsPublished, @Language, @Status, @SeriesId, @SeriesIndex, @CopyRights, @YearPublished, GETDATE(), GETDATE());"; var command = new CommandDefinition(sql, book, cancellationToken: cancellationToken); bookId = await connection.ExecuteScalarAsync(command); @@ -72,6 +72,7 @@ public async Task UpdateBook(int libraryId, BookModel book, CancellationToken ca { var sql = @"Update Book SET Title = @Title, [Description] = @Description, + Publisher = @Publisher, Source = @Source, IsPublic = @IsPublic, IsPublished = @IsPublished, [Language] = @Language, [Status] = @Status, SeriesId = @SeriesId, SeriesIndex = @SeriesIndex, CopyRights = @CopyRights, @@ -325,18 +326,18 @@ AND b.Title Like @Query } } - public async Task> GetBooksByUser(int libraryId, int accountId, int pageNumber, int pageSize, BookStatuses status, BookSortByType sortBy, SortDirection direction, CancellationToken cancellationToken) + public async Task> GetBooksByUser(int libraryId, int accountId, int pageNumber, int pageSize, StatusType status, BookSortByType sortBy, SortDirection direction, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { var sortByQuery = $"b.{GetSortByQuery(sortBy)}"; var sortDirection = direction == SortDirection.Descending ? "DESC" : "ASC"; var assignmentfilter = string.Empty; - if (status == BookStatuses.BeingTyped) + if (status == StatusType.BeingTyped) { assignmentfilter = "AND (bp.WriterAccountId = @AccountId OR c.WriterAccountId = @AccountId)"; } - else if (status == BookStatuses.ProofRead) + else if (status == StatusType.ProofRead) { assignmentfilter = "AND (bp.ReviewerAccountId = @AccountId OR c.ReviewerAccountId = @AccountId)"; } @@ -471,6 +472,47 @@ await connection.QueryAsync(sq } } + public async Task GetBookByPublisher(int libraryId, string publisher, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + BookModel book = null; + var sql = @"Select b.*, s.Name As SeriesName, fl.FilePath AS ImageUrl, + (SELECT COUNT(*) FROM BookPage WHERE BookPage.BookId = b.id) As PageCount, + (SELECT COUNT(*) FROM Chapter WHERE Chapter.BookId = b.id) As ChapterCount, + a.*, c.* + from Book b + Left Outer Join BookAuthor ba ON b.Id = ba.BookId + Left Outer Join Author a On ba.AuthorId = a.Id + Left Outer Join Series s On b.SeriesId = s.id + Left Outer Join BookCategory bc ON b.Id = bc.BookId + Left Outer Join Category c ON bc.CategoryId = c.Id + LEFT OUTER JOIN [File] fl ON fl.Id = b.ImageId + Where b.LibraryId = @LibraryId AND b.Publisher= @Publisher"; + await connection.QueryAsync(sql, (b, a, c) => + { + if (book == null) + { + book = b; + } + + if (!book.Authors.Any(x => x.Id == a.Id)) + { + book.Authors.Add(a); + } + + if (c != null && !book.Categories.Any(x => x.Id == c.Id)) + { + book.Categories.Add(c); + } + + return book; + }, new { LibraryId = libraryId, Publisher = publisher }); + + return book; + } + } + public async Task AddRecentBook(int libraryId, int AccountId, int bookId, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) @@ -519,7 +561,7 @@ public async Task DeleteBookFromFavorites(int libraryId, int AccountId, int book } } - public async Task DeleteBookContent(int libraryId, int bookId, string language, string mimeType, CancellationToken cancellationToken) + public async Task DeleteBookContent(int libraryId, int bookId, int contentId, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { @@ -527,8 +569,8 @@ public async Task DeleteBookContent(int libraryId, int bookId, string language, From BookContent bc Inner Join Book b On b.Id = bc.BookId INNER JOIN [File] f ON bc.FileId = f.Id - Where b.LibraryId = @LibraryId and b.Id = @BookId And f.MimeType = @MimeType AND bc.Language = @Language"; - var command = new CommandDefinition(sql, new { LibraryId = libraryId, Language = language, MimeType = mimeType, BookId = bookId }, cancellationToken: cancellationToken); + Where b.LibraryId = @LibraryId and b.Id = @BookId And bc.id= @Id"; + var command = new CommandDefinition(sql, new { LibraryId = libraryId, Id = contentId, BookId = bookId }, cancellationToken: cancellationToken); await connection.ExecuteAsync(command); } } @@ -537,7 +579,7 @@ public async Task GetBookContent(int libraryId, int bookId, st { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"SELECT bc.Id, bc.BookId, bc.Language, f.MimeType, f.Id As FileId, f.FilePath As ContentUrl + var sql = @"SELECT bc.Id, bc.BookId, bc.Language, f.MimeType, f.Id As FileId, f.FilePath As ContentUrl, f.FileName As FileName FROM BookContent bc INNER JOIN Book b ON b.Id = bc.BookId INNER JOIN [File] f ON bc.FileId = f.Id @@ -547,11 +589,25 @@ FROM BookContent bc } } + public async Task GetBookContent(int libraryId, int bookId, int contentId, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"SELECT bc.Id, bc.BookId, bc.Language, f.MimeType, f.Id As FileId, f.FilePath As ContentUrl, f.FileName As FileName + FROM BookContent bc + INNER JOIN Book b ON b.Id = bc.BookId + INNER JOIN [File] f ON bc.FileId = f.Id + WHERE b.LibraryId = @LibraryId AND bc.BookId = @BookId AND bc.Id = @Id"; + var command = new CommandDefinition(sql, new { LibraryId = libraryId, BookId = bookId, Id = contentId }, cancellationToken: cancellationToken); + return await connection.QuerySingleOrDefaultAsync(command); + } + } + public async Task> GetBookContents(int libraryId, int bookId, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"SELECT bc.Id, bc.BookId, bc.Language, f.MimeType, f.Id As FileId, f.FilePath As ContentUrl + var sql = @"SELECT bc.Id, bc.BookId, bc.Language, f.MimeType, f.Id As FileId, f.FilePath As ContentUrl, f.FileName As FileName FROM BookContent bc INNER JOIN Book b ON b.Id = bc.BookId INNER JOIN [File] f ON bc.FileId = f.Id @@ -561,19 +617,24 @@ FROM BookContent bc } } - public async Task UpdateBookContentUrl(int libraryId, int bookId, string language, string mimeType, string contentUrl, CancellationToken cancellationToken) + public async Task UpdateBookContent(int libraryId, int bookId, int contentId, string language, string mimeType, string contentUrl, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"Update f SET FilePath = @ContentUrl - From [File] f - Inner Join BookContent bc On bc.FileId = f.Id - Inner Join Book b On b.Id = bc.BookId - Where b.LibraryId = @LibraryId and b.Id = @BookId And f.MimeType = @MimeType AND bc.Language = @Language"; + var sql = @"UPDATE f SET FilePath = @ContentUrl + FROM [File] f + INNER JOIN BookContent bc ON bc.FileId = f.Id + INNER JOIN Book b ON b.Id = bc.BookId + Where b.LibraryId = @LibraryId + AND b.Id = @BookId + AND bc.Id = @Id + AND f.MimeType = @MimeType + AND bc.Language = @Language"; var command = new CommandDefinition(sql, new { LibraryId = libraryId, BookId = bookId, + Id = contentId, Language = language, MimeType = mimeType, ContentUrl = contentUrl @@ -582,14 +643,14 @@ From [File] f } } - public async Task AddBookContent(int bookId, int fileId, string language, string mimeType, CancellationToken cancellationToken) + public async Task AddBookContent(int bookId, int fileId, string language, string mimeType, CancellationToken cancellationToken) { using (var connection = _connectionProvider.GetLibraryConnection()) { - var sql = @"Insert Into BookContent (BookId, FileId, Language) - Values (@BookId, @FileId, @Language)"; + var sql = @"INSERT INTO BookContent (BookId, FileId, Language) + OUTPUT Inserted.Id VALUES (@BookId, @FileId, @Language)"; var command = new CommandDefinition(sql, new { FileId = fileId, BookId = bookId, Language = language }, cancellationToken: cancellationToken); - await connection.ExecuteAsync(command); + return await connection.ExecuteScalarAsync(command); } } diff --git a/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssueArticleRepository.cs b/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssueArticleRepository.cs new file mode 100644 index 00000000..e1469072 --- /dev/null +++ b/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssueArticleRepository.cs @@ -0,0 +1,504 @@ +using Dapper; +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; +using Polly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Database.SqlServer.Repositories.Library +{ + public class IssueArticleRepository : IIssueArticleRepository + { + private readonly IProvideConnection _connectionProvider; + + public IssueArticleRepository(IProvideConnection connectionProvider) + { + _connectionProvider = connectionProvider; + } + + public async Task AddArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IssueArticleModel article, CancellationToken cancellationToken) + { + int id; + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"INSERT INTO IssueArticle (Title, IssueId, Status, SequenceNumber, SeriesName, SeriesIndex, WriterAccountId, WriterAssignTimeStamp, ReviewerAccountId, ReviewerAssignTimeStamp) + OUTPUT Inserted.Id VALUES (@Title, (SELECT Id FROM Issue WHERE VolumeNumber = @VolumeNumber AND IssueNumber = @IssueNumber), @Status, @SequenceNumber, @SeriesName, @SeriesIndex, @WriterAccountId, @WriterAssignTimeStamp, @ReviewerAccountId, @ReviewerAssignTimeStamp)"; + var command = new CommandDefinition(sql, new + { + Title = article.Title, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = article.SequenceNumber, + Status = article.Status, + SeriesName = article.SeriesName, + SeriesIndex = article.SeriesIndex, + WriterAccountId = article.WriterAccountId, + WriterAssignTimeStamp = article.WriterAssignTimeStamp, + ReviewerAccountId = article.ReviewerAccountId, + ReviewerAssignTimeStamp = article.ReviewerAssignTimeStamp + }, cancellationToken: cancellationToken); + id = await connection.ExecuteScalarAsync(command); + + var sqlAuthor = @"Insert Into IssueArticleAuthor (ArticleId, AuthorId) Values (@ArticleId, @AuthorId);"; + + if (article.Authors != null && article.Authors.Any()) + { + var bookAuthors = article.Authors.Select(a => new { ArticleId = article.Id, AuthorId = a.Id }); + var commandCategory = new CommandDefinition(sqlAuthor, bookAuthors, cancellationToken: cancellationToken); + await connection.ExecuteAsync(commandCategory); + } + } + + await ReorderArticles(libraryId, periodicalId, volumeNumber, issueNumber, cancellationToken); + return await GetArticleById(id, cancellationToken); + } + + public async Task UpdateArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IssueArticleModel article, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"UPDATE a SET a.Title = @Title, + a.SequenceNumber = @SequenceNumber, + a.SeriesName = @SeriesName, + a.SeriesIndex = @SeriesIndex, + a.WriterAccountId = @WriterAccountId, + a.WriterAssignTimeStamp = @WriterAssignTimeStamp, + a.ReviewerAccountId = @ReviewerAccountId, + a.ReviewerAssignTimeStamp = @ReviewerAssignTimeStamp + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + INNER JOIN Periodical p ON p.Id = i.PeriodicalId + WHERE p.LibraryId = @LibraryId + AND p.Id = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber"; + var args = new + { + LibraryId = libraryId, + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + ArticleId = article.Id, + Title = article.Title, + SequenceNumber = article.SequenceNumber, + SeriesName = article.SeriesName, + SeriesIndex = article.SeriesIndex, + WriterAccountId = article.WriterAccountId, + WriterAssignTimeStamp = article.WriterAssignTimeStamp, + ReviewerAccountId = article.ReviewerAccountId, + ReviewerAssignTimeStamp = article.ReviewerAssignTimeStamp + }; + var command = new CommandDefinition(sql, args, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); + + await ReorderArticles(libraryId, periodicalId, volumeNumber, issueNumber, cancellationToken); + } + } + + public async Task DeleteArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken) + { + await DeleteArticleContent(libraryId, periodicalId, volumeNumber, issueNumber, sequenceNumber, cancellationToken); + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"DELETE a + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + WHERE i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber"; + var command = new CommandDefinition(sql, new + { + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber + }, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); + + await ReorderArticles(libraryId, periodicalId, volumeNumber, issueNumber, cancellationToken); + } + } + + public async Task GetArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + IssueArticleModel article = null; + var sql = @"SELECT a.*, ac.* + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + LEFT OUTER JOIN IssueArticleContent ac ON a.Id = ac.ArticleId + WHERE i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber"; + var command = new CommandDefinition(sql, new + { + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber + }, cancellationToken: cancellationToken); + await connection.QueryAsync(command, (a, ac) => + { + if (article == null) + { + article = a; + } + + if (ac != null) + { + var content = article.Contents.SingleOrDefault(x => x.Id == ac.Id); + if (content == null) + { + article.Contents.Add(ac); + } + } + + return article; + }); + + return article; + } + } + + public async Task GetArticleContentById(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + IssueArticleContentModel articleContent = null; + var sql = @"SELECT a.*, ac.*, i.* + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + LEFT OUTER JOIN IssueArticleContent ac ON a.Id = ac.ArticleId + WHERE i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber + AND ac.Language = @Language"; + var command = new CommandDefinition(sql, new + { + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber, + Language = language + }, cancellationToken: cancellationToken); + await connection.QueryAsync(command, (a, ac, i) => + { + if (articleContent == null) + { + articleContent = ac; + articleContent.PeriodicalId = i.PeriodicalId; + articleContent.VolumeNumber = i.VolumeNumber; + articleContent.IssueNumber = i.IssueNumber; + articleContent.SequenceNumber = a.SequenceNumber; + } + + return articleContent; + }); + + return articleContent; + } + } + + public async Task> GetArticlesByIssue(int libraryId, int periodicalId, int volumeNumber, int issueNumber, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var articles = new Dictionary(); + + var sql = @"SELECT a.*, at.*, i.* + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + LEFT OUTER JOIN IssueArticleContent at ON a.Id = at.ArticleId + WHERE i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + ORDER BY a.SequenceNumber"; + var command = new CommandDefinition(sql, new + { + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + }, cancellationToken: cancellationToken); + await connection.QueryAsync(command, (a, at, i) => + { + if (!articles.TryGetValue(a.Id, out IssueArticleModel article)) + { + articles.Add(a.Id, article = a); + } + + article = articles[a.Id]; + if (at != null) + { + at.VolumeNumber = i.VolumeNumber; + at.IssueNumber = i.IssueNumber; + + var content = article.Contents.SingleOrDefault(x => x.Id == at.Id); + if (content == null) + { + article.Contents.Add(at); + } + } + + return article; + }); + + return articles.Values; + } + } + + public async Task GetArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"SELECT ac.*, a.sequenceNumber, p.Id AS PeriodicalId + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + INNER JOIN Periodical p ON p.Id = i.Periodicalid + LEFT OUTER JOIN IssueArticleContent ac ON a.Id = ac.ArticleId + WHERE p.LibraryId = @LibraryId + AND i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.sequenceNumber = @SequenceNumber + AND ac.Language = @Language"; + var command = new CommandDefinition(sql, new + { + LibraryId = libraryId, + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber, + Language = language + }, cancellationToken: cancellationToken); + return await connection.QuerySingleOrDefaultAsync(command); + } + } + + public async Task> GetArticleContents(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"SELECT ac.*, a.SequenceNumber AS SequenceNumber, p.Id AS PeriodicalId + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + INNER JOIN Periodical p ON p.Id = i.Periodicalid + LEFT OUTER JOIN IssueArticleContent ac ON a.Id = ac.ArticleId + WHERE a.sequenceNumber = @SequenceNumber + AND p.LibraryId = @LibraryId + AND i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber"; + var command = new CommandDefinition(sql, new + { + LibraryId = libraryId, + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber + }, cancellationToken: cancellationToken); + return await connection.QueryAsync(command); + } + } + + public async Task AddArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, string content, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"INSERT INTO IssueArticleContent (ArticleId, [Language], Text) + (SELECT TOp 1 a.Id, @Language, @Text FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + INNER JOIN Periodical p ON p.Id = i.PeriodicalId + WHERE p.LibraryId = @LibraryId + AND i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber)" + ; + var command = new CommandDefinition(sql, new + { + LibraryId = libraryId, + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber, + Language = language, + Text = content + }, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); + return await GetArticleContentById(libraryId, periodicalId, volumeNumber, issueNumber, sequenceNumber, language, cancellationToken); + } + } + + public async Task UpdateArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, string content, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"Update ac SET Text = @Text + FROM IssueArticleContent ac + INNER JOIN IssueArticle a ON a.Id = ac.Articleid + INNER JOIN Issue i ON i.Id = a.IssueId + INNER JOIN Periodical p ON p.Id = i.PeriodicalId + WHERE p.LibraryId = @LibraryId + AND i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber + AND ac.Language = @Language"; + var command = new CommandDefinition(sql, new + { + LibraryId = libraryId, + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber, + Language = language, + Text = content + }, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); + } + + return await GetArticleContent(libraryId, periodicalId, volumeNumber, issueNumber, sequenceNumber, language, cancellationToken); + } + + public async Task DeleteArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"Delete ac + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + INNER JOIN Periodical p ON p.Id = i.Periodicalid + LEFT OUTER JOIN IssueArticleContent ac ON a.Id = ac.ArticleId + WHERE a.sequenceNumber = @SequenceNumber + AND p.LibraryId = @LibraryId + AND i.PeriodicalId = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND a.SequenceNumber = @SequenceNumber"; + var command = new CommandDefinition(sql, new + { + LibraryId = libraryId, + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + SequenceNumber = sequenceNumber + }, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); + } + } + + public Task UpdateWriterAssignment(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, int? accountId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task UpdateReviewerAssignment(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, int? accountId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + private async Task GetArticleById(int articleId, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + IssueArticleModel article = null; + var sql = @"SELECT a.*, ac.* + FROM IssueArticle a + INNER JOIN Issue i ON i.Id = a.IssueId + LEFT OUTER JOIN IssueArticleContent ac ON a.Id = ac.ArticleId + WHERE a.Id = @Id"; + var command = new CommandDefinition(sql, new + { + Id = articleId + }, cancellationToken: cancellationToken); + await connection.QueryAsync(command, (a, ac) => + { + if (article == null) + { + article = a; + } + + if (ac != null) + { + var content = article.Contents.SingleOrDefault(x => x.Id == ac.Id); + if (content == null) + { + article.Contents.Add(ac); + } + } + + return article; + }); + + return article; + } + } + + public async Task ReorderArticles(int libraryId, int periodicalId, int volumeNumber, int issueNumber, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"SELECT a.Id, row_number() OVER (ORDER BY a.SequenceNumber) as 'SequenceNumber' + From IssueArticle a + Inner Join Issue i On i.Id = a.IssueId + Inner Join Periodical p On p.Id = i.PeriodicalId + Where p.LibraryId = @LibraryId + AND p.Id = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + Order By a.SequenceNumber"; + var command = new CommandDefinition(sql, new + { + LibraryId = libraryId, + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber + }, cancellationToken: cancellationToken); + var newOrder = await connection.QueryAsync(command); + + var sql2 = @"UPDATE IssueArticle + SET SequenceNumber = @SequenceNumber + Where Id = @Id"; + var command2 = new CommandDefinition(sql2, newOrder, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command2); + } + } + + public async Task UpdateArticleSequence(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IEnumerable articles, CancellationToken cancellationToken) + { + using (var connection = _connectionProvider.GetLibraryConnection()) + { + var sql = @"Update A Set A.SequenceNumber = @SequenceNumber + From IssueArticle A + Inner Join Issue i On i.Id = A.IssueId + Inner Join Periodical p On p.Id = i.PeriodicalId + Where p.LibraryId = @LibraryId + AND p.Id = @PeriodicalId + AND i.VolumeNumber = @VolumeNumber + AND i.IssueNumber = @IssueNumber + AND A.Id = @Id"; + var args = articles.Select(a => new + { + LibraryId = libraryId, + PeriodicalId = periodicalId, + VolumeNumber = volumeNumber, + IssueNumber = issueNumber, + Id = a.Id, + SequenceNumber = a.SequenceNumber + }); + var command = new CommandDefinition(sql, args, cancellationToken: cancellationToken); + await connection.ExecuteAsync(command); + } + } + } +} diff --git a/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssuePageRepository.cs b/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssuePageRepository.cs index c8fc860c..4b76da28 100644 --- a/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssuePageRepository.cs +++ b/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssuePageRepository.cs @@ -51,7 +51,7 @@ public async Task GetPageBySequenceNumber(int libraryId, int per f.Id As ImageId, f.FilePath AS ImageUrl, ia.Id As ArticleId, ia.Title As ArticleTitle FROM IssuePage AS p LEFT OUTER JOIN [File] f ON f.Id = p.ImageId - LEFT OUTER JOIN [Article] ia ON ia.Id = p.ArticleId + LEFT OUTER JOIN [IssueArticle] ia ON ia.Id = p.ArticleId INNER JOIN Issue i ON i.Id = p.IssueId INNER JOIN Periodical pr on pr.Id = i.PeriodicalId LEFT OUTER JOIN [Accounts] a ON a.Id = p.WriterAccountId @@ -226,7 +226,7 @@ public async Task> GetPagesByIssue(int libraryId, int perio f.Id As ImageId, f.FilePath AS ImageUrl, p.Text, p.ArticleId, ia.Title As ArticleTitle FROM IssuePage AS p LEFT OUTER JOIN [File] f ON f.Id = p.ImageId - LEFT OUTER JOIN [Article] ia ON ia.Id = p.ArticleId + LEFT OUTER JOIN [IssueArticle] ia ON ia.Id = p.ArticleId INNER JOIN Issue i ON i.Id = p.IssueId INNER JOIN Periodical pr on pr.Id = i.PeriodicalId LEFT OUTER JOIN [Accounts] a ON a.Id = p.WriterAccountId @@ -632,7 +632,7 @@ public async Task GetPageById(int pageId, CancellationToken canc f.Id As ImageId, f.FilePath AS ImageUrl, ia.Id As ArticleId, ia.Title As ArticleTitle FROM IssuePage AS p LEFT OUTER JOIN [File] f ON f.Id = p.ImageId - LEFT OUTER JOIN [Article] ia ON ia.Id = p.ArticleId + LEFT OUTER JOIN [IssueArticle] ia ON ia.Id = p.ArticleId INNER JOIN Issue i ON i.Id = p.IssueId INNER JOIN Periodical pr on pr.Id = i.PeriodicalId LEFT OUTER JOIN [Accounts] a ON a.Id = p.WriterAccountId diff --git a/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssueRepository.cs b/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssueRepository.cs index 102b1aa5..f63185be 100644 --- a/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssueRepository.cs +++ b/src/Inshapardaz.Database.SqlServer/Repositories/Library/IssueRepository.cs @@ -27,7 +27,7 @@ public async Task> GetIssues(int libraryId, int periodicalId, i var direction = sortDirection == SortDirection.Descending ? "DESC" : "ASC"; var sql = @"SELECT i.*, f.FilePath as ImageUrl, - (SELECT COUNT(*) FROM Article WHERE IssueId = i.id) As ArticleCount, + (SELECT COUNT(*) FROM IssueArticle WHERE IssueId = i.id) As ArticleCount, (SELECT COUNT(*) FROM IssuePage WHERE IssueId = i.id) As [PageCount], p.* FROM Issue as i @@ -80,7 +80,7 @@ public async Task GetIssue(int libraryId, int periodicalId, int volu using (var connection = _connectionProvider.GetLibraryConnection()) { var sql = @"SELECT i.*, p.*, f.FilePath as ImageUrl, - (SELECT COUNT(*) FROM Article WHERE IssueId = i.id) As ArticleCount, + (SELECT COUNT(*) FROM IssueArticle WHERE IssueId = i.id) As ArticleCount, (SELECT COUNT(*) FROM IssuePage WHERE IssueId = i.id) As [PageCount] FROM Issue as i INNER JOIN Periodical p ON p.Id = i.PeriodicalId @@ -296,7 +296,7 @@ private async Task GetIssueById(int libraryId, int periodicalId, int using (var connection = _connectionProvider.GetLibraryConnection()) { var sql = @"SELECT i.*, p.*, f.FilePath as ImageUrl, - (SELECT COUNT(*) FROM Article WHERE IssueId = i.id) As ArticleCount, + (SELECT COUNT(*) FROM IssueArticle WHERE IssueId = i.id) As ArticleCount, (SELECT COUNT(*) FROM IssuePage WHERE IssueId = i.id) As [PageCount] FROM Issue as i INNER JOIN Periodical p ON p.Id = i.PeriodicalId diff --git a/src/Inshapardaz.Domain/Adapters/IGenerateToken.cs b/src/Inshapardaz.Domain/Adapters/IGenerateToken.cs new file mode 100644 index 00000000..9f3671be --- /dev/null +++ b/src/Inshapardaz.Domain/Adapters/IGenerateToken.cs @@ -0,0 +1,13 @@ +using Inshapardaz.Domain.Models; + +namespace Inshapardaz.Domain.Adapters +{ + public interface IGenerateToken + { + string GenerateAccessToken(AccountModel account); + + RefreshTokenModel GenerateRefreshToken(string ipAddress); + + string GenerateResetToken(); + } +} diff --git a/src/Inshapardaz.Domain/Adapters/Repositories/Library/IArticleRepository.cs b/src/Inshapardaz.Domain/Adapters/Repositories/Library/IArticleRepository.cs index ff96c499..5c5b0554 100644 --- a/src/Inshapardaz.Domain/Adapters/Repositories/Library/IArticleRepository.cs +++ b/src/Inshapardaz.Domain/Adapters/Repositories/Library/IArticleRepository.cs @@ -1,35 +1,43 @@ -using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Library; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Domain.Adapters.Repositories.Library { - public interface IIssueArticleRepository + public interface IArticleRepository { - Task> GetArticlesByIssue(int libraryId, int periodicalId, int volumeNumber, int issueNumber, CancellationToken cancellationToken); + Task> GetArticles(int libraryId, string query, int pageNumber, int pageSize, int? accountId, ArticleFilter filter, ArticleSortByType sortBy, SortDirection sortDirection, CancellationToken cancellationToken); - Task GetArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber,int sequenceNumber, CancellationToken cancellationToken); + Task GetArticle(int libraryId, long articleId, CancellationToken cancellationToken); - Task AddArticle(int libraryId, int peridicalId, int volumeNumber, int issueNumber, IssueArticleModel article, CancellationToken cancellationToken); + Task AddArticle(int libraryId, ArticleModel article, int? accountId, CancellationToken cancellationToken); - Task UpdateArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IssueArticleModel article, CancellationToken cancellationToken); + Task UpdateArticle(int libraryId, ArticleModel article, CancellationToken cancellationToken); - Task> GetArticleContents(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken); + Task> GetArticleContents(int libraryId, long articleId, CancellationToken cancellationToken); - Task DeleteArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken); + Task DeleteArticle(int libraryId, long articleId, CancellationToken cancellationToken); - Task GetArticleContentById(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, CancellationToken cancellationToken); + #region Content + Task AddArticleContent(int libraryId, ArticleContentModel content, CancellationToken cancellationToken); - Task AddArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, string content, CancellationToken cancellationToken); + Task UpdateArticleContent(int libraryId, ArticleContentModel content, CancellationToken cancellationToken); - Task UpdateArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, string content, CancellationToken cancellationToken); + Task GetArticleContent(int libraryId, long articleId, string language, CancellationToken cancellationToken); - Task GetArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, CancellationToken cancellationToken); + Task DeleteArticleContent(int libraryId, long articleId, string language, CancellationToken cancellationToken); + #endregion + Task UpdateWriterAssignment(int libraryId, long articleId, int? accountId, CancellationToken cancellationToken); + + Task UpdateReviewerAssignment(int libraryId, long articleId, int? accountId, CancellationToken cancellationToken); - Task DeleteArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken); - Task UpdateWriterAssignment(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, int? accountId, CancellationToken cancellationToken); - Task UpdateReviewerAssignment(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, int? accountId, CancellationToken cancellationToken); - Task UpdateArticleSequence(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IEnumerable articles, CancellationToken cancellationToken); + Task UpdateArticleImage(int libraryId, long articleId, int imageId, CancellationToken cancellationToken); + + #region Faviorite + Task AddArticleToFavorites(int libraryId, int? accountId, long articleId, CancellationToken cancellationToken); + Task RemoveArticleFromFavorites(int libraryId, int? accountId, long articleId, CancellationToken cancellationToken); + #endregion } } diff --git a/src/Inshapardaz.Domain/Adapters/Repositories/Library/IBookRepository.cs b/src/Inshapardaz.Domain/Adapters/Repositories/Library/IBookRepository.cs index 5db2b462..18fadc53 100644 --- a/src/Inshapardaz.Domain/Adapters/Repositories/Library/IBookRepository.cs +++ b/src/Inshapardaz.Domain/Adapters/Repositories/Library/IBookRepository.cs @@ -27,20 +27,21 @@ public interface IBookRepository Task DeleteBookFromRecent(int libraryId, int accountId, int bookId, CancellationToken cancellationToken); Task AddBookToFavorites(int libraryId, int? accountId, int bookId, CancellationToken cancellationToken); - Task> GetBooksByUser(int libraryId, int accountId, int pageNumber, int pageSize, BookStatuses status, BookSortByType sortBy, SortDirection direction, CancellationToken cancellationToken); + Task> GetBooksByUser(int libraryId, int accountId, int pageNumber, int pageSize, StatusType status, BookSortByType sortBy, SortDirection direction, CancellationToken cancellationToken); Task DeleteBookFromFavorites(int libraryId, int accountId, int bookId, CancellationToken cancellationToken); - Task AddBookContent(int bookId, int fileId, string language, string mimeType, CancellationToken cancellationToken); + Task AddBookContent(int bookId, int fileId, string language, string mimeType, CancellationToken cancellationToken); - Task DeleteBookContent(int libraryId, int bookId, string language, string mimeType, CancellationToken cancellationToken); + Task DeleteBookContent(int libraryId, int bookId, int contentId, CancellationToken cancellationToken); Task GetBookContent(int libraryId, int bookId, string language, string mimeType, CancellationToken cancellationToken); + Task GetBookContent(int libraryId, int bookId, int conetntId, CancellationToken cancellationToken); Task> GetBookContents(int libraryId, int bookId, CancellationToken cancellationToken); Task UpdateBookImage(int libraryId, int bookId, int fileId, CancellationToken cancellationToken); - Task UpdateBookContentUrl(int libraryId, int bookId, string language, string mimeType, string url, CancellationToken cancellationToken); + Task UpdateBookContent(int libraryId, int bookId, int contentId, string language, string mimeType, string url, CancellationToken cancellationToken); Task> GetBookPageSummary(int libraryId, IEnumerable bookIds, CancellationToken cancellationToken); } diff --git a/src/Inshapardaz.Domain/Adapters/Repositories/Library/IIssueArticleRepository.cs b/src/Inshapardaz.Domain/Adapters/Repositories/Library/IIssueArticleRepository.cs new file mode 100644 index 00000000..dd4496b3 --- /dev/null +++ b/src/Inshapardaz.Domain/Adapters/Repositories/Library/IIssueArticleRepository.cs @@ -0,0 +1,35 @@ +using Inshapardaz.Domain.Models.Library; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Adapters.Repositories.Library +{ + public interface IIssueArticleRepository + { + Task> GetArticlesByIssue(int libraryId, int periodicalId, int volumeNumber, int issueNumber, CancellationToken cancellationToken); + + Task GetArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken); + + Task AddArticle(int libraryId, int peridicalId, int volumeNumber, int issueNumber, IssueArticleModel article, CancellationToken cancellationToken); + + Task UpdateArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IssueArticleModel article, CancellationToken cancellationToken); + + Task> GetArticleContents(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken); + + Task DeleteArticle(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken); + + Task GetArticleContentById(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, CancellationToken cancellationToken); + + Task AddArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, string content, CancellationToken cancellationToken); + + Task UpdateArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, string content, CancellationToken cancellationToken); + + Task GetArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, string language, CancellationToken cancellationToken); + + Task DeleteArticleContent(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, CancellationToken cancellationToken); + Task UpdateWriterAssignment(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, int? accountId, CancellationToken cancellationToken); + Task UpdateReviewerAssignment(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int sequenceNumber, int? accountId, CancellationToken cancellationToken); + Task UpdateArticleSequence(int libraryId, int periodicalId, int volumeNumber, int issueNumber, IEnumerable articles, CancellationToken cancellationToken); + } +} diff --git a/src/Inshapardaz.Domain/Common/RandomGenerator.cs b/src/Inshapardaz.Domain/Common/RandomGenerator.cs index a956ca5a..0a1189c2 100644 --- a/src/Inshapardaz.Domain/Common/RandomGenerator.cs +++ b/src/Inshapardaz.Domain/Common/RandomGenerator.cs @@ -3,9 +3,9 @@ namespace Inshapardaz.Domain.Common { - internal static class RandomGenerator + public static class RandomGenerator { - internal static string GenerateRandomString() + public static string GenerateRandomString() { using (var rngCryptoServiceProvider = new RNGCryptoServiceProvider()) { diff --git a/src/Inshapardaz.Domain/Inshapardaz.Domain.csproj b/src/Inshapardaz.Domain/Inshapardaz.Domain.csproj index 9adade4e..4f02892d 100644 --- a/src/Inshapardaz.Domain/Inshapardaz.Domain.csproj +++ b/src/Inshapardaz.Domain/Inshapardaz.Domain.csproj @@ -18,17 +18,16 @@ - + - + - + - diff --git a/src/Inshapardaz.Domain/Models/ArticleFilter.cs b/src/Inshapardaz.Domain/Models/ArticleFilter.cs new file mode 100644 index 00000000..63773068 --- /dev/null +++ b/src/Inshapardaz.Domain/Models/ArticleFilter.cs @@ -0,0 +1,18 @@ +namespace Inshapardaz.Domain.Models.Library +{ + public class ArticleFilter + { + public int? AuthorId { get; set; } + + public int? CategoryId { get; set; } + + public bool? Favorite { get; set; } + + public bool? Read { get; set; } + + public EditingStatus Status { get; set; } + + public AssignmentStatus AssignmentStatus { get; set; } + public ArticleType Type { get; set; } + } +} diff --git a/src/Inshapardaz.Domain/Models/ArticleSortByType.cs b/src/Inshapardaz.Domain/Models/ArticleSortByType.cs new file mode 100644 index 00000000..f71ebf18 --- /dev/null +++ b/src/Inshapardaz.Domain/Models/ArticleSortByType.cs @@ -0,0 +1,8 @@ +namespace Inshapardaz.Domain.Models.Library +{ + public enum ArticleSortByType + { + Title, + LastModified + } +} diff --git a/src/Inshapardaz.Domain/Models/BookAssignmentStatus.cs b/src/Inshapardaz.Domain/Models/BookAssignmentStatus.cs new file mode 100644 index 00000000..6b468f8e --- /dev/null +++ b/src/Inshapardaz.Domain/Models/BookAssignmentStatus.cs @@ -0,0 +1,10 @@ +namespace Inshapardaz.Domain.Models.Library +{ + public enum AssignmentStatus + { + None = 0, + Writer = 1, + Reviewer = 2 + } + +} diff --git a/src/Inshapardaz.Domain/Models/BookFilter.cs b/src/Inshapardaz.Domain/Models/BookFilter.cs index e557c6d9..7f3275f1 100644 --- a/src/Inshapardaz.Domain/Models/BookFilter.cs +++ b/src/Inshapardaz.Domain/Models/BookFilter.cs @@ -12,28 +12,10 @@ public class BookFilter public bool? Read { get; set; } - public BookStatuses Status { get; set; } + public StatusType Status { get; set; } - public BookAssignmentStatus AssignmentStatus { get; set; } + public AssignmentStatus AssignmentStatus { get; set; } public int? BookShelfId { get; set; } } - public enum BookAssignmentStatus - { - None = 0, - Writer =1, - Reviewer = 2 - } - - public class IssueFilter - { - public int? Year { get; set; } - - public int? VolumeNumber { get; set; } - - public BookStatuses Status { get; set; } - - public BookAssignmentStatus AssignmentStatus { get; set; } - } - } diff --git a/src/Inshapardaz.Domain/Models/EditingStatus.cs b/src/Inshapardaz.Domain/Models/EditingStatus.cs index 6ca4a0b7..141a737c 100644 --- a/src/Inshapardaz.Domain/Models/EditingStatus.cs +++ b/src/Inshapardaz.Domain/Models/EditingStatus.cs @@ -5,21 +5,21 @@ namespace Inshapardaz.Domain.Models public enum EditingStatus { [Description("All")] - All = -1, + All = 0, [Description("Available")] - Available = 0, + Available, [Description("Typing")] - Typing = 1, + Typing, [Description("Typed")] - Typed = 2, + Typed, [Description("InReview")] - InReview = 3, + InReview, [Description("Completed")] - Completed = 4 + Completed } } diff --git a/src/Inshapardaz.Domain/Models/IssueFilter.cs b/src/Inshapardaz.Domain/Models/IssueFilter.cs new file mode 100644 index 00000000..596db652 --- /dev/null +++ b/src/Inshapardaz.Domain/Models/IssueFilter.cs @@ -0,0 +1,14 @@ +namespace Inshapardaz.Domain.Models.Library +{ + public class IssueFilter + { + public int? Year { get; set; } + + public int? VolumeNumber { get; set; } + + public StatusType Status { get; set; } + + public AssignmentStatus AssignmentStatus { get; set; } + } + +} diff --git a/src/Inshapardaz.Domain/Models/Library/ArticleContentModel.cs b/src/Inshapardaz.Domain/Models/Library/ArticleContentModel.cs index 9e4f1d42..92a5ed2f 100644 --- a/src/Inshapardaz.Domain/Models/Library/ArticleContentModel.cs +++ b/src/Inshapardaz.Domain/Models/Library/ArticleContentModel.cs @@ -4,14 +4,10 @@ public class ArticleContentModel { public int Id { get; set; } - public int PeriodicalId { get; set; } - - public int VolumeNumber { get; set; } - public int IssueNumber { get; set; } - - public int SequenceNumber { get; set; } + public long ArticleId { get; set; } public string Text { get; set; } public string Language { get; set; } + public string Layout { get; set; } } } diff --git a/src/Inshapardaz.Domain/Models/Library/ArticleModel.cs b/src/Inshapardaz.Domain/Models/Library/ArticleModel.cs index e5f4bde9..b72d725b 100644 --- a/src/Inshapardaz.Domain/Models/Library/ArticleModel.cs +++ b/src/Inshapardaz.Domain/Models/Library/ArticleModel.cs @@ -3,23 +3,21 @@ namespace Inshapardaz.Domain.Models.Library { - public class IssueArticleModel + + public class ArticleModel { - public int Id { get; set; } + public long Id { get; set; } public string Title { get; set; } - public int SequenceNumber { get; set; } - - public string SeriesName { get; set; } - - public int? SeriesIndex { get; set; } - + public bool IsPublic { get; set; } public List Authors { get; set; } = new List(); - - public int IssueId { get; set; } - + public List Categories { get; set; } = new List(); public List Contents { get; set; } = new List(); + public bool IsRead { get; set; } + public bool IsFavorite { get; set; } + public int? ImageId { get; set; } + public ArticleType Type { get; set; } public int? WriterAccountId { get; set; } public string WriterAccountName { get; set; } public DateTime? WriterAssignTimeStamp { get; set; } @@ -27,7 +25,11 @@ public class IssueArticleModel public string ReviewerAccountName { get; set; } public DateTime? ReviewerAssignTimeStamp { get; set; } public EditingStatus Status { get; set; } - public IssueArticleModel PreviousArticle { get; set; } - public IssueArticleModel NextArticle { get; set; } + public ArticleModel PreviousArticle { get; set; } + public ArticleModel NextArticle { get; set; } + public int SourceType { get; set; } + public int SourceId { get; set; } + public DateTime? LastModified { get; set; } + } } diff --git a/src/Inshapardaz.Domain/Models/Library/ArticleType.cs b/src/Inshapardaz.Domain/Models/Library/ArticleType.cs new file mode 100644 index 00000000..c018dd79 --- /dev/null +++ b/src/Inshapardaz.Domain/Models/Library/ArticleType.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; + +namespace Inshapardaz.Domain.Models.Library +{ + public enum ArticleType + { + [Description("Unknown")] + Unknown, + [Description("Writing")] + Writing, + [Description("Poetry")] + Poetry + } +} diff --git a/src/Inshapardaz.Domain/Models/Library/AuthorModel.cs b/src/Inshapardaz.Domain/Models/Library/AuthorModel.cs index 103472a7..4d464df0 100644 --- a/src/Inshapardaz.Domain/Models/Library/AuthorModel.cs +++ b/src/Inshapardaz.Domain/Models/Library/AuthorModel.cs @@ -13,6 +13,7 @@ public class AuthorModel public string ImageUrl { get; set; } public int BookCount { get; set; } + public int ArticleCount { get; set; } public AuthorTypes AuthorType { get; set; } } diff --git a/src/Inshapardaz.Domain/Models/Library/BookContentModel.cs b/src/Inshapardaz.Domain/Models/Library/BookContentModel.cs index e14a92c0..b164bdd5 100644 --- a/src/Inshapardaz.Domain/Models/Library/BookContentModel.cs +++ b/src/Inshapardaz.Domain/Models/Library/BookContentModel.cs @@ -12,6 +12,8 @@ public class BookContentModel public string Language { get; set; } + public string FileName { get; set; } + public int FileId { get; internal set; } } } diff --git a/src/Inshapardaz.Domain/Models/Library/BookModel.cs b/src/Inshapardaz.Domain/Models/Library/BookModel.cs index fa0caa87..5d3aee4a 100644 --- a/src/Inshapardaz.Domain/Models/Library/BookModel.cs +++ b/src/Inshapardaz.Domain/Models/Library/BookModel.cs @@ -35,7 +35,7 @@ public class BookModel public int? SeriesIndex { get; set; } - public BookStatuses Status { get; set; } + public StatusType Status { get; set; } public int? YearPublished { get; set; } @@ -56,5 +56,6 @@ public class BookModel public IEnumerable PageStatus { get; set; } public string Source { get; set; } + public string Publisher { get; set; } } } diff --git a/src/Inshapardaz.Domain/Models/Library/IssueArticleContentModel.cs b/src/Inshapardaz.Domain/Models/Library/IssueArticleContentModel.cs new file mode 100644 index 00000000..7ab2f6ff --- /dev/null +++ b/src/Inshapardaz.Domain/Models/Library/IssueArticleContentModel.cs @@ -0,0 +1,17 @@ +namespace Inshapardaz.Domain.Models.Library +{ + public class IssueArticleContentModel + { + public int Id { get; set; } + + public int PeriodicalId { get; set; } + + public int VolumeNumber { get; set; } + public int IssueNumber { get; set; } + + public int SequenceNumber { get; set; } + + public string Text { get; set; } + public string Language { get; set; } + } +} diff --git a/src/Inshapardaz.Domain/Models/Library/IssueArticleModel.cs b/src/Inshapardaz.Domain/Models/Library/IssueArticleModel.cs new file mode 100644 index 00000000..0eb45031 --- /dev/null +++ b/src/Inshapardaz.Domain/Models/Library/IssueArticleModel.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace Inshapardaz.Domain.Models.Library +{ + public class IssueArticleModel + { + public int Id { get; set; } + + public string Title { get; set; } + public int SequenceNumber { get; set; } + + public string SeriesName { get; set; } + + public int? SeriesIndex { get; set; } + + public List Authors { get; set; } = new List(); + + public int IssueId { get; set; } + + public List Contents { get; set; } = new List(); + + public int? WriterAccountId { get; set; } + public string WriterAccountName { get; set; } + public DateTime? WriterAssignTimeStamp { get; set; } + public int? ReviewerAccountId { get; set; } + public string ReviewerAccountName { get; set; } + public DateTime? ReviewerAssignTimeStamp { get; set; } + public EditingStatus Status { get; set; } + public IssueArticleModel PreviousArticle { get; set; } + public IssueArticleModel NextArticle { get; set; } + } +} diff --git a/src/Inshapardaz.Domain/Models/BookStatuses.cs b/src/Inshapardaz.Domain/Models/StatusType.cs similarity index 78% rename from src/Inshapardaz.Domain/Models/BookStatuses.cs rename to src/Inshapardaz.Domain/Models/StatusType.cs index 44e6ed91..257e77bc 100644 --- a/src/Inshapardaz.Domain/Models/BookStatuses.cs +++ b/src/Inshapardaz.Domain/Models/StatusType.cs @@ -2,10 +2,13 @@ namespace Inshapardaz.Domain.Models { - public enum BookStatuses + public enum StatusType { + [Description("Unknown")] + Unknown = 0, + [Description("Published")] - Published = 0, + Published = 1, [Description("AvailableForTyping")] AvailableForTyping, diff --git a/src/Inshapardaz.Domain/Ports/Handlers/DownloadRekhtaBookRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/DownloadRekhtaBookRequest.cs index 4000da20..9d0cec52 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/DownloadRekhtaBookRequest.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/DownloadRekhtaBookRequest.cs @@ -287,7 +287,7 @@ public async Task SaveBookPdfContents(BookModel book, string filePath, byte[] co }; await _commandProcessor.SendAsync(cmdAddBookContent, cancellationToken: cancellationToken); - var amdAddBookPages = new UploadBookPages(_settings.DefaultLibraryId, book.Id) + var amdAddBookPages = new UploadBookPagesRequest(_settings.DefaultLibraryId, book.Id) { Files = new[] { new FileModel { @@ -313,7 +313,7 @@ public async Task SaveBookPages(BookModel book, string filePath, CancellationTok FileName = Path.GetFileName(f) }).ToList(); - var cmd = new UploadBookPages(_settings.DefaultLibraryId, book.Id) + var cmd = new UploadBookPagesRequest(_settings.DefaultLibraryId, book.Id) { Files = _files }; diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleContentRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleContentRequest.cs new file mode 100644 index 00000000..18a214b6 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleContentRequest.cs @@ -0,0 +1,65 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Domain.Repositories; +using Paramore.Brighter; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class AddArticleContentRequest : LibraryBaseCommand + { + public AddArticleContentRequest(int libraryId) + : base(libraryId) + { + } + + public ArticleContentModel Content { get; set; } + + public ArticleContentModel Result { get; set; } + } + + public class AddArticleContentRequestHandler : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + private readonly IFileStorage _fileStorage; + private readonly ILibraryRepository _libraryRepository; + private readonly IFileRepository _fileRepository; + + public AddArticleContentRequestHandler(IArticleRepository articleRepository, IFileStorage fileStorage, ILibraryRepository libraryRepository, IFileRepository fileRepository) + { + _articleRepository = articleRepository; + _fileStorage = fileStorage; + _libraryRepository = libraryRepository; + _fileRepository = fileRepository; + } + + public override async Task HandleAsync(AddArticleContentRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + if (string.IsNullOrWhiteSpace(command.Content.Language)) + { + var library = await _libraryRepository.GetLibraryById(command.LibraryId, cancellationToken); + if (library == null) + { + throw new BadRequestException(); + } + + command.Content.Language = library.Language; + } + + var article = await _articleRepository.GetArticle(command.LibraryId, command.Content.ArticleId, cancellationToken); + + if (article != null) + { + command.Result = await _articleRepository.AddArticleContent( + command.LibraryId, + command.Content, + cancellationToken); + } + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleRequest.cs new file mode 100644 index 00000000..2822bf10 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleRequest.cs @@ -0,0 +1,77 @@ +using DocumentFormat.OpenXml.Spreadsheet; +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Domain.Repositories.Library; +using Paramore.Brighter; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class AddArticleRequest : LibraryBaseCommand + { + public AddArticleRequest(int libraryId, ArticleModel article) + : base(libraryId) + { + Article = article; + } + + public int? AccountId { get; set; } + + public ArticleModel Result { get; set; } + public ArticleModel Article { get; } + } + + public class AddArticleRequestHandler : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + private readonly IAuthorRepository _authorRepository; + private readonly ICategoryRepository _categoryRepository; + + public AddArticleRequestHandler(IArticleRepository articleRepository, + IAuthorRepository authorRepository, + ICategoryRepository categoryRepository) + { + _articleRepository = articleRepository; + _authorRepository = authorRepository; + _categoryRepository = categoryRepository; + } + + [UseLibraryCheck(1, HandlerTiming.Before)] + public override async Task HandleAsync(AddArticleRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + IEnumerable authors = null; + if (command.Article.Authors != null && command.Article.Authors.Any()) + { + authors = await _authorRepository.GetAuthorByIds(command.LibraryId, command.Article.Authors.Select(a => a.Id), cancellationToken); + if (authors.Count() != command.Article.Authors.Count()) + { + throw new BadRequestException(); + } + } + + if (authors == null || authors.FirstOrDefault() == null) + { + throw new BadRequestException(); + } + + IEnumerable categories = null; + if (command.Article.Categories != null && command.Article.Categories.Any()) + { + categories = await _categoryRepository.GetCategoriesByIds(command.LibraryId, command.Article.Categories.Select(c => c.Id), cancellationToken); + if (categories.Count() != command.Article.Categories.Count()) + { + throw new BadRequestException(); + } + } + + command.Result = await _articleRepository.AddArticle(command.LibraryId, command.Article, command.AccountId, cancellationToken); + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleToFavoriteRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleToFavoriteRequest.cs new file mode 100644 index 00000000..b486e72d --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AddArticleToFavoriteRequest.cs @@ -0,0 +1,44 @@ +using Inshapardaz.Domain.Adapters; +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Repositories.Library; +using Paramore.Brighter; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class AddArticleToFavoriteRequest : LibraryBaseCommand + { + public AddArticleToFavoriteRequest(int libraryId, long articleId, int? accountId) + : base(libraryId) + { + ArticleId = articleId; + AccountId = accountId; + } + + public long ArticleId { get; } + public int? AccountId { get; } + } + + public class AddArticleToFavoriteRequestHandler : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + + public AddArticleToFavoriteRequestHandler(IArticleRepository articleRepository) + { + _articleRepository = articleRepository; + } + + public override async Task HandleAsync(AddArticleToFavoriteRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + var article = await _articleRepository.GetArticle(command.LibraryId, command.ArticleId, cancellationToken); + if (article != null) + { + await _articleRepository.AddArticleToFavorites(command.LibraryId, command.AccountId, command.ArticleId, cancellationToken); + } + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AssignIssueArticleToUserRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AssignIssueArticleToUserRequest.cs new file mode 100644 index 00000000..de1bb6b9 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/AssignIssueArticleToUserRequest.cs @@ -0,0 +1,74 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Domain.Repositories; +using Paramore.Brighter; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class AssignArticleToUserRequest : LibraryBaseCommand + { + public AssignArticleToUserRequest(int libraryId, int articleId, int? accountId, bool isAdmin = false) + : base(libraryId) + { + ArticleId = articleId; + AccountId = accountId; + IsAdmin = isAdmin; + } + + public ArticleModel Result { get; set; } + public int ArticleId { get; set; } + public int? AccountId { get; private set; } + public bool IsAdmin { get; } + } + + public class AssignArticleToUserRequestHandler : RequestHandlerAsync + { + private readonly IAccountRepository _accountRepository; + private readonly IArticleRepository _articleRepository; + + public AssignArticleToUserRequestHandler(IAccountRepository accountRepository, + IArticleRepository articleRepository) + { + _accountRepository = accountRepository; + _articleRepository = articleRepository; + } + + public override async Task HandleAsync(AssignArticleToUserRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + if (!command.IsAdmin) + { + var account = await _accountRepository.GetLibraryAccountById(command.LibraryId, command.AccountId.Value, cancellationToken); + if (account.Role != Role.LibraryAdmin && account.Role != Role.Writer) + { + throw new BadRequestException("user cannot be assigned article"); + } + } + + var article = await _articleRepository.GetArticle(command.LibraryId, command.ArticleId, cancellationToken); + if (article == null) + { + throw new BadRequestException(); + } + + if (article.Status == EditingStatus.Available || article.Status == EditingStatus.Typing) + { + command.Result = await _articleRepository.UpdateWriterAssignment(command.LibraryId, command.ArticleId, command.AccountId, cancellationToken); + } + else if (article.Status == EditingStatus.Typed || article.Status == EditingStatus.InReview) + { + command.Result = await _articleRepository.UpdateReviewerAssignment(command.LibraryId, command.ArticleId, command.AccountId, cancellationToken); + } + else + { + throw new BadRequestException("Article does not allow it to be assigned"); + } + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/DeleteArticleContentRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/DeleteArticleContentRequest.cs new file mode 100644 index 00000000..9beefd14 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/DeleteArticleContentRequest.cs @@ -0,0 +1,43 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Models.Handlers.Library; +using Paramore.Brighter; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class DeleteArticleContentRequest : LibraryBaseCommand + { + public DeleteArticleContentRequest(int libraryId, int articleId, string language) + : base(libraryId) + { + ArticleId = articleId; + Language = language; + } + + public int ArticleId { get; } + public string Language { get; } + } + + public class DeleteArticleContentRequestHandler : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + + public DeleteArticleContentRequestHandler(IArticleRepository articleRepository) + { + _articleRepository = articleRepository; + } + + public override async Task HandleAsync(DeleteArticleContentRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + var content = await _articleRepository.GetArticleContent(command.LibraryId, command.ArticleId, command.Language, cancellationToken); + + if (content != null) + { + await _articleRepository.DeleteArticleContent(command.LibraryId, command.ArticleId, command.Language, cancellationToken); + } + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/DeleteArticleRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/DeleteArticleRequest.cs new file mode 100644 index 00000000..494e6661 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/DeleteArticleRequest.cs @@ -0,0 +1,36 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Models.Handlers.Library; +using Paramore.Brighter; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class DeleteArticleRequest : LibraryBaseCommand + { + public DeleteArticleRequest(int libraryId, int articleId) + : base(libraryId) + { + ArticleId = articleId; + } + + public int ArticleId { get; } + } + + public class DeleteArticleRequestHandler : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + + public DeleteArticleRequestHandler(IArticleRepository articleRepository) + { + _articleRepository = articleRepository; + } + + public override async Task HandleAsync(DeleteArticleRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + await _articleRepository.DeleteArticle(command.LibraryId, command.ArticleId, cancellationToken); + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticleByIdQuery.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticleByIdQuery.cs new file mode 100644 index 00000000..bda52d8f --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticleByIdQuery.cs @@ -0,0 +1,37 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Domain.Repositories.Library; +using Paramore.Darker; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class GetArticleByIdQuery : LibraryBaseQuery + { + public GetArticleByIdQuery(int libraryId, int articleId) + : base(libraryId) + { + ArticleId = articleId; + } + + public int ArticleId { get; } + } + + public class GetArticleByIdQueryHandler : QueryHandlerAsync + { + private readonly IArticleRepository _articleRepository; + + public GetArticleByIdQueryHandler(IArticleRepository articleRepository) + { + _articleRepository = articleRepository; + } + + public override async Task ExecuteAsync(GetArticleByIdQuery command, CancellationToken cancellationToken = new CancellationToken()) + { + return await _articleRepository.GetArticle(command.LibraryId, command.ArticleId, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticleContentQuery.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticleContentQuery.cs new file mode 100644 index 00000000..af3ebafd --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticleContentQuery.cs @@ -0,0 +1,52 @@ +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Repositories; +using Inshapardaz.Domain.Repositories.Library; +using Paramore.Darker; +using System.Threading; +using System.Threading.Tasks; +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Models.Library; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class GetArticleContentQuery : LibraryBaseQuery + { + public GetArticleContentQuery(int libraryId, int articleId, string language) + : base(libraryId) + { + ArticleId = articleId; + Language = language; + } + + public int ArticleId { get; } + public string Language { get; set; } + } + + public class GetArticleContentQueryHandler : QueryHandlerAsync + { + private readonly ILibraryRepository _libraryRepository; + private readonly IArticleRepository _articleRepository; + + public GetArticleContentQueryHandler(ILibraryRepository libraryRepository, IArticleRepository articleRepository) + { + _libraryRepository = libraryRepository; + _articleRepository = articleRepository; + } + + public override async Task ExecuteAsync(GetArticleContentQuery command, CancellationToken cancellationToken = new CancellationToken()) + { + if (string.IsNullOrWhiteSpace(command.Language)) + { + var library = await _libraryRepository.GetLibraryById(command.LibraryId, cancellationToken); + if (library == null) + { + throw new BadRequestException(); + } + + command.Language = library.Language; + } + return await _articleRepository.GetArticleContent(command.LibraryId, command.ArticleId, command.Language, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticlesQuery.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticlesQuery.cs new file mode 100644 index 00000000..98e7191f --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/GetArticlesQuery.cs @@ -0,0 +1,60 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Models.Library; +using Paramore.Darker; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class GetArticlesQuery : LibraryBaseQuery> + { + public GetArticlesQuery(int libraryId, int pageNumber, int pageSize, int? accountId) + : base(libraryId) + { + PageNumber = pageNumber; + PageSize = pageSize; + AccountId = accountId; + } + + public int PageNumber { get; private set; } + + public int PageSize { get; private set; } + public int? AccountId { get; } + public string Query { get; set; } + + public ArticleSortByType SortBy { get; set; } + + public ArticleFilter Filter { get; set; } + public SortDirection SortDirection { get; set; } + + } + + public class GetArticlesQueryHandler : QueryHandlerAsync> + { + private readonly IArticleRepository _articleRepository; + + public GetArticlesQueryHandler(IArticleRepository articleRepository) + { + _articleRepository = articleRepository; + } + + public override async Task> ExecuteAsync(GetArticlesQuery command, CancellationToken cancellationToken = new CancellationToken()) + { + var articles = await _articleRepository.GetArticles( + command.LibraryId, + command.Query, + command.PageNumber, + command.PageSize, + command.AccountId, + command.Filter, + command.SortBy, + command.SortDirection, + cancellationToken); + + return articles; + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/RemoveArticleFromFavoriteRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/RemoveArticleFromFavoriteRequest.cs new file mode 100644 index 00000000..a8d29fd5 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/RemoveArticleFromFavoriteRequest.cs @@ -0,0 +1,39 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Models.Handlers.Library; +using Paramore.Brighter; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class RemoveArticleFromFavoriteRequest : LibraryBaseCommand + { + public RemoveArticleFromFavoriteRequest(int libraryId, long articleId, int? accountId) + : base(libraryId) + { + ArticleId = articleId; + AccountId = accountId; + } + + public long ArticleId { get; set; } + public int? AccountId { get; } + } + + public class RemoveArticleFromFavoriteRequestHandler + : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + + public RemoveArticleFromFavoriteRequestHandler(IArticleRepository articleRepository) + { + _articleRepository = articleRepository; + } + + public override async Task HandleAsync(RemoveArticleFromFavoriteRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + await _articleRepository.RemoveArticleFromFavorites(command.LibraryId, command.AccountId.Value, command.ArticleId, cancellationToken); + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleContentRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleContentRequest.cs new file mode 100644 index 00000000..ad4897db --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleContentRequest.cs @@ -0,0 +1,83 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Domain.Repositories; +using Paramore.Brighter; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class UpdateArticleContentRequest : LibraryBaseCommand + { + public UpdateArticleContentRequest(int libraryId) + : base(libraryId) + { + } + + public ArticleContentModel Content { get; set; } + + + public RequestResult Result { get; set; } = new RequestResult(); + + public class RequestResult + { + public ArticleContentModel Content { get; set; } + + public bool HasAddedNew { get; set; } + } + } + + public class UpdateArticleContentRequestHandler : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + private readonly ILibraryRepository _libraryRepository; + + public UpdateArticleContentRequestHandler(IArticleRepository articleRepository, ILibraryRepository libraryRepository) + { + _articleRepository = articleRepository; + _libraryRepository = libraryRepository; + } + + public override async Task HandleAsync(UpdateArticleContentRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + var article = await _articleRepository.GetArticle(command.LibraryId, command.Content.ArticleId, cancellationToken); + + if (article == null) + { + throw new BadRequestException(); + } + + if (string.IsNullOrWhiteSpace(command.Content.Language)) + { + var library = await _libraryRepository.GetLibraryById(command.LibraryId, cancellationToken); + if (library == null) + { + throw new BadRequestException(); + } + + command.Content.Language = library.Language; + } + + var content = await _articleRepository.GetArticleContent(command.LibraryId, command.Content.ArticleId, command.Content.Language, cancellationToken); + + if (content == null) + { + command.Result.Content = await _articleRepository.AddArticleContent( + command.LibraryId, + command.Content, + cancellationToken); + command.Result.HasAddedNew = true; + } + else + { + command.Result.Content = await _articleRepository.UpdateArticleContent(command.LibraryId, + command.Content, + cancellationToken); + } + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleImageRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleImageRequest.cs new file mode 100644 index 00000000..a976cf91 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleImageRequest.cs @@ -0,0 +1,105 @@ +using Inshapardaz.Domain.Adapters; +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Models; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Repositories; +using Inshapardaz.Domain.Repositories.Library; +using Paramore.Brighter; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class UpdateArticleImageRequest : LibraryBaseCommand + { + public UpdateArticleImageRequest(int libraryId, long articleId, int? accountId) + : base(libraryId) + { + ArticleId = articleId; + AccountId = accountId; + } + + public long ArticleId { get; } + public int? AccountId { get; } + public FileModel Image { get; set; } + + public RequestResult Result { get; set; } = new RequestResult(); + + public class RequestResult + { + public FileModel File { get; set; } + + public bool HasAddedNew { get; set; } + } + } + + public class UpdateArticleImageRequestHandler : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + private readonly IFileRepository _fileRepository; + private readonly IFileStorage _fileStorage; + + public UpdateArticleImageRequestHandler(IArticleRepository articleRepository, IFileRepository fileRepository, IFileStorage fileStorage) + { + _articleRepository = articleRepository; + _fileRepository = fileRepository; + _fileStorage = fileStorage; + } + + public override async Task HandleAsync(UpdateArticleImageRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + var article = await _articleRepository.GetArticle(command.LibraryId, command.ArticleId, cancellationToken); + + if (article == null) + { + throw new NotFoundException(); + } + + if (article.ImageId.HasValue) + { + command.Image.Id = article.ImageId.Value; + var existingImage = await _fileRepository.GetFileById(article.ImageId.Value, cancellationToken); + if (existingImage != null && !string.IsNullOrWhiteSpace(existingImage.FilePath)) + { + await _fileStorage.TryDeleteImage(existingImage.FilePath, cancellationToken); + } + + var url = await AddImageToFileStore(article.Id, command.Image.FileName, command.Image.Contents, command.Image.MimeType, cancellationToken); + + command.Image.FilePath = url; + command.Image.IsPublic = true; + await _fileRepository.UpdateFile(command.Image, cancellationToken); + command.Result.File = command.Image; + command.Result.File.Id = article.ImageId.Value; + } + else + { + command.Image.Id = default; + var url = await AddImageToFileStore(article.Id, command.Image.FileName, command.Image.Contents, command.Image.MimeType, cancellationToken); + command.Image.FilePath = url; + command.Image.IsPublic = true; + command.Result.File = await _fileRepository.AddFile(command.Image, cancellationToken); + command.Result.HasAddedNew = true; + + await _articleRepository.UpdateArticleImage(command.LibraryId, command.ArticleId, command.Result.File.Id, cancellationToken); + } + + return await base.HandleAsync(command, cancellationToken); + } + + private async Task AddImageToFileStore(long articleId, string fileName, byte[] contents, string mimeType, CancellationToken cancellationToken) + { + var filePath = GetUniqueFileName(articleId, fileName); + return await _fileStorage.StoreImage(filePath, contents, mimeType, cancellationToken); + } + + private static string GetUniqueFileName(long articleId, string fileName) + { + var fileNameWithourExtension = Path.GetExtension(fileName).Trim('.'); + return $"articles/{articleId}/title.{fileNameWithourExtension}"; + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleRequest.cs new file mode 100644 index 00000000..0d434e58 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Article/UpdateArticleRequest.cs @@ -0,0 +1,93 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Models.Handlers.Library; +using Inshapardaz.Domain.Models.Library; +using Inshapardaz.Domain.Repositories.Library; +using Paramore.Brighter; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Ports.Handlers.Library.Article +{ + public class UpdateArticleRequest : LibraryBaseCommand + { + public UpdateArticleRequest(int libraryId, ArticleModel article) + : base(libraryId) + { + Article = article; + } + + public RequestResult Result { get; set; } = new RequestResult(); + public ArticleModel Article { get; } + public int? AccountId { get; set; } + + public class RequestResult + { + public ArticleModel Article { get; set; } + + public bool HasAddedNew { get; set; } + } + } + + public class UpdateArticleRequestHandler : RequestHandlerAsync + { + private readonly IArticleRepository _articleRepository; + private readonly IAuthorRepository _authorRepository; + private readonly ICategoryRepository _categoryRepository; + + public UpdateArticleRequestHandler(IArticleRepository articleRepository, IAuthorRepository authorRepository, ICategoryRepository categoryRepository) + { + _articleRepository = articleRepository; + _authorRepository = authorRepository; + _categoryRepository = categoryRepository; + } + + [UseLibraryCheck(1, HandlerTiming.Before)] + public override async Task HandleAsync(UpdateArticleRequest command, CancellationToken cancellationToken = new CancellationToken()) + { + IEnumerable authors = null; + if (command.Article.Authors != null && command.Article.Authors.Any()) + { + authors = await _authorRepository.GetAuthorByIds(command.LibraryId, command.Article.Authors.Select(a => a.Id), cancellationToken); + if (authors.Count() != command.Article.Authors.Count()) + { + throw new BadRequestException(); + } + } + + if (authors == null || !authors.Any()) + { + throw new BadRequestException(); + } + + IEnumerable categories = null; + if (command.Article.Categories != null && command.Article.Categories.Any()) + { + categories = await _categoryRepository.GetCategoriesByIds(command.LibraryId, command.Article.Categories.Select(c => c.Id), cancellationToken); + if (categories.Count() != command.Article.Categories.Count()) + { + throw new BadRequestException(); + } + } + + + var result = await _articleRepository.GetArticle(command.LibraryId, command.Article.Id, cancellationToken); + + if (result == null) + { + var article = command.Article; + article.Id = default; + command.Result.Article = await _articleRepository.AddArticle(command.LibraryId, article, command.AccountId, cancellationToken); + command.Result.HasAddedNew = true; + } + else + { + command.Result.Article = await _articleRepository.UpdateArticle(command.LibraryId, command.Article, cancellationToken); + } + + return await base.HandleAsync(command, cancellationToken); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/AddBookContentRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/AddBookContentRequest.cs index cf392c91..0cd475a9 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/AddBookContentRequest.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/AddBookContentRequest.cs @@ -74,9 +74,9 @@ public AddBookFileRequestHandler(IBookRepository bookRepository, IFileRepository command.Content.FilePath = url; command.Content.IsPublic = true; var file = await _fileRepository.AddFile(command.Content, cancellationToken); - await _bookRepository.AddBookContent(book.Id, file.Id, command.Language, command.MimeType, cancellationToken); + var contentId = await _bookRepository.AddBookContent(book.Id, file.Id, command.Language, command.MimeType, cancellationToken); - command.Result = await _bookRepository.GetBookContent(book.LibraryId, book.Id, command.Language, command.MimeType, cancellationToken); ; + command.Result = await _bookRepository.GetBookContent(command.LibraryId, command.BookId, contentId, cancellationToken); ; } return await base.HandleAsync(command, cancellationToken); diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookContentRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookContentRequest.cs index ba8665f7..072b4b7e 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookContentRequest.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookContentRequest.cs @@ -8,15 +8,13 @@ namespace Inshapardaz.Domain.Ports.Handlers.Library.Book { public class DeleteBookContentRequest : BookRequest { - public DeleteBookContentRequest(int libraryId, int bookId, string language, string mimeType) + public DeleteBookContentRequest(int libraryId, int bookId, int contentId) : base(libraryId, bookId) { - Language = language; - MimeType = mimeType; + ContentId = contentId; } - public string Language { get; } - public string MimeType { get; } + public int ContentId { get; } } public class DeleteBookContentRequestHandler : RequestHandlerAsync @@ -34,11 +32,11 @@ public DeleteBookContentRequestHandler(IBookRepository bookRepository, IFileRepo public override async Task HandleAsync(DeleteBookContentRequest command, CancellationToken cancellationToken = new CancellationToken()) { - var content = await _bookRepository.GetBookContent(command.LibraryId, command.BookId, command.Language, command.MimeType, cancellationToken); + var content = await _bookRepository.GetBookContent(command.LibraryId, command.BookId, command.ContentId, cancellationToken); if (content != null) { await _fileStorage.TryDeleteFile(content.ContentUrl, cancellationToken); - await _bookRepository.DeleteBookContent(command.LibraryId, command.BookId, command.Language, command.MimeType, cancellationToken); + await _bookRepository.DeleteBookContent(command.LibraryId, command.BookId, command.ContentId, cancellationToken); await _fileRepository.DeleteFile(content.FileId, cancellationToken); } diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookToFavoriteRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookFromFavoriteRequest.cs similarity index 52% rename from src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookToFavoriteRequest.cs rename to src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookFromFavoriteRequest.cs index b752d75a..92e2da55 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookToFavoriteRequest.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/DeleteBookFromFavoriteRequest.cs @@ -1,14 +1,13 @@ -using Inshapardaz.Domain.Adapters; -using Inshapardaz.Domain.Repositories.Library; +using Inshapardaz.Domain.Repositories.Library; using Paramore.Brighter; using System.Threading; using System.Threading.Tasks; namespace Inshapardaz.Domain.Ports.Handlers.Library.Book { - public class DeleteBookToFavoriteRequest : BookRequest + public class DeleteBookFromFavoriteRequest : BookRequest { - public DeleteBookToFavoriteRequest(int libraryId, int bookId, int? accountId) + public DeleteBookFromFavoriteRequest(int libraryId, int bookId, int? accountId) : base(libraryId, bookId) { AccountId = accountId; @@ -17,16 +16,16 @@ public DeleteBookToFavoriteRequest(int libraryId, int bookId, int? accountId) public int? AccountId { get; } } - public class DeleteBookToFavoriteRequestHandler : RequestHandlerAsync + public class DeleteBookFromFavoriteRequestHandler : RequestHandlerAsync { private readonly IBookRepository _bookRepository; - public DeleteBookToFavoriteRequestHandler(IBookRepository bookRepository) + public DeleteBookFromFavoriteRequestHandler(IBookRepository bookRepository) { _bookRepository = bookRepository; } - public override async Task HandleAsync(DeleteBookToFavoriteRequest command, CancellationToken cancellationToken = new CancellationToken()) + public override async Task HandleAsync(DeleteBookFromFavoriteRequest command, CancellationToken cancellationToken = new CancellationToken()) { await _bookRepository.DeleteBookFromFavorites(command.LibraryId, command.AccountId.Value, command.BookId, cancellationToken); diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/GetUserBooksQuery.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/GetUserBooksQuery.cs index 91ade3d5..923da14f 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/GetUserBooksQuery.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/GetUserBooksQuery.cs @@ -23,7 +23,7 @@ public GetUserBooksQuery(int libraryId, int accountId, int pageNumber, int pageS public int PageNumber { get; private set; } public int PageSize { get; private set; } - public BookStatuses StatusFilter { get; set; } + public StatusType StatusFilter { get; set; } public int AccountId { get; set; } } diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/Page/UpdateBookPageImageRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/Page/UpdateBookPageImageRequest.cs index 3ae96272..843b85d1 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/Page/UpdateBookPageImageRequest.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/Page/UpdateBookPageImageRequest.cs @@ -98,8 +98,8 @@ private async Task AddImageToFileStore(int bookId, int sequenceNumber, s private static string GetUniqueFileName(int bookId, int sequenceNumber, string fileName) { - var fileNameWithourExtension = Path.GetExtension(fileName).Trim('.'); - return $"books/{bookId}/pages/page_{sequenceNumber:0000}.{fileNameWithourExtension}"; + var extension = Path.GetExtension(fileName).Trim('.'); + return $"books/{bookId}/pages/page_{sequenceNumber:0000}.{extension}"; } } } diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/Page/UploadBookPages.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/Page/UploadBookPages.cs index 7b5946f2..060e7306 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/Page/UploadBookPages.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/Page/UploadBookPages.cs @@ -3,6 +3,7 @@ using Inshapardaz.Domain.Models; using Inshapardaz.Domain.Models.Handlers.Library; using Inshapardaz.Domain.Repositories; +using Microsoft.Extensions.Logging; using Paramore.Brighter; using System; using System.Collections.Generic; @@ -13,9 +14,9 @@ namespace Inshapardaz.Domain.Ports.Handlers.Library.Book.Page { - public class UploadBookPages : LibraryBaseCommand + public class UploadBookPagesRequest : LibraryBaseCommand { - public UploadBookPages(int libraryId, int bookId) + public UploadBookPagesRequest(int libraryId, int bookId) : base(libraryId) { BookId = bookId; @@ -26,27 +27,31 @@ public UploadBookPages(int libraryId, int bookId) public IEnumerable Files { get; set; } } - public class UploadBookPagesHandler : RequestHandlerAsync + public class UploadBookPagesHandler : RequestHandlerAsync { private readonly IBookPageRepository _bookPageRepository; private readonly IFileRepository _fileRepository; private readonly IFileStorage _fileStorage; private readonly IConvertPdf _pdfConverter; private readonly IOpenZip _zipOpener; + private readonly ILogger _logger; public UploadBookPagesHandler(IBookPageRepository bookPageRepository, IFileRepository fileRepository, - IFileStorage fileStorage, IConvertPdf pdfConverter, IOpenZip zipOpener) + IFileStorage fileStorage, IConvertPdf pdfConverter, IOpenZip zipOpener, ILogger logger) { _bookPageRepository = bookPageRepository; _fileRepository = fileRepository; _fileStorage = fileStorage; _pdfConverter = pdfConverter; _zipOpener = zipOpener; + _logger = logger; } - public override async Task HandleAsync(UploadBookPages command, CancellationToken cancellationToken = new CancellationToken()) + public override async Task HandleAsync(UploadBookPagesRequest command, CancellationToken cancellationToken = new CancellationToken()) { + _logger.LogInformation("Upload files {Count} for book {bookId}", command.Files.Count(), command.BookId); var pageNumber = await _bookPageRepository.GetLastPageNumberForBook(command.LibraryId, command.BookId, cancellationToken); + _logger.LogInformation("Last page number is {lastPageNumber}", pageNumber); IEnumerable files = new List(); if (command.Files.Count() == 1 && command.Files.Single().MimeType == MimeTypes.Pdf) @@ -72,7 +77,8 @@ public UploadBookPagesHandler(IBookPageRepository bookPageRepository, IFileRepos { var extension = Path.GetExtension(file.FileName).Trim('.'); var sequenceNumber = ++pageNumber; - var url = await AddImageToFileStore(command.BookId, sequenceNumber, $"{sequenceNumber:0000}.{extension}", file.Contents, file.MimeType, cancellationToken); + var url = await AddImageToFileStore(command.BookId, $"{sequenceNumber:0000}.{extension}", file.Contents, file.MimeType, cancellationToken); + _logger.LogInformation("Added Image {Url} to filestore for book {bookId}", url, command.BookId); var fileModel = await _fileRepository.AddFile(new FileModel { IsPublic = false, @@ -81,19 +87,22 @@ public UploadBookPagesHandler(IBookPageRepository bookPageRepository, IFileRepos FileName = file.FileName, MimeType = file.MimeType }, cancellationToken); + _logger.LogInformation("Added FileModel {id} for book {bookId} with path {FilePath}", fileModel.Id, command.BookId, file.FilePath); var bookPage = await _bookPageRepository.AddPage(command.LibraryId, command.BookId, pageNumber, string.Empty, fileModel.Id, null, cancellationToken); + _logger.LogInformation("Added Book page {id} for book {bookId}", bookPage.ImageId, bookPage.BookId); + } return await base.HandleAsync(command, cancellationToken); } - private async Task AddImageToFileStore(int bookId, int sequenceNumber, string fileName, byte[] contents, string mimeType, CancellationToken cancellationToken) + private async Task AddImageToFileStore(int bookId, string fileName, byte[] contents, string mimeType, CancellationToken cancellationToken) { - var filePath = GetUniqueFileName(bookId, sequenceNumber, fileName); + var filePath = GetUniqueFileName(bookId, fileName); return await _fileStorage.StoreImage(filePath, contents, mimeType, cancellationToken); } - private static string GetUniqueFileName(int bookId, int sequenceNumber, string fileName) + private static string GetUniqueFileName(int bookId, string fileName) { return $"books/{bookId}/pages/{fileName}"; } diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/UpdateBookContentRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/UpdateBookContentRequest.cs index da2ea32a..0f7afd81 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/UpdateBookContentRequest.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Book/UpdateBookContentRequest.cs @@ -14,17 +14,18 @@ namespace Inshapardaz.Domain.Ports.Handlers.Library.Book { public class UpdateBookContentRequest : LibraryBaseCommand { - public UpdateBookContentRequest(int libraryId, int bookId, string language, string mimeType, int? accountId) + public UpdateBookContentRequest(int libraryId, int bookId, int contentId, string language, string mimeType, int? accountId) : base(libraryId) { BookId = bookId; + ContentId = contentId; Language = language; MimeType = mimeType; AccountId = accountId; } public int BookId { get; } - + public int ContentId { get; } public string Language { get; } public string MimeType { get; } public int? AccountId { get; } @@ -58,7 +59,7 @@ public UpdateBookFileRequestHandler(IBookRepository bookRepository, IFileReposit var book = await _bookRepository.GetBookById(command.LibraryId, command.BookId, command.AccountId, cancellationToken); if (book != null) { - var bookContent = await _bookRepository.GetBookContent(command.LibraryId, command.BookId, command.Language, command.MimeType, cancellationToken); + var bookContent = await _bookRepository.GetBookContent(command.LibraryId, command.BookId, command.ContentId, cancellationToken); if (bookContent != null) { if (!string.IsNullOrWhiteSpace(bookContent.ContentUrl)) @@ -68,8 +69,9 @@ public UpdateBookFileRequestHandler(IBookRepository bookRepository, IFileReposit var url = await StoreFile(command.BookId, command.Content.FileName, command.Content.Contents, cancellationToken); bookContent.ContentUrl = url; - await _bookRepository.UpdateBookContentUrl(command.LibraryId, + await _bookRepository.UpdateBookContent(command.LibraryId, command.BookId, + command.ContentId, command.Language, command.MimeType, url, cancellationToken); @@ -82,10 +84,10 @@ await _bookRepository.UpdateBookContentUrl(command.LibraryId, command.Content.FilePath = url; command.Content.IsPublic = book.IsPublic; var file = await _fileRepository.AddFile(command.Content, cancellationToken); - await _bookRepository.AddBookContent(command.BookId, file.Id, command.Language, command.MimeType, cancellationToken); + var contentId = await _bookRepository.AddBookContent(command.BookId, file.Id, command.Language, command.MimeType, cancellationToken); command.Result.HasAddedNew = true; - command.Result.Content = await _bookRepository.GetBookContent(command.LibraryId, command.BookId, command.Language, command.MimeType, cancellationToken); ; + command.Result.Content = await _bookRepository.GetBookContent(command.LibraryId, command.BookId, contentId, cancellationToken); ; } } diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/LibraryCheck.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/LibraryCheck.cs new file mode 100644 index 00000000..b4916995 --- /dev/null +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/LibraryCheck.cs @@ -0,0 +1,47 @@ +using Inshapardaz.Domain.Adapters.Repositories.Library; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Models.Handlers.Library; +using Paramore.Brighter; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Inshapardaz.Domain.Models.Library +{ + public class LibraryCheckerHandler : RequestHandlerAsync where T : LibraryBaseCommand + { + private readonly ILibraryRepository _libraryRepository; + + public LibraryCheckerHandler(ILibraryRepository libraryRepository) + { + _libraryRepository = libraryRepository; + } + + public override async Task HandleAsync(T command, CancellationToken cancellationToken) + { + var libraryCommand = command as LibraryBaseCommand; + var library = await _libraryRepository.GetLibraryById(libraryCommand.LibraryId, cancellationToken); + + if (library == null) + { + throw new NotFoundException(); + } + + return await base.HandleAsync(command, cancellationToken); + } + } + + public class UseLibraryCheckAttribute : RequestHandlerAttribute + { + + public UseLibraryCheckAttribute(int step, HandlerTiming timing = HandlerTiming.Before) + : base(step, timing) + { } + + + public override Type GetHandlerType() + { + return typeof(LibraryCheckerHandler<>); + } + } +} diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/AddIssueArticleContentRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/AddIssueArticleContentRequest.cs index 96535484..94c68336 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/AddIssueArticleContentRequest.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/AddIssueArticleContentRequest.cs @@ -32,7 +32,7 @@ public AddIssueArticleContentRequest(int libraryId, int periodicalId, int volume public string Language { get; set; } - public ArticleContentModel Result { get; set; } + public IssueArticleContentModel Result { get; set; } } public class AddArticleContentRequestHandler : RequestHandlerAsync diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/GetIssueArticleContentQuery.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/GetIssueArticleContentQuery.cs index 1dd02a07..2efa4d07 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/GetIssueArticleContentQuery.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/GetIssueArticleContentQuery.cs @@ -10,7 +10,7 @@ namespace Inshapardaz.Domain.Ports.Handlers.Library.Periodical.Issue.Article { - public class GetIssueArticleContentQuery : LibraryBaseQuery + public class GetIssueArticleContentQuery : LibraryBaseQuery { public GetIssueArticleContentQuery(int libraryId, int periodicalId, int volumeNumber, int issueNumber, int articleId, string language) : base(libraryId) @@ -29,7 +29,7 @@ public GetIssueArticleContentQuery(int libraryId, int periodicalId, int volumeNu public string Language { get; set; } } - public class GetArticleContentQueryHandler : QueryHandlerAsync + public class GetArticleContentQueryHandler : QueryHandlerAsync { private readonly ILibraryRepository _libraryRepository; private readonly IIssueArticleRepository _articleRepository; @@ -40,7 +40,7 @@ public GetArticleContentQueryHandler(ILibraryRepository libraryRepository, IIssu _articleRepository = articleRepository; } - public override async Task ExecuteAsync(GetIssueArticleContentQuery command, CancellationToken cancellationToken = new CancellationToken()) + public override async Task ExecuteAsync(GetIssueArticleContentQuery command, CancellationToken cancellationToken = new CancellationToken()) { if (string.IsNullOrWhiteSpace(command.Language)) { diff --git a/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/UpdateIssueArticleContentRequest.cs b/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/UpdateIssueArticleContentRequest.cs index a4875dd5..5b832785 100644 --- a/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/UpdateIssueArticleContentRequest.cs +++ b/src/Inshapardaz.Domain/Ports/Handlers/Library/Periodical/Issue/Article/UpdateIssueArticleContentRequest.cs @@ -35,7 +35,7 @@ public UpdateIssueArticleContentRequest(int libraryId, int periodicalId, int vol public class RequestResult { - public ArticleContentModel Content { get; set; } + public IssueArticleContentModel Content { get; set; } public bool HasAddedNew { get; set; } } diff --git a/src/Inshapardaz.LibraryMigrator/Inshapardaz.LibraryMigrator.csproj b/src/Inshapardaz.LibraryMigrator/Inshapardaz.LibraryMigrator.csproj index 90aea6db..cc7f46d3 100644 --- a/src/Inshapardaz.LibraryMigrator/Inshapardaz.LibraryMigrator.csproj +++ b/src/Inshapardaz.LibraryMigrator/Inshapardaz.LibraryMigrator.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Inshapardaz.LibraryMigrator/Migrator.cs b/src/Inshapardaz.LibraryMigrator/Migrator.cs index 0788a9a5..db4a2655 100644 --- a/src/Inshapardaz.LibraryMigrator/Migrator.cs +++ b/src/Inshapardaz.LibraryMigrator/Migrator.cs @@ -3,8 +3,6 @@ using Inshapardaz.Database.SqlServer.Repositories.Library; using Inshapardaz.Domain.Models; using Inshapardaz.Domain.Models.Library; -using System.Transactions; -using static System.Formats.Asn1.AsnWriter; namespace Inshapardaz.LibraryMigrator; public class Migrator @@ -52,32 +50,25 @@ public async Task Migrate(int libraryId, CancellationToken cancellationToken) Console.WriteLine($"New library is {newLibrary.Id}"); _accountsMap = await MigrateAccounts(libraryId, newLibrary.Id, cancellationToken); - - Console.WriteLine($"{_accountsMap.Count} Account(s) migrated."); + Console.WriteLine($"-----------------------------------------------------------"); _authorMap = await MigrateAuthors(libraryId, newLibrary.Id, cancellationToken); - - Console.WriteLine($"{_authorMap.Count} Author(s) migrated."); + Console.WriteLine($"-----------------------------------------------------------"); _seriesMap = await MigrateSeries(libraryId, newLibrary.Id, cancellationToken); - - Console.WriteLine($"{_seriesMap.Count} Serie(s) migrated."); + Console.WriteLine($"-----------------------------------------------------------"); _categoriesMap = await MigrateCategories(libraryId, newLibrary.Id, cancellationToken); - - Console.WriteLine($"{_categoriesMap.Count} Categories migrated."); + Console.WriteLine($"-----------------------------------------------------------"); _booksMap = await MigrateBooks(libraryId, newLibrary.Id, _authorMap, _seriesMap, _categoriesMap, _accountsMap, cancellationToken); + Console.WriteLine($"-----------------------------------------------------------"); - Console.WriteLine($"{_booksMap.Count} Books(s) migrated."); - - _periodicalsMap = await MigratePriodicals(libraryId, newLibrary.Id, _authorMap, _categoriesMap, _accountsMap, cancellationToken); - - Console.WriteLine($"{_periodicalsMap.Count} Periodical(s) migrated."); + _periodicalsMap = await MigratePeriodicals(libraryId, newLibrary.Id, _authorMap, _categoriesMap, _accountsMap, cancellationToken); + Console.WriteLine($"-----------------------------------------------------------"); var bookshelfCount = await MigrateBookShelves(libraryId, newLibrary.Id, _accountsMap, _booksMap, cancellationToken); - - Console.WriteLine($"{bookshelfCount} Bookshelve(s) migrated."); + Console.WriteLine($"-----------------------------------------------------------"); //scope.Complete(); @@ -93,6 +84,7 @@ private async Task> MigrateAccounts(int libraryId, int newL Dictionary accountsMap = new Dictionary(); var accounts = await sourceDb.GetAccounts(1, int.MaxValue, cancellationToken); + int i = 0; foreach (var account in accounts.Data) { var existingAccount = await destinationDb.GetAccountByEmail(account.Email, cancellationToken); @@ -104,9 +96,13 @@ private async Task> MigrateAccounts(int libraryId, int newL await destinationDb.AddAccountToLibrary(newLibraryId, existingAccount.Id, account.Role, cancellationToken); + Console.WriteLine($"{++i} of {accounts.TotalCount} Account(s) migrated."); + accountsMap.Add(account.Id, existingAccount.Id); } + Console.WriteLine($"{accountsMap.Count} Account(s) migrated."); + return accountsMap; } @@ -117,6 +113,7 @@ private async Task> MigrateAuthors(int libraryId, int newLi Dictionary authorMap = new Dictionary(); var authors = await sourceDb.GetAuthors(libraryId, null, 1, int.MaxValue, cancellationToken); + int i = 0; foreach (var author in authors.Data) { @@ -127,19 +124,24 @@ private async Task> MigrateAuthors(int libraryId, int newLi } var newAuthor = await destinationDb.AddAuthor(newLibraryId, author, cancellationToken); + Console.WriteLine($"{++i} of {authors.TotalCount} Author(s) migrated."); + authorMap.Add(author.Id, newAuthor.Id); } + Console.WriteLine($"{authorMap.Count} Author(s) migrated."); + return authorMap; } - private async Task> MigrateSeries(int libraryId, int newLibaryId, CancellationToken cancellationToken) + private async Task> MigrateSeries(int libraryId, int newLibraryId, CancellationToken cancellationToken) { var sourceDb = new SeriesRepository(SourceConnectionProvider); var destinationDb = new SeriesRepository(DestinationConnectionProvider); Dictionary seriesMap = new Dictionary(); var series = await sourceDb.GetSeries(libraryId, 1, int.MaxValue, cancellationToken); + int i = 0; foreach (var serie in series.Data) { @@ -149,27 +151,35 @@ private async Task> MigrateSeries(int libraryId, int newLib serie.ImageId = serieImage.Id; } - var newSerie = await destinationDb.AddSeries(newLibaryId, serie, cancellationToken); + var newSerie = await destinationDb.AddSeries(newLibraryId, serie, cancellationToken); + Console.WriteLine($"{++i} of {series.TotalCount} Series(s) migrated."); + seriesMap.Add(serie.Id, newSerie.Id); } + Console.WriteLine($"{seriesMap.Count} Series(s) migrated."); + return seriesMap; } - private async Task> MigrateCategories(int libraryId, int newLibaryId, CancellationToken cancellationToken) + private async Task> MigrateCategories(int libraryId, int newLibraryId, CancellationToken cancellationToken) { var sourceDb = new CategoryRepository(SourceConnectionProvider); var destinationDb = new CategoryRepository(DestinationConnectionProvider); Dictionary categoriesMap = new Dictionary(); - var categories = await sourceDb.GetCategories(libraryId, cancellationToken); + var categories = (await sourceDb.GetCategories(libraryId, cancellationToken)).ToArray(); + int i = 0; foreach (var category in categories) { - var newCategory = await destinationDb.AddCategory(newLibaryId, category, cancellationToken); + var newCategory = await destinationDb.AddCategory(newLibraryId, category, cancellationToken); + Console.WriteLine($"{++i} of {categories.Length} Categories migrated."); categoriesMap.Add(category.Id, newCategory.Id); } + Console.WriteLine($"{categoriesMap.Count} Series(s) migrated."); + return categoriesMap; } @@ -180,6 +190,7 @@ private async Task> MigrateBooks(int libraryId, int newLibr Dictionary booksMap = new Dictionary(); var books = await sourceDb.GetBooks(libraryId, 1, int.MaxValue, cancellationToken); + int i = 0; foreach (var book in books.Data) { @@ -204,8 +215,13 @@ private async Task> MigrateBooks(int libraryId, int newLibr var chaptersMap = await MigrateChapters(libraryId, newLibraryId, book.Id, newBook.Id, accountsMap, cancellationToken); await MigrateBookPages(libraryId, newLibraryId, book.Id, newBook.Id, accountsMap, chaptersMap, cancellationToken); + + Console.WriteLine($"{++i} of {books.TotalCount} Book(s) migrated."); + } + Console.WriteLine($"{booksMap.Count} Book(s) migrated."); + return booksMap; } @@ -215,7 +231,8 @@ private async Task> MigrateChapters(int libraryId, int newL var destinationDb = new ChapterRepository(DestinationConnectionProvider); Dictionary chaptersMap = new Dictionary(); - var chapters = await sourceDb.GetChaptersByBook(libraryId, bookId, cancellationToken); + var chapters = (await sourceDb.GetChaptersByBook(libraryId, bookId, cancellationToken)).ToArray(); + int i = 0; foreach (var chapter in chapters) { @@ -235,17 +252,22 @@ private async Task> MigrateChapters(int libraryId, int newL content.ChapterId = newChapter.Id; await destinationDb.AddChapterContent(newLibraryId, content, cancellationToken); } + + Console.WriteLine($"{++i} of {chapters.Length} Chapter(s) copies."); + } return chaptersMap; } - private async Task MigrateBookPages(int libraryId, int newLibraryid, int bookId, int newBookId, Dictionary accountsMap, Dictionary chaptersMap, CancellationToken cancellationToken) + private async Task MigrateBookPages(int libraryId, int newLibraryId, int bookId, int newBookId, Dictionary accountsMap, Dictionary chaptersMap, CancellationToken cancellationToken) { var sourceDb = new BookPageRepository(SourceConnectionProvider); var destinationDb = new BookPageRepository(DestinationConnectionProvider); - var pages = await sourceDb.GetAllPagesByBook(libraryId, bookId, cancellationToken); + var pages = (await sourceDb.GetAllPagesByBook(libraryId, bookId, cancellationToken)).ToArray(); + int i = 0; + foreach (var page in pages) { page.BookId = newBookId; @@ -259,18 +281,20 @@ private async Task MigrateBookPages(int libraryId, int newLibraryid, int bookId, page.ReviewerAccountId = page.ReviewerAccountId.HasValue ? accountsMap[page.ReviewerAccountId.Value] : null; page.WriterAccountId = page.WriterAccountId.HasValue ? accountsMap[page.WriterAccountId.Value] : null; + Console.WriteLine($"{++i} of {pages.Length} Pages(s) copies."); - await destinationDb.AddPage(newLibraryid, page, cancellationToken); + await destinationDb.AddPage(newLibraryId, page, cancellationToken); } } - private async Task> MigratePriodicals(int libraryId, int newLibraryId, Dictionary authorMap, Dictionary categoriesMap, Dictionary accountsMap, CancellationToken cancellationToken) + private async Task> MigratePeriodicals(int libraryId, int newLibraryId, Dictionary authorMap, Dictionary categoriesMap, Dictionary accountsMap, CancellationToken cancellationToken) { var sourceDb = new PeriodicalRepository(SourceConnectionProvider); var destinationDb = new PeriodicalRepository(DestinationConnectionProvider); var periodicalMap = new Dictionary(); var periodicals = await sourceDb.GetPeriodicals(libraryId, null, 1, int.MaxValue, new PeriodicalFilter(), PeriodicalSortByType.DateCreated, SortDirection.Ascending, cancellationToken); + int i = 0; foreach (var periodical in periodicals.Data) { @@ -287,10 +311,13 @@ private async Task> MigratePriodicals(int libraryId, int ne var newPeriodical = await destinationDb.AddPeriodical(newLibraryId, periodical, cancellationToken); await MigrateIssue(libraryId, newLibraryId, periodical.Id, newPeriodical.Id, authorMap, accountsMap, cancellationToken); + Console.WriteLine($"{++i} of {periodicals.TotalCount} Periodical(s) migrated."); periodicalMap.Add(periodical.Id, newPeriodical.Id); } + Console.WriteLine($"{periodicalMap.Count} Periodical(s) migrated."); + return periodicalMap; } @@ -301,6 +328,7 @@ private async Task> MigrateIssue(int libraryId, int newLibr var issueMap = new Dictionary(); var issues = await sourceDb.GetIssues(libraryId, periodicalId, 1, int.MaxValue, new IssueFilter(), IssueSortByType.VolumeNumberAndIssueNumber, SortDirection.Ascending, cancellationToken); + int i = 0; foreach (var issue in issues.Data) { @@ -310,13 +338,13 @@ private async Task> MigrateIssue(int libraryId, int newLibr issue.ImageId = issueImage.Id; } - var newIssue = await destinationDb.AddIssue(newLibraryId, periodicalId, issue, cancellationToken); + var newIssue = await destinationDb.AddIssue(newLibraryId, newPeriodicalId, issue, cancellationToken); var contents = await sourceDb.GetIssueContents(libraryId, periodicalId, issue.VolumeNumber, issue.IssueNumber, cancellationToken); foreach (var content in contents) { - content.PeriodicalId = periodicalId; + content.PeriodicalId = newPeriodicalId; var newFile = await CopyFile(content.FileId, cancellationToken); await destinationDb.AddIssueContent(newLibraryId, @@ -329,17 +357,19 @@ await destinationDb.AddIssueContent(newLibraryId, cancellationToken); } - await MigrateArticle(libraryId, newLibraryId, periodicalId, newPeriodicalId, newIssue.Id, newIssue.VolumeNumber, newIssue.IssueNumber, authorMap, accountsMap, cancellationToken); + await IssueMigrateArticle(libraryId, newLibraryId, periodicalId, newPeriodicalId, newIssue.Id, newIssue.VolumeNumber, newIssue.IssueNumber, authorMap, accountsMap, cancellationToken); + Console.WriteLine($"{++i} of {issues.TotalCount} Issues(s) migrated for periodical {periodicalId}."); + issueMap.Add(issue.Id, newIssue.Id); } return issueMap; } - private async Task> MigrateArticle(int libraryId, int newLibraryId, int periodicalId, int newPeriodicalId, int newIssueId, int volumeNumber, int issueNumber, Dictionary authorMap, Dictionary accountsMap, CancellationToken cancellationToken) + private async Task> IssueMigrateArticle(int libraryId, int newLibraryId, int periodicalId, int newPeriodicalId, int newIssueId, int volumeNumber, int issueNumber, Dictionary authorMap, Dictionary accountsMap, CancellationToken cancellationToken) { - var sourceDb = new ArticleRepository(SourceConnectionProvider); - var destinationDb = new ArticleRepository(DestinationConnectionProvider); + var sourceDb = new IssueArticleRepository(SourceConnectionProvider); + var destinationDb = new IssueArticleRepository(DestinationConnectionProvider); var articleMap = new Dictionary(); var articles = await sourceDb.GetArticlesByIssue(libraryId, periodicalId, volumeNumber, issueNumber, cancellationToken); diff --git a/src/Inshapardaz.Storage.FileSystem/FileSystemStorage.cs b/src/Inshapardaz.Storage.FileSystem/FileSystemStorage.cs index 36d0f2dd..45f52f6f 100644 --- a/src/Inshapardaz.Storage.FileSystem/FileSystemStorage.cs +++ b/src/Inshapardaz.Storage.FileSystem/FileSystemStorage.cs @@ -1,4 +1,5 @@ -using Inshapardaz.Domain.Helpers; +using Inshapardaz.Domain.Exception; +using Inshapardaz.Domain.Helpers; using Inshapardaz.Domain.Repositories; using System; using System.IO; @@ -22,14 +23,16 @@ public FileSystemStorage(string basePath) public async Task GetFile(string filePath, CancellationToken cancellationToken) { - if (!File.Exists(filePath)) { return new byte[0]; } - return await File.ReadAllBytesAsync(GetFullPath(filePath)); + var fullPath = GetFullPath(filePath); + if (!File.Exists(fullPath)) { throw new NotFoundException(); } + return await File.ReadAllBytesAsync(fullPath); } public async Task GetTextFile(string filePath, CancellationToken cancellationToken) { - if (!File.Exists(filePath)) { return string.Empty; } - return await File.ReadAllTextAsync(GetFullPath(filePath)); + var fullPath = GetFullPath(filePath); + if (!File.Exists(fullPath)) { throw new NotFoundException(); } + return await File.ReadAllTextAsync(fullPath); } public async Task StoreFile(string name, byte[] content, CancellationToken cancellationToken) @@ -37,7 +40,7 @@ public async Task StoreFile(string name, byte[] content, CancellationTok var path = GetFullPath(name); new FileInfo(path).Directory.FullName.CreateIfDirectoryDoesNotExists(); await File.WriteAllBytesAsync(path, content); - return path; + return name; } public async Task StoreImage(string name, byte[] content, string mimeType, CancellationToken cancellationToken) @@ -45,7 +48,7 @@ public async Task StoreImage(string name, byte[] content, string mimeTyp var path = GetFullPath(name); new FileInfo(path).Directory.FullName.CreateIfDirectoryDoesNotExists(); await File.WriteAllBytesAsync(path, content); - return path; + return name; } public async Task StoreTextFile(string name, string content, CancellationToken cancellationToken) @@ -53,7 +56,7 @@ public async Task StoreTextFile(string name, string content, Cancellatio var path = GetFullPath(name); new FileInfo(path).Directory.FullName.CreateIfDirectoryDoesNotExists(); await File.WriteAllTextAsync(path, content); - return path; + return name; } public Task DeleteFile(string filePath, CancellationToken cancellationToken) diff --git a/src/Inshapardaz.Storage.S3/Inshapardaz.Storage.S3.csproj b/src/Inshapardaz.Storage.S3/Inshapardaz.Storage.S3.csproj index 66abf311..ba785b3a 100644 --- a/src/Inshapardaz.Storage.S3/Inshapardaz.Storage.S3.csproj +++ b/src/Inshapardaz.Storage.S3/Inshapardaz.Storage.S3.csproj @@ -5,7 +5,7 @@ - +