From 741c19f2664e168ef43374159f733506446bafa4 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 27 Nov 2023 17:54:14 +0900 Subject: [PATCH 1/5] =?UTF-8?q?chore:=20=ED=81=B4=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EC=96=B8=ED=8A=B8=20=ED=8F=B4=EB=8D=94=20=EC=A0=9C=EC=99=B8=20?= =?UTF-8?q?=EB=AA=A8=EB=93=A0=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.babelrc.json => .babelrc.json | 0 frontend/.eslintrc.js => .eslintrc.js | 0 .github/workflows/test-fe.yml | 9 +- .github/workflows/test.yml | 76 - frontend/.gitignore => .gitignore | 0 frontend/.nvmrc => .nvmrc | 0 frontend/.prettierrc => .prettierrc | 0 {frontend/.storybook => .storybook}/main.ts | 0 .../preview-body.html | 0 .../.storybook => .storybook}/preview.tsx | 0 frontend/.stylelintrc.js => .stylelintrc.js | 0 .../hooks/useImageUploader.test.ts | 0 .../hooks/useStarRating.test.ts | 0 .../hooks/useTabMenu.test.ts | 0 backend/.gitignore | 37 - backend/build.gradle | 40 - backend/gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - backend/gradlew | 245 ---- backend/gradlew.bat | 92 -- backend/settings.gradle | 1 - .../java/com/funeat/FuneatApplication.java | 17 - .../admin/application/AdminChecker.java | 29 - .../admin/application/AdminService.java | 117 -- .../funeat/admin/domain/AdminAuthInfo.java | 20 - .../admin/dto/AdminCategoryResponse.java | 32 - .../admin/dto/AdminProductResponse.java | 48 - .../admin/dto/AdminProductSearchResponse.java | 29 - .../funeat/admin/dto/AdminReviewResponse.java | 54 - .../admin/dto/AdminReviewSearchResponse.java | 29 - .../admin/dto/ProductCreateRequest.java | 32 - .../admin/dto/ProductSearchCondition.java | 39 - .../admin/dto/ProductUpdateRequest.java | 32 - .../admin/dto/ReviewSearchCondition.java | 53 - .../admin/presentation/AdminController.java | 70 - .../presentation/AdminLoginController.java | 38 - .../repository/AdminProductRepository.java | 7 - .../repository/AdminReviewRepository.java | 7 - .../AdminProductSpecification.java | 70 - .../AdminReviewSpecification.java | 82 -- .../admin/util/AdminCheckInterceptor.java | 42 - .../funeat/auth/application/AuthService.java | 46 - .../com/funeat/auth/dto/KakaoTokenDto.java | 53 - .../com/funeat/auth/dto/KakaoUserInfoDto.java | 61 - .../java/com/funeat/auth/dto/LoginInfo.java | 14 - .../java/com/funeat/auth/dto/SignUserDto.java | 26 - .../com/funeat/auth/dto/TokenResponse.java | 14 - .../java/com/funeat/auth/dto/UserInfoDto.java | 40 - .../funeat/auth/exception/AuthErrorCode.java | 32 - .../funeat/auth/exception/AuthException.java | 18 - .../auth/presentation/AuthApiController.java | 69 - .../auth/presentation/AuthController.java | 42 - .../auth/util/AuthArgumentResolver.java | 31 - .../auth/util/AuthHandlerInterceptor.java | 26 - .../auth/util/AuthenticationPrincipal.java | 11 - .../auth/util/KakaoPlatformUserProvider.java | 142 -- .../auth/util/PlatformUserProvider.java | 12 - .../banner/application/BannerService.java | 28 - .../java/com/funeat/banner/domain/Banner.java | 38 - .../com/funeat/banner/dto/BannerResponse.java | 32 - .../banner/persistence/BannerRepository.java | 10 - .../presentation/BannerApiController.java | 21 - .../banner/presentation/BannerController.java | 25 - .../com/funeat/comment/domain/Comment.java | 59 - .../persistence/CommentRepository.java | 8 - .../specification/CommentSpecification.java | 56 - ...PageableHandlerMethodArgumentResolver.java | 26 - .../java/com/funeat/common/ImageUploader.java | 10 - .../java/com/funeat/common/OpenApiConfig.java | 27 - .../common/StringToCategoryTypeConverter.java | 12 - .../java/com/funeat/common/WebConfig.java | 66 - .../java/com/funeat/common/dto/PageDto.java | 58 - .../common/exception/CommonException.java | 31 - .../com/funeat/common/logging/Logging.java | 11 - .../funeat/common/logging/LoggingAspect.java | 92 -- .../common/repository/BaseRepository.java | 17 - .../common/repository/BaseRepositoryImpl.java | 51 - .../java/com/funeat/common/s3/AwsConfig.java | 28 - .../java/com/funeat/common/s3/S3Uploader.java | 101 -- .../com/funeat/exception/CommonErrorCode.java | 33 - .../java/com/funeat/exception/ErrorCode.java | 34 - .../com/funeat/exception/GlobalException.java | 23 - .../presentation/GlobalControllerAdvice.java | 105 -- .../member/application/MemberService.java | 76 - .../java/com/funeat/member/domain/Member.java | 84 -- .../domain/favorite/RecipeFavorite.java | 76 - .../domain/favorite/ReviewFavorite.java | 77 -- .../member/dto/MemberProfileResponse.java | 26 - .../funeat/member/dto/MemberRecipeDto.java | 73 - .../member/dto/MemberRecipeProductDto.java | 26 - .../member/dto/MemberRecipesResponse.java | 28 - .../com/funeat/member/dto/MemberRequest.java | 18 - .../funeat/member/dto/MemberReviewDto.java | 66 - .../member/dto/MemberReviewsResponse.java | 27 - .../member/exception/MemberErrorCode.java | 33 - .../member/exception/MemberException.java | 30 - .../member/persistence/MemberRepository.java | 10 - .../persistence/RecipeFavoriteRepository.java | 14 - .../persistence/ReviewFavoriteRepository.java | 17 - .../presentation/MemberApiController.java | 83 -- .../member/presentation/MemberController.java | 69 - .../product/application/CategoryService.java | 23 - .../product/application/ProductService.java | 177 --- .../com/funeat/product/domain/Category.java | 52 - .../funeat/product/domain/CategoryType.java | 30 - .../com/funeat/product/domain/Product.java | 166 --- .../funeat/product/domain/ProductRecipe.java | 34 - .../funeat/product/dto/CategoryResponse.java | 32 - .../product/dto/ProductInCategoryDto.java | 57 - .../funeat/product/dto/ProductResponse.java | 72 - .../product/dto/ProductReviewCountDto.java | 22 - .../product/dto/ProductSortCondition.java | 25 - .../dto/ProductsInCategoryResponse.java | 27 - .../funeat/product/dto/RankingProductDto.java | 39 - .../product/dto/RankingProductsResponse.java | 20 - .../funeat/product/dto/SearchProductDto.java | 32 - .../product/dto/SearchProductResultDto.java | 58 - .../dto/SearchProductResultsResponse.java | 28 - .../product/dto/SearchProductsResponse.java | 27 - .../product/exception/CategoryErrorCode.java | 32 - .../product/exception/CategoryException.java | 24 - .../product/exception/ProductErrorCode.java | 32 - .../product/exception/ProductException.java | 24 - .../persistence/CategoryRepository.java | 11 - .../persistence/ProductRecipeRepository.java | 14 - .../persistence/ProductRepository.java | 39 - .../persistence/ProductSpecification.java | 108 -- .../presentation/CategoryApiController.java | 31 - .../presentation/CategoryController.java | 23 - .../presentation/ProductApiController.java | 74 - .../presentation/ProductController.java | 76 - .../recipe/application/RecipeService.java | 282 ---- .../java/com/funeat/recipe/domain/Recipe.java | 100 -- .../com/funeat/recipe/domain/RecipeImage.java | 43 - .../funeat/recipe/dto/ProductRecipeDto.java | 32 - .../funeat/recipe/dto/RankingRecipeDto.java | 60 - .../recipe/dto/RankingRecipesResponse.java | 20 - .../funeat/recipe/dto/RecipeAuthorDto.java | 26 - .../recipe/dto/RecipeCommentCondition.java | 20 - .../dto/RecipeCommentCreateRequest.java | 20 - .../dto/RecipeCommentMemberResponse.java | 26 - .../recipe/dto/RecipeCommentResponse.java | 42 - .../recipe/dto/RecipeCommentsResponse.java | 34 - .../recipe/dto/RecipeCreateRequest.java | 38 - .../recipe/dto/RecipeDetailResponse.java | 92 -- .../java/com/funeat/recipe/dto/RecipeDto.java | 73 - .../recipe/dto/RecipeFavoriteRequest.java | 20 - .../recipe/dto/SearchRecipeResultDto.java | 75 - .../dto/SearchRecipeResultsResponse.java | 28 - .../recipe/dto/SortingRecipesResponse.java | 27 - .../recipe/exception/RecipeErrorCode.java | 31 - .../recipe/exception/RecipeException.java | 18 - .../persistence/RecipeImageRepository.java | 11 - .../recipe/persistence/RecipeRepository.java | 40 - .../presentation/RecipeApiController.java | 113 -- .../recipe/presentation/RecipeController.java | 107 -- .../util/RecipeDetailHandlerInterceptor.java | 26 - .../recipe/util/RecipeHandlerInterceptor.java | 32 - .../review/application/ReviewDeleteEvent.java | 14 - .../ReviewDeleteEventListener.java | 27 - .../review/application/ReviewService.java | 301 ---- .../java/com/funeat/review/domain/Review.java | 159 --- .../com/funeat/review/domain/ReviewTag.java | 52 - .../dto/MostFavoriteReviewResponse.java | 106 -- .../funeat/review/dto/RankingReviewDto.java | 73 - .../review/dto/RankingReviewsResponse.java | 20 - .../review/dto/ReviewCreateRequest.java | 46 - .../review/dto/ReviewDetailResponse.java | 121 -- .../review/dto/ReviewFavoriteRequest.java | 20 - .../funeat/review/dto/SortingReviewDto.java | 110 -- .../dto/SortingReviewDtoWithoutTag.java | 84 -- .../review/dto/SortingReviewRequest.java | 27 - .../review/dto/SortingReviewsResponse.java | 26 - .../review/exception/ReviewErrorCode.java | 33 - .../review/exception/ReviewException.java | 30 - .../persistence/ReviewCustomRepository.java | 14 - .../review/persistence/ReviewRepository.java | 37 - .../persistence/ReviewRepositoryImpl.java | 91 -- .../persistence/ReviewTagRepository.java | 24 - .../presentation/ReviewApiController.java | 94 -- .../review/presentation/ReviewController.java | 84 -- .../specification/LongTypeReviewSortSpec.java | 27 - .../SortingReviewSpecification.java | 161 --- .../funeat/tag/application/TagService.java | 37 - .../main/java/com/funeat/tag/domain/Tag.java | 41 - .../java/com/funeat/tag/domain/TagType.java | 6 - .../main/java/com/funeat/tag/dto/TagDto.java | 33 - .../java/com/funeat/tag/dto/TagsResponse.java | 26 - .../funeat/tag/persistence/TagRepository.java | 21 - .../tag/presentation/TagApiController.java | 24 - .../tag/presentation/TagController.java | 21 - .../src/main/resources/application-dev.yml | 46 - .../src/main/resources/application-local.yml | 31 - .../src/main/resources/application-prod.yml | 45 - backend/src/main/resources/application.yml | 42 - .../src/main/resources/logback-spring-dev.xml | 121 -- .../main/resources/logback-spring-prod.xml | 97 -- backend/src/main/resources/logback-spring.xml | 12 - .../src/main/resources/logback-variables.yml | 7 - .../com/funeat/FuneatApplicationTests.java | 12 - .../acceptance/auth/AuthAcceptanceTest.java | 112 -- .../funeat/acceptance/auth/LoginSteps.java | 49 - .../banner/BannerAcceptanceTest.java | 62 - .../funeat/acceptance/banner/BannerSteps.java | 17 - .../acceptance/common/AcceptanceTest.java | 99 -- .../funeat/acceptance/common/CommonSteps.java | 83 -- .../common/TestPlatformUserProvider.java | 26 - .../member/MemberAcceptanceTest.java | 431 ------ .../funeat/acceptance/member/MemberSteps.java | 74 - .../product/CategoryAcceptanceTest.java | 88 -- .../acceptance/product/CategorySteps.java | 19 - .../product/ProductAcceptanceTest.java | 734 ---------- .../acceptance/product/ProductSteps.java | 69 - .../recipe/RecipeAcceptanceTest.java | 806 ----------- .../funeat/acceptance/recipe/RecipeSteps.java | 121 -- .../review/ReviewAcceptanceTest.java | 752 ---------- .../funeat/acceptance/review/ReviewSteps.java | 94 -- .../acceptance/tag/TagAcceptanceTest.java | 56 - .../com/funeat/acceptance/tag/TagSteps.java | 18 - .../auth/application/AuthServiceTest.java | 50 - .../banner/application/BannerServiceTest.java | 47 - .../persistence/BannerRepositoryTest.java | 39 - .../java/com/funeat/common/DataCleaner.java | 47 - .../com/funeat/common/DataClearExtension.java | 19 - .../java/com/funeat/common/EventTest.java | 66 - .../com/funeat/common/RepositoryTest.java | 201 --- .../java/com/funeat/common/ServiceTest.java | 214 --- .../com/funeat/common/TestImageUploader.java | 46 - .../com/funeat/fixture/BannerFixture.java | 26 - .../com/funeat/fixture/CategoryFixture.java | 52 - .../java/com/funeat/fixture/ImageFixture.java | 29 - .../com/funeat/fixture/MemberFixture.java | 29 - .../java/com/funeat/fixture/PageFixture.java | 81 -- .../com/funeat/fixture/ProductFixture.java | 152 -- .../com/funeat/fixture/RecipeFixture.java | 65 - .../com/funeat/fixture/ReviewFixture.java | 124 -- .../java/com/funeat/fixture/ScoreFixture.java | 11 - .../java/com/funeat/fixture/TagFixture.java | 35 - .../member/application/MemberServiceTest.java | 309 ----- .../member/application/TestMemberService.java | 22 - .../com/funeat/member/domain/MemberTest.java | 69 - .../domain/favorite/RecipeFavoriteTest.java | 95 -- .../persistence/MemberRepositoryTest.java | 50 - .../RecipeFavoriteRepositoryTest.java | 126 -- .../ReviewFavoriteRepositoryTest.java | 184 --- .../application/ProductServiceTest.java | 204 --- .../funeat/product/domain/ProductTest.java | 124 -- .../domain/favorite/ReviewFavoriteTest.java | 98 -- .../persistence/CategoryRepositoryTest.java | 77 -- .../ProductRecipeRepositoryTest.java | 51 - .../persistence/ProductRepositoryTest.java | 166 --- .../recipe/application/RecipeServiceTest.java | 913 ------------ .../com/funeat/recipe/domain/RecipeTest.java | 36 - .../RecipeImageRepositoryTest.java | 57 - .../persistence/RecipeRepositoryTest.java | 307 ----- .../ReviewDeleteEventListenerTest.java | 110 -- .../review/application/ReviewServiceTest.java | 1224 ----------------- .../com/funeat/review/domain/ReviewTest.java | 40 - .../persistence/ReviewRepositoryTest.java | 221 --- .../persistence/ReviewTagRepositoryTest.java | 152 -- .../tag/persistence/TagRepositoryTest.java | 68 - backend/src/test/resources/application.yml | 45 - frontend/jest.config.js => jest.config.js | 0 frontend/package.json => package.json | 2 +- .../assets/apple-icon-180x180.png | Bin .../assets/favicon-16x16.png | Bin .../assets/favicon-32x32.png | Bin .../public => public}/assets/favicon.ico | Bin .../public => public}/assets/og-image.png | Bin {frontend/public => public}/index.html | 0 {frontend/public => public}/manifest.json | 0 .../public => public}/mockServiceWorker.js | 0 {frontend/public => public}/robots.txt | 0 {frontend/public => public}/sitemap.xml | 0 {frontend/src => src}/apis/ApiClient.ts | 0 {frontend/src => src}/apis/fetch.ts | 0 {frontend/src => src}/apis/index.ts | 0 {frontend/src => src}/assets/characters.svg | 0 {frontend/src => src}/assets/logo.svg | 0 {frontend/src => src}/assets/plate.svg | 0 {frontend/src => src}/assets/samgakgimbab.svg | 0 .../components/Common/Banner/Banner.tsx | 0 .../CategoryFoodList.stories.tsx | 0 .../CategoryFoodList/CategoryFoodList.tsx | 0 .../CategoryFoodTab.stories.tsx | 0 .../CategoryFoodTab/CategoryFoodTab.tsx | 0 .../CategoryItem/CategoryItem.stories.tsx | 0 .../Common/CategoryItem/CategoryItem.tsx | 0 .../CategoryStoreList.stories.tsx | 0 .../CategoryStoreList/CategoryStoreList.tsx | 0 .../CategoryStoreTab.stories.tsx | 0 .../CategoryStoreTab/CategoryStoreTab.tsx | 0 .../Common/ErrorBoundary/ErrorBoundary.tsx | 0 .../ErrorComponent/ErrorComponent.stories.tsx | 0 .../Common/ErrorComponent/ErrorComponent.tsx | 0 .../Common/Header/Header.stories.tsx | 0 .../components/Common/Header/Header.tsx | 0 .../ImageUploader/ImageUploader.stories.tsx | 0 .../Common/ImageUploader/ImageUploader.tsx | 0 .../Common/Loading/Loading.stories.tsx | 0 .../components/Common/Loading/Loading.tsx | 0 .../Common/MarkedText/MarkedText.tsx | 0 .../NavigableSectionTitle.stories.tsx | 0 .../NavigableSectionTitle.tsx | 0 .../NavigationBar/NavigationBar.stories.tsx | 0 .../Common/NavigationBar/NavigationBar.tsx | 0 .../Common/RegisterButton/RegisterButton.tsx | 0 .../ScrollButton/ScrollButton.stories.tsx | 0 .../Common/ScrollButton/ScrollButton.tsx | 0 .../SectionTitle/SectionTitle.stories.tsx | 0 .../Common/SectionTitle/SectionTitle.tsx | 0 .../Common/SortButton/SortButton.stories.tsx | 0 .../Common/SortButton/SortButton.tsx | 0 .../SortOptionList/SortOptionList.stories.tsx | 0 .../Common/SortOptionList/SortOptionList.tsx | 0 .../components/Common/Svg/SvgIcon.stories.tsx | 0 .../components/Common/Svg/SvgIcon.tsx | 0 .../components/Common/Svg/SvgSprite.tsx | 0 .../Common/TabMenu/TabMenu.stories.tsx | 0 .../components/Common/TabMenu/TabMenu.tsx | 0 .../Common/TagList/TagList.stories.tsx | 0 .../components/Common/TagList/TagList.tsx | 0 .../src => src}/components/Common/index.ts | 0 .../components/Layout/AuthLayout.tsx | 0 .../components/Layout/DefaultLayout.tsx | 0 .../components/Layout/HeaderOnlyLayout.tsx | 0 .../components/Layout/MinimalLayout.tsx | 0 .../components/Layout/SimpleHeaderLayout.tsx | 0 .../src => src}/components/Layout/index.ts | 0 .../MemberModifyInput/MemberModifyInput.tsx | 0 .../MemberRecipeList.stories.tsx | 0 .../MemberRecipeList/MemberRecipeList.tsx | 0 .../MemberReviewItem.stories.tsx | 0 .../MemberReviewItem/MemberReviewItem.tsx | 0 .../MemberReviewList.stories.tsx | 0 .../MemberReviewList/MemberReviewList.tsx | 0 .../Members/MembersInfo/MembersInfo.tsx | 0 .../MembersInfo/MyPageInfo.stories.tsx | 0 .../src => src}/components/Members/index.ts | 0 .../ProductDetailItem.stories.tsx | 0 .../ProductDetailItem/ProductDetailItem.tsx | 0 .../ProductItem/ProductItem.stories.tsx | 0 .../Product/ProductItem/ProductItem.tsx | 0 .../ProductList/ProductList.stories.tsx | 0 .../Product/ProductList/ProductList.tsx | 0 .../ProductOverviewItem.stories.tsx | 0 .../ProductOverviewItem.tsx | 0 .../ProductRecipeList/ProductRecipeList.tsx | 0 .../ProductTitle/ProductTitle.stories.tsx | 0 .../Product/ProductTitle/ProductTitle.tsx | 0 .../src => src}/components/Product/index.ts | 0 .../ProductRankingList.stories.tsx | 0 .../ProductRankingList/ProductRankingList.tsx | 0 .../RecipeRankingItem.stories.tsx | 0 .../RecipeRankingItem/RecipeRankingItem.tsx | 0 .../RecipeRankingList.stories.tsx | 0 .../RecipeRankingList/RecipeRankingList.tsx | 0 .../ReviewRankingItem.stories.tsx | 0 .../ReviewRankingItem/ReviewRankingItem.tsx | 0 .../ReviewRankingList.stories.tsx | 0 .../ReviewRankingList/ReviewRankingList.tsx | 0 .../src => src}/components/Rank/index.ts | 2 +- .../CommentForm/CommentForm.stories.tsx | 0 .../Recipe/CommentForm/CommentForm.tsx | 0 .../CommentItem/CommentItem.stories.tsx | 0 .../Recipe/CommentItem/CommentItem.tsx | 0 .../CommentList/CommentList.stories.tsx | 0 .../Recipe/CommentList/CommentList.tsx | 0 .../RecipeDetailTextarea.stories.tsx | 2 +- .../RecipeDetailTextarea.tsx | 0 .../RecipeFavoriteButton.tsx | 0 .../Recipe/RecipeItem/RecipeItem.stories.tsx | 0 .../Recipe/RecipeItem/RecipeItem.tsx | 0 .../Recipe/RecipeList/RecipeList.stories.tsx | 0 .../Recipe/RecipeList/RecipeList.tsx | 0 .../RecipeNameInput.stories.tsx | 0 .../RecipeNameInput/RecipeNameInput.tsx | 0 .../RecipeRegisterForm.stories.tsx | 0 .../RecipeRegisterForm/RecipeRegisterForm.tsx | 0 .../RecipeUsedProducts.stories.tsx | 0 .../RecipeUsedProducts/RecipeUsedProducts.tsx | 0 .../SearchedProductList.tsx | 0 .../src => src}/components/Recipe/index.ts | 0 .../BestReviewItem/BestReviewItem.stories.tsx | 0 .../Review/BestReviewItem/BestReviewItem.tsx | 0 .../Review/RebuyCheckbox/RebuyCheckbox.tsx | 0 .../ReviewFavoriteButton.tsx | 0 .../Review/ReviewItem/ReviewItem.stories.tsx | 0 .../Review/ReviewItem/ReviewItem.tsx | 0 .../Review/ReviewList/ReviewList.tsx | 0 .../ReviewRegisterForm.stories.tsx | 0 .../ReviewRegisterForm/ReviewRegisterForm.tsx | 0 .../ReviewTagItem/ReviewTagItem.stories.tsx | 0 .../Review/ReviewTagItem/ReviewTagItem.tsx | 0 .../ReviewTagList/ReviewTagList.stories.tsx | 0 .../Review/ReviewTagList/ReviewTagList.tsx | 0 .../ReviewTextarea/ReviewTextarea.stories.tsx | 0 .../Review/ReviewTextarea/ReviewTextarea.tsx | 0 .../Review/StarRate/StarRate.stories.tsx | 0 .../components/Review/StarRate/StarRate.tsx | 0 .../src => src}/components/Review/index.ts | 0 .../ProductSearchResultList.tsx | 0 .../RecipeSearchResultList.tsx | 0 .../Search/RecommendList/RecommendList.tsx | 0 .../src => src}/components/Search/index.ts | 0 {frontend/src => src}/constants/index.ts | 0 {frontend/src => src}/constants/path.ts | 0 .../src => src}/contexts/CategoryContext.tsx | 0 .../contexts/RecipeFormContext.tsx | 0 .../contexts/ReviewFormContext.tsx | 0 {frontend/src => src}/hooks/common/index.ts | 0 .../src => src}/hooks/common/useDebounce.ts | 0 .../hooks/common/useEnterKeyDown.ts | 0 .../src => src}/hooks/common/useFormData.ts | 0 {frontend/src => src}/hooks/common/useGA.ts | 0 .../hooks/common/useImageUploader.ts | 0 .../hooks/common/useIntersectionObserver.ts | 0 .../hooks/common/useRouteChangeTracker.ts | 0 .../src => src}/hooks/common/useRoutePage.ts | 0 .../src => src}/hooks/common/useScroll.ts | 0 .../hooks/common/useScrollRestoration.ts | 0 .../src => src}/hooks/common/useSortOption.ts | 0 .../src => src}/hooks/common/useTabMenu.ts | 0 .../src => src}/hooks/common/useTimeout.ts | 0 {frontend/src => src}/hooks/context/index.ts | 0 .../hooks/context/useCategoryActionContext.ts | 0 .../hooks/context/useCategoryValueContext.ts | 0 .../context/useRecipeFormActionContext.ts | 0 .../context/useRecipeFormValueContext.ts | 0 .../context/useReviewFormActionContext.ts | 0 .../context/useReviewFormValueContext.ts | 0 .../src => src}/hooks/queries/banner/index.ts | 0 .../hooks/queries/banner/useBannerQuery.ts | 0 {frontend/src => src}/hooks/queries/index.ts | 0 .../hooks/queries/members/index.ts | 0 .../hooks/queries/members/useDeleteReview.ts | 0 .../members/useInfiniteMemberRecipeQuery.ts | 2 +- .../members/useInfiniteMemberReviewQuery.ts | 2 +- .../queries/members/useLogoutMutation.ts | 0 .../members/useMemberModifyMutation.ts | 0 .../hooks/queries/members/useMemberQuery.ts | 2 +- .../hooks/queries/product/index.ts | 0 .../hooks/queries/product/useCategoryQuery.ts | 2 +- .../product/useInfiniteProductRecipesQuery.ts | 0 .../product/useInfiniteProductReviewsQuery.ts | 2 +- .../product/useInfiniteProductsQuery.ts | 2 +- .../queries/product/useProductDetailQuery.ts | 2 +- .../src => src}/hooks/queries/rank/index.ts | 0 .../hooks/queries/rank/useBestReviewQuery.ts | 0 .../queries/rank/useProductRankingQuery.ts | 2 +- .../queries/rank/useRecipeRankingQuery.ts | 0 .../queries/rank/useReviewRankingQuery.ts | 2 +- .../src => src}/hooks/queries/recipe/index.ts | 0 .../recipe/useInfiniteRecipeCommentQuery.ts | 0 .../queries/recipe/useInfiniteRecipesQuery.ts | 2 +- .../recipe/useRecipeCommentMutation.ts | 0 .../queries/recipe/useRecipeDetailQuery.ts | 2 +- .../recipe/useRecipeFavoriteMutation.ts | 0 .../recipe/useRecipeRegisterFormMutation.ts | 0 .../src => src}/hooks/queries/review/index.ts | 0 .../queries/review/useReviewDetailQuery.ts | 0 .../review/useReviewFavoriteMutation.ts | 0 .../review/useReviewRegisterFormMutation.ts | 0 .../queries/review/useReviewTagsQuery.ts | 2 +- .../src => src}/hooks/queries/search/index.ts | 0 ...eInfiniteProductSearchAutocompleteQuery.ts | 2 +- .../useInfiniteProductSearchResultsQuery.ts | 2 +- .../useInfiniteRecipeSearchResultsQuery.ts | 2 +- .../queries/useSuspendedInfiniteQuery.ts | 0 .../hooks/queries/useSuspendedQuery.ts | 0 {frontend/src => src}/hooks/review/index.ts | 0 .../src => src}/hooks/review/useDisplayTag.ts | 0 .../hooks/review/useStarRatingHover.ts | 0 {frontend/src => src}/hooks/search/index.ts | 0 .../src => src}/hooks/search/useSearch.ts | 0 {frontend/src => src}/index.tsx | 0 {frontend/src => src}/mocks/browser.ts | 0 {frontend/src => src}/mocks/data/banners.json | 0 .../src => src}/mocks/data/comments.json | 0 .../src => src}/mocks/data/foodCategory.json | 0 .../src => src}/mocks/data/memberRecipes.json | 0 .../src => src}/mocks/data/memberReviews.json | 0 {frontend/src => src}/mocks/data/members.json | 0 .../src => src}/mocks/data/pbProducts.json | 0 .../src => src}/mocks/data/productDetail.json | 0 .../mocks/data/productDetails.json | 0 .../mocks/data/productRankingList.json | 0 .../mocks/data/productSearchResults.json | 0 .../src => src}/mocks/data/products.json | 0 .../src => src}/mocks/data/recipeDetail.json | 0 .../mocks/data/recipeRankingList.json | 0 {frontend/src => src}/mocks/data/recipes.json | 0 .../src => src}/mocks/data/reviewDetail.json | 0 .../mocks/data/reviewRankingList.json | 0 .../src => src}/mocks/data/reviewTagList.json | 0 {frontend/src => src}/mocks/data/reviews.json | 0 .../mocks/data/searchingProducts.json | 0 .../src => src}/mocks/data/storeCategory.json | 0 .../mocks/handlers/bannerHandlers.ts | 0 {frontend/src => src}/mocks/handlers/index.ts | 0 .../mocks/handlers/loginHandlers.ts | 0 .../mocks/handlers/logoutHandlers.ts | 0 .../mocks/handlers/memberHandlers.ts | 0 .../mocks/handlers/productHandlers.ts | 0 .../mocks/handlers/rankingHandlers.ts | 0 .../mocks/handlers/recipeHandlers.ts | 0 .../mocks/handlers/reviewHandlers.ts | 0 .../mocks/handlers/searchHandlers.ts | 0 {frontend/src => src}/mocks/handlers/utils.ts | 0 {frontend/src => src}/pages/AuthPage.tsx | 0 {frontend/src => src}/pages/HomePage.tsx | 0 .../pages/IntegratedSearchPage.tsx | 0 {frontend/src => src}/pages/LoginPage.tsx | 0 .../src => src}/pages/MemberModifyPage.tsx | 0 {frontend/src => src}/pages/MemberPage.tsx | 0 .../src => src}/pages/MemberRecipePage.tsx | 0 .../src => src}/pages/MemberReviewPage.tsx | 0 {frontend/src => src}/pages/NotFoundPage.tsx | 0 .../src => src}/pages/ProductDetailPage.tsx | 0 .../src => src}/pages/ProductListPage.tsx | 0 .../src => src}/pages/RecipeDetailPage.tsx | 0 {frontend/src => src}/pages/RecipePage.tsx | 0 .../src => src}/pages/ReviewDetailPage.tsx | 0 {frontend/src => src}/pages/SearchPage.tsx | 0 {frontend/src => src}/router/App.tsx | 0 {frontend/src => src}/router/index.tsx | 0 {frontend/src => src}/service/channelTalk.ts | 0 {frontend/src => src}/styles/animations.ts | 0 {frontend/src => src}/styles/font.ts | 0 {frontend/src => src}/styles/globalStyle.ts | 0 {frontend/src => src}/types/banner.ts | 0 {frontend/src => src}/types/common.ts | 0 {frontend/src => src}/types/images.d.ts | 0 {frontend/src => src}/types/member.ts | 0 {frontend/src => src}/types/product.ts | 0 {frontend/src => src}/types/ranking.ts | 0 {frontend/src => src}/types/recipe.ts | 0 {frontend/src => src}/types/response.ts | 0 {frontend/src => src}/types/review.ts | 0 {frontend/src => src}/types/search.ts | 0 {frontend/src => src}/types/styled.d.ts | 0 {frontend/src => src}/utils/category.ts | 0 .../src => src}/utils/convertTagColor.ts | 0 {frontend/src => src}/utils/date.ts | 0 {frontend/src => src}/utils/displaySlice.ts | 0 {frontend/src => src}/utils/localStorage.ts | 0 {frontend/src => src}/utils/uuid.ts | 0 frontend/tsconfig.json => tsconfig.json | 11 +- .../webpack.common.js => webpack.common.js | 0 frontend/webpack.dev.js => webpack.dev.js | 0 frontend/webpack.prod.js => webpack.prod.js | 0 frontend/yarn.lock => yarn.lock | 0 552 files changed, 29 insertions(+), 18882 deletions(-) rename frontend/.babelrc.json => .babelrc.json (100%) rename frontend/.eslintrc.js => .eslintrc.js (100%) delete mode 100644 .github/workflows/test.yml rename frontend/.gitignore => .gitignore (100%) rename frontend/.nvmrc => .nvmrc (100%) rename frontend/.prettierrc => .prettierrc (100%) rename {frontend/.storybook => .storybook}/main.ts (100%) rename {frontend/.storybook => .storybook}/preview-body.html (100%) rename {frontend/.storybook => .storybook}/preview.tsx (100%) rename frontend/.stylelintrc.js => .stylelintrc.js (100%) rename {frontend/__tests__ => __tests__}/hooks/useImageUploader.test.ts (100%) rename {frontend/__tests__ => __tests__}/hooks/useStarRating.test.ts (100%) rename {frontend/__tests__ => __tests__}/hooks/useTabMenu.test.ts (100%) delete mode 100644 backend/.gitignore delete mode 100644 backend/build.gradle delete mode 100644 backend/gradle/wrapper/gradle-wrapper.jar delete mode 100644 backend/gradle/wrapper/gradle-wrapper.properties delete mode 100755 backend/gradlew delete mode 100644 backend/gradlew.bat delete mode 100644 backend/settings.gradle delete mode 100644 backend/src/main/java/com/funeat/FuneatApplication.java delete mode 100644 backend/src/main/java/com/funeat/admin/application/AdminChecker.java delete mode 100644 backend/src/main/java/com/funeat/admin/application/AdminService.java delete mode 100644 backend/src/main/java/com/funeat/admin/domain/AdminAuthInfo.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/AdminCategoryResponse.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/AdminProductResponse.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/AdminProductSearchResponse.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/AdminReviewResponse.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/AdminReviewSearchResponse.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/ProductCreateRequest.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/ProductSearchCondition.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/ProductUpdateRequest.java delete mode 100644 backend/src/main/java/com/funeat/admin/dto/ReviewSearchCondition.java delete mode 100644 backend/src/main/java/com/funeat/admin/presentation/AdminController.java delete mode 100644 backend/src/main/java/com/funeat/admin/presentation/AdminLoginController.java delete mode 100644 backend/src/main/java/com/funeat/admin/repository/AdminProductRepository.java delete mode 100644 backend/src/main/java/com/funeat/admin/repository/AdminReviewRepository.java delete mode 100644 backend/src/main/java/com/funeat/admin/specification/AdminProductSpecification.java delete mode 100644 backend/src/main/java/com/funeat/admin/specification/AdminReviewSpecification.java delete mode 100644 backend/src/main/java/com/funeat/admin/util/AdminCheckInterceptor.java delete mode 100644 backend/src/main/java/com/funeat/auth/application/AuthService.java delete mode 100644 backend/src/main/java/com/funeat/auth/dto/KakaoTokenDto.java delete mode 100644 backend/src/main/java/com/funeat/auth/dto/KakaoUserInfoDto.java delete mode 100644 backend/src/main/java/com/funeat/auth/dto/LoginInfo.java delete mode 100644 backend/src/main/java/com/funeat/auth/dto/SignUserDto.java delete mode 100644 backend/src/main/java/com/funeat/auth/dto/TokenResponse.java delete mode 100644 backend/src/main/java/com/funeat/auth/dto/UserInfoDto.java delete mode 100644 backend/src/main/java/com/funeat/auth/exception/AuthErrorCode.java delete mode 100644 backend/src/main/java/com/funeat/auth/exception/AuthException.java delete mode 100644 backend/src/main/java/com/funeat/auth/presentation/AuthApiController.java delete mode 100644 backend/src/main/java/com/funeat/auth/presentation/AuthController.java delete mode 100644 backend/src/main/java/com/funeat/auth/util/AuthArgumentResolver.java delete mode 100644 backend/src/main/java/com/funeat/auth/util/AuthHandlerInterceptor.java delete mode 100644 backend/src/main/java/com/funeat/auth/util/AuthenticationPrincipal.java delete mode 100644 backend/src/main/java/com/funeat/auth/util/KakaoPlatformUserProvider.java delete mode 100644 backend/src/main/java/com/funeat/auth/util/PlatformUserProvider.java delete mode 100644 backend/src/main/java/com/funeat/banner/application/BannerService.java delete mode 100644 backend/src/main/java/com/funeat/banner/domain/Banner.java delete mode 100644 backend/src/main/java/com/funeat/banner/dto/BannerResponse.java delete mode 100644 backend/src/main/java/com/funeat/banner/persistence/BannerRepository.java delete mode 100644 backend/src/main/java/com/funeat/banner/presentation/BannerApiController.java delete mode 100644 backend/src/main/java/com/funeat/banner/presentation/BannerController.java delete mode 100644 backend/src/main/java/com/funeat/comment/domain/Comment.java delete mode 100644 backend/src/main/java/com/funeat/comment/persistence/CommentRepository.java delete mode 100644 backend/src/main/java/com/funeat/comment/specification/CommentSpecification.java delete mode 100644 backend/src/main/java/com/funeat/common/CustomPageableHandlerMethodArgumentResolver.java delete mode 100644 backend/src/main/java/com/funeat/common/ImageUploader.java delete mode 100644 backend/src/main/java/com/funeat/common/OpenApiConfig.java delete mode 100644 backend/src/main/java/com/funeat/common/StringToCategoryTypeConverter.java delete mode 100644 backend/src/main/java/com/funeat/common/WebConfig.java delete mode 100644 backend/src/main/java/com/funeat/common/dto/PageDto.java delete mode 100644 backend/src/main/java/com/funeat/common/exception/CommonException.java delete mode 100644 backend/src/main/java/com/funeat/common/logging/Logging.java delete mode 100644 backend/src/main/java/com/funeat/common/logging/LoggingAspect.java delete mode 100644 backend/src/main/java/com/funeat/common/repository/BaseRepository.java delete mode 100644 backend/src/main/java/com/funeat/common/repository/BaseRepositoryImpl.java delete mode 100644 backend/src/main/java/com/funeat/common/s3/AwsConfig.java delete mode 100644 backend/src/main/java/com/funeat/common/s3/S3Uploader.java delete mode 100644 backend/src/main/java/com/funeat/exception/CommonErrorCode.java delete mode 100644 backend/src/main/java/com/funeat/exception/ErrorCode.java delete mode 100644 backend/src/main/java/com/funeat/exception/GlobalException.java delete mode 100644 backend/src/main/java/com/funeat/exception/presentation/GlobalControllerAdvice.java delete mode 100644 backend/src/main/java/com/funeat/member/application/MemberService.java delete mode 100644 backend/src/main/java/com/funeat/member/domain/Member.java delete mode 100644 backend/src/main/java/com/funeat/member/domain/favorite/RecipeFavorite.java delete mode 100644 backend/src/main/java/com/funeat/member/domain/favorite/ReviewFavorite.java delete mode 100644 backend/src/main/java/com/funeat/member/dto/MemberProfileResponse.java delete mode 100644 backend/src/main/java/com/funeat/member/dto/MemberRecipeDto.java delete mode 100644 backend/src/main/java/com/funeat/member/dto/MemberRecipeProductDto.java delete mode 100644 backend/src/main/java/com/funeat/member/dto/MemberRecipesResponse.java delete mode 100644 backend/src/main/java/com/funeat/member/dto/MemberRequest.java delete mode 100644 backend/src/main/java/com/funeat/member/dto/MemberReviewDto.java delete mode 100644 backend/src/main/java/com/funeat/member/dto/MemberReviewsResponse.java delete mode 100644 backend/src/main/java/com/funeat/member/exception/MemberErrorCode.java delete mode 100644 backend/src/main/java/com/funeat/member/exception/MemberException.java delete mode 100644 backend/src/main/java/com/funeat/member/persistence/MemberRepository.java delete mode 100644 backend/src/main/java/com/funeat/member/persistence/RecipeFavoriteRepository.java delete mode 100644 backend/src/main/java/com/funeat/member/persistence/ReviewFavoriteRepository.java delete mode 100644 backend/src/main/java/com/funeat/member/presentation/MemberApiController.java delete mode 100644 backend/src/main/java/com/funeat/member/presentation/MemberController.java delete mode 100644 backend/src/main/java/com/funeat/product/application/CategoryService.java delete mode 100644 backend/src/main/java/com/funeat/product/application/ProductService.java delete mode 100644 backend/src/main/java/com/funeat/product/domain/Category.java delete mode 100644 backend/src/main/java/com/funeat/product/domain/CategoryType.java delete mode 100644 backend/src/main/java/com/funeat/product/domain/Product.java delete mode 100644 backend/src/main/java/com/funeat/product/domain/ProductRecipe.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/CategoryResponse.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/ProductInCategoryDto.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/ProductResponse.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/ProductReviewCountDto.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/ProductSortCondition.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/ProductsInCategoryResponse.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/RankingProductDto.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/RankingProductsResponse.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/SearchProductDto.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/SearchProductResultDto.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/SearchProductResultsResponse.java delete mode 100644 backend/src/main/java/com/funeat/product/dto/SearchProductsResponse.java delete mode 100644 backend/src/main/java/com/funeat/product/exception/CategoryErrorCode.java delete mode 100644 backend/src/main/java/com/funeat/product/exception/CategoryException.java delete mode 100644 backend/src/main/java/com/funeat/product/exception/ProductErrorCode.java delete mode 100644 backend/src/main/java/com/funeat/product/exception/ProductException.java delete mode 100644 backend/src/main/java/com/funeat/product/persistence/CategoryRepository.java delete mode 100644 backend/src/main/java/com/funeat/product/persistence/ProductRecipeRepository.java delete mode 100644 backend/src/main/java/com/funeat/product/persistence/ProductRepository.java delete mode 100644 backend/src/main/java/com/funeat/product/persistence/ProductSpecification.java delete mode 100644 backend/src/main/java/com/funeat/product/presentation/CategoryApiController.java delete mode 100644 backend/src/main/java/com/funeat/product/presentation/CategoryController.java delete mode 100644 backend/src/main/java/com/funeat/product/presentation/ProductApiController.java delete mode 100644 backend/src/main/java/com/funeat/product/presentation/ProductController.java delete mode 100644 backend/src/main/java/com/funeat/recipe/application/RecipeService.java delete mode 100644 backend/src/main/java/com/funeat/recipe/domain/Recipe.java delete mode 100644 backend/src/main/java/com/funeat/recipe/domain/RecipeImage.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/ProductRecipeDto.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RankingRecipeDto.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RankingRecipesResponse.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeAuthorDto.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeCommentCondition.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeCommentCreateRequest.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeCommentMemberResponse.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeCommentResponse.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeCommentsResponse.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeCreateRequest.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeDetailResponse.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeDto.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeFavoriteRequest.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/SearchRecipeResultDto.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/SearchRecipeResultsResponse.java delete mode 100644 backend/src/main/java/com/funeat/recipe/dto/SortingRecipesResponse.java delete mode 100644 backend/src/main/java/com/funeat/recipe/exception/RecipeErrorCode.java delete mode 100644 backend/src/main/java/com/funeat/recipe/exception/RecipeException.java delete mode 100644 backend/src/main/java/com/funeat/recipe/persistence/RecipeImageRepository.java delete mode 100644 backend/src/main/java/com/funeat/recipe/persistence/RecipeRepository.java delete mode 100644 backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java delete mode 100644 backend/src/main/java/com/funeat/recipe/presentation/RecipeController.java delete mode 100644 backend/src/main/java/com/funeat/recipe/util/RecipeDetailHandlerInterceptor.java delete mode 100644 backend/src/main/java/com/funeat/recipe/util/RecipeHandlerInterceptor.java delete mode 100644 backend/src/main/java/com/funeat/review/application/ReviewDeleteEvent.java delete mode 100644 backend/src/main/java/com/funeat/review/application/ReviewDeleteEventListener.java delete mode 100644 backend/src/main/java/com/funeat/review/application/ReviewService.java delete mode 100644 backend/src/main/java/com/funeat/review/domain/Review.java delete mode 100644 backend/src/main/java/com/funeat/review/domain/ReviewTag.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/MostFavoriteReviewResponse.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/RankingReviewDto.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/RankingReviewsResponse.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/ReviewCreateRequest.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/ReviewDetailResponse.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/ReviewFavoriteRequest.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/SortingReviewDto.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/SortingReviewDtoWithoutTag.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/SortingReviewRequest.java delete mode 100644 backend/src/main/java/com/funeat/review/dto/SortingReviewsResponse.java delete mode 100644 backend/src/main/java/com/funeat/review/exception/ReviewErrorCode.java delete mode 100644 backend/src/main/java/com/funeat/review/exception/ReviewException.java delete mode 100644 backend/src/main/java/com/funeat/review/persistence/ReviewCustomRepository.java delete mode 100644 backend/src/main/java/com/funeat/review/persistence/ReviewRepository.java delete mode 100644 backend/src/main/java/com/funeat/review/persistence/ReviewRepositoryImpl.java delete mode 100644 backend/src/main/java/com/funeat/review/persistence/ReviewTagRepository.java delete mode 100644 backend/src/main/java/com/funeat/review/presentation/ReviewApiController.java delete mode 100644 backend/src/main/java/com/funeat/review/presentation/ReviewController.java delete mode 100644 backend/src/main/java/com/funeat/review/specification/LongTypeReviewSortSpec.java delete mode 100644 backend/src/main/java/com/funeat/review/specification/SortingReviewSpecification.java delete mode 100644 backend/src/main/java/com/funeat/tag/application/TagService.java delete mode 100644 backend/src/main/java/com/funeat/tag/domain/Tag.java delete mode 100644 backend/src/main/java/com/funeat/tag/domain/TagType.java delete mode 100644 backend/src/main/java/com/funeat/tag/dto/TagDto.java delete mode 100644 backend/src/main/java/com/funeat/tag/dto/TagsResponse.java delete mode 100644 backend/src/main/java/com/funeat/tag/persistence/TagRepository.java delete mode 100644 backend/src/main/java/com/funeat/tag/presentation/TagApiController.java delete mode 100644 backend/src/main/java/com/funeat/tag/presentation/TagController.java delete mode 100644 backend/src/main/resources/application-dev.yml delete mode 100644 backend/src/main/resources/application-local.yml delete mode 100644 backend/src/main/resources/application-prod.yml delete mode 100644 backend/src/main/resources/application.yml delete mode 100644 backend/src/main/resources/logback-spring-dev.xml delete mode 100644 backend/src/main/resources/logback-spring-prod.xml delete mode 100644 backend/src/main/resources/logback-spring.xml delete mode 100644 backend/src/main/resources/logback-variables.yml delete mode 100644 backend/src/test/java/com/funeat/FuneatApplicationTests.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/auth/AuthAcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/auth/LoginSteps.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/banner/BannerAcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/banner/BannerSteps.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/common/AcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/common/CommonSteps.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/common/TestPlatformUserProvider.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/member/MemberAcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/member/MemberSteps.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/product/CategoryAcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/product/CategorySteps.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/product/ProductAcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/product/ProductSteps.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/review/ReviewAcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/review/ReviewSteps.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/tag/TagAcceptanceTest.java delete mode 100644 backend/src/test/java/com/funeat/acceptance/tag/TagSteps.java delete mode 100644 backend/src/test/java/com/funeat/auth/application/AuthServiceTest.java delete mode 100644 backend/src/test/java/com/funeat/banner/application/BannerServiceTest.java delete mode 100644 backend/src/test/java/com/funeat/banner/persistence/BannerRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/common/DataCleaner.java delete mode 100644 backend/src/test/java/com/funeat/common/DataClearExtension.java delete mode 100644 backend/src/test/java/com/funeat/common/EventTest.java delete mode 100644 backend/src/test/java/com/funeat/common/RepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/common/ServiceTest.java delete mode 100644 backend/src/test/java/com/funeat/common/TestImageUploader.java delete mode 100644 backend/src/test/java/com/funeat/fixture/BannerFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/CategoryFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/ImageFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/MemberFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/PageFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/ProductFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/RecipeFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/ReviewFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/ScoreFixture.java delete mode 100644 backend/src/test/java/com/funeat/fixture/TagFixture.java delete mode 100644 backend/src/test/java/com/funeat/member/application/MemberServiceTest.java delete mode 100644 backend/src/test/java/com/funeat/member/application/TestMemberService.java delete mode 100644 backend/src/test/java/com/funeat/member/domain/MemberTest.java delete mode 100644 backend/src/test/java/com/funeat/member/domain/favorite/RecipeFavoriteTest.java delete mode 100644 backend/src/test/java/com/funeat/member/persistence/MemberRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/member/persistence/RecipeFavoriteRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/member/persistence/ReviewFavoriteRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/product/application/ProductServiceTest.java delete mode 100644 backend/src/test/java/com/funeat/product/domain/ProductTest.java delete mode 100644 backend/src/test/java/com/funeat/product/domain/favorite/ReviewFavoriteTest.java delete mode 100644 backend/src/test/java/com/funeat/product/persistence/CategoryRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/product/persistence/ProductRecipeRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/product/persistence/ProductRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java delete mode 100644 backend/src/test/java/com/funeat/recipe/domain/RecipeTest.java delete mode 100644 backend/src/test/java/com/funeat/recipe/persistence/RecipeImageRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/recipe/persistence/RecipeRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/review/application/ReviewDeleteEventListenerTest.java delete mode 100644 backend/src/test/java/com/funeat/review/application/ReviewServiceTest.java delete mode 100644 backend/src/test/java/com/funeat/review/domain/ReviewTest.java delete mode 100644 backend/src/test/java/com/funeat/review/persistence/ReviewRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/review/persistence/ReviewTagRepositoryTest.java delete mode 100644 backend/src/test/java/com/funeat/tag/persistence/TagRepositoryTest.java delete mode 100644 backend/src/test/resources/application.yml rename frontend/jest.config.js => jest.config.js (100%) rename frontend/package.json => package.json (97%) rename {frontend/public => public}/assets/apple-icon-180x180.png (100%) rename {frontend/public => public}/assets/favicon-16x16.png (100%) rename {frontend/public => public}/assets/favicon-32x32.png (100%) rename {frontend/public => public}/assets/favicon.ico (100%) rename {frontend/public => public}/assets/og-image.png (100%) rename {frontend/public => public}/index.html (100%) rename {frontend/public => public}/manifest.json (100%) rename {frontend/public => public}/mockServiceWorker.js (100%) rename {frontend/public => public}/robots.txt (100%) rename {frontend/public => public}/sitemap.xml (100%) rename {frontend/src => src}/apis/ApiClient.ts (100%) rename {frontend/src => src}/apis/fetch.ts (100%) rename {frontend/src => src}/apis/index.ts (100%) rename {frontend/src => src}/assets/characters.svg (100%) rename {frontend/src => src}/assets/logo.svg (100%) rename {frontend/src => src}/assets/plate.svg (100%) rename {frontend/src => src}/assets/samgakgimbab.svg (100%) rename {frontend/src => src}/components/Common/Banner/Banner.tsx (100%) rename {frontend/src => src}/components/Common/CategoryFoodList/CategoryFoodList.stories.tsx (100%) rename {frontend/src => src}/components/Common/CategoryFoodList/CategoryFoodList.tsx (100%) rename {frontend/src => src}/components/Common/CategoryFoodTab/CategoryFoodTab.stories.tsx (100%) rename {frontend/src => src}/components/Common/CategoryFoodTab/CategoryFoodTab.tsx (100%) rename {frontend/src => src}/components/Common/CategoryItem/CategoryItem.stories.tsx (100%) rename {frontend/src => src}/components/Common/CategoryItem/CategoryItem.tsx (100%) rename {frontend/src => src}/components/Common/CategoryStoreList/CategoryStoreList.stories.tsx (100%) rename {frontend/src => src}/components/Common/CategoryStoreList/CategoryStoreList.tsx (100%) rename {frontend/src => src}/components/Common/CategoryStoreTab/CategoryStoreTab.stories.tsx (100%) rename {frontend/src => src}/components/Common/CategoryStoreTab/CategoryStoreTab.tsx (100%) rename {frontend/src => src}/components/Common/ErrorBoundary/ErrorBoundary.tsx (100%) rename {frontend/src => src}/components/Common/ErrorComponent/ErrorComponent.stories.tsx (100%) rename {frontend/src => src}/components/Common/ErrorComponent/ErrorComponent.tsx (100%) rename {frontend/src => src}/components/Common/Header/Header.stories.tsx (100%) rename {frontend/src => src}/components/Common/Header/Header.tsx (100%) rename {frontend/src => src}/components/Common/ImageUploader/ImageUploader.stories.tsx (100%) rename {frontend/src => src}/components/Common/ImageUploader/ImageUploader.tsx (100%) rename {frontend/src => src}/components/Common/Loading/Loading.stories.tsx (100%) rename {frontend/src => src}/components/Common/Loading/Loading.tsx (100%) rename {frontend/src => src}/components/Common/MarkedText/MarkedText.tsx (100%) rename {frontend/src => src}/components/Common/NavigableSectionTitle/NavigableSectionTitle.stories.tsx (100%) rename {frontend/src => src}/components/Common/NavigableSectionTitle/NavigableSectionTitle.tsx (100%) rename {frontend/src => src}/components/Common/NavigationBar/NavigationBar.stories.tsx (100%) rename {frontend/src => src}/components/Common/NavigationBar/NavigationBar.tsx (100%) rename {frontend/src => src}/components/Common/RegisterButton/RegisterButton.tsx (100%) rename {frontend/src => src}/components/Common/ScrollButton/ScrollButton.stories.tsx (100%) rename {frontend/src => src}/components/Common/ScrollButton/ScrollButton.tsx (100%) rename {frontend/src => src}/components/Common/SectionTitle/SectionTitle.stories.tsx (100%) rename {frontend/src => src}/components/Common/SectionTitle/SectionTitle.tsx (100%) rename {frontend/src => src}/components/Common/SortButton/SortButton.stories.tsx (100%) rename {frontend/src => src}/components/Common/SortButton/SortButton.tsx (100%) rename {frontend/src => src}/components/Common/SortOptionList/SortOptionList.stories.tsx (100%) rename {frontend/src => src}/components/Common/SortOptionList/SortOptionList.tsx (100%) rename {frontend/src => src}/components/Common/Svg/SvgIcon.stories.tsx (100%) rename {frontend/src => src}/components/Common/Svg/SvgIcon.tsx (100%) rename {frontend/src => src}/components/Common/Svg/SvgSprite.tsx (100%) rename {frontend/src => src}/components/Common/TabMenu/TabMenu.stories.tsx (100%) rename {frontend/src => src}/components/Common/TabMenu/TabMenu.tsx (100%) rename {frontend/src => src}/components/Common/TagList/TagList.stories.tsx (100%) rename {frontend/src => src}/components/Common/TagList/TagList.tsx (100%) rename {frontend/src => src}/components/Common/index.ts (100%) rename {frontend/src => src}/components/Layout/AuthLayout.tsx (100%) rename {frontend/src => src}/components/Layout/DefaultLayout.tsx (100%) rename {frontend/src => src}/components/Layout/HeaderOnlyLayout.tsx (100%) rename {frontend/src => src}/components/Layout/MinimalLayout.tsx (100%) rename {frontend/src => src}/components/Layout/SimpleHeaderLayout.tsx (100%) rename {frontend/src => src}/components/Layout/index.ts (100%) rename {frontend/src => src}/components/Members/MemberModifyInput/MemberModifyInput.tsx (100%) rename {frontend/src => src}/components/Members/MemberRecipeList/MemberRecipeList.stories.tsx (100%) rename {frontend/src => src}/components/Members/MemberRecipeList/MemberRecipeList.tsx (100%) rename {frontend/src => src}/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx (100%) rename {frontend/src => src}/components/Members/MemberReviewItem/MemberReviewItem.tsx (100%) rename {frontend/src => src}/components/Members/MemberReviewList/MemberReviewList.stories.tsx (100%) rename {frontend/src => src}/components/Members/MemberReviewList/MemberReviewList.tsx (100%) rename {frontend/src => src}/components/Members/MembersInfo/MembersInfo.tsx (100%) rename {frontend/src => src}/components/Members/MembersInfo/MyPageInfo.stories.tsx (100%) rename {frontend/src => src}/components/Members/index.ts (100%) rename {frontend/src => src}/components/Product/ProductDetailItem/ProductDetailItem.stories.tsx (100%) rename {frontend/src => src}/components/Product/ProductDetailItem/ProductDetailItem.tsx (100%) rename {frontend/src => src}/components/Product/ProductItem/ProductItem.stories.tsx (100%) rename {frontend/src => src}/components/Product/ProductItem/ProductItem.tsx (100%) rename {frontend/src => src}/components/Product/ProductList/ProductList.stories.tsx (100%) rename {frontend/src => src}/components/Product/ProductList/ProductList.tsx (100%) rename {frontend/src => src}/components/Product/ProductOverviewItem/ProductOverviewItem.stories.tsx (100%) rename {frontend/src => src}/components/Product/ProductOverviewItem/ProductOverviewItem.tsx (100%) rename {frontend/src => src}/components/Product/ProductRecipeList/ProductRecipeList.tsx (100%) rename {frontend/src => src}/components/Product/ProductTitle/ProductTitle.stories.tsx (100%) rename {frontend/src => src}/components/Product/ProductTitle/ProductTitle.tsx (100%) rename {frontend/src => src}/components/Product/index.ts (100%) rename {frontend/src => src}/components/Rank/ProductRankingList/ProductRankingList.stories.tsx (100%) rename {frontend/src => src}/components/Rank/ProductRankingList/ProductRankingList.tsx (100%) rename {frontend/src => src}/components/Rank/RecipeRankingItem/RecipeRankingItem.stories.tsx (100%) rename {frontend/src => src}/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx (100%) rename {frontend/src => src}/components/Rank/RecipeRankingList/RecipeRankingList.stories.tsx (100%) rename {frontend/src => src}/components/Rank/RecipeRankingList/RecipeRankingList.tsx (100%) rename {frontend/src => src}/components/Rank/ReviewRankingItem/ReviewRankingItem.stories.tsx (100%) rename {frontend/src => src}/components/Rank/ReviewRankingItem/ReviewRankingItem.tsx (100%) rename {frontend/src => src}/components/Rank/ReviewRankingList/ReviewRankingList.stories.tsx (100%) rename {frontend/src => src}/components/Rank/ReviewRankingList/ReviewRankingList.tsx (100%) rename {frontend/src => src}/components/Rank/index.ts (79%) rename {frontend/src => src}/components/Recipe/CommentForm/CommentForm.stories.tsx (100%) rename {frontend/src => src}/components/Recipe/CommentForm/CommentForm.tsx (100%) rename {frontend/src => src}/components/Recipe/CommentItem/CommentItem.stories.tsx (100%) rename {frontend/src => src}/components/Recipe/CommentItem/CommentItem.tsx (100%) rename {frontend/src => src}/components/Recipe/CommentList/CommentList.stories.tsx (100%) rename {frontend/src => src}/components/Recipe/CommentList/CommentList.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx (91%) rename {frontend/src => src}/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeItem/RecipeItem.stories.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeItem/RecipeItem.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeList/RecipeList.stories.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeList/RecipeList.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeNameInput/RecipeNameInput.stories.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeNameInput/RecipeNameInput.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.stories.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.stories.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx (100%) rename {frontend/src => src}/components/Recipe/RecipeUsedProducts/SearchedProductList.tsx (100%) rename {frontend/src => src}/components/Recipe/index.ts (100%) rename {frontend/src => src}/components/Review/BestReviewItem/BestReviewItem.stories.tsx (100%) rename {frontend/src => src}/components/Review/BestReviewItem/BestReviewItem.tsx (100%) rename {frontend/src => src}/components/Review/RebuyCheckbox/RebuyCheckbox.tsx (100%) rename {frontend/src => src}/components/Review/ReviewFavoriteButton/ReviewFavoriteButton.tsx (100%) rename {frontend/src => src}/components/Review/ReviewItem/ReviewItem.stories.tsx (100%) rename {frontend/src => src}/components/Review/ReviewItem/ReviewItem.tsx (100%) rename {frontend/src => src}/components/Review/ReviewList/ReviewList.tsx (100%) rename {frontend/src => src}/components/Review/ReviewRegisterForm/ReviewRegisterForm.stories.tsx (100%) rename {frontend/src => src}/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx (100%) rename {frontend/src => src}/components/Review/ReviewTagItem/ReviewTagItem.stories.tsx (100%) rename {frontend/src => src}/components/Review/ReviewTagItem/ReviewTagItem.tsx (100%) rename {frontend/src => src}/components/Review/ReviewTagList/ReviewTagList.stories.tsx (100%) rename {frontend/src => src}/components/Review/ReviewTagList/ReviewTagList.tsx (100%) rename {frontend/src => src}/components/Review/ReviewTextarea/ReviewTextarea.stories.tsx (100%) rename {frontend/src => src}/components/Review/ReviewTextarea/ReviewTextarea.tsx (100%) rename {frontend/src => src}/components/Review/StarRate/StarRate.stories.tsx (100%) rename {frontend/src => src}/components/Review/StarRate/StarRate.tsx (100%) rename {frontend/src => src}/components/Review/index.ts (100%) rename {frontend/src => src}/components/Search/ProductSearchResultList/ProductSearchResultList.tsx (100%) rename {frontend/src => src}/components/Search/RecipeSearchResultList/RecipeSearchResultList.tsx (100%) rename {frontend/src => src}/components/Search/RecommendList/RecommendList.tsx (100%) rename {frontend/src => src}/components/Search/index.ts (100%) rename {frontend/src => src}/constants/index.ts (100%) rename {frontend/src => src}/constants/path.ts (100%) rename {frontend/src => src}/contexts/CategoryContext.tsx (100%) rename {frontend/src => src}/contexts/RecipeFormContext.tsx (100%) rename {frontend/src => src}/contexts/ReviewFormContext.tsx (100%) rename {frontend/src => src}/hooks/common/index.ts (100%) rename {frontend/src => src}/hooks/common/useDebounce.ts (100%) rename {frontend/src => src}/hooks/common/useEnterKeyDown.ts (100%) rename {frontend/src => src}/hooks/common/useFormData.ts (100%) rename {frontend/src => src}/hooks/common/useGA.ts (100%) rename {frontend/src => src}/hooks/common/useImageUploader.ts (100%) rename {frontend/src => src}/hooks/common/useIntersectionObserver.ts (100%) rename {frontend/src => src}/hooks/common/useRouteChangeTracker.ts (100%) rename {frontend/src => src}/hooks/common/useRoutePage.ts (100%) rename {frontend/src => src}/hooks/common/useScroll.ts (100%) rename {frontend/src => src}/hooks/common/useScrollRestoration.ts (100%) rename {frontend/src => src}/hooks/common/useSortOption.ts (100%) rename {frontend/src => src}/hooks/common/useTabMenu.ts (100%) rename {frontend/src => src}/hooks/common/useTimeout.ts (100%) rename {frontend/src => src}/hooks/context/index.ts (100%) rename {frontend/src => src}/hooks/context/useCategoryActionContext.ts (100%) rename {frontend/src => src}/hooks/context/useCategoryValueContext.ts (100%) rename {frontend/src => src}/hooks/context/useRecipeFormActionContext.ts (100%) rename {frontend/src => src}/hooks/context/useRecipeFormValueContext.ts (100%) rename {frontend/src => src}/hooks/context/useReviewFormActionContext.ts (100%) rename {frontend/src => src}/hooks/context/useReviewFormValueContext.ts (100%) rename {frontend/src => src}/hooks/queries/banner/index.ts (100%) rename {frontend/src => src}/hooks/queries/banner/useBannerQuery.ts (100%) rename {frontend/src => src}/hooks/queries/index.ts (100%) rename {frontend/src => src}/hooks/queries/members/index.ts (100%) rename {frontend/src => src}/hooks/queries/members/useDeleteReview.ts (100%) rename {frontend/src => src}/hooks/queries/members/useInfiniteMemberRecipeQuery.ts (93%) rename {frontend/src => src}/hooks/queries/members/useInfiniteMemberReviewQuery.ts (93%) rename {frontend/src => src}/hooks/queries/members/useLogoutMutation.ts (100%) rename {frontend/src => src}/hooks/queries/members/useMemberModifyMutation.ts (100%) rename {frontend/src => src}/hooks/queries/members/useMemberQuery.ts (90%) rename {frontend/src => src}/hooks/queries/product/index.ts (100%) rename {frontend/src => src}/hooks/queries/product/useCategoryQuery.ts (93%) rename {frontend/src => src}/hooks/queries/product/useInfiniteProductRecipesQuery.ts (100%) rename {frontend/src => src}/hooks/queries/product/useInfiniteProductReviewsQuery.ts (94%) rename {frontend/src => src}/hooks/queries/product/useInfiniteProductsQuery.ts (94%) rename {frontend/src => src}/hooks/queries/product/useProductDetailQuery.ts (91%) rename {frontend/src => src}/hooks/queries/rank/index.ts (100%) rename {frontend/src => src}/hooks/queries/rank/useBestReviewQuery.ts (100%) rename {frontend/src => src}/hooks/queries/rank/useProductRankingQuery.ts (90%) rename {frontend/src => src}/hooks/queries/rank/useRecipeRankingQuery.ts (100%) rename {frontend/src => src}/hooks/queries/rank/useReviewRankingQuery.ts (90%) rename {frontend/src => src}/hooks/queries/recipe/index.ts (100%) rename {frontend/src => src}/hooks/queries/recipe/useInfiniteRecipeCommentQuery.ts (100%) rename {frontend/src => src}/hooks/queries/recipe/useInfiniteRecipesQuery.ts (93%) rename {frontend/src => src}/hooks/queries/recipe/useRecipeCommentMutation.ts (100%) rename {frontend/src => src}/hooks/queries/recipe/useRecipeDetailQuery.ts (91%) rename {frontend/src => src}/hooks/queries/recipe/useRecipeFavoriteMutation.ts (100%) rename {frontend/src => src}/hooks/queries/recipe/useRecipeRegisterFormMutation.ts (100%) rename {frontend/src => src}/hooks/queries/review/index.ts (100%) rename {frontend/src => src}/hooks/queries/review/useReviewDetailQuery.ts (100%) rename {frontend/src => src}/hooks/queries/review/useReviewFavoriteMutation.ts (100%) rename {frontend/src => src}/hooks/queries/review/useReviewRegisterFormMutation.ts (100%) rename {frontend/src => src}/hooks/queries/review/useReviewTagsQuery.ts (89%) rename {frontend/src => src}/hooks/queries/search/index.ts (100%) rename {frontend/src => src}/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts (94%) rename {frontend/src => src}/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts (94%) rename {frontend/src => src}/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts (94%) rename {frontend/src => src}/hooks/queries/useSuspendedInfiniteQuery.ts (100%) rename {frontend/src => src}/hooks/queries/useSuspendedQuery.ts (100%) rename {frontend/src => src}/hooks/review/index.ts (100%) rename {frontend/src => src}/hooks/review/useDisplayTag.ts (100%) rename {frontend/src => src}/hooks/review/useStarRatingHover.ts (100%) rename {frontend/src => src}/hooks/search/index.ts (100%) rename {frontend/src => src}/hooks/search/useSearch.ts (100%) rename {frontend/src => src}/index.tsx (100%) rename {frontend/src => src}/mocks/browser.ts (100%) rename {frontend/src => src}/mocks/data/banners.json (100%) rename {frontend/src => src}/mocks/data/comments.json (100%) rename {frontend/src => src}/mocks/data/foodCategory.json (100%) rename {frontend/src => src}/mocks/data/memberRecipes.json (100%) rename {frontend/src => src}/mocks/data/memberReviews.json (100%) rename {frontend/src => src}/mocks/data/members.json (100%) rename {frontend/src => src}/mocks/data/pbProducts.json (100%) rename {frontend/src => src}/mocks/data/productDetail.json (100%) rename {frontend/src => src}/mocks/data/productDetails.json (100%) rename {frontend/src => src}/mocks/data/productRankingList.json (100%) rename {frontend/src => src}/mocks/data/productSearchResults.json (100%) rename {frontend/src => src}/mocks/data/products.json (100%) rename {frontend/src => src}/mocks/data/recipeDetail.json (100%) rename {frontend/src => src}/mocks/data/recipeRankingList.json (100%) rename {frontend/src => src}/mocks/data/recipes.json (100%) rename {frontend/src => src}/mocks/data/reviewDetail.json (100%) rename {frontend/src => src}/mocks/data/reviewRankingList.json (100%) rename {frontend/src => src}/mocks/data/reviewTagList.json (100%) rename {frontend/src => src}/mocks/data/reviews.json (100%) rename {frontend/src => src}/mocks/data/searchingProducts.json (100%) rename {frontend/src => src}/mocks/data/storeCategory.json (100%) rename {frontend/src => src}/mocks/handlers/bannerHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/index.ts (100%) rename {frontend/src => src}/mocks/handlers/loginHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/logoutHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/memberHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/productHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/rankingHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/recipeHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/reviewHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/searchHandlers.ts (100%) rename {frontend/src => src}/mocks/handlers/utils.ts (100%) rename {frontend/src => src}/pages/AuthPage.tsx (100%) rename {frontend/src => src}/pages/HomePage.tsx (100%) rename {frontend/src => src}/pages/IntegratedSearchPage.tsx (100%) rename {frontend/src => src}/pages/LoginPage.tsx (100%) rename {frontend/src => src}/pages/MemberModifyPage.tsx (100%) rename {frontend/src => src}/pages/MemberPage.tsx (100%) rename {frontend/src => src}/pages/MemberRecipePage.tsx (100%) rename {frontend/src => src}/pages/MemberReviewPage.tsx (100%) rename {frontend/src => src}/pages/NotFoundPage.tsx (100%) rename {frontend/src => src}/pages/ProductDetailPage.tsx (100%) rename {frontend/src => src}/pages/ProductListPage.tsx (100%) rename {frontend/src => src}/pages/RecipeDetailPage.tsx (100%) rename {frontend/src => src}/pages/RecipePage.tsx (100%) rename {frontend/src => src}/pages/ReviewDetailPage.tsx (100%) rename {frontend/src => src}/pages/SearchPage.tsx (100%) rename {frontend/src => src}/router/App.tsx (100%) rename {frontend/src => src}/router/index.tsx (100%) rename {frontend/src => src}/service/channelTalk.ts (100%) rename {frontend/src => src}/styles/animations.ts (100%) rename {frontend/src => src}/styles/font.ts (100%) rename {frontend/src => src}/styles/globalStyle.ts (100%) rename {frontend/src => src}/types/banner.ts (100%) rename {frontend/src => src}/types/common.ts (100%) rename {frontend/src => src}/types/images.d.ts (100%) rename {frontend/src => src}/types/member.ts (100%) rename {frontend/src => src}/types/product.ts (100%) rename {frontend/src => src}/types/ranking.ts (100%) rename {frontend/src => src}/types/recipe.ts (100%) rename {frontend/src => src}/types/response.ts (100%) rename {frontend/src => src}/types/review.ts (100%) rename {frontend/src => src}/types/search.ts (100%) rename {frontend/src => src}/types/styled.d.ts (100%) rename {frontend/src => src}/utils/category.ts (100%) rename {frontend/src => src}/utils/convertTagColor.ts (100%) rename {frontend/src => src}/utils/date.ts (100%) rename {frontend/src => src}/utils/displaySlice.ts (100%) rename {frontend/src => src}/utils/localStorage.ts (100%) rename {frontend/src => src}/utils/uuid.ts (100%) rename frontend/tsconfig.json => tsconfig.json (76%) rename frontend/webpack.common.js => webpack.common.js (100%) rename frontend/webpack.dev.js => webpack.dev.js (100%) rename frontend/webpack.prod.js => webpack.prod.js (100%) rename frontend/yarn.lock => yarn.lock (100%) diff --git a/frontend/.babelrc.json b/.babelrc.json similarity index 100% rename from frontend/.babelrc.json rename to .babelrc.json diff --git a/frontend/.eslintrc.js b/.eslintrc.js similarity index 100% rename from frontend/.eslintrc.js rename to .eslintrc.js diff --git a/.github/workflows/test-fe.yml b/.github/workflows/test-fe.yml index 4c2de2320..b8c436089 100644 --- a/.github/workflows/test-fe.yml +++ b/.github/workflows/test-fe.yml @@ -5,9 +5,6 @@ on: branches: - main - develop - paths: - - '.github/**' - - 'frontend/**' jobs: test: @@ -31,7 +28,7 @@ jobs: id: cache uses: actions/cache@v3 with: - path: '**/frontend/node_modules' + path: '**/node_modules' key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-node- @@ -50,13 +47,13 @@ jobs: uses: EnricoMi/publish-unit-test-result-action@v2 if: always() with: - files: '**/frontend/test-results/results.xml' + files: '**/test-results/results.xml' - name: ν…ŒμŠ€νŠΈ μ‹€νŒ¨ μ‹œ, μ‹€νŒ¨ν•œ μ½”λ“œ 라인에 Check μ½”λ©˜νŠΈλ₯Ό 등둝 uses: mikepenz/action-junit-report@v3 if: always() with: - report_paths: '**/frontend/test-results/results.xml' + report_paths: '**/test-results/results.xml' token: ${{ github.token }} - name: build μ‹€νŒ¨ μ‹œ Slack으둜 μ•Œλ¦½λ‹ˆλ‹€ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 160ab01ed..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: PR Test - -on: - pull_request: - branches: - - main - - develop - paths: - - '.github/**' - - 'backend/**' - -jobs: - test: - runs-on: ubuntu-latest - timeout-minutes: 10 - - permissions: - checks: write - pull-requests: write - - steps: - - name: Repository 체크아웃 - uses: actions/checkout@v3 - - - name: JDK 11 μ„€μ • - uses: actions/setup-java@v3 - with: - java-version: 11 - distribution: temurin - - - name: Gradle 캐싱 - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - - name: Gradle κΆŒν•œ λΆ€μ—¬ - working-directory: backend/ - run: chmod +x ./gradlew - - - name: ν…ŒμŠ€νŠΈ μ‹€ν–‰ - working-directory: backend/ - run: ./gradlew --info test - - - name: ν…ŒμŠ€νŠΈ κ²°κ³Ό PR에 μ½”λ©˜νŠΈ 등둝 - uses: EnricoMi/publish-unit-test-result-action@v2 - if: always() - with: - files: '**/backend/build/test-results/test/TEST-*.xml' - - - name: ν…ŒμŠ€νŠΈ μ‹€νŒ¨ μ‹œ, μ‹€νŒ¨ν•œ μ½”λ“œ 라인에 Check μ½”λ©˜νŠΈλ₯Ό 등둝 - uses: mikepenz/action-junit-report@v3 - if: always() - with: - report_paths: '**/backend/build/test-results/test/TEST-*.xml' - token: ${{ github.token }} - - - name: build μ‹€νŒ¨ μ‹œ Slack으둜 μ•Œλ¦½λ‹ˆλ‹€ - uses: 8398a7/action-slack@v3 - with: - status: ${{ job.status }} - author_name: λ°±μ—”λ“œ ν…ŒμŠ€νŠΈ μ‹€νŒ¨ μ•Œλ¦Ό - fields: repo, message, commit, author, action, eventName, ref, workflow, job, took - env: - SLACK_CHANNEL: group-dev - SLACK_COLOR: '#FF2D00' - SLACK_USERNAME: 'Github Action' - SLACK_ICON: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png - SLACK_TITLE: Build Failure - ${{ github.event.pull_request.title }} - SLACK_MESSAGE: PR Url - ${{ github.event.pull_request.url }} - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: failure() diff --git a/frontend/.gitignore b/.gitignore similarity index 100% rename from frontend/.gitignore rename to .gitignore diff --git a/frontend/.nvmrc b/.nvmrc similarity index 100% rename from frontend/.nvmrc rename to .nvmrc diff --git a/frontend/.prettierrc b/.prettierrc similarity index 100% rename from frontend/.prettierrc rename to .prettierrc diff --git a/frontend/.storybook/main.ts b/.storybook/main.ts similarity index 100% rename from frontend/.storybook/main.ts rename to .storybook/main.ts diff --git a/frontend/.storybook/preview-body.html b/.storybook/preview-body.html similarity index 100% rename from frontend/.storybook/preview-body.html rename to .storybook/preview-body.html diff --git a/frontend/.storybook/preview.tsx b/.storybook/preview.tsx similarity index 100% rename from frontend/.storybook/preview.tsx rename to .storybook/preview.tsx diff --git a/frontend/.stylelintrc.js b/.stylelintrc.js similarity index 100% rename from frontend/.stylelintrc.js rename to .stylelintrc.js diff --git a/frontend/__tests__/hooks/useImageUploader.test.ts b/__tests__/hooks/useImageUploader.test.ts similarity index 100% rename from frontend/__tests__/hooks/useImageUploader.test.ts rename to __tests__/hooks/useImageUploader.test.ts diff --git a/frontend/__tests__/hooks/useStarRating.test.ts b/__tests__/hooks/useStarRating.test.ts similarity index 100% rename from frontend/__tests__/hooks/useStarRating.test.ts rename to __tests__/hooks/useStarRating.test.ts diff --git a/frontend/__tests__/hooks/useTabMenu.test.ts b/__tests__/hooks/useTabMenu.test.ts similarity index 100% rename from frontend/__tests__/hooks/useTabMenu.test.ts rename to __tests__/hooks/useTabMenu.test.ts diff --git a/backend/.gitignore b/backend/.gitignore deleted file mode 100644 index c2065bc26..000000000 --- a/backend/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/backend/build.gradle b/backend/build.gradle deleted file mode 100644 index 3d46c806e..000000000 --- a/backend/build.gradle +++ /dev/null @@ -1,40 +0,0 @@ -plugins { - id 'java' - id 'org.springframework.boot' version '2.7.13' - id 'io.spring.dependency-management' version '1.0.15.RELEASE' -} - -group = 'com.funeat' -version = '0.0.1-SNAPSHOT' - -java { - sourceCompatibility = '11' -} - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-web' - runtimeOnly 'com.mysql:mysql-connector-j' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'io.rest-assured:rest-assured:4.4.0' - testRuntimeOnly 'com.h2database:h2' - - implementation 'org.springdoc:springdoc-openapi-ui:1.7.0' - implementation 'com.github.maricn:logback-slack-appender:1.4.0' - - implementation 'org.springframework.boot:spring-boot-starter-actuator' - runtimeOnly 'io.micrometer:micrometer-registry-prometheus' - - implementation 'com.amazonaws:aws-java-sdk-s3:1.12.547' - - implementation 'org.springframework.session:spring-session-jdbc' -} - -tasks.named('test') { - useJUnitPlatform() -} diff --git a/backend/gradle/wrapper/gradle-wrapper.jar b/backend/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index c1962a79e29d3e0ab67b14947c167a862655af9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62076 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 diff --git a/backend/gradle/wrapper/gradle-wrapper.properties b/backend/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 37aef8d3f..000000000 --- a/backend/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip -networkTimeout=10000 -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/backend/gradlew b/backend/gradlew deleted file mode 100755 index aeb74cbb4..000000000 --- a/backend/gradlew +++ /dev/null @@ -1,245 +0,0 @@ -#!/bin/sh - -# -# Copyright Β© 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions Β«$varΒ», Β«${var}Β», Β«${var:-default}Β», Β«${var+SET}Β», -# Β«${var#prefix}Β», Β«${var%suffix}Β», and Β«$( cmd )Β»; -# * compound commands having a testable exit status, especially Β«caseΒ»; -# * various built-in commands including Β«commandΒ», Β«setΒ», and Β«ulimitΒ». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/backend/gradlew.bat b/backend/gradlew.bat deleted file mode 100644 index 93e3f59f1..000000000 --- a/backend/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/backend/settings.gradle b/backend/settings.gradle deleted file mode 100644 index 7f580408d..000000000 --- a/backend/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'funeat' diff --git a/backend/src/main/java/com/funeat/FuneatApplication.java b/backend/src/main/java/com/funeat/FuneatApplication.java deleted file mode 100644 index 34909202c..000000000 --- a/backend/src/main/java/com/funeat/FuneatApplication.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.funeat; - -import com.funeat.common.repository.BaseRepositoryImpl; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; - -@EnableAsync -@SpringBootApplication -@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class) -public class FuneatApplication { - - public static void main(String[] args) { - SpringApplication.run(FuneatApplication.class, args); - } -} diff --git a/backend/src/main/java/com/funeat/admin/application/AdminChecker.java b/backend/src/main/java/com/funeat/admin/application/AdminChecker.java deleted file mode 100644 index 39045ce22..000000000 --- a/backend/src/main/java/com/funeat/admin/application/AdminChecker.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.funeat.admin.application; - -import com.funeat.admin.domain.AdminAuthInfo; -import com.funeat.auth.exception.AuthErrorCode; -import com.funeat.auth.exception.AuthException.NotLoggedInException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@Component -public class AdminChecker { - - @Value("${back-office.id}") - private String id; - - @Value("${back-office.key}") - private String key; - - public boolean check(final AdminAuthInfo adminAuthInfo) { - if (!id.equals(adminAuthInfo.getId())) { - throw new NotLoggedInException(AuthErrorCode.LOGIN_ADMIN_NOT_FOUND); - } - - if (!key.equals(adminAuthInfo.getKey())) { - throw new NotLoggedInException(AuthErrorCode.LOGIN_ADMIN_NOT_FOUND); - } - - return true; - } -} diff --git a/backend/src/main/java/com/funeat/admin/application/AdminService.java b/backend/src/main/java/com/funeat/admin/application/AdminService.java deleted file mode 100644 index 3c97c3c1b..000000000 --- a/backend/src/main/java/com/funeat/admin/application/AdminService.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.funeat.admin.application; - -import static com.funeat.product.exception.CategoryErrorCode.CATEGORY_NOT_FOUND; -import static com.funeat.product.exception.ProductErrorCode.PRODUCT_NOT_FOUND; - -import com.funeat.admin.dto.AdminProductResponse; -import com.funeat.admin.dto.AdminProductSearchResponse; -import com.funeat.admin.dto.AdminReviewResponse; -import com.funeat.admin.dto.AdminReviewSearchResponse; -import com.funeat.admin.dto.ProductCreateRequest; -import com.funeat.admin.dto.ProductSearchCondition; -import com.funeat.admin.dto.ProductUpdateRequest; -import com.funeat.admin.dto.ReviewSearchCondition; -import com.funeat.admin.repository.AdminProductRepository; -import com.funeat.admin.repository.AdminReviewRepository; -import com.funeat.admin.specification.AdminProductSpecification; -import com.funeat.admin.specification.AdminReviewSpecification; -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import com.funeat.product.dto.CategoryResponse; -import com.funeat.product.exception.CategoryException.CategoryNotFoundException; -import com.funeat.product.exception.ProductException.ProductNotFoundException; -import com.funeat.product.persistence.CategoryRepository; -import com.funeat.product.persistence.ProductRepository; -import com.funeat.review.domain.Review; -import java.util.List; -import java.util.stream.Collectors; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -public class AdminService { - - private static final int DEFAULT_PAGE_SIZE = 10; - - private final ProductRepository productRepository; - private final AdminProductRepository adminProductRepository; - private final CategoryRepository categoryRepository; - private final AdminReviewRepository adminReviewRepository; - - public AdminService(final ProductRepository productRepository, final AdminProductRepository adminProductRepository, - final CategoryRepository categoryRepository, final AdminReviewRepository adminReviewRepository) { - this.productRepository = productRepository; - this.adminProductRepository = adminProductRepository; - this.categoryRepository = categoryRepository; - this.adminReviewRepository = adminReviewRepository; - } - - @Transactional - public Long addProduct(final ProductCreateRequest request) { - final Category findCategory = categoryRepository.findById(request.getCategoryId()) - .orElseThrow(() -> new CategoryNotFoundException(CATEGORY_NOT_FOUND, request.getCategoryId())); - - final Product product = Product.create(request.getName(), request.getPrice(), request.getContent(), - findCategory); - - return productRepository.save(product).getId(); - } - - public List getAllCategories() { - final List findCategories = categoryRepository.findAll(); - - return findCategories.stream() - .map(CategoryResponse::toResponse) - .collect(Collectors.toList()); - } - - public AdminProductSearchResponse getSearchProducts(final ProductSearchCondition condition, - final Pageable pageable) { - final Specification specification = AdminProductSpecification.searchBy(condition); - - final Page findProducts = adminProductRepository.findAllForPagination(specification, pageable, - condition.getTotalElements()); - - final List productResponses = findProducts.stream() - .map(AdminProductResponse::toResponse) - .collect(Collectors.toList()); - - final Boolean isLastPage = isLastPage(findProducts, condition.getPrePage()); - - return new AdminProductSearchResponse(productResponses, findProducts.getTotalElements(), isLastPage); - } - - private boolean isLastPage(final Page findProducts, Long prePage) { - return prePage * DEFAULT_PAGE_SIZE + findProducts.getContent().size() == findProducts.getTotalElements(); - } - - @Transactional - public void updateProduct(final Long productId, final ProductUpdateRequest request) { - final Product findProduct = productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId)); - - final Category findCategory = categoryRepository.findById(request.getCategoryId()) - .orElseThrow(() -> new CategoryNotFoundException(CATEGORY_NOT_FOUND, request.getCategoryId())); - - findProduct.update(request.getName(), request.getContent(), request.getPrice(), findCategory); - } - - public AdminReviewSearchResponse getSearchReviews(final ReviewSearchCondition condition, final Pageable pageable) { - final Specification specification = AdminReviewSpecification.searchBy(condition); - - final Page findReviews = adminReviewRepository.findAllForPagination(specification, pageable, - condition.getTotalElements()); - - final List reviewResponses = findReviews.stream() - .map(AdminReviewResponse::toResponse) - .collect(Collectors.toList()); - - final Boolean isLastPage = isLastPage(findReviews, condition.getPrePage()); - - return new AdminReviewSearchResponse(reviewResponses, findReviews.getTotalElements(), isLastPage); - } -} diff --git a/backend/src/main/java/com/funeat/admin/domain/AdminAuthInfo.java b/backend/src/main/java/com/funeat/admin/domain/AdminAuthInfo.java deleted file mode 100644 index 1a1fb23b8..000000000 --- a/backend/src/main/java/com/funeat/admin/domain/AdminAuthInfo.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.funeat.admin.domain; - -public class AdminAuthInfo { - - private final String id; - private final String key; - - public AdminAuthInfo(final String id, final String key) { - this.id = id; - this.key = key; - } - - public String getId() { - return id; - } - - public String getKey() { - return key; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/AdminCategoryResponse.java b/backend/src/main/java/com/funeat/admin/dto/AdminCategoryResponse.java deleted file mode 100644 index 86c47a715..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/AdminCategoryResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.admin.dto; - -import com.funeat.product.domain.Category; - -public class AdminCategoryResponse { - - private final Long id; - private final String name; - private final String image; - - public AdminCategoryResponse(final Long id, final String name, final String image) { - this.id = id; - this.name = name; - this.image = image; - } - - public static AdminCategoryResponse toResponse(final Category category) { - return new AdminCategoryResponse(category.getId(), category.getName(), category.getImage()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getImage() { - return image; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/AdminProductResponse.java b/backend/src/main/java/com/funeat/admin/dto/AdminProductResponse.java deleted file mode 100644 index 0f5d2dac5..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/AdminProductResponse.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.funeat.admin.dto; - -import com.funeat.product.domain.Product; - -public class AdminProductResponse { - - private final Long id; - private final String name; - private final String content; - private final Long price; - private final AdminCategoryResponse categoryResponse; - - private AdminProductResponse(final Long id, final String name, final String content, - final Long price, final AdminCategoryResponse categoryResponse) { - this.id = id; - this.name = name; - this.content = content; - this.price = price; - this.categoryResponse = categoryResponse; - } - - public static AdminProductResponse toResponse(final Product product) { - final AdminCategoryResponse categoryResponse = AdminCategoryResponse.toResponse(product.getCategory()); - - return new AdminProductResponse(product.getId(), product.getName(), product.getContent(), product.getPrice(), - categoryResponse); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getContent() { - return content; - } - - public Long getPrice() { - return price; - } - - public AdminCategoryResponse getCategoryResponse() { - return categoryResponse; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/AdminProductSearchResponse.java b/backend/src/main/java/com/funeat/admin/dto/AdminProductSearchResponse.java deleted file mode 100644 index 0f543344e..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/AdminProductSearchResponse.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.funeat.admin.dto; - -import java.util.List; - -public class AdminProductSearchResponse { - - private final List productResponses; - private final Long totalElements; - private final Boolean isLastPage; - - public AdminProductSearchResponse(final List productResponses, final Long totalElements, - final Boolean isLastPage) { - this.productResponses = productResponses; - this.totalElements = totalElements; - this.isLastPage = isLastPage; - } - - public List getProductResponses() { - return productResponses; - } - - public Long getTotalElements() { - return totalElements; - } - - public Boolean isLastPage() { - return isLastPage; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/AdminReviewResponse.java b/backend/src/main/java/com/funeat/admin/dto/AdminReviewResponse.java deleted file mode 100644 index d9f4bddcf..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/AdminReviewResponse.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.funeat.admin.dto; - -import com.funeat.review.domain.Review; -import java.time.LocalDateTime; - -public class AdminReviewResponse { - - private final Long id; - private final String userName; - private final String content; - private final String image; - private final String productName; - private final LocalDateTime createdAt; - - private AdminReviewResponse(final Long id, final String userName, final String content, - final String image, final String productName, - final LocalDateTime createdAt) { - this.id = id; - this.userName = userName; - this.content = content; - this.image = image; - this.productName = productName; - this.createdAt = createdAt; - } - - public static AdminReviewResponse toResponse(final Review review) { - return new AdminReviewResponse(review.getId(), review.getMember().getNickname(), review.getContent(), - review.getImage(), review.getProduct().getName(), review.getCreatedAt()); - } - - public Long getId() { - return id; - } - - public String getUserName() { - return userName; - } - - public String getContent() { - return content; - } - - public String getImage() { - return image; - } - - public String getProductName() { - return productName; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/AdminReviewSearchResponse.java b/backend/src/main/java/com/funeat/admin/dto/AdminReviewSearchResponse.java deleted file mode 100644 index 1b5c0c12b..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/AdminReviewSearchResponse.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.funeat.admin.dto; - -import java.util.List; - -public class AdminReviewSearchResponse { - - private final List reviewResponses; - private final Long totalElements; - private final Boolean isLastPage; - - public AdminReviewSearchResponse(final List reviewResponses, final Long totalElements, - final Boolean isLastPage) { - this.reviewResponses = reviewResponses; - this.totalElements = totalElements; - this.isLastPage = isLastPage; - } - - public List getReviewResponses() { - return reviewResponses; - } - - public Long getTotalElements() { - return totalElements; - } - - public Boolean getLastPage() { - return isLastPage; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/ProductCreateRequest.java b/backend/src/main/java/com/funeat/admin/dto/ProductCreateRequest.java deleted file mode 100644 index dd835efa3..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/ProductCreateRequest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.admin.dto; - -public class ProductCreateRequest { - - private final String name; - private final Long price; - private final String content; - private final Long categoryId; - - public ProductCreateRequest(final String name, final Long price, final String content, final Long categoryId) { - this.name = name; - this.price = price; - this.content = content; - this.categoryId = categoryId; - } - - public String getName() { - return name; - } - - public Long getPrice() { - return price; - } - - public String getContent() { - return content; - } - - public Long getCategoryId() { - return categoryId; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/ProductSearchCondition.java b/backend/src/main/java/com/funeat/admin/dto/ProductSearchCondition.java deleted file mode 100644 index 6114176c2..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/ProductSearchCondition.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.funeat.admin.dto; - -public class ProductSearchCondition { - - private final String name; - private final Long id; - private final Long categoryId; - private final Long totalElements; - private final Long prePage; - - public ProductSearchCondition(final String name, final Long id, final Long categoryId, - final Long totalElements, final Long prePage) { - this.name = name; - this.id = id; - this.categoryId = categoryId; - this.totalElements = totalElements; - this.prePage = prePage; - } - - public String getName() { - return name; - } - - public Long getId() { - return id; - } - - public Long getCategoryId() { - return categoryId; - } - - public Long getTotalElements() { - return totalElements; - } - - public Long getPrePage() { - return prePage; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/ProductUpdateRequest.java b/backend/src/main/java/com/funeat/admin/dto/ProductUpdateRequest.java deleted file mode 100644 index 31d639be4..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/ProductUpdateRequest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.admin.dto; - -public class ProductUpdateRequest { - - private final String name; - private final Long price; - private final String content; - private final Long categoryId; - - public ProductUpdateRequest(final String name, final Long price, final String content, final Long categoryId) { - this.name = name; - this.price = price; - this.content = content; - this.categoryId = categoryId; - } - - public String getName() { - return name; - } - - public Long getPrice() { - return price; - } - - public String getContent() { - return content; - } - - public Long getCategoryId() { - return categoryId; - } -} diff --git a/backend/src/main/java/com/funeat/admin/dto/ReviewSearchCondition.java b/backend/src/main/java/com/funeat/admin/dto/ReviewSearchCondition.java deleted file mode 100644 index 02ce7e902..000000000 --- a/backend/src/main/java/com/funeat/admin/dto/ReviewSearchCondition.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.funeat.admin.dto; - -import java.time.LocalDateTime; -import org.springframework.format.annotation.DateTimeFormat; - -public class ReviewSearchCondition { - - private final Long productId; - - @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private final LocalDateTime from; - - @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private final LocalDateTime to; - - private final Long id; - private final Long totalElements; - private final Long prePage; - - public ReviewSearchCondition(final Long productId, final LocalDateTime from, final LocalDateTime to, - final Long id, final Long totalElements, final Long prePage) { - this.productId = productId; - this.from = from; - this.to = to; - this.id = id; - this.totalElements = totalElements; - this.prePage = prePage; - } - - public Long getProductId() { - return productId; - } - - public LocalDateTime getFrom() { - return from; - } - - public LocalDateTime getTo() { - return to; - } - - public Long getId() { - return id; - } - - public Long getTotalElements() { - return totalElements; - } - - public Long getPrePage() { - return prePage; - } -} diff --git a/backend/src/main/java/com/funeat/admin/presentation/AdminController.java b/backend/src/main/java/com/funeat/admin/presentation/AdminController.java deleted file mode 100644 index 6b22890b3..000000000 --- a/backend/src/main/java/com/funeat/admin/presentation/AdminController.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.funeat.admin.presentation; - -import com.funeat.admin.application.AdminService; -import com.funeat.admin.dto.AdminProductSearchResponse; -import com.funeat.admin.dto.AdminReviewSearchResponse; -import com.funeat.admin.dto.ProductCreateRequest; -import com.funeat.admin.dto.ProductSearchCondition; -import com.funeat.admin.dto.ProductUpdateRequest; -import com.funeat.admin.dto.ReviewSearchCondition; -import com.funeat.product.dto.CategoryResponse; -import java.net.URI; -import java.util.List; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/admin") -public class AdminController { - - private final AdminService adminService; - - public AdminController(final AdminService adminService) { - this.adminService = adminService; - } - - @PostMapping("/products") - public ResponseEntity addProduct(@RequestBody final ProductCreateRequest request) { - final Long productId = adminService.addProduct(request); - - return ResponseEntity.created(URI.create("/api/products/" + productId)).build(); - } - - @GetMapping("/products") - public ResponseEntity getSearchProducts( - @ModelAttribute final ProductSearchCondition condition, - @PageableDefault final Pageable pageable) { - final AdminProductSearchResponse response = adminService.getSearchProducts(condition, pageable); - return ResponseEntity.ok(response); - } - - @PutMapping("/products/{productId}") - public ResponseEntity updateProduct(@PathVariable final Long productId, - @RequestBody final ProductUpdateRequest request) { - adminService.updateProduct(productId, request); - return ResponseEntity.noContent().build(); - } - - @GetMapping("/categories") - public ResponseEntity> getAllCategories() { - final List responses = adminService.getAllCategories(); - return ResponseEntity.ok(responses); - } - - @GetMapping("/reviews") - public ResponseEntity getSearchReviews( - @ModelAttribute final ReviewSearchCondition condition, - @PageableDefault final Pageable pageable) { - final AdminReviewSearchResponse responses = adminService.getSearchReviews(condition, pageable); - return ResponseEntity.ok(responses); - } -} diff --git a/backend/src/main/java/com/funeat/admin/presentation/AdminLoginController.java b/backend/src/main/java/com/funeat/admin/presentation/AdminLoginController.java deleted file mode 100644 index d23125a85..000000000 --- a/backend/src/main/java/com/funeat/admin/presentation/AdminLoginController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.funeat.admin.presentation; - -import com.funeat.admin.application.AdminChecker; -import com.funeat.admin.domain.AdminAuthInfo; -import javax.servlet.http.HttpServletRequest; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/admin") -public class AdminLoginController { - - private final AdminChecker adminChecker; - - public AdminLoginController(final AdminChecker adminChecker) { - this.adminChecker = adminChecker; - } - - @PostMapping("/login") - public ResponseEntity login(@RequestBody final AdminAuthInfo adminAuthInfo, - final HttpServletRequest request) { - adminChecker.check(adminAuthInfo); - - request.getSession().setAttribute("authId", adminAuthInfo.getId()); - request.getSession().setAttribute("authKey", adminAuthInfo.getKey()); - - return ResponseEntity.noContent().build(); - } - - @GetMapping("/logged-check") - public ResponseEntity validLoggedInAdmin() { - return ResponseEntity.ok(true); - } -} diff --git a/backend/src/main/java/com/funeat/admin/repository/AdminProductRepository.java b/backend/src/main/java/com/funeat/admin/repository/AdminProductRepository.java deleted file mode 100644 index 6dddc02a2..000000000 --- a/backend/src/main/java/com/funeat/admin/repository/AdminProductRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.funeat.admin.repository; - -import com.funeat.common.repository.BaseRepository; -import com.funeat.product.domain.Product; - -public interface AdminProductRepository extends BaseRepository { -} diff --git a/backend/src/main/java/com/funeat/admin/repository/AdminReviewRepository.java b/backend/src/main/java/com/funeat/admin/repository/AdminReviewRepository.java deleted file mode 100644 index 5da483f2e..000000000 --- a/backend/src/main/java/com/funeat/admin/repository/AdminReviewRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.funeat.admin.repository; - -import com.funeat.common.repository.BaseRepository; -import com.funeat.review.domain.Review; - -public interface AdminReviewRepository extends BaseRepository { -} diff --git a/backend/src/main/java/com/funeat/admin/specification/AdminProductSpecification.java b/backend/src/main/java/com/funeat/admin/specification/AdminProductSpecification.java deleted file mode 100644 index c48ea0305..000000000 --- a/backend/src/main/java/com/funeat/admin/specification/AdminProductSpecification.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.funeat.admin.specification; - -import com.funeat.admin.dto.ProductSearchCondition; -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import java.util.List; -import java.util.Objects; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Path; -import org.springframework.data.jpa.domain.Specification; - -public class AdminProductSpecification { - - private static final List> COUNT_RESULT_TYPES = List.of(Long.class, long.class); - - private AdminProductSpecification() { - } - - public static Specification searchBy(final ProductSearchCondition condition) { - return (root, query, criteriaBuilder) -> { - if (!COUNT_RESULT_TYPES.contains(query.getResultType())) { - root.fetch("category", JoinType.LEFT); - } - - criteriaBuilder.desc(root.get("id")); - - return Specification - .where(like(condition.getName())) - .and(lessThan(condition.getId())) - .and(sameCategory(condition.getCategoryId())) - .toPredicate(root, query, criteriaBuilder); - }; - } - - private static Specification like(final String productName) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(productName)) { - return null; - } - - final Path namePath = root.get("name"); - - return criteriaBuilder.like(namePath, "%" + productName + "%"); - }; - } - - private static Specification lessThan(final Long productId) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(productId)) { - return null; - } - - final Path productIdPath = root.get("id"); - - return criteriaBuilder.lessThan(productIdPath, productId); - }; - } - - private static Specification sameCategory(final Long categoryId) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(categoryId)) { - return null; - } - - final Path categoryPath = root.get("category"); - - return criteriaBuilder.equal(categoryPath, categoryId); - }; - } -} diff --git a/backend/src/main/java/com/funeat/admin/specification/AdminReviewSpecification.java b/backend/src/main/java/com/funeat/admin/specification/AdminReviewSpecification.java deleted file mode 100644 index 045147de5..000000000 --- a/backend/src/main/java/com/funeat/admin/specification/AdminReviewSpecification.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.funeat.admin.specification; - -import com.funeat.admin.dto.ReviewSearchCondition; -import com.funeat.product.domain.Product; -import com.funeat.review.domain.Review; -import java.time.LocalDateTime; -import java.util.Objects; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Path; -import org.springframework.data.jpa.domain.Specification; - -public class AdminReviewSpecification { - - private AdminReviewSpecification() { - } - - public static Specification searchBy(final ReviewSearchCondition condition) { - return (root, query, criteriaBuilder) -> { - if (query.getResultType() != Long.class && query.getResultType() != long.class) { - root.fetch("member", JoinType.LEFT); - root.fetch("product", JoinType.LEFT); - } - - criteriaBuilder.desc(root.get("id")); - - return Specification - .where(to(condition.getTo())) - .and(from(condition.getFrom())) - .and(sameProduct(condition.getProductId())) - .and(lessThan(condition.getId())) - .toPredicate(root, query, criteriaBuilder); - }; - } - - private static Specification to(final LocalDateTime to) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(to)) { - return null; - } - - final Path toPath = root.get("createdAt"); - - return criteriaBuilder.lessThanOrEqualTo(toPath, to); - }; - } - - private static Specification from(final LocalDateTime from) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(from)) { - return null; - } - - final Path fromPath = root.get("createdAt"); - - return criteriaBuilder.greaterThanOrEqualTo(fromPath, from); - }; - } - - private static Specification sameProduct(final Long productId) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(productId)) { - return null; - } - - final Path productPath = root.get("product"); - - return criteriaBuilder.equal(productPath, productId); - }; - } - - private static Specification lessThan(final Long reviewId) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(reviewId)) { - return null; - } - - final Path reviewIdPath = root.get("id"); - - return criteriaBuilder.lessThan(reviewIdPath, reviewId); - }; - } -} diff --git a/backend/src/main/java/com/funeat/admin/util/AdminCheckInterceptor.java b/backend/src/main/java/com/funeat/admin/util/AdminCheckInterceptor.java deleted file mode 100644 index 59ef45b49..000000000 --- a/backend/src/main/java/com/funeat/admin/util/AdminCheckInterceptor.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.funeat.admin.util; - -import static com.funeat.auth.exception.AuthErrorCode.LOGIN_ADMIN_NOT_FOUND; - -import com.funeat.admin.application.AdminChecker; -import com.funeat.admin.domain.AdminAuthInfo; -import com.funeat.auth.exception.AuthException.NotLoggedInException; -import java.util.Objects; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@Component -public class AdminCheckInterceptor implements HandlerInterceptor { - - private final AdminChecker adminChecker; - - public AdminCheckInterceptor(final AdminChecker adminChecker) { - this.adminChecker = adminChecker; - } - - @Override - public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, - final Object handler) { - final HttpSession session = request.getSession(false); - - if (Objects.isNull(session)) { - throw new NotLoggedInException(LOGIN_ADMIN_NOT_FOUND); - } - - final String authId = String.valueOf(session.getAttribute("authId")); - final String authKey = String.valueOf(session.getAttribute("authKey")); - - if (Objects.isNull(authId) || Objects.isNull(authKey)) { - throw new NotLoggedInException(LOGIN_ADMIN_NOT_FOUND); - } - - return adminChecker.check(new AdminAuthInfo(authId, authKey)); - } -} diff --git a/backend/src/main/java/com/funeat/auth/application/AuthService.java b/backend/src/main/java/com/funeat/auth/application/AuthService.java deleted file mode 100644 index 20a24345c..000000000 --- a/backend/src/main/java/com/funeat/auth/application/AuthService.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.funeat.auth.application; - -import com.funeat.auth.dto.SignUserDto; -import com.funeat.auth.dto.UserInfoDto; -import com.funeat.auth.util.PlatformUserProvider; -import com.funeat.member.application.MemberService; -import javax.servlet.http.Cookie; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -public class AuthService { - - private static final String COOKIE_NAME = "SESSION"; - - private final MemberService memberService; - private final PlatformUserProvider platformUserProvider; - - public AuthService(final MemberService memberService, final PlatformUserProvider platformUserProvider) { - this.memberService = memberService; - this.platformUserProvider = platformUserProvider; - } - - public SignUserDto loginWithKakao(final String code) { - final UserInfoDto userInfoDto = platformUserProvider.getPlatformUser(code); - return memberService.findOrCreateMember(userInfoDto); - } - - public String getLoginRedirectUri() { - return platformUserProvider.getRedirectURI(); - } - - public void logoutWithKakao(final Long memberId) { - final String platformId = memberService.findPlatformId(memberId); - platformUserProvider.logout(platformId); - } - - public Cookie expireCookie() { - final Cookie cookie = new Cookie(COOKIE_NAME, null); - cookie.setMaxAge(0); - cookie.setPath("/"); - - return cookie; - } -} diff --git a/backend/src/main/java/com/funeat/auth/dto/KakaoTokenDto.java b/backend/src/main/java/com/funeat/auth/dto/KakaoTokenDto.java deleted file mode 100644 index 6b4f0995e..000000000 --- a/backend/src/main/java/com/funeat/auth/dto/KakaoTokenDto.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.funeat.auth.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class KakaoTokenDto { - - private final String accessToken; - private final String tokenType; - private final String refreshToken; - private final String expiresIn; - private final String scope; - private final String refreshTokenExpiresIn; - - @JsonCreator - public KakaoTokenDto(@JsonProperty("access_token") final String accessToken, - @JsonProperty("token_type") final String tokenType, - @JsonProperty("refresh_token") final String refreshToken, - @JsonProperty("expires_in") final String expiresIn, - @JsonProperty("scope") final String scope, - @JsonProperty("refresh_token_expires_in") final String refreshTokenExpiresIn) { - this.accessToken = accessToken; - this.tokenType = tokenType; - this.refreshToken = refreshToken; - this.expiresIn = expiresIn; - this.scope = scope; - this.refreshTokenExpiresIn = refreshTokenExpiresIn; - } - - public String getAccessToken() { - return accessToken; - } - - public String getTokenType() { - return tokenType; - } - - public String getRefreshToken() { - return refreshToken; - } - - public String getExpiresIn() { - return expiresIn; - } - - public String getScope() { - return scope; - } - - public String getRefreshTokenExpiresIn() { - return refreshTokenExpiresIn; - } -} diff --git a/backend/src/main/java/com/funeat/auth/dto/KakaoUserInfoDto.java b/backend/src/main/java/com/funeat/auth/dto/KakaoUserInfoDto.java deleted file mode 100644 index 8b9424045..000000000 --- a/backend/src/main/java/com/funeat/auth/dto/KakaoUserInfoDto.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.funeat.auth.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class KakaoUserInfoDto { - - private final Long id; - private final KakaoAccount kakaoAccount; - - @JsonCreator - public KakaoUserInfoDto(@JsonProperty("id") final Long id, - @JsonProperty("kakao_account") final KakaoAccount kakaoAccount) { - this.id = id; - this.kakaoAccount = kakaoAccount; - } - - public Long getId() { - return id; - } - - public KakaoAccount getKakaoAccount() { - return kakaoAccount; - } - - public static class KakaoAccount { - - private final KakaoProfile profile; - - @JsonCreator - public KakaoAccount(@JsonProperty("profile") final KakaoProfile profile) { - this.profile = profile; - } - - public KakaoProfile getProfile() { - return profile; - } - } - - public static class KakaoProfile { - - private final String nickname; - private final String profileImageUrl; - - @JsonCreator - public KakaoProfile( - @JsonProperty("nickname") final String nickname, - @JsonProperty("profile_image_url") final String profileImageUrl) { - this.nickname = nickname; - this.profileImageUrl = profileImageUrl; - } - - public String getNickname() { - return nickname; - } - - public String getProfileImageUrl() { - return profileImageUrl; - } - } -} diff --git a/backend/src/main/java/com/funeat/auth/dto/LoginInfo.java b/backend/src/main/java/com/funeat/auth/dto/LoginInfo.java deleted file mode 100644 index 2987c111a..000000000 --- a/backend/src/main/java/com/funeat/auth/dto/LoginInfo.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.funeat.auth.dto; - -public class LoginInfo { - - private final Long id; - - public LoginInfo(final Long id) { - this.id = id; - } - - public Long getId() { - return id; - } -} diff --git a/backend/src/main/java/com/funeat/auth/dto/SignUserDto.java b/backend/src/main/java/com/funeat/auth/dto/SignUserDto.java deleted file mode 100644 index 2e910ee77..000000000 --- a/backend/src/main/java/com/funeat/auth/dto/SignUserDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.auth.dto; - -import com.funeat.member.domain.Member; - -public class SignUserDto { - - private final boolean isSignUp; - private final Member member; - - public SignUserDto(final boolean isSignUp, final Member member) { - this.isSignUp = isSignUp; - this.member = member; - } - - public static SignUserDto of(final boolean isSignUp, final Member member) { - return new SignUserDto(isSignUp, member); - } - - public boolean isSignUp() { - return isSignUp; - } - - public Member getMember() { - return member; - } -} diff --git a/backend/src/main/java/com/funeat/auth/dto/TokenResponse.java b/backend/src/main/java/com/funeat/auth/dto/TokenResponse.java deleted file mode 100644 index 842cea22b..000000000 --- a/backend/src/main/java/com/funeat/auth/dto/TokenResponse.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.funeat.auth.dto; - -public class TokenResponse { - - private String accessToken; - - public TokenResponse(final String accessToken) { - this.accessToken = accessToken; - } - - public String getAccessToken() { - return accessToken; - } -} diff --git a/backend/src/main/java/com/funeat/auth/dto/UserInfoDto.java b/backend/src/main/java/com/funeat/auth/dto/UserInfoDto.java deleted file mode 100644 index 3861eac64..000000000 --- a/backend/src/main/java/com/funeat/auth/dto/UserInfoDto.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.funeat.auth.dto; - -import com.funeat.member.domain.Member; - -public class UserInfoDto { - - private final Long id; - private final String nickname; - private final String profileImageUrl; - - public UserInfoDto(final Long id, final String nickname, final String profileImageUrl) { - this.id = id; - this.nickname = nickname; - this.profileImageUrl = profileImageUrl; - } - - public static UserInfoDto from(final KakaoUserInfoDto kakaoUserInfoDto) { - return new UserInfoDto( - kakaoUserInfoDto.getId(), - kakaoUserInfoDto.getKakaoAccount().getProfile().getNickname(), - kakaoUserInfoDto.getKakaoAccount().getProfile().getProfileImageUrl() - ); - } - - public Member toMember() { - return new Member(this.nickname, this.profileImageUrl, this.id.toString()); - } - - public Long getId() { - return id; - } - - public String getNickname() { - return nickname; - } - - public String getProfileImageUrl() { - return profileImageUrl; - } -} diff --git a/backend/src/main/java/com/funeat/auth/exception/AuthErrorCode.java b/backend/src/main/java/com/funeat/auth/exception/AuthErrorCode.java deleted file mode 100644 index e47350078..000000000 --- a/backend/src/main/java/com/funeat/auth/exception/AuthErrorCode.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.auth.exception; - -import org.springframework.http.HttpStatus; - -public enum AuthErrorCode { - - LOGIN_MEMBER_NOT_FOUND(HttpStatus.UNAUTHORIZED, "둜그인 ν•˜μ§€ μ•Šμ€ νšŒμ›μž…λ‹ˆλ‹€. λ‘œκ·ΈμΈμ„ ν•΄μ£Όμ„Έμš”.", "6001"), - LOGIN_ADMIN_NOT_FOUND(HttpStatus.UNAUTHORIZED, "둜그인 ν•˜μ§€ μ•Šμ€ κ΄€λ¦¬μžμž…λ‹ˆλ‹€. λ‘œκ·ΈμΈμ„ ν•΄μ£Όμ„Έμš”.", "6002"), - ; - - private final HttpStatus status; - private final String message; - private final String code; - - AuthErrorCode(final HttpStatus status, final String message, final String code) { - this.status = status; - this.message = message; - this.code = code; - } - - public HttpStatus getStatus() { - return status; - } - - public String getMessage() { - return message; - } - - public String getCode() { - return code; - } -} diff --git a/backend/src/main/java/com/funeat/auth/exception/AuthException.java b/backend/src/main/java/com/funeat/auth/exception/AuthException.java deleted file mode 100644 index c8ee3ef92..000000000 --- a/backend/src/main/java/com/funeat/auth/exception/AuthException.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.funeat.auth.exception; - -import com.funeat.exception.ErrorCode; -import com.funeat.exception.GlobalException; -import org.springframework.http.HttpStatus; - -public class AuthException extends GlobalException { - - public AuthException(final HttpStatus status, final ErrorCode errorCode) { - super(status, errorCode); - } - - public static class NotLoggedInException extends AuthException { - public NotLoggedInException(final AuthErrorCode errorCode) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage())); - } - } -} diff --git a/backend/src/main/java/com/funeat/auth/presentation/AuthApiController.java b/backend/src/main/java/com/funeat/auth/presentation/AuthApiController.java deleted file mode 100644 index f7931460c..000000000 --- a/backend/src/main/java/com/funeat/auth/presentation/AuthApiController.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.funeat.auth.presentation; - -import com.funeat.auth.application.AuthService; -import com.funeat.auth.dto.LoginInfo; -import com.funeat.auth.dto.SignUserDto; -import com.funeat.auth.util.AuthenticationPrincipal; -import java.net.URI; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class AuthApiController implements AuthController { - - private static final String SESSION_ATTRIBUTE_NAME = "member"; - private static final String HOME = "/"; - private static final String MY_PAGE = "/members"; - - private final AuthService authService; - - public AuthApiController(final AuthService authService) { - this.authService = authService; - } - - @GetMapping("/api/auth/kakao") - public ResponseEntity kakaoLogin() { - return ResponseEntity.status(HttpStatus.FOUND) - .location(URI.create(authService.getLoginRedirectUri())) - .build(); - } - - @GetMapping("/api/login/oauth2/code/kakao") - public ResponseEntity loginAuthorizeUser(@RequestParam("code") final String code, - final HttpServletRequest request) { - final SignUserDto signUserDto = authService.loginWithKakao(code); - final Long memberId = signUserDto.getMember().getId(); - request.getSession().setAttribute(SESSION_ATTRIBUTE_NAME, memberId); - - if (signUserDto.isSignUp()) { - return ResponseEntity.ok() - .location(URI.create(MY_PAGE)) - .build(); - } - return ResponseEntity.ok() - .location(URI.create(HOME)) - .build(); - } - - @PostMapping("/api/logout") - public ResponseEntity logout(@AuthenticationPrincipal final LoginInfo loginInfo, - final HttpServletRequest request, final HttpServletResponse response) { - authService.logoutWithKakao(loginInfo.getId()); - - request.getSession().removeAttribute(SESSION_ATTRIBUTE_NAME); - - final Cookie cookie = authService.expireCookie(); - response.addCookie(cookie); - - return ResponseEntity.status(HttpStatus.FOUND) - .location(URI.create(HOME)) - .build(); - } -} diff --git a/backend/src/main/java/com/funeat/auth/presentation/AuthController.java b/backend/src/main/java/com/funeat/auth/presentation/AuthController.java deleted file mode 100644 index db05a7f8b..000000000 --- a/backend/src/main/java/com/funeat/auth/presentation/AuthController.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.funeat.auth.presentation; - -import com.funeat.auth.dto.LoginInfo; -import com.funeat.auth.util.AuthenticationPrincipal; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; - -@Tag(name = "06.Login", description = "둜그인 κ΄€λ ¨ API μž…λ‹ˆλ‹€.") -public interface AuthController { - - @Operation(summary = "카카였 둜그인", description = "카카였 λ‘œκ·ΈμΈμ„ ν•œλ‹€") - @ApiResponse( - responseCode = "302", - description = "둜그인이 μ„±κ³΅ν•˜μ—¬ λ¦¬λ‹€μ΄λ ‰νŠΈν•¨" - ) - @GetMapping - ResponseEntity kakaoLogin(); - - @Operation(summary = "μœ μ € 인증", description = "μœ μ € 인증을 ν•œλ‹€") - @ApiResponse( - responseCode = "302", - description = "κΈ°μ‘΄ νšŒμ›μ΄λ©΄ ν™ˆμœΌλ‘œ 이동, μ‹ κ·œ νšŒμ›μ΄λ©΄ λ§ˆμ΄νŽ˜μ΄μ§€λ‘œ 이동." - ) - @GetMapping - ResponseEntity loginAuthorizeUser(@RequestParam("code") final String code, final HttpServletRequest request); - - @Operation(summary = "λ‘œκ·Έμ•„μ›ƒ", description = "λ‘œκ·Έμ•„μ›ƒμ„ ν•œλ‹€") - @ApiResponse( - responseCode = "302", - description = "λ‘œκ·Έμ•„μ›ƒ 성곡." - ) - @PostMapping - ResponseEntity logout(@AuthenticationPrincipal final LoginInfo loginInfo, final HttpServletRequest request, - final HttpServletResponse response); -} diff --git a/backend/src/main/java/com/funeat/auth/util/AuthArgumentResolver.java b/backend/src/main/java/com/funeat/auth/util/AuthArgumentResolver.java deleted file mode 100644 index e5a3e0e9b..000000000 --- a/backend/src/main/java/com/funeat/auth/util/AuthArgumentResolver.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.funeat.auth.util; - -import com.funeat.auth.dto.LoginInfo; -import java.util.Objects; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import org.springframework.core.MethodParameter; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.method.support.ModelAndViewContainer; - -@Component -public class AuthArgumentResolver implements HandlerMethodArgumentResolver { - - @Override - public boolean supportsParameter(final MethodParameter parameter) { - return parameter.hasParameterAnnotation(AuthenticationPrincipal.class); - } - - @Override - public Object resolveArgument(final MethodParameter parameter, final ModelAndViewContainer mavContainer, - final NativeWebRequest webRequest, final WebDataBinderFactory binderFactory) { - final HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); - final HttpSession session = Objects.requireNonNull(request).getSession(false); - final String id = String.valueOf(session.getAttribute("member")); - - return new LoginInfo(Long.valueOf(id)); - } -} diff --git a/backend/src/main/java/com/funeat/auth/util/AuthHandlerInterceptor.java b/backend/src/main/java/com/funeat/auth/util/AuthHandlerInterceptor.java deleted file mode 100644 index 48339aee9..000000000 --- a/backend/src/main/java/com/funeat/auth/util/AuthHandlerInterceptor.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.auth.util; - -import com.funeat.auth.exception.AuthErrorCode; -import com.funeat.auth.exception.AuthException.NotLoggedInException; -import java.util.Objects; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@Component -public class AuthHandlerInterceptor implements HandlerInterceptor { - - @Override - public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, - final Object handler) { - final HttpSession session = request.getSession(false); - - if (Objects.isNull(session)) { - throw new NotLoggedInException(AuthErrorCode.LOGIN_MEMBER_NOT_FOUND); - } - - return true; - } -} diff --git a/backend/src/main/java/com/funeat/auth/util/AuthenticationPrincipal.java b/backend/src/main/java/com/funeat/auth/util/AuthenticationPrincipal.java deleted file mode 100644 index a7c0b0cdc..000000000 --- a/backend/src/main/java/com/funeat/auth/util/AuthenticationPrincipal.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.funeat.auth.util; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.RUNTIME) -public @interface AuthenticationPrincipal { -} diff --git a/backend/src/main/java/com/funeat/auth/util/KakaoPlatformUserProvider.java b/backend/src/main/java/com/funeat/auth/util/KakaoPlatformUserProvider.java deleted file mode 100644 index c1cc463ca..000000000 --- a/backend/src/main/java/com/funeat/auth/util/KakaoPlatformUserProvider.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.funeat.auth.util; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.funeat.auth.dto.KakaoTokenDto; -import com.funeat.auth.dto.KakaoUserInfoDto; -import com.funeat.auth.dto.UserInfoDto; -import java.util.StringJoiner; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Profile; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.client.RestTemplate; - -@Component -@Profile("!test") -public class KakaoPlatformUserProvider implements PlatformUserProvider { - - private static final String AUTHORIZATION_BASE_URL = "https://kauth.kakao.com"; - private static final String RESOURCE_BASE_URL = "https://kapi.kakao.com"; - private static final String OAUTH_URI = "/oauth/authorize"; - private static final String ACCESS_TOKEN_URI = "/oauth/token"; - private static final String USER_INFO_URI = "/v2/user/me"; - private static final String LOGOUT_URI = "/v1/user/logout"; - private static final String AUTHORIZATION_CODE = "authorization_code"; - - private final RestTemplate restTemplate; - private final ObjectMapper objectMapper; - - @Value("${kakao.rest-api-key}") - private String kakaoRestApiKey; - - @Value("${kakao.redirect-uri}") - private String redirectUri; - - @Value("${kakao.admin-key}") - private String kakaoAdminKey; - - public KakaoPlatformUserProvider(final RestTemplateBuilder restTemplateBuilder, - final ObjectMapper objectMapper) { - this.restTemplate = restTemplateBuilder.build(); - this.objectMapper = objectMapper; - } - - @Override - public UserInfoDto getPlatformUser(final String code) { - final KakaoTokenDto accessTokenDto = findAccessToken(code); - final KakaoUserInfoDto kakaoUserInfoDto = findKakaoUserInfo(accessTokenDto.getAccessToken()); - return UserInfoDto.from(kakaoUserInfoDto); - } - - private KakaoTokenDto findAccessToken(final String code) { - final ResponseEntity response = requestAccessToken(code); - validateResponse(response, HttpStatus.OK); - return convertJsonToKakaoTokenDto(response.getBody()); - } - - private ResponseEntity requestAccessToken(final String code) { - final HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - - final MultiValueMap body = new LinkedMultiValueMap<>(); - body.add("grant_type", AUTHORIZATION_CODE); - body.add("client_id", kakaoRestApiKey); - body.add("redirect_uri", redirectUri); - body.add("code", code); - - final HttpEntity> request = new HttpEntity<>(body, headers); - final ResponseEntity response = restTemplate.postForEntity(AUTHORIZATION_BASE_URL + ACCESS_TOKEN_URI, - request, String.class); - - return response; - } - - private void validateResponse(final ResponseEntity response, final HttpStatus status) { - if (response.getStatusCode() != status) { - throw new IllegalArgumentException(); - } - } - - private KakaoTokenDto convertJsonToKakaoTokenDto(final String responseBody) { - try { - return objectMapper.readValue(responseBody, KakaoTokenDto.class); - } catch (final JsonProcessingException e) { - throw new IllegalArgumentException(); - } - } - - private KakaoUserInfoDto findKakaoUserInfo(final String accessToken) { - final ResponseEntity response = requestKakaoUserInfo(accessToken); - validateResponse(response, HttpStatus.OK); - return convertJsonToKakaoUserDto(response.getBody()); - } - - private ResponseEntity requestKakaoUserInfo(final String accessToken) { - final HttpHeaders headers = new HttpHeaders(); - headers.setBearerAuth(accessToken); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - - final HttpEntity> request = new HttpEntity<>(null, headers); - return restTemplate.postForEntity(RESOURCE_BASE_URL + USER_INFO_URI, request, String.class); - } - - private KakaoUserInfoDto convertJsonToKakaoUserDto(final String responseBody) { - try { - return objectMapper.readValue(responseBody, KakaoUserInfoDto.class); - } catch (final JsonProcessingException e) { - throw new IllegalArgumentException(); - } - } - - @Override - public String getRedirectURI() { - final StringJoiner joiner = new StringJoiner("&") - .add("response_type=code") - .add("client_id=" + kakaoRestApiKey) - .add("redirect_uri=" + redirectUri); - - return AUTHORIZATION_BASE_URL + OAUTH_URI + "?" + joiner; - } - - @Override - public void logout(final String platformId) { - final HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - headers.add("Authorization", "KakaoAK " + kakaoAdminKey); - - final MultiValueMap body = new LinkedMultiValueMap<>(); - body.add("target_id_type", "user_id"); - body.add("target_id", platformId); - - final HttpEntity> request = new HttpEntity<>(body, headers); - restTemplate.postForEntity(RESOURCE_BASE_URL + LOGOUT_URI, request, String.class); - } -} diff --git a/backend/src/main/java/com/funeat/auth/util/PlatformUserProvider.java b/backend/src/main/java/com/funeat/auth/util/PlatformUserProvider.java deleted file mode 100644 index 1913b1570..000000000 --- a/backend/src/main/java/com/funeat/auth/util/PlatformUserProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.funeat.auth.util; - -import com.funeat.auth.dto.UserInfoDto; - -public interface PlatformUserProvider { - - UserInfoDto getPlatformUser(final String code); - - String getRedirectURI(); - - void logout(final String platformId); -} diff --git a/backend/src/main/java/com/funeat/banner/application/BannerService.java b/backend/src/main/java/com/funeat/banner/application/BannerService.java deleted file mode 100644 index 48864670a..000000000 --- a/backend/src/main/java/com/funeat/banner/application/BannerService.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.funeat.banner.application; - -import com.funeat.banner.domain.Banner; -import com.funeat.banner.dto.BannerResponse; -import com.funeat.banner.persistence.BannerRepository; -import java.util.List; -import java.util.stream.Collectors; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -public class BannerService { - - private final BannerRepository bannerRepository; - - public BannerService(final BannerRepository bannerRepository) { - this.bannerRepository = bannerRepository; - } - - public List getAllBanners() { - final List findBanners = bannerRepository.findAllByOrderByIdDesc(); - - return findBanners.stream() - .map(BannerResponse::toResponse) - .collect(Collectors.toList()); - } -} diff --git a/backend/src/main/java/com/funeat/banner/domain/Banner.java b/backend/src/main/java/com/funeat/banner/domain/Banner.java deleted file mode 100644 index 9ea8eabd2..000000000 --- a/backend/src/main/java/com/funeat/banner/domain/Banner.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.funeat.banner.domain; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -@Entity -public class Banner { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String link; - - private String image; - - protected Banner() { - } - - public Banner(final String link, final String image) { - this.link = link; - this.image = image; - } - - public Long getId() { - return id; - } - - public String getLink() { - return link; - } - - public String getImage() { - return image; - } -} diff --git a/backend/src/main/java/com/funeat/banner/dto/BannerResponse.java b/backend/src/main/java/com/funeat/banner/dto/BannerResponse.java deleted file mode 100644 index fcff62c2f..000000000 --- a/backend/src/main/java/com/funeat/banner/dto/BannerResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.banner.dto; - -import com.funeat.banner.domain.Banner; - -public class BannerResponse { - - private final Long id; - private final String link; - private final String image; - - private BannerResponse(final Long id, final String link, final String image) { - this.id = id; - this.link = link; - this.image = image; - } - - public static BannerResponse toResponse(final Banner banner) { - return new BannerResponse(banner.getId(), banner.getLink(), banner.getImage()); - } - - public Long getId() { - return id; - } - - public String getLink() { - return link; - } - - public String getImage() { - return image; - } -} diff --git a/backend/src/main/java/com/funeat/banner/persistence/BannerRepository.java b/backend/src/main/java/com/funeat/banner/persistence/BannerRepository.java deleted file mode 100644 index 30f598755..000000000 --- a/backend/src/main/java/com/funeat/banner/persistence/BannerRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.funeat.banner.persistence; - -import com.funeat.banner.domain.Banner; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface BannerRepository extends JpaRepository { - - List findAllByOrderByIdDesc(); -} diff --git a/backend/src/main/java/com/funeat/banner/presentation/BannerApiController.java b/backend/src/main/java/com/funeat/banner/presentation/BannerApiController.java deleted file mode 100644 index 7465189ab..000000000 --- a/backend/src/main/java/com/funeat/banner/presentation/BannerApiController.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.funeat.banner.presentation; - -import com.funeat.banner.dto.BannerResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import java.util.List; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; - -@Tag(name = "08.Banner", description = "λ°°λ„ˆ κ΄€λ ¨ API μž…λ‹ˆλ‹€.") -public interface BannerApiController { - - @Operation(summary = "λ°°λ„ˆ 전체 쑰회", description = "λ°°λ„ˆ 전체λ₯Ό μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "λ°°λ„ˆ 전체 쑰회 성곡." - ) - @GetMapping - ResponseEntity> getBanners(); -} diff --git a/backend/src/main/java/com/funeat/banner/presentation/BannerController.java b/backend/src/main/java/com/funeat/banner/presentation/BannerController.java deleted file mode 100644 index 164df97cd..000000000 --- a/backend/src/main/java/com/funeat/banner/presentation/BannerController.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.funeat.banner.presentation; - -import com.funeat.banner.application.BannerService; -import com.funeat.banner.dto.BannerResponse; -import java.util.List; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class BannerController implements BannerApiController { - - private final BannerService bannerService; - - public BannerController(final BannerService bannerService) { - this.bannerService = bannerService; - } - - @GetMapping("/api/banners") - public ResponseEntity> getBanners() { - final List responses = bannerService.getAllBanners(); - - return ResponseEntity.ok(responses); - } -} diff --git a/backend/src/main/java/com/funeat/comment/domain/Comment.java b/backend/src/main/java/com/funeat/comment/domain/Comment.java deleted file mode 100644 index 4e6798b9d..000000000 --- a/backend/src/main/java/com/funeat/comment/domain/Comment.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.funeat.comment.domain; - -import com.funeat.member.domain.Member; -import com.funeat.recipe.domain.Recipe; -import java.time.LocalDateTime; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; - -@Entity -public class Comment { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String comment; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "recipe_id") - private Recipe recipe; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - - @Column(nullable = false) - private LocalDateTime createdAt = LocalDateTime.now(); - - protected Comment() { - } - - public Comment(final Recipe recipe, final Member member, final String comment) { - this.recipe = recipe; - this.member = member; - this.comment = comment; - } - - public Long getId() { - return id; - } - - public String getComment() { - return comment; - } - - public Member getMember() { - return member; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/comment/persistence/CommentRepository.java b/backend/src/main/java/com/funeat/comment/persistence/CommentRepository.java deleted file mode 100644 index e40a47f67..000000000 --- a/backend/src/main/java/com/funeat/comment/persistence/CommentRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.funeat.comment.persistence; - -import com.funeat.comment.domain.Comment; -import com.funeat.common.repository.BaseRepository; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface CommentRepository extends JpaRepository, BaseRepository { -} diff --git a/backend/src/main/java/com/funeat/comment/specification/CommentSpecification.java b/backend/src/main/java/com/funeat/comment/specification/CommentSpecification.java deleted file mode 100644 index db6c734bb..000000000 --- a/backend/src/main/java/com/funeat/comment/specification/CommentSpecification.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.funeat.comment.specification; - -import com.funeat.comment.domain.Comment; -import com.funeat.recipe.domain.Recipe; -import java.util.List; -import java.util.Objects; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Path; -import org.springframework.data.jpa.domain.Specification; - -public class CommentSpecification { - - private CommentSpecification() { - } - - private static final List> COUNT_RESULT_TYPES = List.of(Long.class, long.class); - - public static Specification findAllByRecipe(final Recipe recipe, final Long lastCommentId) { - return (root, query, criteriaBuilder) -> { - if (!COUNT_RESULT_TYPES.contains(query.getResultType())) { - root.fetch("member", JoinType.LEFT); - } - - criteriaBuilder.desc(root.get("id")); - - return Specification - .where(lessThan(lastCommentId)) - .and(equalToRecipe(recipe)) - .toPredicate(root, query, criteriaBuilder); - }; - } - - private static Specification lessThan(final Long commentId) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(commentId)) { - return null; - } - - final Path commentIdPath = root.get("id"); - - return criteriaBuilder.lessThan(commentIdPath, commentId); - }; - } - - private static Specification equalToRecipe(final Recipe recipe) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(recipe)) { - return null; - } - - final Path recipePath = root.get("recipe"); - - return criteriaBuilder.equal(recipePath, recipe); - }; - } -} diff --git a/backend/src/main/java/com/funeat/common/CustomPageableHandlerMethodArgumentResolver.java b/backend/src/main/java/com/funeat/common/CustomPageableHandlerMethodArgumentResolver.java deleted file mode 100644 index acb481f97..000000000 --- a/backend/src/main/java/com/funeat/common/CustomPageableHandlerMethodArgumentResolver.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.common; - -import org.springframework.core.MethodParameter; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableHandlerMethodArgumentResolver; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.method.support.ModelAndViewContainer; - -@Component -public class CustomPageableHandlerMethodArgumentResolver extends PageableHandlerMethodArgumentResolver { - - @Override - public Pageable resolveArgument(final MethodParameter methodParameter, final ModelAndViewContainer mavContainer, - final NativeWebRequest webRequest, final WebDataBinderFactory binderFactory) { - final Pageable pageable = super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory); - - final Sort lastPrioritySort = Sort.by("id").descending(); - - return PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), - pageable.getSort().and(lastPrioritySort)); - } -} diff --git a/backend/src/main/java/com/funeat/common/ImageUploader.java b/backend/src/main/java/com/funeat/common/ImageUploader.java deleted file mode 100644 index afd4b5c10..000000000 --- a/backend/src/main/java/com/funeat/common/ImageUploader.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.funeat.common; - -import org.springframework.web.multipart.MultipartFile; - -public interface ImageUploader { - - String upload(final MultipartFile image); - - void delete(final String fileName); -} diff --git a/backend/src/main/java/com/funeat/common/OpenApiConfig.java b/backend/src/main/java/com/funeat/common/OpenApiConfig.java deleted file mode 100644 index 51c42429d..000000000 --- a/backend/src/main/java/com/funeat/common/OpenApiConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.funeat.common; - -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.info.Info; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.context.annotation.Configuration; - -@OpenAPIDefinition( - info = @Info( - title = "νŽ€μž‡ API λͺ…μ„Έμ„œ", - description = "νŽ€μž‡νŒ€ API λͺ…μ„Έμ„œμž…λ‹ˆλ‹€.", - version = "v1" - ), - tags = { - @Tag(name = "01.Product", description = "μƒν’ˆ κΈ°λŠ₯"), - @Tag(name = "02.Category", description = "μΉ΄ν…Œκ³ λ¦¬ κΈ°λŠ₯"), - @Tag(name = "03.Review", description = "리뷰 κΈ°λŠ₯"), - @Tag(name = "04.Tag", description = "νƒœκ·Έ κΈ°λŠ₯"), - @Tag(name = "05.Member", description = "μ‚¬μš©μž κΈ°λŠ₯"), - @Tag(name = "06.Login", description = "둜그인 κΈ°λŠ₯"), - @Tag(name = "07.Recipe", description = "κΏ€μ‘°ν•© κΈ°λŠ₯"), - @Tag(name = "08.Banner", description = "λ°°λ„ˆ κΈ°λŠ₯"), - } -) -@Configuration -public class OpenApiConfig { -} diff --git a/backend/src/main/java/com/funeat/common/StringToCategoryTypeConverter.java b/backend/src/main/java/com/funeat/common/StringToCategoryTypeConverter.java deleted file mode 100644 index 8873f0a7b..000000000 --- a/backend/src/main/java/com/funeat/common/StringToCategoryTypeConverter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.funeat.common; - -import com.funeat.product.domain.CategoryType; -import org.springframework.core.convert.converter.Converter; - -public class StringToCategoryTypeConverter implements Converter { - - @Override - public CategoryType convert(final String source) { - return CategoryType.findCategoryType(source); - } -} diff --git a/backend/src/main/java/com/funeat/common/WebConfig.java b/backend/src/main/java/com/funeat/common/WebConfig.java deleted file mode 100644 index c6a0b0e7a..000000000 --- a/backend/src/main/java/com/funeat/common/WebConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.funeat.common; - -import com.funeat.admin.util.AdminCheckInterceptor; -import com.funeat.auth.util.AuthArgumentResolver; -import com.funeat.auth.util.AuthHandlerInterceptor; -import com.funeat.recipe.util.RecipeDetailHandlerInterceptor; -import com.funeat.recipe.util.RecipeHandlerInterceptor; -import java.util.List; -import org.springframework.context.annotation.Configuration; -import org.springframework.format.FormatterRegistry; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -public class WebConfig implements WebMvcConfigurer { - - private final CustomPageableHandlerMethodArgumentResolver customPageableHandlerMethodArgumentResolver; - private final AuthArgumentResolver authArgumentResolver; - private final AuthHandlerInterceptor authHandlerInterceptor; - private final RecipeHandlerInterceptor recipeHandlerInterceptor; - private final RecipeDetailHandlerInterceptor recipeDetailHandlerInterceptor; - - private final AdminCheckInterceptor adminCheckInterceptor; - - public WebConfig(final CustomPageableHandlerMethodArgumentResolver customPageableHandlerMethodArgumentResolver, - final AuthArgumentResolver authArgumentResolver, - final AuthHandlerInterceptor authHandlerInterceptor, - final RecipeHandlerInterceptor recipeHandlerInterceptor, - final RecipeDetailHandlerInterceptor recipeDetailHandlerInterceptor, - final AdminCheckInterceptor adminCheckInterceptor) { - this.customPageableHandlerMethodArgumentResolver = customPageableHandlerMethodArgumentResolver; - this.authArgumentResolver = authArgumentResolver; - this.authHandlerInterceptor = authHandlerInterceptor; - this.recipeHandlerInterceptor = recipeHandlerInterceptor; - this.recipeDetailHandlerInterceptor = recipeDetailHandlerInterceptor; - this.adminCheckInterceptor = adminCheckInterceptor; - } - - @Override - public void addInterceptors(final InterceptorRegistry registry) { - registry.addInterceptor(authHandlerInterceptor) - .addPathPatterns("/api/products/**/reviews/**") - .addPathPatterns("/api/members/**") - .addPathPatterns("/api/logout"); - registry.addInterceptor(recipeHandlerInterceptor) - .addPathPatterns("/api/recipes"); - registry.addInterceptor(recipeDetailHandlerInterceptor) - .addPathPatterns("/api/recipes/**") - .excludePathPatterns("/api/recipes"); - registry.addInterceptor(adminCheckInterceptor) - .excludePathPatterns("/api/admin/login") - .addPathPatterns("/api/admin/**"); - } - - @Override - public void addFormatters(final FormatterRegistry registry) { - registry.addConverter(new StringToCategoryTypeConverter()); - } - - @Override - public void addArgumentResolvers(final List resolvers) { - resolvers.add(customPageableHandlerMethodArgumentResolver); - resolvers.add(authArgumentResolver); - } -} diff --git a/backend/src/main/java/com/funeat/common/dto/PageDto.java b/backend/src/main/java/com/funeat/common/dto/PageDto.java deleted file mode 100644 index 6d561c7cd..000000000 --- a/backend/src/main/java/com/funeat/common/dto/PageDto.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.funeat.common.dto; - -import org.springframework.data.domain.Page; - -public class PageDto { - - private final Long totalDataCount; - private final Long totalPages; - private final boolean firstPage; - private final boolean lastPage; - private final Long requestPage; - private final Long requestSize; - - public PageDto(final Long totalDataCount, final Long totalPages, final boolean firstPage, final boolean lastPage, - final Long requestPage, final Long requestSize) { - this.totalDataCount = totalDataCount; - this.totalPages = totalPages; - this.firstPage = firstPage; - this.lastPage = lastPage; - this.requestPage = requestPage; - this.requestSize = requestSize; - } - - public static PageDto toDto(final Page page) { - return new PageDto( - page.getTotalElements(), - Long.valueOf(page.getTotalPages()), - page.isFirst(), - page.isLast(), - Long.valueOf(page.getNumber()), - Long.valueOf(page.getSize()) - ); - } - - public Long getTotalDataCount() { - return totalDataCount; - } - - public Long getTotalPages() { - return totalPages; - } - - public boolean isFirstPage() { - return firstPage; - } - - public boolean isLastPage() { - return lastPage; - } - - public Long getRequestPage() { - return requestPage; - } - - public Long getRequestSize() { - return requestSize; - } -} diff --git a/backend/src/main/java/com/funeat/common/exception/CommonException.java b/backend/src/main/java/com/funeat/common/exception/CommonException.java deleted file mode 100644 index 55be12d5d..000000000 --- a/backend/src/main/java/com/funeat/common/exception/CommonException.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.funeat.common.exception; - -import com.funeat.exception.CommonErrorCode; -import com.funeat.exception.ErrorCode; -import com.funeat.exception.GlobalException; -import org.springframework.http.HttpStatus; - -public class CommonException extends GlobalException { - - public CommonException(final HttpStatus status, final ErrorCode errorCode) { - super(status, errorCode); - } - - public static class NotAllowedFileExtensionException extends CommonException { - public NotAllowedFileExtensionException(final CommonErrorCode errorCode, final String extension) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), extension)); - } - } - - public static class S3UploadFailException extends CommonException { - public S3UploadFailException(final CommonErrorCode errorCode) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage())); - } - } - - public static class S3DeleteFailException extends CommonException { - public S3DeleteFailException(final CommonErrorCode errorCode) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage())); - } - } -} diff --git a/backend/src/main/java/com/funeat/common/logging/Logging.java b/backend/src/main/java/com/funeat/common/logging/Logging.java deleted file mode 100644 index 475a43b4b..000000000 --- a/backend/src/main/java/com/funeat/common/logging/Logging.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.funeat.common.logging; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Logging { -} diff --git a/backend/src/main/java/com/funeat/common/logging/LoggingAspect.java b/backend/src/main/java/com/funeat/common/logging/LoggingAspect.java deleted file mode 100644 index 13758c6c9..000000000 --- a/backend/src/main/java/com/funeat/common/logging/LoggingAspect.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.funeat.common.logging; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.annotation.AfterReturning; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.aspectj.lang.annotation.Pointcut; -import org.aspectj.lang.reflect.CodeSignature; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -@Aspect -@Component -public class LoggingAspect { - - private static final List excludeNames = Arrays.asList("image", "images", "request"); - - private final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - @Pointcut("execution(public * com.funeat.*.presentation.*.*(..))") - private void allPresentation() { - } - - @Pointcut("@annotation(com.funeat.common.logging.Logging)") - private void logging() { - } - - @Before("allPresentation() && logging()") - public void requestLogging(final JoinPoint joinPoint) { - final HttpServletRequest request = getRequest(); - final Map args = getSpecificParameters(joinPoint); - - printRequestLog(request, args); - } - - private HttpServletRequest getRequest() { - final ServletRequestAttributes servletRequestAttributes - = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); - return servletRequestAttributes.getRequest(); - } - - private Map getSpecificParameters(final JoinPoint joinPoint) { - final CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature(); - final String[] parameterNames = codeSignature.getParameterNames(); - final Object[] args = joinPoint.getArgs(); - - final Map params = new HashMap<>(); - for (int i = 0; i < parameterNames.length; i++) { - if (!excludeNames.contains(parameterNames[i])) { - params.put(parameterNames[i], args[i]); - } - } - - return params; - } - - private void printRequestLog(final HttpServletRequest request, final Object value) { - try { - log.info("[REQUEST {}] [PATH {}] {}", - request.getMethod(), request.getRequestURI(), objectMapper.writeValueAsString(value)); - } catch (final JsonProcessingException e) { - log.warn("[LOGGING ERROR] Request λ‘œκΉ…μ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€"); - } - } - - @AfterReturning(value = "allPresentation() && logging()", returning = "responseEntity") - public void requestLogging(final ResponseEntity responseEntity) { - printResponseLog(responseEntity); - } - - private void printResponseLog(final ResponseEntity responseEntity) { - try { - final String responseStatus = responseEntity.getStatusCode().toString(); - log.info("[RESPONSE {}] {}", responseStatus, objectMapper.writeValueAsString(responseEntity.getBody())); - } catch (final JsonProcessingException e) { - log.warn("[LOGGING ERROR] Response λ‘œκΉ…μ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€"); - } - } -} diff --git a/backend/src/main/java/com/funeat/common/repository/BaseRepository.java b/backend/src/main/java/com/funeat/common/repository/BaseRepository.java deleted file mode 100644 index 448db7766..000000000 --- a/backend/src/main/java/com/funeat/common/repository/BaseRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.funeat.common.repository; - -import java.io.Serializable; -import java.util.List; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.repository.NoRepositoryBean; - -@NoRepositoryBean -public interface BaseRepository extends JpaRepository { - - Page findAllForPagination(final Specification spec, final Pageable pageable, final Long totalElements); - - List findAllWithSpecification(final Specification spec, final int pageSize); -} diff --git a/backend/src/main/java/com/funeat/common/repository/BaseRepositoryImpl.java b/backend/src/main/java/com/funeat/common/repository/BaseRepositoryImpl.java deleted file mode 100644 index 64cd508f6..000000000 --- a/backend/src/main/java/com/funeat/common/repository/BaseRepositoryImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.funeat.common.repository; - -import java.io.Serializable; -import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.TypedQuery; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.repository.support.JpaEntityInformation; -import org.springframework.data.jpa.repository.support.SimpleJpaRepository; - -public class BaseRepositoryImpl extends SimpleJpaRepository - implements BaseRepository { - - public BaseRepositoryImpl(final JpaEntityInformation entityInformation, final EntityManager entityManager) { - super(entityInformation, entityManager); - } - - @Override - public Page findAllForPagination(final Specification spec, final Pageable pageable, - final Long totalElements) { - final TypedQuery query = getQuery(spec, pageable.getSort()); - - final int pageSize = pageable.getPageSize(); - - if (totalElements == null) { - return findAll(spec, pageable); - } - - if (pageSize < 1) { - throw new IllegalArgumentException("νŽ˜μ΄μ§€λŠ” 1미만이 될 수 μ—†μŠ΅λ‹ˆλ‹€."); - } - - query.setMaxResults(pageable.getPageSize()); - - return new PageImpl<>(query.getResultList(), PageRequest.of(0, pageSize), totalElements); - } - - @Override - public List findAllWithSpecification(final Specification spec, final int pageSize) { - final TypedQuery query = getQuery(spec, Sort.unsorted()); - query.setMaxResults(pageSize); - - return query.getResultList(); - } -} diff --git a/backend/src/main/java/com/funeat/common/s3/AwsConfig.java b/backend/src/main/java/com/funeat/common/s3/AwsConfig.java deleted file mode 100644 index 83a7e67d5..000000000 --- a/backend/src/main/java/com/funeat/common/s3/AwsConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.funeat.common.s3; - -import com.amazonaws.auth.InstanceProfileCredentialsProvider; -import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.AmazonS3ClientBuilder; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class AwsConfig { - - @Value("${cloud.aws.region.static}") - private String region; - - @Bean - public InstanceProfileCredentialsProvider awsCredentialsProvider() { - return InstanceProfileCredentialsProvider.getInstance(); - } - - @Bean - public AmazonS3 amazonS3Client() { - return AmazonS3ClientBuilder.standard() - .withRegion(region) - .withCredentials(awsCredentialsProvider()) - .build(); - } -} diff --git a/backend/src/main/java/com/funeat/common/s3/S3Uploader.java b/backend/src/main/java/com/funeat/common/s3/S3Uploader.java deleted file mode 100644 index 97e6241b7..000000000 --- a/backend/src/main/java/com/funeat/common/s3/S3Uploader.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.funeat.common.s3; - -import static com.funeat.exception.CommonErrorCode.IMAGE_EXTENSION_ERROR_CODE; -import static com.funeat.exception.CommonErrorCode.UNKNOWN_SERVER_ERROR_CODE; - -import com.amazonaws.AmazonServiceException; -import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.model.ObjectMetadata; -import com.amazonaws.services.s3.model.PutObjectRequest; -import com.funeat.common.ImageUploader; -import com.funeat.common.exception.CommonException.NotAllowedFileExtensionException; -import com.funeat.common.exception.CommonException.S3DeleteFailException; -import com.funeat.common.exception.CommonException.S3UploadFailException; -import java.io.IOException; -import java.util.List; -import java.util.UUID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; - -@Component -@Profile("!test") -public class S3Uploader implements ImageUploader { - - private static final int BEGIN_FILE_NAME_INDEX_WITHOUT_CLOUDFRONT_PATH = 31; - private static final List INCLUDE_EXTENSIONS = List.of("image/jpeg", "image/png", "image/webp"); - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - @Value("${cloud.aws.s3.bucket}") - private String bucket; - - @Value("${cloud.aws.s3.folder}") - private String folder; - - @Value("${cloud.aws.s3.cloudfrontPath}") - private String cloudfrontPath; - - private final AmazonS3 amazonS3; - - public S3Uploader(final AmazonS3 amazonS3) { - this.amazonS3 = amazonS3; - } - - @Override - public String upload(final MultipartFile image) { - validateExtension(image); - final String randomImageName = getRandomImageName(image); - final ObjectMetadata metadata = getMetadata(image); - try { - final String key = folder + randomImageName; - amazonS3.putObject(getPutObjectRequest(image, key, metadata)); - - return getCloudfrontImagePath(randomImageName); - } catch (IOException e) { - throw new S3UploadFailException(UNKNOWN_SERVER_ERROR_CODE); - } - } - - @Override - public void delete(final String image) { - final String imageName = image.substring(BEGIN_FILE_NAME_INDEX_WITHOUT_CLOUDFRONT_PATH); - try { - final String key = folder + imageName; - amazonS3.deleteObject(bucket, key); - } catch (final AmazonServiceException e) { - log.error("S3 이미지 μ‚­μ œμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€. 이미지 경둜 : {}", image); - throw new S3DeleteFailException(UNKNOWN_SERVER_ERROR_CODE); - } - } - - private void validateExtension(final MultipartFile image) { - final String contentType = image.getContentType(); - if (!INCLUDE_EXTENSIONS.contains(contentType)) { - throw new NotAllowedFileExtensionException(IMAGE_EXTENSION_ERROR_CODE, contentType); - } - } - - private String getRandomImageName(final MultipartFile image) { - return UUID.randomUUID() + image.getOriginalFilename(); - } - - private ObjectMetadata getMetadata(final MultipartFile image) { - final ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentType(image.getContentType()); - metadata.setContentLength(image.getSize()); - return metadata; - } - - private PutObjectRequest getPutObjectRequest(final MultipartFile image, final String key, - final ObjectMetadata metadata) throws IOException { - return new PutObjectRequest(bucket, key, image.getInputStream(), metadata); - } - - private String getCloudfrontImagePath(final String imageName) { - return cloudfrontPath + imageName; - } -} diff --git a/backend/src/main/java/com/funeat/exception/CommonErrorCode.java b/backend/src/main/java/com/funeat/exception/CommonErrorCode.java deleted file mode 100644 index 9bc4a5486..000000000 --- a/backend/src/main/java/com/funeat/exception/CommonErrorCode.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.funeat.exception; - -import org.springframework.http.HttpStatus; - -public enum CommonErrorCode { - - UNKNOWN_SERVER_ERROR_CODE(HttpStatus.INTERNAL_SERVER_ERROR, "μ•Œ 수 μ—†λŠ” μ—λŸ¬μž…λ‹ˆλ‹€.", "0000"), - REQUEST_VALID_ERROR_CODE(HttpStatus.BAD_REQUEST, "μš”μ²­μ„ λ‹€μ‹œ ν™•μΈν•΄μ£Όμ„Έμš”.", "0001"), - IMAGE_EXTENSION_ERROR_CODE(HttpStatus.BAD_REQUEST, "파일 ν™•μž₯자λ₯Ό ν™•μΈν•΄μ£Όμ„Έμš”.", "0002"), - ; - - private final HttpStatus status; - private final String message; - private final String code; - - CommonErrorCode(final HttpStatus status, final String message, final String code) { - this.status = status; - this.message = message; - this.code = code; - } - - public HttpStatus getStatus() { - return status; - } - - public String getMessage() { - return message; - } - - public String getCode() { - return code; - } -} diff --git a/backend/src/main/java/com/funeat/exception/ErrorCode.java b/backend/src/main/java/com/funeat/exception/ErrorCode.java deleted file mode 100644 index ee454207e..000000000 --- a/backend/src/main/java/com/funeat/exception/ErrorCode.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.funeat.exception; - -import com.fasterxml.jackson.annotation.JsonInclude; - -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ErrorCode { - - private final String code; - private final String message; - private T info; - - public ErrorCode(final String code, final String message, final T info) { - this.code = code; - this.message = message; - this.info = info; - } - - public ErrorCode(final String code, final String message) { - this.code = code; - this.message = message; - } - - public String getCode() { - return code; - } - - public String getMessage() { - return message; - } - - public T getInfo() { - return info; - } -} diff --git a/backend/src/main/java/com/funeat/exception/GlobalException.java b/backend/src/main/java/com/funeat/exception/GlobalException.java deleted file mode 100644 index 976619a36..000000000 --- a/backend/src/main/java/com/funeat/exception/GlobalException.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.funeat.exception; - -import org.springframework.http.HttpStatus; - -public class GlobalException extends RuntimeException { - - private final HttpStatus status; - private final ErrorCode errorCode; - - public GlobalException(final HttpStatus status, final ErrorCode errorCode) { - super(errorCode.getMessage()); - this.status = status; - this.errorCode = errorCode; - } - - public HttpStatus getStatus() { - return status; - } - - public ErrorCode getErrorCode() { - return errorCode; - } -} diff --git a/backend/src/main/java/com/funeat/exception/presentation/GlobalControllerAdvice.java b/backend/src/main/java/com/funeat/exception/presentation/GlobalControllerAdvice.java deleted file mode 100644 index b6fed678c..000000000 --- a/backend/src/main/java/com/funeat/exception/presentation/GlobalControllerAdvice.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.funeat.exception.presentation; - -import static com.funeat.exception.CommonErrorCode.REQUEST_VALID_ERROR_CODE; -import static com.funeat.exception.CommonErrorCode.UNKNOWN_SERVER_ERROR_CODE; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.funeat.exception.ErrorCode; -import com.funeat.exception.GlobalException; -import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.support.DefaultMessageSourceResolvable; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.FieldError; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.MissingServletRequestParameterException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestControllerAdvice; -import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; - -@RestControllerAdvice -public class GlobalControllerAdvice { - - private static final String ERROR_MESSAGE_DELIMITER = ", "; - private static final String RESPONSE_DELIMITER = ". "; - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - private final ObjectMapper objectMapper; - - public GlobalControllerAdvice(final ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - } - - @ExceptionHandler({MethodArgumentTypeMismatchException.class, MissingServletRequestParameterException.class}) - public ResponseEntity handleParamValidationException(final Exception e, final HttpServletRequest request) { - log.warn("{} = {}, code = {} message = {}", request.getMethod(), request.getRequestURI(), - REQUEST_VALID_ERROR_CODE.getCode(), e.getMessage()); - - final ErrorCode errorCode = new ErrorCode<>(REQUEST_VALID_ERROR_CODE.getCode(), - REQUEST_VALID_ERROR_CODE.getMessage()); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorCode); - } - - @ExceptionHandler(MethodArgumentNotValidException.class) - public ResponseEntity handleParamValidationException(final MethodArgumentNotValidException e, - final HttpServletRequest request) { - final String filedErrorLogMessages = getMethodArgumentExceptionLogMessage(e); - - final String errorMessage = e.getBindingResult() - .getAllErrors() - .stream() - .map(DefaultMessageSourceResolvable::getDefaultMessage) - .collect(Collectors.joining(ERROR_MESSAGE_DELIMITER)); - - final String responseErrorMessage = errorMessage + RESPONSE_DELIMITER + REQUEST_VALID_ERROR_CODE.getMessage(); - - final ErrorCode errorCode = new ErrorCode<>(REQUEST_VALID_ERROR_CODE.getCode(), responseErrorMessage); - - log.warn("{} = {}, message = {} ", request.getMethod(), request.getRequestURI(), - filedErrorLogMessages); - return ResponseEntity.status(REQUEST_VALID_ERROR_CODE.getStatus()).body(errorCode); - } - - private static String getMethodArgumentExceptionLogMessage(final MethodArgumentNotValidException e) { - final String filedErrorMessages = e.getBindingResult() - .getFieldErrors() - .stream() - .map(FieldError::getField) - .collect(Collectors.joining(ERROR_MESSAGE_DELIMITER)); - - return filedErrorMessages + " μš”μ²­ μ‹€νŒ¨"; - } - - @ExceptionHandler(GlobalException.class) - public ResponseEntity handleGlobalException(final GlobalException e, final HttpServletRequest request) - throws JsonProcessingException { - final String exceptionSource = getExceptionSource(e); - log.warn("source = {} , {} = {} code = {} message = {} info = {}", exceptionSource, request.getMethod(), - request.getRequestURI(), e.getErrorCode().getCode(), e.getErrorCode().getMessage(), - objectMapper.writeValueAsString(e.getErrorCode().getInfo())); - - final ErrorCode errorCode = new ErrorCode<>(e.getErrorCode().getCode(), e.getMessage()); - return ResponseEntity.status(e.getStatus()).body(errorCode); - } - - private String getExceptionSource(final Exception e) { - final StackTraceElement[] stackTrace = e.getStackTrace(); - if (stackTrace.length > 0) { - return stackTrace[0].toString(); - } - return "Unknown location"; - } - - @ExceptionHandler(Exception.class) - public ResponseEntity handleServerException(final Exception e) { - log.error("", e); - - final ErrorCode errorCode = new ErrorCode<>(UNKNOWN_SERVER_ERROR_CODE.getCode(), - UNKNOWN_SERVER_ERROR_CODE.getMessage()); - return ResponseEntity.status(UNKNOWN_SERVER_ERROR_CODE.getStatus()).body(errorCode); - } -} diff --git a/backend/src/main/java/com/funeat/member/application/MemberService.java b/backend/src/main/java/com/funeat/member/application/MemberService.java deleted file mode 100644 index 43e1bf069..000000000 --- a/backend/src/main/java/com/funeat/member/application/MemberService.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.funeat.member.application; - -import static com.funeat.member.exception.MemberErrorCode.MEMBER_NOT_FOUND; -import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW; - -import com.funeat.auth.dto.SignUserDto; -import com.funeat.auth.dto.UserInfoDto; -import com.funeat.common.ImageUploader; -import com.funeat.member.domain.Member; -import com.funeat.member.dto.MemberProfileResponse; -import com.funeat.member.dto.MemberRequest; -import com.funeat.member.exception.MemberErrorCode; -import com.funeat.member.exception.MemberException.MemberNotFoundException; -import com.funeat.member.persistence.MemberRepository; -import java.util.Objects; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -@Service -@Transactional(readOnly = true) -public class MemberService { - - private final MemberRepository memberRepository; - private final ImageUploader imageUploader; - - public MemberService(final MemberRepository memberRepository, final ImageUploader imageUploader) { - this.memberRepository = memberRepository; - this.imageUploader = imageUploader; - } - - @Transactional(propagation = REQUIRES_NEW) - public SignUserDto findOrCreateMember(final UserInfoDto userInfoDto) { - final String platformId = userInfoDto.getId().toString(); - - return memberRepository.findByPlatformId(platformId) - .map(member -> SignUserDto.of(false, member)) - .orElseGet(() -> save(userInfoDto)); - } - - private SignUserDto save(final UserInfoDto userInfoDto) { - final Member member = userInfoDto.toMember(); - memberRepository.save(member); - - return SignUserDto.of(true, member); - } - - public MemberProfileResponse getMemberProfile(final Long memberId) { - final Member findMember = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MemberErrorCode.MEMBER_NOT_FOUND, memberId)); - - return MemberProfileResponse.toResponse(findMember); - } - - @Transactional - public void modify(final Long memberId, final MultipartFile image, final MemberRequest request) { - final Member findMember = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MemberErrorCode.MEMBER_NOT_FOUND, memberId)); - - final String nickname = request.getNickname(); - - if (Objects.isNull(image)) { - findMember.modifyNickname(nickname); - return; - } - final String imageUrl = imageUploader.upload(image); - findMember.modifyProfile(nickname, imageUrl); - } - - public String findPlatformId(final Long memberId) { - final Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - - return member.getPlatformId(); - } -} diff --git a/backend/src/main/java/com/funeat/member/domain/Member.java b/backend/src/main/java/com/funeat/member/domain/Member.java deleted file mode 100644 index 2096d0ff6..000000000 --- a/backend/src/main/java/com/funeat/member/domain/Member.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.funeat.member.domain; - -import static com.funeat.member.exception.MemberErrorCode.MEMBER_UPDATE_ERROR; - -import com.funeat.member.domain.favorite.RecipeFavorite; -import com.funeat.member.domain.favorite.ReviewFavorite; -import com.funeat.member.exception.MemberException.MemberUpdateException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import org.springframework.util.StringUtils; - -@Entity -public class Member { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String nickname; - - private String profileImage; - - private String platformId; - - @OneToMany(mappedBy = "member") - private List reviewFavorites = new ArrayList<>(); - - @OneToMany(mappedBy = "member") - private List recipeFavorites; - - protected Member() { - } - - public Member(final String nickname, final String profileImage, final String platformId) { - this.nickname = nickname; - this.profileImage = profileImage; - this.platformId = platformId; - } - - public Long getId() { - return id; - } - - public String getNickname() { - return nickname; - } - - public String getProfileImage() { - return profileImage; - } - - public String getPlatformId() { - return platformId; - } - - public List getReviewFavorites() { - return reviewFavorites; - } - - public List getRecipeFavorites() { - return recipeFavorites; - } - - public void modifyProfile(final String nickname, final String profileImage) { - if (!StringUtils.hasText(nickname) || Objects.isNull(profileImage)) { - throw new MemberUpdateException(MEMBER_UPDATE_ERROR); - } - this.nickname = nickname; - this.profileImage = profileImage; - } - - public void modifyNickname(final String nickname) { - if (!StringUtils.hasText(nickname)) { - throw new MemberUpdateException(MEMBER_UPDATE_ERROR); - } - this.nickname = nickname; - } -} diff --git a/backend/src/main/java/com/funeat/member/domain/favorite/RecipeFavorite.java b/backend/src/main/java/com/funeat/member/domain/favorite/RecipeFavorite.java deleted file mode 100644 index 161f83483..000000000 --- a/backend/src/main/java/com/funeat/member/domain/favorite/RecipeFavorite.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.funeat.member.domain.favorite; - -import com.funeat.member.domain.Member; -import com.funeat.recipe.domain.Recipe; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -@Entity -@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"member_id", "recipe_id"})) -public class RecipeFavorite { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "recipe_id") - private Recipe recipe; - - private Boolean favorite; - - protected RecipeFavorite() { - } - - public RecipeFavorite(final Member member, final Recipe recipe, final Boolean favorite) { - this.member = member; - this.recipe = recipe; - this.favorite = favorite; - } - - public static RecipeFavorite create(final Member member, final Recipe recipe, final Boolean favorite) { - if (favorite == true) { - recipe.addFavoriteCount(); - } - return new RecipeFavorite(member, recipe, favorite); - } - - public void updateFavorite(final Boolean favorite) { - if (!this.favorite && favorite) { - this.recipe.addFavoriteCount(); - this.favorite = favorite; - return; - } - if (this.favorite && !favorite) { - this.recipe.minusFavoriteCount(); - this.favorite = favorite; - } - } - - public Long getId() { - return id; - } - - public Member getMember() { - return member; - } - - public Recipe getRecipe() { - return recipe; - } - - public Boolean getFavorite() { - return favorite; - } -} diff --git a/backend/src/main/java/com/funeat/member/domain/favorite/ReviewFavorite.java b/backend/src/main/java/com/funeat/member/domain/favorite/ReviewFavorite.java deleted file mode 100644 index 7e8768f47..000000000 --- a/backend/src/main/java/com/funeat/member/domain/favorite/ReviewFavorite.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.funeat.member.domain.favorite; - -import com.funeat.member.domain.Member; -import com.funeat.review.domain.Review; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -@Entity -@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"member_id", "review_id"})) -public class ReviewFavorite { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "review_id") - private Review review; - - private Boolean favorite; - - protected ReviewFavorite() { - } - - public ReviewFavorite(final Member member, final Review review) { - this.member = member; - this.review = review; - } - - public static ReviewFavorite create(final Member member, final Review review, final Boolean favorite) { - final ReviewFavorite reviewFavorite = new ReviewFavorite(member, review); - reviewFavorite.review.getReviewFavorites().add(reviewFavorite); - reviewFavorite.member.getReviewFavorites().add(reviewFavorite); - reviewFavorite.favorite = favorite; - reviewFavorite.review.addFavoriteCount(); - return reviewFavorite; - } - - public void updateChecked(final Boolean favorite) { - if (!this.favorite && favorite) { - this.review.addFavoriteCount(); - this.favorite = favorite; - return; - } - if (this.favorite && !favorite) { - this.review.minusFavoriteCount(); - this.favorite = favorite; - } - } - - public Long getId() { - return id; - } - - public Member getMember() { - return member; - } - - public Review getReview() { - return review; - } - - public Boolean getFavorite() { - return favorite; - } -} diff --git a/backend/src/main/java/com/funeat/member/dto/MemberProfileResponse.java b/backend/src/main/java/com/funeat/member/dto/MemberProfileResponse.java deleted file mode 100644 index 84e915ebe..000000000 --- a/backend/src/main/java/com/funeat/member/dto/MemberProfileResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.member.dto; - -import com.funeat.member.domain.Member; - -public class MemberProfileResponse { - - private final String nickname; - private final String profileImage; - - public MemberProfileResponse(final String nickname, final String profileImage) { - this.nickname = nickname; - this.profileImage = profileImage; - } - - public static MemberProfileResponse toResponse(final Member member) { - return new MemberProfileResponse(member.getNickname(), member.getProfileImage()); - } - - public String getNickname() { - return nickname; - } - - public String getProfileImage() { - return profileImage; - } -} diff --git a/backend/src/main/java/com/funeat/member/dto/MemberRecipeDto.java b/backend/src/main/java/com/funeat/member/dto/MemberRecipeDto.java deleted file mode 100644 index 4c01ce95d..000000000 --- a/backend/src/main/java/com/funeat/member/dto/MemberRecipeDto.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.funeat.member.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import java.time.LocalDateTime; -import java.util.List; - -public class MemberRecipeDto { - - private final Long id; - private final String title; - private final String content; - private final LocalDateTime createdAt; - private final String image; - private final Long favoriteCount; - private final List products; - - private MemberRecipeDto(final Long id, final String title, final String content, final LocalDateTime createdAt, - final Long favoriteCount, final List products) { - this(id, title, content, createdAt, null, favoriteCount, products); - } - - @JsonCreator - private MemberRecipeDto(final Long id, final String title, final String content, final LocalDateTime createdAt, - final String image, final Long favoriteCount, final List products) { - this.id = id; - this.title = title; - this.content = content; - this.createdAt = createdAt; - this.image = image; - this.favoriteCount = favoriteCount; - this.products = products; - } - - public static MemberRecipeDto toDto(final Recipe recipe, final List findRecipeImages, - final List memberRecipeProductDtos) { - if (findRecipeImages.isEmpty()) { - return new MemberRecipeDto(recipe.getId(), recipe.getTitle(), recipe.getContent(), recipe.getCreatedAt(), - recipe.getFavoriteCount(), memberRecipeProductDtos); - } - return new MemberRecipeDto(recipe.getId(), recipe.getTitle(), recipe.getContent(), recipe.getCreatedAt(), - findRecipeImages.get(0).getImage(), recipe.getFavoriteCount(), memberRecipeProductDtos); - } - - public Long getId() { - return id; - } - - public String getTitle() { - return title; - } - - public String getContent() { - return content; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public String getImage() { - return image; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public List getProducts() { - return products; - } -} diff --git a/backend/src/main/java/com/funeat/member/dto/MemberRecipeProductDto.java b/backend/src/main/java/com/funeat/member/dto/MemberRecipeProductDto.java deleted file mode 100644 index eec5ef79a..000000000 --- a/backend/src/main/java/com/funeat/member/dto/MemberRecipeProductDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.member.dto; - -import com.funeat.product.domain.Product; - -public class MemberRecipeProductDto { - - private final Long id; - private final String name; - - private MemberRecipeProductDto(final Long id, final String name) { - this.id = id; - this.name = name; - } - - public static MemberRecipeProductDto toDto(final Product product) { - return new MemberRecipeProductDto(product.getId(), product.getName()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } -} diff --git a/backend/src/main/java/com/funeat/member/dto/MemberRecipesResponse.java b/backend/src/main/java/com/funeat/member/dto/MemberRecipesResponse.java deleted file mode 100644 index 29a28fbc2..000000000 --- a/backend/src/main/java/com/funeat/member/dto/MemberRecipesResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.funeat.member.dto; - -import com.funeat.common.dto.PageDto; -import java.util.List; - -public class MemberRecipesResponse { - - private final PageDto page; - private final List recipes; - - private MemberRecipesResponse(final PageDto page, final List recipes) { - this.page = page; - this.recipes = recipes; - } - - public static MemberRecipesResponse toResponse(final PageDto page, - final List recipes) { - return new MemberRecipesResponse(page, recipes); - } - - public PageDto getPage() { - return page; - } - - public List getRecipes() { - return recipes; - } -} diff --git a/backend/src/main/java/com/funeat/member/dto/MemberRequest.java b/backend/src/main/java/com/funeat/member/dto/MemberRequest.java deleted file mode 100644 index c8a2f9726..000000000 --- a/backend/src/main/java/com/funeat/member/dto/MemberRequest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.funeat.member.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; - -public class MemberRequest { - - @NotBlank(message = "λ‹‰λ„€μž„μ„ ν™•μΈν•΄μ£Όμ„Έμš”") - private final String nickname; - - public MemberRequest(@JsonProperty("nickname") final String nickname) { - this.nickname = nickname; - } - - public String getNickname() { - return nickname; - } -} diff --git a/backend/src/main/java/com/funeat/member/dto/MemberReviewDto.java b/backend/src/main/java/com/funeat/member/dto/MemberReviewDto.java deleted file mode 100644 index 082b4dd72..000000000 --- a/backend/src/main/java/com/funeat/member/dto/MemberReviewDto.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.funeat.member.dto; - -import com.funeat.review.domain.Review; - -public class MemberReviewDto { - - private final Long reviewId; - private final Long productId; - private final String categoryType; - private final String productName; - private final String content; - private final Long rating; - private final Long favoriteCount; - - private MemberReviewDto(final Long reviewId, final Long productId, final String categoryType, - final String productName, final String content, - final Long rating, final Long favoriteCount) { - this.reviewId = reviewId; - this.productId = productId; - this.categoryType = categoryType; - this.productName = productName; - this.content = content; - this.rating = rating; - this.favoriteCount = favoriteCount; - } - - public static MemberReviewDto toDto(final Review review) { - return new MemberReviewDto( - review.getId(), - review.getProduct().getId(), - review.getProduct().getCategory().getType().getName(), - review.getProduct().getName(), - review.getContent(), - review.getRating(), - review.getFavoriteCount() - ); - } - - public Long getReviewId() { - return reviewId; - } - - public Long getProductId() { - return productId; - } - - public String getProductName() { - return productName; - } - - public String getContent() { - return content; - } - - public Long getRating() { - return rating; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public String getCategoryType() { - return categoryType; - } -} diff --git a/backend/src/main/java/com/funeat/member/dto/MemberReviewsResponse.java b/backend/src/main/java/com/funeat/member/dto/MemberReviewsResponse.java deleted file mode 100644 index e21fe33b7..000000000 --- a/backend/src/main/java/com/funeat/member/dto/MemberReviewsResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.funeat.member.dto; - -import com.funeat.common.dto.PageDto; -import java.util.List; - -public class MemberReviewsResponse { - - private final PageDto page; - private final List reviews; - - private MemberReviewsResponse(final PageDto page, final List reviews) { - this.page = page; - this.reviews = reviews; - } - - public static MemberReviewsResponse toResponse(final PageDto page, final List reviews) { - return new MemberReviewsResponse(page, reviews); - } - - public PageDto getPage() { - return page; - } - - public List getReviews() { - return reviews; - } -} diff --git a/backend/src/main/java/com/funeat/member/exception/MemberErrorCode.java b/backend/src/main/java/com/funeat/member/exception/MemberErrorCode.java deleted file mode 100644 index 91b37d3c8..000000000 --- a/backend/src/main/java/com/funeat/member/exception/MemberErrorCode.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.funeat.member.exception; - -import org.springframework.http.HttpStatus; - -public enum MemberErrorCode { - - MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” νšŒμ›μž…λ‹ˆλ‹€. νšŒμ› idλ₯Ό ν™•μΈν•˜μ„Έμš”.", "5001"), - MEMBER_UPDATE_ERROR(HttpStatus.BAD_REQUEST, "λ‹‰λ„€μž„ λ˜λŠ” 이미지λ₯Ό ν™•μΈν•˜μ„Έμš”.", "5002"), - MEMBER_DUPLICATE_FAVORITE(HttpStatus.CONFLICT, "이미 μ’‹μ•„μš”λ₯Ό λˆ„λ₯Έ μƒνƒœμž…λ‹ˆλ‹€.", "5003"), - ; - - private final HttpStatus status; - private final String message; - private final String code; - - MemberErrorCode(final HttpStatus status, final String message, final String code) { - this.status = status; - this.message = message; - this.code = code; - } - - public HttpStatus getStatus() { - return status; - } - - public String getMessage() { - return message; - } - - public String getCode() { - return code; - } -} diff --git a/backend/src/main/java/com/funeat/member/exception/MemberException.java b/backend/src/main/java/com/funeat/member/exception/MemberException.java deleted file mode 100644 index c0dab99e6..000000000 --- a/backend/src/main/java/com/funeat/member/exception/MemberException.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.funeat.member.exception; - -import com.funeat.exception.ErrorCode; -import com.funeat.exception.GlobalException; -import org.springframework.http.HttpStatus; - -public class MemberException extends GlobalException { - - public MemberException(final HttpStatus status, final ErrorCode errorCode) { - super(status, errorCode); - } - - public static class MemberNotFoundException extends MemberException { - public MemberNotFoundException(final MemberErrorCode errorCode, final Long memberId) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), memberId)); - } - } - - public static class MemberUpdateException extends MemberException { - public MemberUpdateException(final MemberErrorCode errorCode) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage())); - } - } - - public static class MemberDuplicateFavoriteException extends MemberException { - public MemberDuplicateFavoriteException(final MemberErrorCode errorCode, final Long memberId) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), memberId)); - } - } -} diff --git a/backend/src/main/java/com/funeat/member/persistence/MemberRepository.java b/backend/src/main/java/com/funeat/member/persistence/MemberRepository.java deleted file mode 100644 index 832c48a38..000000000 --- a/backend/src/main/java/com/funeat/member/persistence/MemberRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.funeat.member.persistence; - -import com.funeat.member.domain.Member; -import java.util.Optional; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface MemberRepository extends JpaRepository { - - Optional findByPlatformId(final String platformId); -} diff --git a/backend/src/main/java/com/funeat/member/persistence/RecipeFavoriteRepository.java b/backend/src/main/java/com/funeat/member/persistence/RecipeFavoriteRepository.java deleted file mode 100644 index 8eddf02cb..000000000 --- a/backend/src/main/java/com/funeat/member/persistence/RecipeFavoriteRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.funeat.member.persistence; - -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.RecipeFavorite; -import com.funeat.recipe.domain.Recipe; -import java.util.Optional; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface RecipeFavoriteRepository extends JpaRepository { - - Optional findByMemberAndRecipe(final Member member, final Recipe recipe); - - boolean existsByMemberAndRecipeAndFavoriteTrue(final Member member, final Recipe recipe); -} diff --git a/backend/src/main/java/com/funeat/member/persistence/ReviewFavoriteRepository.java b/backend/src/main/java/com/funeat/member/persistence/ReviewFavoriteRepository.java deleted file mode 100644 index f1ae40e5d..000000000 --- a/backend/src/main/java/com/funeat/member/persistence/ReviewFavoriteRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.funeat.member.persistence; - -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.ReviewFavorite; -import com.funeat.review.domain.Review; -import java.util.List; -import java.util.Optional; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ReviewFavoriteRepository extends JpaRepository { - - Optional findByMemberAndReview(final Member member, final Review review); - - void deleteByReview(final Review review); - - List findByReview(final Review review); -} diff --git a/backend/src/main/java/com/funeat/member/presentation/MemberApiController.java b/backend/src/main/java/com/funeat/member/presentation/MemberApiController.java deleted file mode 100644 index af00932f7..000000000 --- a/backend/src/main/java/com/funeat/member/presentation/MemberApiController.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.funeat.member.presentation; - -import com.funeat.auth.dto.LoginInfo; -import com.funeat.auth.util.AuthenticationPrincipal; -import com.funeat.common.logging.Logging; -import com.funeat.member.application.MemberService; -import com.funeat.member.dto.MemberProfileResponse; -import com.funeat.member.dto.MemberRecipesResponse; -import com.funeat.member.dto.MemberRequest; -import com.funeat.member.dto.MemberReviewsResponse; -import com.funeat.recipe.application.RecipeService; -import com.funeat.review.application.ReviewService; -import javax.validation.Valid; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -@RestController -@RequestMapping("/api/members") -public class MemberApiController implements MemberController { - - private final MemberService memberService; - private final ReviewService reviewService; - private final RecipeService recipeService; - - public MemberApiController(final MemberService memberService, final ReviewService reviewService, - final RecipeService recipeService) { - this.memberService = memberService; - this.reviewService = reviewService; - this.recipeService = recipeService; - } - - @GetMapping - public ResponseEntity getMemberProfile(@AuthenticationPrincipal final LoginInfo loginInfo) { - final MemberProfileResponse response = memberService.getMemberProfile(loginInfo.getId()); - - return ResponseEntity.ok(response); - } - - @Logging - @PutMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE}) - public ResponseEntity putMemberProfile(@AuthenticationPrincipal final LoginInfo loginInfo, - @RequestPart(required = false) final MultipartFile image, - @RequestPart @Valid final MemberRequest memberRequest) { - memberService.modify(loginInfo.getId(), image, memberRequest); - - return ResponseEntity.noContent().build(); - } - - @GetMapping("/reviews") - public ResponseEntity getMemberReview(@AuthenticationPrincipal final LoginInfo loginInfo, - @PageableDefault final Pageable pageable) { - final MemberReviewsResponse response = reviewService.findReviewByMember(loginInfo.getId(), pageable); - - return ResponseEntity.ok().body(response); - } - - @GetMapping("/recipes") - public ResponseEntity getMemberRecipe(@AuthenticationPrincipal final LoginInfo loginInfo, - @PageableDefault final Pageable pageable) { - final MemberRecipesResponse response = recipeService.findRecipeByMember(loginInfo.getId(), pageable); - - return ResponseEntity.ok().body(response); - } - - @Logging - @DeleteMapping("/reviews/{reviewId}") - public ResponseEntity deleteReview(@PathVariable final Long reviewId, - @AuthenticationPrincipal final LoginInfo loginInfo) { - reviewService.deleteReview(reviewId, loginInfo.getId()); - - return ResponseEntity.noContent().build(); - } -} diff --git a/backend/src/main/java/com/funeat/member/presentation/MemberController.java b/backend/src/main/java/com/funeat/member/presentation/MemberController.java deleted file mode 100644 index 9c5e60763..000000000 --- a/backend/src/main/java/com/funeat/member/presentation/MemberController.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.funeat.member.presentation; - -import com.funeat.auth.dto.LoginInfo; -import com.funeat.auth.util.AuthenticationPrincipal; -import com.funeat.member.dto.MemberProfileResponse; -import com.funeat.member.dto.MemberRecipesResponse; -import com.funeat.member.dto.MemberRequest; -import com.funeat.member.dto.MemberReviewsResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.multipart.MultipartFile; - -@Tag(name = "05.Member", description = "μ‚¬μš©μž κΈ°λŠ₯") -public interface MemberController { - - @Operation(summary = "μ‚¬μš©μž 정보 쑰회", description = "μ‚¬μš©μž λ‹‰λ„€μž„κ³Ό ν”„λ‘œν•„ 사진을 μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "μ‚¬μš©μž 정보 쑰회 성곡." - ) - @GetMapping - ResponseEntity getMemberProfile(@AuthenticationPrincipal final LoginInfo loginInfo); - - @Operation(summary = "μ‚¬μš©μž 정보 μˆ˜μ •", description = "μ‚¬μš©μž λ‹‰λ„€μž„κ³Ό ν”„λ‘œν•„ 사진을 μˆ˜μ •ν•œλ‹€.") - @ApiResponse( - responseCode = "204", - description = "μ‚¬μš©μž 정보 μˆ˜μ • 성곡." - ) - @PutMapping - public ResponseEntity putMemberProfile(@AuthenticationPrincipal final LoginInfo loginInfo, - @RequestPart final MultipartFile image, - @RequestPart final MemberRequest request); - - @Operation(summary = "μ‚¬μš©μž 리뷰 쑰회", description = "μ‚¬μš©μžκ°€ μž‘μ„±ν•œ 리뷰λ₯Ό μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "μ‚¬μš©μž 리뷰 쑰회 성곡." - ) - @GetMapping - ResponseEntity getMemberReview(@AuthenticationPrincipal final LoginInfo loginInfo, - @PageableDefault final Pageable pageable); - - @Operation(summary = "μ‚¬μš©μž κΏ€μ‘°ν•© 쑰회", description = "μ‚¬μš©μžκ°€ μž‘μ„±ν•œ 꿀쑰합을 μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "μ‚¬μš©μž κΏ€μ‘°ν•© 쑰회 성곡." - ) - @GetMapping - ResponseEntity getMemberRecipe(@AuthenticationPrincipal final LoginInfo loginInfo, - @PageableDefault final Pageable pageable); - - @Operation(summary = "리뷰 μ‚­μ œ", description = "μžμ‹ μ΄ μž‘μ„±ν•œ 리뷰λ₯Ό μ‚­μ œν•œλ‹€.") - @ApiResponse( - responseCode = "204", - description = "리뷰 μ‚­μ œ 성곡." - ) - @DeleteMapping - ResponseEntity deleteReview(@PathVariable final Long reviewId, - @AuthenticationPrincipal final LoginInfo loginInfo); -} diff --git a/backend/src/main/java/com/funeat/product/application/CategoryService.java b/backend/src/main/java/com/funeat/product/application/CategoryService.java deleted file mode 100644 index 7b99b6f3c..000000000 --- a/backend/src/main/java/com/funeat/product/application/CategoryService.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.funeat.product.application; - -import com.funeat.product.domain.Category; -import com.funeat.product.domain.CategoryType; -import com.funeat.product.persistence.CategoryRepository; -import java.util.List; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -public class CategoryService { - - private final CategoryRepository categoryRepository; - - public CategoryService(final CategoryRepository categoryRepository) { - this.categoryRepository = categoryRepository; - } - - public List findAllCategoriesByType(final CategoryType type) { - return categoryRepository.findAllByType(type); - } -} diff --git a/backend/src/main/java/com/funeat/product/application/ProductService.java b/backend/src/main/java/com/funeat/product/application/ProductService.java deleted file mode 100644 index 021ffe126..000000000 --- a/backend/src/main/java/com/funeat/product/application/ProductService.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.funeat.product.application; - -import static com.funeat.product.exception.CategoryErrorCode.CATEGORY_NOT_FOUND; -import static com.funeat.product.exception.ProductErrorCode.PRODUCT_NOT_FOUND; - -import com.funeat.common.dto.PageDto; -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import com.funeat.product.dto.ProductInCategoryDto; -import com.funeat.product.dto.ProductResponse; -import com.funeat.product.dto.ProductReviewCountDto; -import com.funeat.product.dto.ProductSortCondition; -import com.funeat.product.dto.ProductsInCategoryResponse; -import com.funeat.product.dto.RankingProductDto; -import com.funeat.product.dto.RankingProductsResponse; -import com.funeat.product.dto.SearchProductDto; -import com.funeat.product.dto.SearchProductResultDto; -import com.funeat.product.dto.SearchProductResultsResponse; -import com.funeat.product.dto.SearchProductsResponse; -import com.funeat.product.exception.CategoryException.CategoryNotFoundException; -import com.funeat.product.exception.ProductException.ProductNotFoundException; -import com.funeat.product.persistence.CategoryRepository; -import com.funeat.product.persistence.ProductRecipeRepository; -import com.funeat.product.persistence.ProductRepository; -import com.funeat.product.persistence.ProductSpecification; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import com.funeat.recipe.dto.RecipeDto; -import com.funeat.recipe.dto.SortingRecipesResponse; -import com.funeat.recipe.persistence.RecipeImageRepository; -import com.funeat.recipe.persistence.RecipeRepository; -import com.funeat.review.persistence.ReviewRepository; -import com.funeat.review.persistence.ReviewTagRepository; -import com.funeat.tag.domain.Tag; -import java.time.LocalDateTime; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -public class ProductService { - - private static final int THREE = 3; - private static final int TOP = 0; - private static final int RANKING_SIZE = 3; - private static final int DEFAULT_PAGE_SIZE = 10; - private static final int DEFAULT_CURSOR_PAGINATION_SIZE = 11; - - private final CategoryRepository categoryRepository; - private final ProductRepository productRepository; - private final ReviewTagRepository reviewTagRepository; - private final ReviewRepository reviewRepository; - private final ProductRecipeRepository productRecipeRepository; - private final RecipeImageRepository recipeImageRepository; - private final RecipeRepository recipeRepository; - - public ProductService(final CategoryRepository categoryRepository, final ProductRepository productRepository, - final ReviewTagRepository reviewTagRepository, final ReviewRepository reviewRepository, - final ProductRecipeRepository productRecipeRepository, - final RecipeImageRepository recipeImageRepository, - final RecipeRepository recipeRepository) { - this.categoryRepository = categoryRepository; - this.productRepository = productRepository; - this.reviewTagRepository = reviewTagRepository; - this.reviewRepository = reviewRepository; - this.productRecipeRepository = productRecipeRepository; - this.recipeImageRepository = recipeImageRepository; - this.recipeRepository = recipeRepository; - } - - public ProductsInCategoryResponse getAllProductsInCategory(final Long categoryId, final Long lastProductId, - final ProductSortCondition sortCondition) { - final Category category = categoryRepository.findById(categoryId) - .orElseThrow(() -> new CategoryNotFoundException(CATEGORY_NOT_FOUND, categoryId)); - final Product lastProduct = productRepository.findById(lastProductId).orElse(null); - - final Specification specification = ProductSpecification.searchBy(category, lastProduct, sortCondition); - final List findResults = productRepository.findAllWithSpecification(specification, DEFAULT_CURSOR_PAGINATION_SIZE); - - final List productDtos = getProductInCategoryDtos(findResults); - final boolean hasNext = hasNextPage(findResults); - - return ProductsInCategoryResponse.toResponse(hasNext, productDtos); - } - - private List getProductInCategoryDtos(final List findProducts) { - final int resultSize = getResultSize(findProducts); - final List products = findProducts.subList(0, resultSize); - - return products.stream() - .map(ProductInCategoryDto::toDto) - .collect(Collectors.toList()); - } - - private int getResultSize(final List findProducts) { - if (findProducts.size() < DEFAULT_CURSOR_PAGINATION_SIZE) { - return findProducts.size(); - } - return DEFAULT_PAGE_SIZE; - } - - private boolean hasNextPage(final List findProducts) { - return findProducts.size() > DEFAULT_PAGE_SIZE; - } - - public ProductResponse findProductDetail(final Long productId) { - final Product product = productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId)); - final List tags = reviewTagRepository.findTop3TagsByReviewIn(productId, PageRequest.of(TOP, THREE)); - - return ProductResponse.toResponse(product, tags); - } - - public RankingProductsResponse getTop3Products() { - final LocalDateTime endDateTime = LocalDateTime.now(); - final LocalDateTime startDateTime = endDateTime.minusWeeks(2L); - final List productsAndReviewCounts = productRepository.findAllByAverageRatingGreaterThan3(startDateTime, endDateTime); - final Comparator rankingScoreComparator = Comparator.comparing( - (ProductReviewCountDto it) -> it.getProduct().calculateRankingScore(it.getReviewCount()) - ).reversed(); - - final List rankingProductDtos = productsAndReviewCounts.stream() - .sorted(rankingScoreComparator) - .limit(RANKING_SIZE) - .map(it -> RankingProductDto.toDto(it.getProduct())) - .collect(Collectors.toList()); - - return RankingProductsResponse.toResponse(rankingProductDtos); - } - - public SearchProductsResponse searchProducts(final String query, final Pageable pageable) { - final Page products = productRepository.findAllByNameContaining(query, pageable); - - final PageDto pageDto = PageDto.toDto(products); - final List productDtos = products.stream() - .map(SearchProductDto::toDto) - .collect(Collectors.toList()); - - return SearchProductsResponse.toResponse(pageDto, productDtos); - } - - public SearchProductResultsResponse getSearchResults(final String query, final Pageable pageable) { - final Page products = productRepository.findAllWithReviewCountByNameContaining(query, - pageable); - - final PageDto pageDto = PageDto.toDto(products); - final List resultDtos = products.stream() - .map(it -> SearchProductResultDto.toDto(it.getProduct(), it.getReviewCount())) - .collect(Collectors.toList()); - - return SearchProductResultsResponse.toResponse(pageDto, resultDtos); - } - - public SortingRecipesResponse getProductRecipes(final Long productId, final Pageable pageable) { - final Product product = productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId)); - - final Page recipes = recipeRepository.findRecipesByProduct(product, pageable); - - final PageDto pageDto = PageDto.toDto(recipes); - final List recipeDtos = recipes.stream() - .map(recipe -> { - final List images = recipeImageRepository.findByRecipe(recipe); - final List products = productRecipeRepository.findProductByRecipe(recipe); - return RecipeDto.toDto(recipe, images, products); - }) - .collect(Collectors.toList()); - return SortingRecipesResponse.toResponse(pageDto, recipeDtos); - } -} diff --git a/backend/src/main/java/com/funeat/product/domain/Category.java b/backend/src/main/java/com/funeat/product/domain/Category.java deleted file mode 100644 index 7504aad1d..000000000 --- a/backend/src/main/java/com/funeat/product/domain/Category.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.funeat.product.domain; - -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -@Entity -public class Category { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String name; - - @Enumerated(EnumType.STRING) - private CategoryType type; - - private String image; - - protected Category() { - } - - public Category(final String name, final CategoryType type, final String image) { - this.name = name; - this.type = type; - this.image = image; - } - - public boolean isFood() { - return type == CategoryType.FOOD; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public CategoryType getType() { - return type; - } - - public String getImage() { - return image; - } -} diff --git a/backend/src/main/java/com/funeat/product/domain/CategoryType.java b/backend/src/main/java/com/funeat/product/domain/CategoryType.java deleted file mode 100644 index f80311161..000000000 --- a/backend/src/main/java/com/funeat/product/domain/CategoryType.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.funeat.product.domain; - -import static com.funeat.product.exception.CategoryErrorCode.CATEGORY_TYPE_NOT_FOUND; - -import com.funeat.product.exception.CategoryException.CategoryTypeNotFoundException; -import java.util.Arrays; - -public enum CategoryType { - - FOOD("food"), - STORE("store"), - ; - - private final String name; - - CategoryType(final String name) { - this.name = name; - } - - public static CategoryType findCategoryType(final String type) { - return Arrays.stream(values()) - .filter(it -> it.name().equals(type.toUpperCase())) - .findFirst() - .orElseThrow(() -> new CategoryTypeNotFoundException(CATEGORY_TYPE_NOT_FOUND, type)); - } - - public String getName() { - return name; - } -} diff --git a/backend/src/main/java/com/funeat/product/domain/Product.java b/backend/src/main/java/com/funeat/product/domain/Product.java deleted file mode 100644 index a95a7b91e..000000000 --- a/backend/src/main/java/com/funeat/product/domain/Product.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.funeat.product.domain; - -import com.funeat.review.domain.Review; -import java.util.List; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -@Entity -public class Product { - - public static final String BASIC_IMAGE = null; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String name; - - private Long price; - - private String image; - - private String content; - - private Double averageRating = 0.0; - - private Long reviewCount = 0L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "category_id") - private Category category; - - @OneToMany(mappedBy = "product") - private List reviews; - - @OneToMany(mappedBy = "product") - private List productRecipes; - - protected Product() { - } - - public Product(final String name, final Long price, final String image, final String content, - final Category category) { - this.name = name; - this.price = price; - this.image = image; - this.content = content; - this.category = category; - } - - public Product(final String name, final Long price, final String image, final String content, - final Double averageRating, final Category category) { - this.name = name; - this.price = price; - this.image = image; - this.content = content; - this.averageRating = averageRating; - this.category = category; - } - - public Product(final String name, final Long price, final String image, final String content, - final Category category, final Long reviewCount) { - this.name = name; - this.price = price; - this.image = image; - this.content = content; - this.category = category; - this.reviewCount = reviewCount; - } - - public Product(final String name, final Long price, final String image, final String content, - final Double averageRating, final Category category, final Long reviewCount) { - this.name = name; - this.price = price; - this.image = image; - this.content = content; - this.averageRating = averageRating; - this.category = category; - this.reviewCount = reviewCount; - } - - public static Product create(final String name, final Long price, final String content, final Category category) { - return new Product(name, price, null, content, category); - } - - public void updateAverageRatingForInsert(final Long count, final Long rating) { - final double calculatedRating = ((count - 1) * averageRating + rating) / count; - this.averageRating = Math.round(calculatedRating * 10.0) / 10.0; - } - - public void updateAverageRatingForDelete(final Long deletedRating) { - if (reviewCount == 1) { - this.averageRating = 0.0; - return; - } - final double calculatedRating = (reviewCount * averageRating - deletedRating) / (reviewCount - 1); - this.averageRating = Math.round(calculatedRating * 10.0) / 10.0; - } - - public Double calculateRankingScore(final Long reviewCount) { - final double exponent = -Math.log10(reviewCount + 1); - final double factor = Math.pow(2, exponent); - return averageRating - (averageRating - 3.0) * factor; - } - - public void updateBasicImage() { - this.image = BASIC_IMAGE; - } - - public void updateFavoriteImage(final String topFavoriteImage) { - this.image = topFavoriteImage; - } - - public void update(final String name, final String content, final Long price, final Category category) { - this.name = name; - this.content = content; - this.price = price; - this.category = category; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public Long getPrice() { - return price; - } - - public String getImage() { - return image; - } - - public String getContent() { - return content; - } - - public Double getAverageRating() { - return averageRating; - } - - public Category getCategory() { - return category; - } - - public Long getReviewCount() { - return reviewCount; - } - - public void addReviewCount() { - reviewCount++; - } - - public void minusReviewCount() { - reviewCount--; - } -} diff --git a/backend/src/main/java/com/funeat/product/domain/ProductRecipe.java b/backend/src/main/java/com/funeat/product/domain/ProductRecipe.java deleted file mode 100644 index 4bca08c3d..000000000 --- a/backend/src/main/java/com/funeat/product/domain/ProductRecipe.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.funeat.product.domain; - -import com.funeat.recipe.domain.Recipe; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; - -@Entity -public class ProductRecipe { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "product_id") - private Product product; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "recipe_id") - private Recipe recipe; - - protected ProductRecipe() { - } - - public ProductRecipe(final Product product, final Recipe recipe) { - this.product = product; - this.recipe = recipe; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/CategoryResponse.java b/backend/src/main/java/com/funeat/product/dto/CategoryResponse.java deleted file mode 100644 index 3ea9e59a5..000000000 --- a/backend/src/main/java/com/funeat/product/dto/CategoryResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.product.domain.Category; - -public class CategoryResponse { - - private final Long id; - private final String name; - private final String image; - - public CategoryResponse(final Long id, final String name, final String image) { - this.id = id; - this.name = name; - this.image = image; - } - - public static CategoryResponse toResponse(final Category category) { - return new CategoryResponse(category.getId(), category.getName(), category.getImage()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getImage() { - return image; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/ProductInCategoryDto.java b/backend/src/main/java/com/funeat/product/dto/ProductInCategoryDto.java deleted file mode 100644 index e4c73b606..000000000 --- a/backend/src/main/java/com/funeat/product/dto/ProductInCategoryDto.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.product.domain.Product; - -public class ProductInCategoryDto { - - private final Long id; - private final String name; - private final Long price; - private final String image; - private final Double averageRating; - private final Long reviewCount; - - public ProductInCategoryDto(final Long id, final String name, final Long price, final String image, - final Double averageRating, final Long reviewCount) { - this.id = id; - this.name = name; - this.price = price; - this.image = image; - this.averageRating = averageRating; - this.reviewCount = reviewCount; - } - - public static ProductInCategoryDto toDto(final Product product) { - return new ProductInCategoryDto(product.getId(), product.getName(), product.getPrice(), product.getImage(), - product.getAverageRating(), product.getReviewCount()); - } - - public static ProductInCategoryDto toDto(final Product product, final Long reviewCount) { - return new ProductInCategoryDto(product.getId(), product.getName(), product.getPrice(), product.getImage(), - product.getAverageRating(), reviewCount); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public Long getPrice() { - return price; - } - - public String getImage() { - return image; - } - - public Double getAverageRating() { - return averageRating; - } - - public Long getReviewCount() { - return reviewCount; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/ProductResponse.java b/backend/src/main/java/com/funeat/product/dto/ProductResponse.java deleted file mode 100644 index d3c0ed264..000000000 --- a/backend/src/main/java/com/funeat/product/dto/ProductResponse.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.product.domain.Product; -import com.funeat.tag.domain.Tag; -import com.funeat.tag.dto.TagDto; -import java.util.ArrayList; -import java.util.List; - -public class ProductResponse { - - private final Long id; - private final String name; - private final Long price; - private final String image; - private final String content; - private final Double averageRating; - private final Long reviewCount; - private final List tags; - - public ProductResponse(final Long id, final String name, final Long price, final String image, final String content, - final Double averageRating, final Long reviewCount, final List tags) { - this.id = id; - this.name = name; - this.price = price; - this.image = image; - this.content = content; - this.averageRating = averageRating; - this.reviewCount = reviewCount; - this.tags = tags; - } - - public static ProductResponse toResponse(final Product product, final List tags) { - List tagDtos = new ArrayList<>(); - for (Tag tag : tags) { - tagDtos.add(TagDto.toDto(tag)); - } - return new ProductResponse(product.getId(), product.getName(), product.getPrice(), product.getImage(), - product.getContent(), product.getAverageRating(), product.getReviewCount(), tagDtos); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public Long getPrice() { - return price; - } - - public String getImage() { - return image; - } - - public String getContent() { - return content; - } - - public Double getAverageRating() { - return averageRating; - } - - public Long getReviewCount() { - return reviewCount; - } - - public List getTags() { - return tags; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/ProductReviewCountDto.java b/backend/src/main/java/com/funeat/product/dto/ProductReviewCountDto.java deleted file mode 100644 index f769b708d..000000000 --- a/backend/src/main/java/com/funeat/product/dto/ProductReviewCountDto.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.product.domain.Product; - -public class ProductReviewCountDto { - - private final Product product; - private final Long reviewCount; - - public ProductReviewCountDto(final Product product, final Long reviewCount) { - this.product = product; - this.reviewCount = reviewCount; - } - - public Product getProduct() { - return product; - } - - public Long getReviewCount() { - return reviewCount; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/ProductSortCondition.java b/backend/src/main/java/com/funeat/product/dto/ProductSortCondition.java deleted file mode 100644 index 8a929f99c..000000000 --- a/backend/src/main/java/com/funeat/product/dto/ProductSortCondition.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.funeat.product.dto; - -public class ProductSortCondition { - - private final String by; - private final String order; - - private ProductSortCondition(final String by, final String order) { - this.by = by; - this.order = order; - } - - public static ProductSortCondition toDto(final String sort) { - final String[] split = sort.split(","); - return new ProductSortCondition(split[0], split[1]); - } - - public String getBy() { - return by; - } - - public String getOrder() { - return order; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/ProductsInCategoryResponse.java b/backend/src/main/java/com/funeat/product/dto/ProductsInCategoryResponse.java deleted file mode 100644 index 39c685268..000000000 --- a/backend/src/main/java/com/funeat/product/dto/ProductsInCategoryResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.funeat.product.dto; - -import java.util.List; - -public class ProductsInCategoryResponse { - - private final boolean hasNext; - private final List products; - - public ProductsInCategoryResponse(final boolean hasNext, final List products) { - this.hasNext = hasNext; - this.products = products; - } - - public static ProductsInCategoryResponse toResponse(final boolean hasNext, - final List products) { - return new ProductsInCategoryResponse(hasNext, products); - } - - public boolean isHasNext() { - return hasNext; - } - - public List getProducts() { - return products; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/RankingProductDto.java b/backend/src/main/java/com/funeat/product/dto/RankingProductDto.java deleted file mode 100644 index 0b14c0efd..000000000 --- a/backend/src/main/java/com/funeat/product/dto/RankingProductDto.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.product.domain.Product; - -public class RankingProductDto { - - private final Long id; - private final String name; - private final String image; - private final String categoryType; - - public RankingProductDto(final Long id, final String name, final String image, final String categoryType) { - this.id = id; - this.name = name; - this.image = image; - this.categoryType = categoryType; - } - - public static RankingProductDto toDto(final Product product) { - return new RankingProductDto(product.getId(), product.getName(), product.getImage(), - product.getCategory().getType().getName()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getImage() { - return image; - } - - public String getCategoryType() { - return categoryType; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/RankingProductsResponse.java b/backend/src/main/java/com/funeat/product/dto/RankingProductsResponse.java deleted file mode 100644 index 14bfcf158..000000000 --- a/backend/src/main/java/com/funeat/product/dto/RankingProductsResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.funeat.product.dto; - -import java.util.List; - -public class RankingProductsResponse { - - private final List products; - - public RankingProductsResponse(final List products) { - this.products = products; - } - - public static RankingProductsResponse toResponse(final List products) { - return new RankingProductsResponse(products); - } - - public List getProducts() { - return products; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/SearchProductDto.java b/backend/src/main/java/com/funeat/product/dto/SearchProductDto.java deleted file mode 100644 index f41bfa110..000000000 --- a/backend/src/main/java/com/funeat/product/dto/SearchProductDto.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.product.domain.Product; - -public class SearchProductDto { - - private final Long id; - private final String name; - private final String categoryType; - - public SearchProductDto(final Long id, final String name, final String categoryType) { - this.id = id; - this.name = name; - this.categoryType = categoryType; - } - - public static SearchProductDto toDto(final Product product) { - return new SearchProductDto(product.getId(), product.getName(), product.getCategory().getType().getName()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getCategoryType() { - return categoryType; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/SearchProductResultDto.java b/backend/src/main/java/com/funeat/product/dto/SearchProductResultDto.java deleted file mode 100644 index d4119da49..000000000 --- a/backend/src/main/java/com/funeat/product/dto/SearchProductResultDto.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.product.domain.Product; - -public class SearchProductResultDto { - - private final Long id; - private final String name; - private final Long price; - private final String image; - private final Double averageRating; - private final Long reviewCount; - private final String categoryType; - - public SearchProductResultDto(final Long id, final String name, final Long price, final String image, - final Double averageRating, final Long reviewCount, final String categoryType) { - this.id = id; - this.name = name; - this.price = price; - this.image = image; - this.averageRating = averageRating; - this.reviewCount = reviewCount; - this.categoryType = categoryType; - } - - public static SearchProductResultDto toDto(final Product product, final Long reviewCount) { - return new SearchProductResultDto(product.getId(), product.getName(), product.getPrice(), product.getImage(), - product.getAverageRating(), reviewCount, product.getCategory().getType().getName()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public Long getPrice() { - return price; - } - - public String getImage() { - return image; - } - - public Double getAverageRating() { - return averageRating; - } - - public Long getReviewCount() { - return reviewCount; - } - - public String getCategoryType() { - return categoryType; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/SearchProductResultsResponse.java b/backend/src/main/java/com/funeat/product/dto/SearchProductResultsResponse.java deleted file mode 100644 index 98aa9eb7c..000000000 --- a/backend/src/main/java/com/funeat/product/dto/SearchProductResultsResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.common.dto.PageDto; -import java.util.List; - -public class SearchProductResultsResponse { - - private final PageDto page; - private final List products; - - public SearchProductResultsResponse(final PageDto page, final List products) { - this.page = page; - this.products = products; - } - - public static SearchProductResultsResponse toResponse(final PageDto page, - final List products) { - return new SearchProductResultsResponse(page, products); - } - - public PageDto getPage() { - return page; - } - - public List getProducts() { - return products; - } -} diff --git a/backend/src/main/java/com/funeat/product/dto/SearchProductsResponse.java b/backend/src/main/java/com/funeat/product/dto/SearchProductsResponse.java deleted file mode 100644 index ccdeade5a..000000000 --- a/backend/src/main/java/com/funeat/product/dto/SearchProductsResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.funeat.product.dto; - -import com.funeat.common.dto.PageDto; -import java.util.List; - -public class SearchProductsResponse { - - private final PageDto page; - private final List products; - - public SearchProductsResponse(final PageDto page, final List products) { - this.page = page; - this.products = products; - } - - public static SearchProductsResponse toResponse(final PageDto page, final List products) { - return new SearchProductsResponse(page, products); - } - - public PageDto getPage() { - return page; - } - - public List getProducts() { - return products; - } -} diff --git a/backend/src/main/java/com/funeat/product/exception/CategoryErrorCode.java b/backend/src/main/java/com/funeat/product/exception/CategoryErrorCode.java deleted file mode 100644 index 5214a03b6..000000000 --- a/backend/src/main/java/com/funeat/product/exception/CategoryErrorCode.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.product.exception; - -import org.springframework.http.HttpStatus; - -public enum CategoryErrorCode { - - CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μΉ΄ν…Œκ³ λ¦¬μž…λ‹ˆλ‹€. μΉ΄ν…Œκ³ λ¦¬ idλ₯Ό ν™•μΈν•˜μ„Έμš”.", "2001"), - CATEGORY_TYPE_NOT_FOUND(HttpStatus.NOT_FOUND, "μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μΉ΄ν…Œκ³ λ¦¬ νƒ€μž…μž…λ‹ˆλ‹€. μΉ΄ν…Œκ³ λ¦¬ νƒ€μž…μ„ ν™•μΈν•˜μ„Έμš”.", "2002"), - ; - - private final HttpStatus status; - private final String message; - private final String code; - - CategoryErrorCode(final HttpStatus status, final String message, final String code) { - this.status = status; - this.message = message; - this.code = code; - } - - public HttpStatus getStatus() { - return status; - } - - public String getMessage() { - return message; - } - - public String getCode() { - return code; - } -} diff --git a/backend/src/main/java/com/funeat/product/exception/CategoryException.java b/backend/src/main/java/com/funeat/product/exception/CategoryException.java deleted file mode 100644 index 6402c250a..000000000 --- a/backend/src/main/java/com/funeat/product/exception/CategoryException.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.funeat.product.exception; - -import com.funeat.exception.ErrorCode; -import com.funeat.exception.GlobalException; -import org.springframework.http.HttpStatus; - -public class CategoryException extends GlobalException { - - public CategoryException(final HttpStatus status, final ErrorCode errorCode) { - super(status, errorCode); - } - - public static class CategoryNotFoundException extends CategoryException { - public CategoryNotFoundException(final CategoryErrorCode errorCode, final Long categoryId) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), categoryId)); - } - } - - public static class CategoryTypeNotFoundException extends CategoryException { - public CategoryTypeNotFoundException(final CategoryErrorCode errorCode, final String type) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), type)); - } - } -} diff --git a/backend/src/main/java/com/funeat/product/exception/ProductErrorCode.java b/backend/src/main/java/com/funeat/product/exception/ProductErrorCode.java deleted file mode 100644 index e3b4d3ccc..000000000 --- a/backend/src/main/java/com/funeat/product/exception/ProductErrorCode.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.product.exception; - -import org.springframework.http.HttpStatus; - -public enum ProductErrorCode { - - PRODUCT_NOT_FOUND(HttpStatus.NOT_FOUND, "μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μƒν’ˆμž…λ‹ˆλ‹€. μƒν’ˆ idλ₯Ό ν™•μΈν•˜μ„Έμš”.", "1001"), - NOT_SUPPORTED_PRODUCT_SORTING_CONDITION(HttpStatus.BAD_REQUEST, "μ •λ ¬ 쑰건이 μ˜¬λ°”λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ •λ ¬ 쑰건을 ν™•μΈν•˜μ„Έμš”", "1002"); - ; - - private final HttpStatus status; - private final String message; - private final String code; - - ProductErrorCode(final HttpStatus status, final String message, final String code) { - this.status = status; - this.message = message; - this.code = code; - } - - public HttpStatus getStatus() { - return status; - } - - public String getMessage() { - return message; - } - - public String getCode() { - return code; - } -} diff --git a/backend/src/main/java/com/funeat/product/exception/ProductException.java b/backend/src/main/java/com/funeat/product/exception/ProductException.java deleted file mode 100644 index bdbb4782b..000000000 --- a/backend/src/main/java/com/funeat/product/exception/ProductException.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.funeat.product.exception; - -import com.funeat.exception.ErrorCode; -import com.funeat.exception.GlobalException; -import org.springframework.http.HttpStatus; - -public class ProductException extends GlobalException { - - public ProductException(final HttpStatus status, final ErrorCode errorCode) { - super(status, errorCode); - } - - public static class ProductNotFoundException extends ProductException { - public ProductNotFoundException(final ProductErrorCode errorCode, final Long productId) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), productId)); - } - } - - public static class NotSupportedProductSortingConditionException extends ProductException { - public NotSupportedProductSortingConditionException(final ProductErrorCode errorCode, final String sortBy) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), sortBy)); - } - } -} diff --git a/backend/src/main/java/com/funeat/product/persistence/CategoryRepository.java b/backend/src/main/java/com/funeat/product/persistence/CategoryRepository.java deleted file mode 100644 index 4da064517..000000000 --- a/backend/src/main/java/com/funeat/product/persistence/CategoryRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.funeat.product.persistence; - -import com.funeat.product.domain.Category; -import com.funeat.product.domain.CategoryType; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface CategoryRepository extends JpaRepository { - - List findAllByType(final CategoryType type); -} diff --git a/backend/src/main/java/com/funeat/product/persistence/ProductRecipeRepository.java b/backend/src/main/java/com/funeat/product/persistence/ProductRecipeRepository.java deleted file mode 100644 index a5c819571..000000000 --- a/backend/src/main/java/com/funeat/product/persistence/ProductRecipeRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.funeat.product.persistence; - -import com.funeat.product.domain.Product; -import com.funeat.product.domain.ProductRecipe; -import com.funeat.recipe.domain.Recipe; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -public interface ProductRecipeRepository extends JpaRepository { - - @Query("SELECT pr.product FROM ProductRecipe pr WHERE pr.recipe = :recipe") - List findProductByRecipe(final Recipe recipe); -} diff --git a/backend/src/main/java/com/funeat/product/persistence/ProductRepository.java b/backend/src/main/java/com/funeat/product/persistence/ProductRepository.java deleted file mode 100644 index 27208f254..000000000 --- a/backend/src/main/java/com/funeat/product/persistence/ProductRepository.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.funeat.product.persistence; - -import com.funeat.common.repository.BaseRepository; -import com.funeat.product.domain.Product; -import com.funeat.product.dto.ProductReviewCountDto; -import java.time.LocalDateTime; -import java.util.List; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface ProductRepository extends BaseRepository { - - @Query("SELECT new com.funeat.product.dto.ProductReviewCountDto(p, COUNT(r.id)) " - + "FROM Product p " - + "LEFT JOIN Review r ON r.product.id = p.id " - + "WHERE p.averageRating > 3.0 " - + "AND r.createdAt BETWEEN :startDateTime AND :endDateTime " - + "GROUP BY p.id") - List findAllByAverageRatingGreaterThan3(final LocalDateTime startDateTime, - final LocalDateTime endDateTime); - - @Query("SELECT p FROM Product p " - + "WHERE p.name LIKE CONCAT('%', :name, '%') " - + "ORDER BY " - + "(CASE WHEN p.name LIKE CONCAT(:name, '%') THEN 1 ELSE 2 END), " - + "p.id DESC") - Page findAllByNameContaining(@Param("name") final String name, final Pageable pageable); - - @Query("SELECT new com.funeat.product.dto.ProductReviewCountDto(p, COUNT(r.id)) FROM Product p " - + "LEFT JOIN Review r ON r.product.id = p.id " - + "WHERE p.name LIKE CONCAT('%', :name, '%') " - + "GROUP BY p.id " - + "ORDER BY " - + "(CASE WHEN p.name LIKE CONCAT(:name, '%') THEN 1 ELSE 2 END), p.id DESC") - Page findAllWithReviewCountByNameContaining(@Param("name") final String name, - final Pageable pageable); -} diff --git a/backend/src/main/java/com/funeat/product/persistence/ProductSpecification.java b/backend/src/main/java/com/funeat/product/persistence/ProductSpecification.java deleted file mode 100644 index f2dbd2ff2..000000000 --- a/backend/src/main/java/com/funeat/product/persistence/ProductSpecification.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.funeat.product.persistence; - -import static com.funeat.product.exception.ProductErrorCode.NOT_SUPPORTED_PRODUCT_SORTING_CONDITION; - -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import com.funeat.product.dto.ProductSortCondition; -import com.funeat.product.exception.ProductException.NotSupportedProductSortingConditionException; -import java.util.Objects; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Path; -import javax.persistence.criteria.Root; -import org.springframework.data.jpa.domain.Specification; - -public class ProductSpecification { - - private ProductSpecification() { - } - - private static final String DESC = "desc"; - private static final String CATEGORY = "category"; - private static final String ID = "id"; - private static final String REVIEW_COUNT = "reviewCount"; - private static final String AVERAGE_RATING = "averageRating"; - private static final String PRICE = "price"; - - public static Specification searchBy(final Category category, final Product lastProduct, - final ProductSortCondition sortCondition) { - return (root, query, builder) -> { - setOrderBy(sortCondition, root, query, builder); - - return Specification - .where(sameCategory(category)) - .and(nextCursor(lastProduct, sortCondition)) - .toPredicate(root, query, builder); - }; - } - - private static void setOrderBy(final ProductSortCondition sortCondition, final Root root, - final CriteriaQuery query, final CriteriaBuilder builder) { - final String sortBy = sortCondition.getBy(); - final String sortOrder = sortCondition.getOrder(); - - if (DESC.equals(sortOrder)) { - query.orderBy(builder.desc(root.get(sortBy)), builder.desc(root.get(ID))); - } else { - query.orderBy(builder.asc(root.get(sortBy)), builder.desc(root.get(ID))); - } - } - - private static Specification sameCategory(final Category category) { - return (root, query, builder) -> { - final Path categoryPath = root.get(CATEGORY); - - return builder.equal(categoryPath, category); - }; - } - - private static Specification nextCursor(final Product lastProduct, final ProductSortCondition sortCondition) { - final String sortBy = sortCondition.getBy(); - final String sortOrder = sortCondition.getOrder(); - - return (root, query, builder) -> { - if (Objects.isNull(lastProduct)) { - return null; - } - - final Comparable comparisonValue = (Comparable) getComparisonValue(lastProduct, sortBy); - - return builder.or( - sameValueAndSmallerId(sortBy, lastProduct.getId(), comparisonValue).toPredicate(root, query, builder), - nextValue(sortBy, sortOrder, comparisonValue).toPredicate(root, query, builder) - ); - }; - } - - private static Object getComparisonValue(final Product lastProduct, final String sortBy) { - if (PRICE.equals(sortBy)) { - return lastProduct.getPrice(); - } - if (AVERAGE_RATING.equals(sortBy)) { - return lastProduct.getAverageRating(); - } - if (REVIEW_COUNT.equals(sortBy)) { - return lastProduct.getReviewCount(); - } - throw new NotSupportedProductSortingConditionException(NOT_SUPPORTED_PRODUCT_SORTING_CONDITION, sortBy); - } - - private static Specification sameValueAndSmallerId(final String sortBy, final Long lastProductId, - final Comparable comparisonValue) { - return (root, query, builder) -> builder.and( - builder.equal(root.get(sortBy), comparisonValue), - builder.lessThan(root.get(ID), lastProductId)); - } - - private static Specification nextValue(final String sortBy, final String sortOrder, - final Comparable comparisonValue) { - return (root, query, builder) -> { - if (DESC.equals(sortOrder)) { - return builder.lessThan(root.get(sortBy), comparisonValue); - } else { - return builder.greaterThan(root.get(sortBy), comparisonValue); - } - }; - } -} diff --git a/backend/src/main/java/com/funeat/product/presentation/CategoryApiController.java b/backend/src/main/java/com/funeat/product/presentation/CategoryApiController.java deleted file mode 100644 index f084fc174..000000000 --- a/backend/src/main/java/com/funeat/product/presentation/CategoryApiController.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.funeat.product.presentation; - -import com.funeat.product.application.CategoryService; -import com.funeat.product.domain.CategoryType; -import com.funeat.product.dto.CategoryResponse; -import java.util.List; -import java.util.stream.Collectors; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/categories") -public class CategoryApiController implements CategoryController { - - private final CategoryService categoryService; - - public CategoryApiController(final CategoryService categoryService) { - this.categoryService = categoryService; - } - - @GetMapping - public ResponseEntity> getAllCategoriesByType(@RequestParam final CategoryType type) { - final List responses = categoryService.findAllCategoriesByType(type).stream() - .map(CategoryResponse::toResponse) - .collect(Collectors.toList()); - return ResponseEntity.ok(responses); - } -} diff --git a/backend/src/main/java/com/funeat/product/presentation/CategoryController.java b/backend/src/main/java/com/funeat/product/presentation/CategoryController.java deleted file mode 100644 index 53625ffb6..000000000 --- a/backend/src/main/java/com/funeat/product/presentation/CategoryController.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.funeat.product.presentation; - -import com.funeat.product.domain.CategoryType; -import com.funeat.product.dto.CategoryResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import java.util.List; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; - -@Tag(name = "02.Category", description = "μΉ΄ν…Œκ³ λ¦¬ κΈ°λŠ₯") -public interface CategoryController { - - @Operation(summary = "ν•΄λ‹Ή type μΉ΄ν…Œκ³ λ¦¬ 전체 쑰회", description = "FOOD λ˜λŠ” STORE λ₯Ό λ°›μ•„ ν•΄λ‹Ή μΉ΄ν…Œκ³ λ¦¬λ₯Ό 전체 μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "ν•΄λ‹Ή type μΉ΄ν…Œκ³ λ¦¬ 전체 쑰회 성곡." - ) - @GetMapping - ResponseEntity> getAllCategoriesByType(@RequestParam final CategoryType type); -} diff --git a/backend/src/main/java/com/funeat/product/presentation/ProductApiController.java b/backend/src/main/java/com/funeat/product/presentation/ProductApiController.java deleted file mode 100644 index 46435aee7..000000000 --- a/backend/src/main/java/com/funeat/product/presentation/ProductApiController.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.funeat.product.presentation; - -import com.funeat.product.application.ProductService; -import com.funeat.product.dto.ProductResponse; -import com.funeat.product.dto.ProductSortCondition; -import com.funeat.product.dto.ProductsInCategoryResponse; -import com.funeat.product.dto.RankingProductsResponse; -import com.funeat.product.dto.SearchProductResultsResponse; -import com.funeat.product.dto.SearchProductsResponse; -import com.funeat.recipe.dto.SortingRecipesResponse; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api") -public class ProductApiController implements ProductController { - - private final ProductService productService; - - public ProductApiController(final ProductService productService) { - this.productService = productService; - } - - @GetMapping("/categories/{categoryId}/products") - public ResponseEntity getAllProductsInCategory(@PathVariable final Long categoryId, - @RequestParam final Long lastProductId, - @RequestParam final String sort) { - final ProductSortCondition sortCondition = ProductSortCondition.toDto(sort); - final ProductsInCategoryResponse response = productService.getAllProductsInCategory(categoryId, lastProductId, sortCondition); - return ResponseEntity.ok(response); - } - - @GetMapping("/products/{productId}") - public ResponseEntity getProductDetail(@PathVariable final Long productId) { - final ProductResponse response = productService.findProductDetail(productId); - return ResponseEntity.ok(response); - } - - @GetMapping("/ranks/products") - public ResponseEntity getRankingProducts() { - final RankingProductsResponse response = productService.getTop3Products(); - return ResponseEntity.ok(response); - } - - @GetMapping("/search/products") - public ResponseEntity searchProducts(@RequestParam final String query, - @PageableDefault final Pageable pageable) { - final PageRequest pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize()); - final SearchProductsResponse response = productService.searchProducts(query, pageRequest); - return ResponseEntity.ok(response); - } - - @GetMapping("/search/products/results") - public ResponseEntity getSearchResults(@RequestParam final String query, - @PageableDefault final Pageable pageable) { - final PageRequest pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize()); - final SearchProductResultsResponse response = productService.getSearchResults(query, pageRequest); - return ResponseEntity.ok(response); - } - - @GetMapping("/products/{productId}/recipes") - public ResponseEntity getProductRecipes(@PathVariable final Long productId, - @PageableDefault final Pageable pageable) { - final SortingRecipesResponse response = productService.getProductRecipes(productId, pageable); - return ResponseEntity.ok(response); - } -} diff --git a/backend/src/main/java/com/funeat/product/presentation/ProductController.java b/backend/src/main/java/com/funeat/product/presentation/ProductController.java deleted file mode 100644 index 3fa704eb7..000000000 --- a/backend/src/main/java/com/funeat/product/presentation/ProductController.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.funeat.product.presentation; - -import com.funeat.product.dto.ProductResponse; -import com.funeat.product.dto.ProductsInCategoryResponse; -import com.funeat.product.dto.RankingProductsResponse; -import com.funeat.product.dto.SearchProductResultsResponse; -import com.funeat.product.dto.SearchProductsResponse; -import com.funeat.recipe.dto.SortingRecipesResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestParam; - -@Tag(name = "01.Product", description = "μƒν’ˆ κΈ°λŠ₯") -public interface ProductController { - - @Operation(summary = "ν•΄λ‹Ή μΉ΄ν…Œκ³ λ¦¬ μƒν’ˆ 쑰회", description = "ν•΄λ‹Ή μΉ΄ν…Œκ³ λ¦¬μ˜ μƒν’ˆμ„ μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "ν•΄λ‹Ή μΉ΄ν…Œκ³ λ¦¬ μƒν’ˆ 쑰회 성곡." - ) - @GetMapping - ResponseEntity getAllProductsInCategory( - @PathVariable final Long categoryId, - @RequestParam final Long lastProductId, - @RequestParam final String sort - ); - - @Operation(summary = "ν•΄λ‹Ή μƒν’ˆ 상세 쑰회", description = "ν•΄λ‹Ή μƒν’ˆ 상세정보λ₯Ό μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "ν•΄λ‹Ή μƒν’ˆ 상세 쑰회 성곡." - ) - @GetMapping - ResponseEntity getProductDetail(@PathVariable final Long productId); - - @Operation(summary = "전체 μƒν’ˆ λž­ν‚Ή 쑰회", description = "전체 μƒν’ˆλ“€ μ€‘μ—μ„œ λž­ν‚Ή TOP3λ₯Ό μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "전체 μƒν’ˆ λž­ν‚Ή 쑰회 성곡." - ) - @GetMapping - ResponseEntity getRankingProducts(); - - @Operation(summary = "μƒν’ˆ μžλ™ μ™„μ„± 검색", description = "곡톡 μƒν’ˆ 및 PB μƒν’ˆλ“€μ˜ 이름 쀑에 ν•΄λ‹Ήν•˜λŠ” λ¬Έμžμ—΄μ΄ ν¬ν•¨λ˜μ–΄ μžˆλŠ”μ§€ κ²€μƒ‰ν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "μƒν’ˆ 검색 성곡." - ) - @GetMapping - ResponseEntity searchProducts(@RequestParam final String query, - @PageableDefault final Pageable pageable); - - @Operation(summary = "μƒν’ˆ 검색 κ²°κ³Ό 쑰회", description = "λ¬Έμžμ—΄μ„ λ°›μ•„ μƒν’ˆμ„ κ²€μƒ‰ν•˜κ³  검색 결과듀을 μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "μƒν’ˆ 검색 κ²°κ³Ό 쑰회 성곡." - ) - @GetMapping - ResponseEntity getSearchResults(@RequestParam final String query, - @PageableDefault final Pageable pageable); - - @Operation(summary = "ν•΄λ‹Ή μƒν’ˆ κΏ€μ‘°ν•© λͺ©λ‘ 쑰회", description = "ν•΄λ‹Ή μƒν’ˆμ΄ ν¬ν•¨λœ κΏ€μ‘°ν•© λͺ©λ‘μ„ μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "ν•΄λ‹Ή μƒν’ˆ κΏ€μ‘°ν•© λͺ©λ‘ 쑰회 성곡." - ) - @GetMapping - ResponseEntity getProductRecipes(@PathVariable final Long productId, - @PageableDefault final Pageable pageable); -} diff --git a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java deleted file mode 100644 index 19545b20b..000000000 --- a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.funeat.recipe.application; - -import static com.funeat.member.exception.MemberErrorCode.MEMBER_DUPLICATE_FAVORITE; -import static com.funeat.member.exception.MemberErrorCode.MEMBER_NOT_FOUND; -import static com.funeat.product.exception.ProductErrorCode.PRODUCT_NOT_FOUND; -import static com.funeat.recipe.exception.RecipeErrorCode.RECIPE_NOT_FOUND; - -import com.funeat.comment.domain.Comment; -import com.funeat.comment.persistence.CommentRepository; -import com.funeat.comment.specification.CommentSpecification; -import com.funeat.common.ImageUploader; -import com.funeat.common.dto.PageDto; -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.RecipeFavorite; -import com.funeat.member.dto.MemberRecipeDto; -import com.funeat.member.dto.MemberRecipeProductDto; -import com.funeat.member.dto.MemberRecipesResponse; -import com.funeat.member.exception.MemberException.MemberDuplicateFavoriteException; -import com.funeat.member.exception.MemberException.MemberNotFoundException; -import com.funeat.member.persistence.MemberRepository; -import com.funeat.member.persistence.RecipeFavoriteRepository; -import com.funeat.product.domain.Product; -import com.funeat.product.domain.ProductRecipe; -import com.funeat.product.exception.ProductException.ProductNotFoundException; -import com.funeat.product.persistence.ProductRecipeRepository; -import com.funeat.product.persistence.ProductRepository; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import com.funeat.recipe.dto.RankingRecipeDto; -import com.funeat.recipe.dto.RankingRecipesResponse; -import com.funeat.recipe.dto.RecipeAuthorDto; -import com.funeat.recipe.dto.RecipeCommentCondition; -import com.funeat.recipe.dto.RecipeCommentCreateRequest; -import com.funeat.recipe.dto.RecipeCommentResponse; -import com.funeat.recipe.dto.RecipeCommentsResponse; -import com.funeat.recipe.dto.RecipeCreateRequest; -import com.funeat.recipe.dto.RecipeDetailResponse; -import com.funeat.recipe.dto.RecipeDto; -import com.funeat.recipe.dto.RecipeFavoriteRequest; -import com.funeat.recipe.dto.SearchRecipeResultDto; -import com.funeat.recipe.dto.SearchRecipeResultsResponse; -import com.funeat.recipe.dto.SortingRecipesResponse; -import com.funeat.recipe.exception.RecipeException.RecipeNotFoundException; -import com.funeat.recipe.persistence.RecipeImageRepository; -import com.funeat.recipe.persistence.RecipeRepository; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -@Service -@Transactional(readOnly = true) -public class RecipeService { - - private static final long RANKING_MINIMUM_FAVORITE_COUNT = 1L; - private static final int RANKING_SIZE = 3; - private static final int RECIPE_COMMENT_PAGE_SIZE = 10; - private static final int DEFAULT_CURSOR_PAGINATION_SIZE = 11; - - private final MemberRepository memberRepository; - private final ProductRepository productRepository; - private final ProductRecipeRepository productRecipeRepository; - private final RecipeRepository recipeRepository; - private final RecipeImageRepository recipeImageRepository; - private final RecipeFavoriteRepository recipeFavoriteRepository; - private final CommentRepository commentRepository; - private final ImageUploader imageUploader; - - public RecipeService(final MemberRepository memberRepository, final ProductRepository productRepository, - final ProductRecipeRepository productRecipeRepository, final RecipeRepository recipeRepository, - final RecipeImageRepository recipeImageRepository, - final RecipeFavoriteRepository recipeFavoriteRepository, - final CommentRepository commentRepository, final ImageUploader imageUploader) { - this.memberRepository = memberRepository; - this.productRepository = productRepository; - this.productRecipeRepository = productRecipeRepository; - this.recipeRepository = recipeRepository; - this.recipeImageRepository = recipeImageRepository; - this.recipeFavoriteRepository = recipeFavoriteRepository; - this.commentRepository = commentRepository; - this.imageUploader = imageUploader; - } - - @Transactional - public Long create(final Long memberId, final List images, final RecipeCreateRequest request) { - final Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - - final Recipe savedRecipe = recipeRepository.save(new Recipe(request.getTitle(), request.getContent(), member)); - request.getProductIds() - .stream() - .map(productId -> productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId))) - .forEach(product -> productRecipeRepository.save(new ProductRecipe(product, savedRecipe))); - - if (Objects.nonNull(images)) { - images.forEach(image -> { - final String imageUrl = imageUploader.upload(image); - recipeImageRepository.save(new RecipeImage(imageUrl, savedRecipe)); - }); - } - - return savedRecipe.getId(); - } - - public RecipeDetailResponse getRecipeDetail(final Long memberId, final Long recipeId) { - final Recipe recipe = recipeRepository.findById(recipeId) - .orElseThrow(() -> new RecipeNotFoundException(RECIPE_NOT_FOUND, recipeId)); - final List images = recipeImageRepository.findByRecipe(recipe); - final List products = productRecipeRepository.findProductByRecipe(recipe); - final Long totalPrice = products.stream() - .mapToLong(Product::getPrice) - .sum(); - - final Boolean favorite = calculateFavoriteChecked(memberId, recipe); - - return RecipeDetailResponse.toResponse(recipe, images, products, totalPrice, favorite); - } - - private Boolean calculateFavoriteChecked(final Long memberId, final Recipe recipe) { - final Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - return recipeFavoriteRepository.existsByMemberAndRecipeAndFavoriteTrue(member, recipe); - } - - public MemberRecipesResponse findRecipeByMember(final Long memberId, final Pageable pageable) { - final Member findMember = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - - final Page sortedRecipePages = recipeRepository.findRecipesByMember(findMember, pageable); - - final PageDto page = PageDto.toDto(sortedRecipePages); - final List dtos = sortedRecipePages.stream() - .map(recipe -> { - final List findRecipeImages = recipeImageRepository.findByRecipe(recipe); - final List productsByRecipe = productRecipeRepository.findProductByRecipe(recipe); - final List memberRecipeProductDtos = productsByRecipe.stream() - .map(MemberRecipeProductDto::toDto) - .collect(Collectors.toList()); - return MemberRecipeDto.toDto(recipe, findRecipeImages, memberRecipeProductDtos); - }) - .collect(Collectors.toList()); - - return MemberRecipesResponse.toResponse(page, dtos); - } - - public SortingRecipesResponse getSortingRecipes(final Pageable pageable) { - final Page pages = recipeRepository.findAll(pageable); - - final PageDto page = PageDto.toDto(pages); - final List recipes = pages.getContent().stream() - .map(recipe -> { - final List images = recipeImageRepository.findByRecipe(recipe); - final List products = productRecipeRepository.findProductByRecipe(recipe); - return RecipeDto.toDto(recipe, images, products); - }) - .collect(Collectors.toList()); - - return SortingRecipesResponse.toResponse(page, recipes); - } - - @Transactional - public void likeRecipe(final Long memberId, final Long recipeId, final RecipeFavoriteRequest request) { - final Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - final Recipe recipe = recipeRepository.findByIdForUpdate(recipeId) - .orElseThrow(() -> new RecipeNotFoundException(RECIPE_NOT_FOUND, recipeId)); - - final RecipeFavorite recipeFavorite = recipeFavoriteRepository.findByMemberAndRecipe(member, recipe) - .orElseGet(() -> createAndSaveRecipeFavorite(member, recipe, request.getFavorite())); - - recipeFavorite.updateFavorite(request.getFavorite()); - } - - private RecipeFavorite createAndSaveRecipeFavorite(final Member member, final Recipe recipe, - final Boolean favorite) { - try { - final RecipeFavorite recipeFavorite = RecipeFavorite.create(member, recipe, favorite); - return recipeFavoriteRepository.save(recipeFavorite); - } catch (final DataIntegrityViolationException e) { - throw new MemberDuplicateFavoriteException(MEMBER_DUPLICATE_FAVORITE, member.getId()); - } - } - - public SearchRecipeResultsResponse getSearchResults(final String query, final Pageable pageable) { - final Page recipePages = recipeRepository.findAllByProductNameContaining(query, pageable); - - final PageDto page = PageDto.toDto(recipePages); - final List dtos = recipePages.stream() - .map(recipe -> { - final List findRecipeImages = recipeImageRepository.findByRecipe(recipe); - final List productsByRecipe = productRecipeRepository.findProductByRecipe(recipe); - return SearchRecipeResultDto.toDto(recipe, findRecipeImages, productsByRecipe); - }) - .collect(Collectors.toList()); - return SearchRecipeResultsResponse.toResponse(page, dtos); - } - - public RankingRecipesResponse getTop3Recipes() { - final List recipes = recipeRepository.findRecipesByFavoriteCountGreaterThanEqual(RANKING_MINIMUM_FAVORITE_COUNT); - - final List dtos = recipes.stream() - .sorted(Comparator.comparing(Recipe::calculateRankingScore).reversed()) - .limit(RANKING_SIZE) - .map(recipe -> { - final List findRecipeImages = recipeImageRepository.findByRecipe(recipe); - final RecipeAuthorDto author = RecipeAuthorDto.toDto(recipe.getMember()); - return RankingRecipeDto.toDto(recipe, findRecipeImages, author); - }) - .collect(Collectors.toList()); - return RankingRecipesResponse.toResponse(dtos); - } - - @Transactional - public Long writeCommentOfRecipe(final Long memberId, final Long recipeId, - final RecipeCommentCreateRequest request) { - final Member findMember = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - - final Recipe findRecipe = recipeRepository.findById(recipeId) - .orElseThrow(() -> new RecipeNotFoundException(RECIPE_NOT_FOUND, recipeId)); - - final Comment comment = new Comment(findRecipe, findMember, request.getComment()); - - final Comment savedComment = commentRepository.save(comment); - return savedComment.getId(); - } - - public RecipeCommentsResponse getCommentsOfRecipe(final Long recipeId, final RecipeCommentCondition condition) { - final Recipe findRecipe = recipeRepository.findById(recipeId) - .orElseThrow(() -> new RecipeNotFoundException(RECIPE_NOT_FOUND, recipeId)); - - final Specification specification = CommentSpecification.findAllByRecipe(findRecipe, - condition.getLastId()); - - final PageRequest pageable = PageRequest.of(0, DEFAULT_CURSOR_PAGINATION_SIZE, Sort.by("id").descending()); - - final Page commentPaginationResult = commentRepository.findAllForPagination(specification, pageable, - condition.getTotalElements()); - - final List recipeCommentResponses = getRecipeCommentResponses( - commentPaginationResult.getContent()); - - final Boolean hasNext = hasNextPage(commentPaginationResult); - - return RecipeCommentsResponse.toResponse(recipeCommentResponses, hasNext, - commentPaginationResult.getTotalElements()); - } - - private List getRecipeCommentResponses(final List findComments) { - final List recipeCommentResponses = new ArrayList<>(); - final int resultSize = getResultSize(findComments); - final List comments = findComments.subList(0, resultSize); - - for (final Comment comment : comments) { - final RecipeCommentResponse recipeCommentResponse = RecipeCommentResponse.toResponse(comment); - recipeCommentResponses.add(recipeCommentResponse); - } - return recipeCommentResponses; - } - - private int getResultSize(final List findComments) { - if (findComments.size() < DEFAULT_CURSOR_PAGINATION_SIZE) { - return findComments.size(); - } - return RECIPE_COMMENT_PAGE_SIZE; - } - - private Boolean hasNextPage(final Page findComments) { - return findComments.getContent().size() > RECIPE_COMMENT_PAGE_SIZE; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/domain/Recipe.java b/backend/src/main/java/com/funeat/recipe/domain/Recipe.java deleted file mode 100644 index 5ffb0438b..000000000 --- a/backend/src/main/java/com/funeat/recipe/domain/Recipe.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.funeat.recipe.domain; - -import com.funeat.member.domain.Member; -import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; - -@Entity -public class Recipe { - - private static final double RANKING_GRAVITY = 0.1; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String title; - - private String content; - - @Column(nullable = false) - private LocalDateTime createdAt = LocalDateTime.now(); - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - - private Long favoriteCount = 0L; - - protected Recipe() { - } - - public Recipe(final String title, final String content, final Member member) { - this.title = title; - this.content = content; - this.member = member; - } - - public Recipe(final String title, final String content, final Member member, - final Long favoriteCount) { - this.title = title; - this.content = content; - this.member = member; - this.favoriteCount = favoriteCount; - } - - public Recipe(final String title, final String content, final Member member, final Long favoriteCount, - final LocalDateTime createdAt) { - this.title = title; - this.content = content; - this.member = member; - this.favoriteCount = favoriteCount; - this.createdAt = createdAt; - } - - public Double calculateRankingScore() { - final long age = ChronoUnit.DAYS.between(createdAt, LocalDateTime.now()); - final double denominator = Math.pow(age + 1.0, RANKING_GRAVITY); - return favoriteCount / denominator; - } - - public void addFavoriteCount() { - this.favoriteCount++; - } - - public void minusFavoriteCount() { - this.favoriteCount--; - } - - public Long getId() { - return id; - } - - public String getTitle() { - return title; - } - - public String getContent() { - return content; - } - - public Member getMember() { - return member; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/domain/RecipeImage.java b/backend/src/main/java/com/funeat/recipe/domain/RecipeImage.java deleted file mode 100644 index 0dffc61ee..000000000 --- a/backend/src/main/java/com/funeat/recipe/domain/RecipeImage.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.funeat.recipe.domain; - -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; - -@Entity -public class RecipeImage { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String image; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "recipe_id") - private Recipe recipe; - - protected RecipeImage() { - } - - public RecipeImage(final String image, final Recipe recipe) { - this.image = image; - this.recipe = recipe; - } - - public Long getId() { - return id; - } - - public String getImage() { - return image; - } - - public Recipe getRecipe() { - return recipe; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/ProductRecipeDto.java b/backend/src/main/java/com/funeat/recipe/dto/ProductRecipeDto.java deleted file mode 100644 index 60ab88ea9..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/ProductRecipeDto.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.product.domain.Product; - -public class ProductRecipeDto { - - private final Long id; - private final String name; - private final Long price; - - private ProductRecipeDto(final Long id, final String name, final Long price) { - this.id = id; - this.name = name; - this.price = price; - } - - public static ProductRecipeDto toDto(final Product product) { - return new ProductRecipeDto(product.getId(), product.getName(), product.getPrice()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public Long getPrice() { - return price; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RankingRecipeDto.java b/backend/src/main/java/com/funeat/recipe/dto/RankingRecipeDto.java deleted file mode 100644 index 3f26a69ca..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RankingRecipeDto.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import java.time.LocalDateTime; -import java.util.List; - -public class RankingRecipeDto { - - private final Long id; - private final String image; - private final String title; - private final RecipeAuthorDto author; - private final Long favoriteCount; - private final LocalDateTime createdAt; - - public RankingRecipeDto(final Long id, final String image, final String title, final RecipeAuthorDto author, - final Long favoriteCount, final LocalDateTime createdAt) { - this.id = id; - this.image = image; - this.title = title; - this.author = author; - this.favoriteCount = favoriteCount; - this.createdAt = createdAt; - } - - public static RankingRecipeDto toDto(final Recipe recipe, final List images, - final RecipeAuthorDto author) { - if (images.isEmpty()) { - return new RankingRecipeDto(recipe.getId(), null, recipe.getTitle(), author, - recipe.getFavoriteCount(), recipe.getCreatedAt()); - } - return new RankingRecipeDto(recipe.getId(), images.get(0).getImage(), recipe.getTitle(), author, - recipe.getFavoriteCount(), recipe.getCreatedAt()); - } - - public Long getId() { - return id; - } - - public String getImage() { - return image; - } - - public String getTitle() { - return title; - } - - public RecipeAuthorDto getAuthor() { - return author; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RankingRecipesResponse.java b/backend/src/main/java/com/funeat/recipe/dto/RankingRecipesResponse.java deleted file mode 100644 index d446d340e..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RankingRecipesResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.funeat.recipe.dto; - -import java.util.List; - -public class RankingRecipesResponse { - - private final List recipes; - - public RankingRecipesResponse(final List recipes) { - this.recipes = recipes; - } - - public static RankingRecipesResponse toResponse(final List recipes) { - return new RankingRecipesResponse(recipes); - } - - public List getRecipes() { - return recipes; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeAuthorDto.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeAuthorDto.java deleted file mode 100644 index 881cca1da..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeAuthorDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.member.domain.Member; - -public class RecipeAuthorDto { - - private final String profileImage; - private final String nickname; - - private RecipeAuthorDto(final String profileImage, final String nickname) { - this.profileImage = profileImage; - this.nickname = nickname; - } - - public static RecipeAuthorDto toDto(final Member member) { - return new RecipeAuthorDto(member.getProfileImage(), member.getNickname()); - } - - public String getProfileImage() { - return profileImage; - } - - public String getNickname() { - return nickname; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentCondition.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentCondition.java deleted file mode 100644 index dcb3cf2d1..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentCondition.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.funeat.recipe.dto; - -public class RecipeCommentCondition { - - private final Long lastId; - private final Long totalElements; - - public RecipeCommentCondition(final Long lastId, final Long totalElements) { - this.lastId = lastId; - this.totalElements = totalElements; - } - - public Long getLastId() { - return lastId; - } - - public Long getTotalElements() { - return totalElements; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentCreateRequest.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentCreateRequest.java deleted file mode 100644 index 2b24e9207..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentCreateRequest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.funeat.recipe.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; - -public class RecipeCommentCreateRequest { - - @NotBlank(message = "κΏ€μ‘°ν•© λŒ“κΈ€μ„ 확인해 μ£Όμ„Έμš”") - @Size(max = 200, message = "κΏ€μ‘°ν•© λŒ“κΈ€μ€ μ΅œλŒ€ 200μžκΉŒμ§€ μž…λ ₯ κ°€λŠ₯ν•©λ‹ˆλ‹€") - private final String comment; - - public RecipeCommentCreateRequest(@JsonProperty("comment") final String comment) { - this.comment = comment; - } - - public String getComment() { - return comment; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentMemberResponse.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentMemberResponse.java deleted file mode 100644 index ad66d7811..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentMemberResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.member.domain.Member; - -public class RecipeCommentMemberResponse { - - private final String nickname; - private final String profileImage; - - private RecipeCommentMemberResponse(final String nickname, final String profileImage) { - this.nickname = nickname; - this.profileImage = profileImage; - } - - public static RecipeCommentMemberResponse toResponse(final Member member) { - return new RecipeCommentMemberResponse(member.getNickname(), member.getProfileImage()); - } - - public String getNickname() { - return nickname; - } - - public String getProfileImage() { - return profileImage; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentResponse.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentResponse.java deleted file mode 100644 index 989e52bd5..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentResponse.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.comment.domain.Comment; -import java.time.LocalDateTime; - -public class RecipeCommentResponse { - - private final Long id; - private final String comment; - private final LocalDateTime createdAt; - private final RecipeCommentMemberResponse author; - - private RecipeCommentResponse(final Long id, final String comment, final LocalDateTime createdAt, - final RecipeCommentMemberResponse author) { - this.id = id; - this.comment = comment; - this.createdAt = createdAt; - this.author = author; - } - - public static RecipeCommentResponse toResponse(final Comment comment) { - final RecipeCommentMemberResponse author = RecipeCommentMemberResponse.toResponse(comment.getMember()); - - return new RecipeCommentResponse(comment.getId(), comment.getComment(), comment.getCreatedAt(), author); - } - - public Long getId() { - return id; - } - - public String getComment() { - return comment; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public RecipeCommentMemberResponse getAuthor() { - return author; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentsResponse.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentsResponse.java deleted file mode 100644 index 7e7d6dc19..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeCommentsResponse.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.funeat.recipe.dto; - -import java.util.List; - -public class RecipeCommentsResponse { - - private final List comments; - private final boolean hasNext; - private final Long totalElements; - - private RecipeCommentsResponse(final List comments, final boolean hasNext, - final Long totalElements) { - this.comments = comments; - this.hasNext = hasNext; - this.totalElements = totalElements; - } - - public static RecipeCommentsResponse toResponse(final List comments, final boolean hasNext, - final Long totalElements) { - return new RecipeCommentsResponse(comments, hasNext, totalElements); - } - - public List getComments() { - return comments; - } - - public boolean getHasNext() { - return hasNext; - } - - public Long getTotalElements() { - return totalElements; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeCreateRequest.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeCreateRequest.java deleted file mode 100644 index 201c28cf0..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeCreateRequest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.funeat.recipe.dto; - -import java.util.List; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -public class RecipeCreateRequest { - - @NotBlank(message = "κΏ€μ‘°ν•© 이름을 확인해 μ£Όμ„Έμš”") - private final String title; - - @NotNull(message = "μƒν’ˆ ID λͺ©λ‘μ„ 확인해 μ£Όμ„Έμš”") - @Size(min = 1, message = "적어도 1개의 μƒν’ˆ IDκ°€ ν•„μš”ν•©λ‹ˆλ‹€") - private final List productIds; - - @NotBlank(message = "κΏ€μ‘°ν•© λ‚΄μš©μ„ 확인해 μ£Όμ„Έμš”") - @Size(max = 500, message = "κΏ€μ‘°ν•© λ‚΄μš©μ€ μ΅œλŒ€ 500μžκΉŒμ§€ μž…λ ₯ κ°€λŠ₯ν•©λ‹ˆλ‹€") - private final String content; - - public RecipeCreateRequest(final String title, final List productIds, final String content) { - this.title = title; - this.productIds = productIds; - this.content = content; - } - - public String getTitle() { - return title; - } - - public List getProductIds() { - return productIds; - } - - public String getContent() { - return content; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeDetailResponse.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeDetailResponse.java deleted file mode 100644 index 6ccef9410..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeDetailResponse.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.product.domain.Product; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import java.time.LocalDateTime; -import java.util.List; -import java.util.stream.Collectors; - -public class RecipeDetailResponse { - - private final Long id; - private final List images; - private final String title; - private final String content; - private final RecipeAuthorDto author; - private final List products; - private final Long totalPrice; - private final Long favoriteCount; - private final Boolean favorite; - private final LocalDateTime createdAt; - - public RecipeDetailResponse(final Long id, final List images, final String title, final String content, - final RecipeAuthorDto author, final List products, - final Long totalPrice, final Long favoriteCount, final Boolean favorite, - final LocalDateTime createdAt) { - this.id = id; - this.images = images; - this.title = title; - this.content = content; - this.author = author; - this.products = products; - this.totalPrice = totalPrice; - this.favoriteCount = favoriteCount; - this.favorite = favorite; - this.createdAt = createdAt; - } - - public static RecipeDetailResponse toResponse(final Recipe recipe, final List recipeImages, - final List products, final Long totalPrice, - final Boolean favorite) { - final RecipeAuthorDto authorDto = RecipeAuthorDto.toDto(recipe.getMember()); - final List productDtos = products.stream() - .map(ProductRecipeDto::toDto) - .collect(Collectors.toList()); - final List images = recipeImages.stream() - .map(RecipeImage::getImage) - .collect(Collectors.toList()); - return new RecipeDetailResponse(recipe.getId(), images, recipe.getTitle(), recipe.getContent(), - authorDto, productDtos, totalPrice, recipe.getFavoriteCount(), favorite, recipe.getCreatedAt()); - } - - public Long getId() { - return id; - } - - public List getImages() { - return images; - } - - public String getTitle() { - return title; - } - - public String getContent() { - return content; - } - - public RecipeAuthorDto getAuthor() { - return author; - } - - public List getProducts() { - return products; - } - - public Long getTotalPrice() { - return totalPrice; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public Boolean getFavorite() { - return favorite; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeDto.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeDto.java deleted file mode 100644 index 51cd78fc2..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeDto.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.product.domain.Product; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import java.time.LocalDateTime; -import java.util.List; -import java.util.stream.Collectors; - -public class RecipeDto { - - private final Long id; - private final String image; - private final String title; - private final RecipeAuthorDto author; - private final List products; - private final Long favoriteCount; - private final LocalDateTime createdAt; - - public RecipeDto(final Long id, final String image, final String title, final RecipeAuthorDto author, - final List products, - final Long favoriteCount, final LocalDateTime createdAt) { - this.id = id; - this.image = image; - this.title = title; - this.author = author; - this.products = products; - this.favoriteCount = favoriteCount; - this.createdAt = createdAt; - } - - public static RecipeDto toDto(final Recipe recipe, final List recipeImages, - final List products) { - final RecipeAuthorDto authorDto = RecipeAuthorDto.toDto(recipe.getMember()); - final List productDtos = products.stream() - .map(ProductRecipeDto::toDto) - .collect(Collectors.toList()); - if (recipeImages.isEmpty()) { - return new RecipeDto(recipe.getId(), null, recipe.getTitle(), authorDto, productDtos, - recipe.getFavoriteCount(), recipe.getCreatedAt()); - } - return new RecipeDto(recipe.getId(), recipeImages.get(0).getImage(), recipe.getTitle(), authorDto, productDtos, - recipe.getFavoriteCount(), recipe.getCreatedAt()); - } - - public Long getId() { - return id; - } - - public String getImage() { - return image; - } - - public String getTitle() { - return title; - } - - public RecipeAuthorDto getAuthor() { - return author; - } - - public List getProducts() { - return products; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeFavoriteRequest.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeFavoriteRequest.java deleted file mode 100644 index f82ada428..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/RecipeFavoriteRequest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.funeat.recipe.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotNull; - -public class RecipeFavoriteRequest { - - @NotNull(message = "μ’‹μ•„μš”λ₯Ό ν™•μΈν•΄μ£Όμ„Έμš”") - private final Boolean favorite; - - @JsonCreator - public RecipeFavoriteRequest(@JsonProperty("favorite") final Boolean favorite) { - this.favorite = favorite; - } - - public Boolean getFavorite() { - return favorite; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/SearchRecipeResultDto.java b/backend/src/main/java/com/funeat/recipe/dto/SearchRecipeResultDto.java deleted file mode 100644 index 0feb4b71d..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/SearchRecipeResultDto.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.product.domain.Product; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import java.time.LocalDateTime; -import java.util.List; -import java.util.stream.Collectors; - -public class SearchRecipeResultDto { - - private final Long id; - private final String image; - private final String title; - private final RecipeAuthorDto author; - private final List products; - private final Long favoriteCount; - private final LocalDateTime createdAt; - - public SearchRecipeResultDto(final Long id, final String image, final String title, final RecipeAuthorDto author, - final List products, final Long favoriteCount, - final LocalDateTime createdAt) { - this.id = id; - this.image = image; - this.title = title; - this.author = author; - this.products = products; - this.favoriteCount = favoriteCount; - this.createdAt = createdAt; - } - - public static SearchRecipeResultDto toDto(final Recipe recipe, final List images, - final List products) { - final List productRecipes = products.stream() - .map(ProductRecipeDto::toDto) - .collect(Collectors.toList()); - - if (images.isEmpty()) { - return new SearchRecipeResultDto(recipe.getId(), null, recipe.getTitle(), - RecipeAuthorDto.toDto(recipe.getMember()), productRecipes, recipe.getFavoriteCount(), - recipe.getCreatedAt()); - } - return new SearchRecipeResultDto(recipe.getId(), images.get(0).getImage(), recipe.getTitle(), - RecipeAuthorDto.toDto(recipe.getMember()), productRecipes, recipe.getFavoriteCount(), - recipe.getCreatedAt()); - } - - public Long getId() { - return id; - } - - public String getImage() { - return image; - } - - public String getTitle() { - return title; - } - - public RecipeAuthorDto getAuthor() { - return author; - } - - public List getProducts() { - return products; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/SearchRecipeResultsResponse.java b/backend/src/main/java/com/funeat/recipe/dto/SearchRecipeResultsResponse.java deleted file mode 100644 index 3fb88dc53..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/SearchRecipeResultsResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.common.dto.PageDto; -import java.util.List; - -public class SearchRecipeResultsResponse { - - private final PageDto page; - private final List recipes; - - public SearchRecipeResultsResponse(final PageDto page, final List recipes) { - this.page = page; - this.recipes = recipes; - } - - public static SearchRecipeResultsResponse toResponse(final PageDto page, - final List recipes) { - return new SearchRecipeResultsResponse(page, recipes); - } - - public PageDto getPage() { - return page; - } - - public List getRecipes() { - return recipes; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/dto/SortingRecipesResponse.java b/backend/src/main/java/com/funeat/recipe/dto/SortingRecipesResponse.java deleted file mode 100644 index e6e6003f0..000000000 --- a/backend/src/main/java/com/funeat/recipe/dto/SortingRecipesResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.funeat.recipe.dto; - -import com.funeat.common.dto.PageDto; -import java.util.List; - -public class SortingRecipesResponse { - - private final PageDto page; - private final List recipes; - - public SortingRecipesResponse(final PageDto page, final List recipes) { - this.page = page; - this.recipes = recipes; - } - - public static SortingRecipesResponse toResponse(final PageDto page, final List recipes) { - return new SortingRecipesResponse(page, recipes); - } - - public PageDto getPage() { - return page; - } - - public List getRecipes() { - return recipes; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/exception/RecipeErrorCode.java b/backend/src/main/java/com/funeat/recipe/exception/RecipeErrorCode.java deleted file mode 100644 index 887da8864..000000000 --- a/backend/src/main/java/com/funeat/recipe/exception/RecipeErrorCode.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.funeat.recipe.exception; - -import org.springframework.http.HttpStatus; - -public enum RecipeErrorCode { - - RECIPE_NOT_FOUND(HttpStatus.NOT_FOUND, "μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” κΏ€μ‘°ν•©μž…λ‹ˆλ‹€. κΏ€μ‘°ν•© idλ₯Ό ν™•μΈν•˜μ„Έμš”.", "7001"), - ; - - private final HttpStatus status; - private final String message; - private final String code; - - RecipeErrorCode(final HttpStatus status, final String message, final String code) { - this.status = status; - this.message = message; - this.code = code; - } - - public HttpStatus getStatus() { - return status; - } - - public String getMessage() { - return message; - } - - public String getCode() { - return code; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/exception/RecipeException.java b/backend/src/main/java/com/funeat/recipe/exception/RecipeException.java deleted file mode 100644 index f7352c746..000000000 --- a/backend/src/main/java/com/funeat/recipe/exception/RecipeException.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.funeat.recipe.exception; - -import com.funeat.exception.ErrorCode; -import com.funeat.exception.GlobalException; -import org.springframework.http.HttpStatus; - -public class RecipeException extends GlobalException { - - public RecipeException(final HttpStatus status, final ErrorCode errorCode) { - super(status, errorCode); - } - - public static class RecipeNotFoundException extends RecipeException { - public RecipeNotFoundException(final RecipeErrorCode errorCode, final Long RecipeId) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), RecipeId)); - } - } -} diff --git a/backend/src/main/java/com/funeat/recipe/persistence/RecipeImageRepository.java b/backend/src/main/java/com/funeat/recipe/persistence/RecipeImageRepository.java deleted file mode 100644 index 04d2ca6a1..000000000 --- a/backend/src/main/java/com/funeat/recipe/persistence/RecipeImageRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.funeat.recipe.persistence; - -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface RecipeImageRepository extends JpaRepository { - - List findByRecipe(final Recipe recipe); -} diff --git a/backend/src/main/java/com/funeat/recipe/persistence/RecipeRepository.java b/backend/src/main/java/com/funeat/recipe/persistence/RecipeRepository.java deleted file mode 100644 index ce5ef3c31..000000000 --- a/backend/src/main/java/com/funeat/recipe/persistence/RecipeRepository.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.funeat.recipe.persistence; - -import static javax.persistence.LockModeType.PESSIMISTIC_WRITE; - -import com.funeat.member.domain.Member; -import com.funeat.product.domain.Product; -import com.funeat.recipe.domain.Recipe; -import java.util.List; -import java.util.Optional; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Lock; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface RecipeRepository extends JpaRepository { - - @Query("SELECT r FROM Recipe r " - + "JOIN FETCH r.member m") - Recipe findRecipeWithMemberById(final Long id); - - Page findRecipesByMember(final Member member, final Pageable pageable); - - @Query("SELECT DISTINCT r FROM Recipe r " - + "LEFT JOIN ProductRecipe pr ON pr.recipe.id = r.id " - + "WHERE pr.product.name LIKE CONCAT('%', :name, '%')") - Page findAllByProductNameContaining(@Param("name") final String name, final Pageable pageable); - - Page findAll(final Pageable pageable); - - @Query("SELECT r FROM Recipe r LEFT JOIN ProductRecipe pr ON pr.product = :product WHERE pr.recipe.id = r.id") - Page findRecipesByProduct(final Product product, final Pageable pageable); - - @Lock(PESSIMISTIC_WRITE) - @Query("SELECT r FROM Recipe r WHERE r.id=:id") - Optional findByIdForUpdate(final Long id); - - List findRecipesByFavoriteCountGreaterThanEqual(final Long favoriteCount); -} diff --git a/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java b/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java deleted file mode 100644 index 17eb1f1d6..000000000 --- a/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.funeat.recipe.presentation; - -import com.funeat.auth.dto.LoginInfo; -import com.funeat.auth.util.AuthenticationPrincipal; -import com.funeat.common.logging.Logging; -import com.funeat.recipe.application.RecipeService; -import com.funeat.recipe.dto.RankingRecipesResponse; -import com.funeat.recipe.dto.RecipeCommentCondition; -import com.funeat.recipe.dto.RecipeCommentCreateRequest; -import com.funeat.recipe.dto.RecipeCommentsResponse; -import com.funeat.recipe.dto.RecipeCreateRequest; -import com.funeat.recipe.dto.RecipeDetailResponse; -import com.funeat.recipe.dto.RecipeFavoriteRequest; -import com.funeat.recipe.dto.SearchRecipeResultsResponse; -import com.funeat.recipe.dto.SortingRecipesResponse; -import java.net.URI; -import java.util.List; -import javax.validation.Valid; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -@RestController -public class RecipeApiController implements RecipeController { - - private final RecipeService recipeService; - - public RecipeApiController(final RecipeService recipeService) { - this.recipeService = recipeService; - } - - @Logging - @PostMapping(value = "/api/recipes", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, - MediaType.APPLICATION_JSON_VALUE}) - public ResponseEntity writeRecipe(@AuthenticationPrincipal final LoginInfo loginInfo, - @RequestPart(required = false) final List images, - @RequestPart @Valid final RecipeCreateRequest recipeRequest) { - final Long recipeId = recipeService.create(loginInfo.getId(), images, recipeRequest); - - return ResponseEntity.created(URI.create("/api/recipes/" + recipeId)).build(); - } - - @GetMapping(value = "/api/recipes/{recipeId}") - public ResponseEntity getRecipeDetail(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long recipeId) { - final RecipeDetailResponse response = recipeService.getRecipeDetail(loginInfo.getId(), recipeId); - - return ResponseEntity.ok(response); - } - - @GetMapping(value = "/api/recipes") - public ResponseEntity getSortingRecipes(@PageableDefault final Pageable pageable) { - final SortingRecipesResponse response = recipeService.getSortingRecipes(pageable); - - return ResponseEntity.ok(response); - } - - @Logging - @PatchMapping(value = "/api/recipes/{recipeId}") - public ResponseEntity likeRecipe(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long recipeId, - @RequestBody @Valid final RecipeFavoriteRequest request) { - recipeService.likeRecipe(loginInfo.getId(), recipeId, request); - - return ResponseEntity.noContent().build(); - } - - @GetMapping("/api/ranks/recipes") - public ResponseEntity getRankingRecipes() { - final RankingRecipesResponse response = recipeService.getTop3Recipes(); - - return ResponseEntity.ok(response); - } - - @GetMapping("/api/search/recipes/results") - public ResponseEntity getSearchResults(@RequestParam final String query, - @PageableDefault final Pageable pageable) { - final PageRequest pageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize()); - final SearchRecipeResultsResponse response = recipeService.getSearchResults(query, pageRequest); - - return ResponseEntity.ok(response); - } - - @PostMapping("/api/recipes/{recipeId}/comments") - public ResponseEntity writeComment(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long recipeId, - @RequestBody @Valid final RecipeCommentCreateRequest request) { - final Long savedCommentId = recipeService.writeCommentOfRecipe(loginInfo.getId(), recipeId, request); - - return ResponseEntity.created(URI.create("/api/recipes/" + recipeId + "/" + savedCommentId)).build(); - } - - @GetMapping("/api/recipes/{recipeId}/comments") - public ResponseEntity getCommentsOfRecipe( - @AuthenticationPrincipal final LoginInfo loginInfo, @PathVariable final Long recipeId, - @ModelAttribute final RecipeCommentCondition condition) { - final RecipeCommentsResponse response = recipeService.getCommentsOfRecipe(recipeId, condition); - - return ResponseEntity.ok(response); - } -} diff --git a/backend/src/main/java/com/funeat/recipe/presentation/RecipeController.java b/backend/src/main/java/com/funeat/recipe/presentation/RecipeController.java deleted file mode 100644 index 05602cc7f..000000000 --- a/backend/src/main/java/com/funeat/recipe/presentation/RecipeController.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.funeat.recipe.presentation; - -import com.funeat.auth.dto.LoginInfo; -import com.funeat.auth.util.AuthenticationPrincipal; -import com.funeat.recipe.dto.RankingRecipesResponse; -import com.funeat.recipe.dto.RecipeCommentCondition; -import com.funeat.recipe.dto.RecipeCommentCreateRequest; -import com.funeat.recipe.dto.RecipeCommentsResponse; -import com.funeat.recipe.dto.RecipeCreateRequest; -import com.funeat.recipe.dto.RecipeDetailResponse; -import com.funeat.recipe.dto.RecipeFavoriteRequest; -import com.funeat.recipe.dto.SearchRecipeResultsResponse; -import com.funeat.recipe.dto.SortingRecipesResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import java.util.List; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.multipart.MultipartFile; - -@Tag(name = "07.Recipe", description = "κΏ€μ‘°ν•© κ΄€λ ¨ API μž…λ‹ˆλ‹€.") -public interface RecipeController { - - @Operation(summary = "κΏ€μ‘°ν•© μΆ”κ°€", description = "꿀쑰합을 μž‘μ„±ν•œλ‹€.") - @ApiResponse( - responseCode = "201", - description = "κΏ€μ‘°ν•© μž‘μ„± 성곡." - ) - @PostMapping - ResponseEntity writeRecipe(@AuthenticationPrincipal final LoginInfo loginInfo, - @RequestPart final List images, - @RequestPart final RecipeCreateRequest recipeRequest); - - @Operation(summary = "κΏ€μ‘°ν•© 상세 쑰회", description = "κΏ€μ‘°ν•©μ˜ 상세 정보λ₯Ό μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "κΏ€μ‘°ν•© 상세 쑰회 성곡." - ) - @GetMapping - ResponseEntity getRecipeDetail(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long recipeId); - - @Operation(summary = "κΏ€μ‘°ν•© λͺ©λ‘ 쑰회", description = "κΏ€μ‘°ν•©μ˜ λͺ©λ‘μ„ μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "κΏ€μ‘°ν•© λͺ©λ‘ 쑰회 성곡." - ) - @GetMapping - ResponseEntity getSortingRecipes(@PageableDefault final Pageable pageable); - - @Operation(summary = "κΏ€μ‘°ν•© μ’‹μ•„μš”", description = "꿀쑰합에 μ’‹μ•„μš” λ˜λŠ” μ·¨μ†Œλ₯Ό ν•œλ‹€.") - @ApiResponse( - responseCode = "204", - description = "κΏ€μ‘°ν•© μ’‹μ•„μš”(λ˜λŠ” μ’‹μ•„μš” μ·¨μ†Œ) 성곡." - ) - @PatchMapping - ResponseEntity likeRecipe(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long recipeId, - @RequestBody final RecipeFavoriteRequest request); - - @Operation(summary = "κΏ€μ‘°ν•© λž­ν‚Ή 쑰회", description = "전체 κΏ€μ‘°ν•©λ“€ μ€‘μ—μ„œ λž­ν‚Ή TOP3λ₯Ό μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "κΏ€μ‘°ν•© λž­ν‚Ή 쑰회 성곡." - ) - @GetMapping - ResponseEntity getRankingRecipes(); - - @Operation(summary = "κΏ€μ‘°ν•© 검색 κ²°κ³Ό 쑰회", description = "검색어가 ν¬ν•¨λœ μƒν’ˆμ΄ μžˆλŠ” κΏ€μ‘°ν•© λͺ©λ‘μ„ μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "κΏ€μ‘°ν•© 검색 κ²°κ³Ό 쑰회 성곡." - ) - @GetMapping - ResponseEntity getSearchResults(@RequestParam final String query, - @PageableDefault final Pageable pageable); - - @Operation(summary = "κΏ€μ‘°ν•© λŒ“κΈ€ μž‘μ„±", description = "κΏ€μ‘°ν•© μƒμ„Έμ—μ„œ λŒ“κΈ€μ„ μž‘μ„±ν•œλ‹€.") - @ApiResponse( - responseCode = "201", - description = "κΏ€μ‘°ν•© λŒ“κΈ€ μž‘μ„± 성곡." - ) - @PostMapping("/api/recipes/{recipeId}/comments") - ResponseEntity writeComment(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long recipeId, - @RequestBody final RecipeCommentCreateRequest request); - - @Operation(summary = "κΏ€μ‘°ν•© λŒ“κΈ€ 쑰회", description = "κΏ€μ‘°ν•© μƒμ„Έμ—μ„œ λŒ“κΈ€μ„ μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "κΏ€μ‘°ν•© λŒ“κΈ€ 쑰회 성곡." - ) - @GetMapping("/api/recipes/{recipeId}/comments") - ResponseEntity getCommentsOfRecipe(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long recipeId, - @ModelAttribute final RecipeCommentCondition condition); -} diff --git a/backend/src/main/java/com/funeat/recipe/util/RecipeDetailHandlerInterceptor.java b/backend/src/main/java/com/funeat/recipe/util/RecipeDetailHandlerInterceptor.java deleted file mode 100644 index 9bca8ce25..000000000 --- a/backend/src/main/java/com/funeat/recipe/util/RecipeDetailHandlerInterceptor.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.recipe.util; - -import com.funeat.auth.exception.AuthErrorCode; -import com.funeat.auth.exception.AuthException.NotLoggedInException; -import java.util.Objects; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@Component -public class RecipeDetailHandlerInterceptor implements HandlerInterceptor { - - @Override - public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, - final Object handler) { - final HttpSession session = request.getSession(false); - - if (Objects.isNull(session)) { - throw new NotLoggedInException(AuthErrorCode.LOGIN_MEMBER_NOT_FOUND); - } - - return true; - } -} diff --git a/backend/src/main/java/com/funeat/recipe/util/RecipeHandlerInterceptor.java b/backend/src/main/java/com/funeat/recipe/util/RecipeHandlerInterceptor.java deleted file mode 100644 index 192f5714d..000000000 --- a/backend/src/main/java/com/funeat/recipe/util/RecipeHandlerInterceptor.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.funeat.recipe.util; - -import com.funeat.auth.exception.AuthErrorCode; -import com.funeat.auth.exception.AuthException.NotLoggedInException; -import java.util.Objects; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import org.springframework.stereotype.Component; -import org.springframework.web.servlet.HandlerInterceptor; - -@Component -public class RecipeHandlerInterceptor implements HandlerInterceptor { - - private static final String GET = "GET"; - - @Override - public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, - final Object handler) { - if (GET.equals(request.getMethod())) { - return true; - } - - final HttpSession session = request.getSession(false); - - if (Objects.isNull(session)) { - throw new NotLoggedInException(AuthErrorCode.LOGIN_MEMBER_NOT_FOUND); - } - - return true; - } -} diff --git a/backend/src/main/java/com/funeat/review/application/ReviewDeleteEvent.java b/backend/src/main/java/com/funeat/review/application/ReviewDeleteEvent.java deleted file mode 100644 index 7c69eee3c..000000000 --- a/backend/src/main/java/com/funeat/review/application/ReviewDeleteEvent.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.funeat.review.application; - -public class ReviewDeleteEvent { - - private final String image; - - public ReviewDeleteEvent(final String image) { - this.image = image; - } - - public String getImage() { - return image; - } -} diff --git a/backend/src/main/java/com/funeat/review/application/ReviewDeleteEventListener.java b/backend/src/main/java/com/funeat/review/application/ReviewDeleteEventListener.java deleted file mode 100644 index a92c4f943..000000000 --- a/backend/src/main/java/com/funeat/review/application/ReviewDeleteEventListener.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.funeat.review.application; - -import com.funeat.common.ImageUploader; -import io.micrometer.core.instrument.util.StringUtils; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Component; -import org.springframework.transaction.event.TransactionPhase; -import org.springframework.transaction.event.TransactionalEventListener; - -@Component -public class ReviewDeleteEventListener { - - private final ImageUploader imageUploader; - - public ReviewDeleteEventListener(final ImageUploader imageUploader) { - this.imageUploader = imageUploader; - } - - @Async - @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) - public void deleteReviewImageInS3(final ReviewDeleteEvent event) { - final String image = event.getImage(); - if (!StringUtils.isBlank(image)) { - imageUploader.delete(image); - } - } -} diff --git a/backend/src/main/java/com/funeat/review/application/ReviewService.java b/backend/src/main/java/com/funeat/review/application/ReviewService.java deleted file mode 100644 index a65922c82..000000000 --- a/backend/src/main/java/com/funeat/review/application/ReviewService.java +++ /dev/null @@ -1,301 +0,0 @@ -package com.funeat.review.application; - -import static com.funeat.member.exception.MemberErrorCode.MEMBER_DUPLICATE_FAVORITE; -import static com.funeat.member.exception.MemberErrorCode.MEMBER_NOT_FOUND; -import static com.funeat.product.exception.ProductErrorCode.PRODUCT_NOT_FOUND; -import static com.funeat.review.exception.ReviewErrorCode.NOT_AUTHOR_OF_REVIEW; -import static com.funeat.review.exception.ReviewErrorCode.REVIEW_NOT_FOUND; - -import com.funeat.common.ImageUploader; -import com.funeat.common.dto.PageDto; -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.ReviewFavorite; -import com.funeat.member.dto.MemberReviewDto; -import com.funeat.member.dto.MemberReviewsResponse; -import com.funeat.member.exception.MemberException.MemberDuplicateFavoriteException; -import com.funeat.member.exception.MemberException.MemberNotFoundException; -import com.funeat.member.persistence.MemberRepository; -import com.funeat.member.persistence.ReviewFavoriteRepository; -import com.funeat.product.domain.Product; -import com.funeat.product.exception.ProductException.ProductNotFoundException; -import com.funeat.product.persistence.ProductRepository; -import com.funeat.review.domain.Review; -import com.funeat.review.domain.ReviewTag; -import com.funeat.review.dto.MostFavoriteReviewResponse; -import com.funeat.review.dto.RankingReviewDto; -import com.funeat.review.dto.RankingReviewsResponse; -import com.funeat.review.dto.ReviewCreateRequest; -import com.funeat.review.dto.ReviewDetailResponse; -import com.funeat.review.dto.ReviewFavoriteRequest; -import com.funeat.review.dto.SortingReviewDto; -import com.funeat.review.dto.SortingReviewDtoWithoutTag; -import com.funeat.review.dto.SortingReviewRequest; -import com.funeat.review.dto.SortingReviewsResponse; -import com.funeat.review.exception.ReviewException.NotAuthorOfReviewException; -import com.funeat.review.exception.ReviewException.ReviewNotFoundException; -import com.funeat.review.persistence.ReviewRepository; -import com.funeat.review.persistence.ReviewTagRepository; -import com.funeat.review.specification.SortingReviewSpecification; -import com.funeat.tag.domain.Tag; -import com.funeat.tag.persistence.TagRepository; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -@Service -@Transactional(readOnly = true) -public class ReviewService { - - private static final int FIRST_PAGE = 0; - private static final int START_INDEX = 0; - private static final int ONE = 1; - private static final String EMPTY_URL = ""; - private static final int RANKING_SIZE = 3; - private static final long RANKING_MINIMUM_FAVORITE_COUNT = 1L; - private static final int REVIEW_PAGE_SIZE = 10; - - private final ReviewRepository reviewRepository; - private final TagRepository tagRepository; - private final ReviewTagRepository reviewTagRepository; - private final MemberRepository memberRepository; - private final ProductRepository productRepository; - private final ReviewFavoriteRepository reviewFavoriteRepository; - private final ImageUploader imageUploader; - private final ApplicationEventPublisher eventPublisher; - - public ReviewService(final ReviewRepository reviewRepository, final TagRepository tagRepository, - final ReviewTagRepository reviewTagRepository, final MemberRepository memberRepository, - final ProductRepository productRepository, - final ReviewFavoriteRepository reviewFavoriteRepository, - final ImageUploader imageUploader, final ApplicationEventPublisher eventPublisher) { - this.reviewRepository = reviewRepository; - this.tagRepository = tagRepository; - this.reviewTagRepository = reviewTagRepository; - this.memberRepository = memberRepository; - this.productRepository = productRepository; - this.reviewFavoriteRepository = reviewFavoriteRepository; - this.imageUploader = imageUploader; - this.eventPublisher = eventPublisher; - } - - @Transactional - public void create(final Long productId, final Long memberId, final MultipartFile image, - final ReviewCreateRequest reviewRequest) { - final Member findMember = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - final Product findProduct = productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId)); - - final String imageUrl = Optional.ofNullable(image) - .map(imageUploader::upload) - .orElse(EMPTY_URL); - final Review savedReview = reviewRepository.save( - new Review(findMember, findProduct, imageUrl, reviewRequest.getRating(), reviewRequest.getContent(), - reviewRequest.getRebuy())); - - final List findTags = tagRepository.findTagsByIdIn(reviewRequest.getTagIds()); - - final List reviewTags = findTags.stream() - .map(findTag -> ReviewTag.createReviewTag(savedReview, findTag)) - .collect(Collectors.toList()); - - final Long countByProduct = reviewRepository.countByProduct(findProduct); - - findProduct.updateAverageRatingForInsert(countByProduct, savedReview.getRating()); - findProduct.addReviewCount(); - reviewTagRepository.saveAll(reviewTags); - } - - @Transactional - public void likeReview(final Long reviewId, final Long memberId, final ReviewFavoriteRequest request) { - final Member findMember = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - final Review findReview = reviewRepository.findByIdForUpdate(reviewId) - .orElseThrow(() -> new ReviewNotFoundException(REVIEW_NOT_FOUND, reviewId)); - - final ReviewFavorite savedReviewFavorite = reviewFavoriteRepository.findByMemberAndReview(findMember, - findReview).orElseGet(() -> saveReviewFavorite(findMember, findReview, request.getFavorite())); - - savedReviewFavorite.updateChecked(request.getFavorite()); - } - - private ReviewFavorite saveReviewFavorite(final Member member, final Review review, final Boolean favorite) { - try { - final ReviewFavorite reviewFavorite = ReviewFavorite.create(member, review, favorite); - return reviewFavoriteRepository.save(reviewFavorite); - } catch (final DataIntegrityViolationException e) { - throw new MemberDuplicateFavoriteException(MEMBER_DUPLICATE_FAVORITE, member.getId()); - } - } - - @Transactional - public void updateProductImage(final Long productId) { - final Product product = productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId)); - - final PageRequest pageRequest = PageRequest.of(FIRST_PAGE, ONE); - - final List topFavoriteReview = reviewRepository.findPopularReviewWithImage(productId, pageRequest); - if (topFavoriteReview.isEmpty()) { - product.updateBasicImage(); - return; - } - final String topFavoriteReviewImage = topFavoriteReview.get(START_INDEX).getImage(); - product.updateFavoriteImage(topFavoriteReviewImage); - } - - public SortingReviewsResponse sortingReviews(final Long productId, final Long memberId, - final SortingReviewRequest request) { - final Member findMember = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - final Product findProduct = productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId)); - - final List sortingReviews = getSortingReviews(findMember, findProduct, request); - final int resultSize = getResultSize(sortingReviews); - - final List resizeSortingReviews = sortingReviews.subList(START_INDEX, resultSize); - final Boolean hasNext = hasNextPage(sortingReviews); - - return SortingReviewsResponse.toResponse(resizeSortingReviews, hasNext); - } - - private List getSortingReviews(final Member member, final Product product, - final SortingReviewRequest request) { - final Long lastReviewId = request.getLastReviewId(); - final String sortOption = request.getSort(); - - final Specification specification = getSortingSpecification(product, sortOption, lastReviewId); - final List sortingReviewDtoWithoutTags = reviewRepository.getSortingReview(member, - specification, sortOption); - - return addTagsToSortingReviews(sortingReviewDtoWithoutTags); - } - - private List addTagsToSortingReviews( - final List sortingReviewDtoWithoutTags) { - return sortingReviewDtoWithoutTags.stream() - .map(reviewDto -> SortingReviewDto.toDto(reviewDto, - tagRepository.findTagsByReviewId(reviewDto.getId()))) - .collect(Collectors.toList()); - } - - private Specification getSortingSpecification(final Product product, final String sortOption, - final Long lastReviewId) { - if (lastReviewId == FIRST_PAGE) { - return SortingReviewSpecification.sortingFirstPageBy(product); - } - - final Review lastReview = reviewRepository.findById(lastReviewId) - .orElseThrow(() -> new ReviewNotFoundException(REVIEW_NOT_FOUND, lastReviewId)); - - return SortingReviewSpecification.sortingBy(product, sortOption, lastReview); - } - - private int getResultSize(final List sortingReviews) { - if (sortingReviews.size() <= REVIEW_PAGE_SIZE) { - return sortingReviews.size(); - } - return REVIEW_PAGE_SIZE; - } - - private Boolean hasNextPage(final List sortingReviews) { - return sortingReviews.size() > REVIEW_PAGE_SIZE; - } - - public RankingReviewsResponse getTopReviews() { - final List reviews = reviewRepository.findReviewsByFavoriteCountGreaterThanEqual(RANKING_MINIMUM_FAVORITE_COUNT); - final List dtos = reviews.stream() - .sorted(Comparator.comparing(Review::calculateRankingScore).reversed()) - .limit(RANKING_SIZE) - .map(RankingReviewDto::toDto) - .collect(Collectors.toList()); - - return RankingReviewsResponse.toResponse(dtos); - } - - public MemberReviewsResponse findReviewByMember(final Long memberId, final Pageable pageable) { - final Member findMember = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - - final Page sortedReviewPages = reviewRepository.findReviewsByMember(findMember, pageable); - final PageDto pageDto = PageDto.toDto(sortedReviewPages); - - final List dtos = sortedReviewPages.stream() - .map(MemberReviewDto::toDto) - .collect(Collectors.toList()); - - return MemberReviewsResponse.toResponse(pageDto, dtos); - } - - @Transactional - public void deleteReview(final Long reviewId, final Long memberId) { - final Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - final Review review = reviewRepository.findById(reviewId) - .orElseThrow(() -> new ReviewNotFoundException(REVIEW_NOT_FOUND, reviewId)); - final Product product = review.getProduct(); - final String image = review.getImage(); - - if (review.checkAuthor(member)) { - eventPublisher.publishEvent(new ReviewDeleteEvent(image)); - deleteThingsRelatedToReview(review); - updateProduct(product, review.getRating()); - return; - } - throw new NotAuthorOfReviewException(NOT_AUTHOR_OF_REVIEW, memberId); - } - - private void deleteThingsRelatedToReview(final Review review) { - deleteReviewTags(review); - deleteReviewFavorites(review); - reviewRepository.delete(review); - } - - private void deleteReviewTags(final Review review) { - final List reviewTags = reviewTagRepository.findByReview(review); - final List ids = reviewTags.stream() - .map(ReviewTag::getId) - .collect(Collectors.toList()); - reviewTagRepository.deleteAllByIdInBatch(ids); - } - - private void deleteReviewFavorites(final Review review) { - final List reviewFavorites = reviewFavoriteRepository.findByReview(review); - final List ids = reviewFavorites.stream() - .map(ReviewFavorite::getId) - .collect(Collectors.toList()); - reviewFavoriteRepository.deleteAllByIdInBatch(ids); - } - - private void updateProduct(final Product product, final Long deletedRating) { - product.updateAverageRatingForDelete(deletedRating); - product.minusReviewCount(); - updateProductImage(product.getId()); - } - - public Optional getMostFavoriteReview(final Long productId) { - final Product findProduct = productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId)); - - final Optional review = reviewRepository.findTopByProductOrderByFavoriteCountDescIdDesc(findProduct); - - return MostFavoriteReviewResponse.toResponse(review); - } - - public ReviewDetailResponse getReviewDetail(final Long reviewId) { - final Review review = reviewRepository.findById(reviewId) - .orElseThrow(() -> new ReviewNotFoundException(REVIEW_NOT_FOUND, reviewId)); - return ReviewDetailResponse.toResponse(review); - } -} diff --git a/backend/src/main/java/com/funeat/review/domain/Review.java b/backend/src/main/java/com/funeat/review/domain/Review.java deleted file mode 100644 index 9b1a458d3..000000000 --- a/backend/src/main/java/com/funeat/review/domain/Review.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.funeat.review.domain; - -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.ReviewFavorite; -import com.funeat.product.domain.Product; -import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -@Entity -public class Review { - - private static final double RANKING_GRAVITY = 0.5; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String image; - - private Long rating; - - private String content; - - private Boolean reBuy; - - @Column(nullable = false) - private LocalDateTime createdAt = LocalDateTime.now(); - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "product_id") - private Product product; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - - @OneToMany(mappedBy = "review") - private List reviewTags = new ArrayList<>(); - - @OneToMany(mappedBy = "review") - private List reviewFavorites = new ArrayList<>(); - - private Long favoriteCount = 0L; - - protected Review() { - } - - public Review(final Member member, final Product findProduct, final Long rating, final String content, - final Boolean reBuy) { - this(member, findProduct, null, rating, content, reBuy); - } - - public Review(final Member member, final Product findProduct, final String image, final Long rating, - final String content, final Boolean reBuy) { - this.member = member; - this.product = findProduct; - this.image = image; - this.rating = rating; - this.content = content; - this.reBuy = reBuy; - } - - public Review(final Member member, final Product findProduct, final String image, final Long rating, - final String content, final Boolean reBuy, final Long favoriteCount) { - this.member = member; - this.product = findProduct; - this.image = image; - this.rating = rating; - this.content = content; - this.reBuy = reBuy; - this.favoriteCount = favoriteCount; - } - - public Review(final Member member, final Product findProduct, final String image, final Long rating, - final String content, final Boolean reBuy, final Long favoriteCount, final LocalDateTime createdAt) { - this.member = member; - this.product = findProduct; - this.image = image; - this.rating = rating; - this.content = content; - this.reBuy = reBuy; - this.favoriteCount = favoriteCount; - this.createdAt = createdAt; - } - - public void addFavoriteCount() { - this.favoriteCount++; - } - - public void minusFavoriteCount() { - this.favoriteCount--; - } - - public Double calculateRankingScore() { - final long age = ChronoUnit.DAYS.between(createdAt, LocalDateTime.now()); - final double denominator = Math.pow(age + 1.0, RANKING_GRAVITY); - return favoriteCount / denominator; - } - - public boolean checkAuthor(final Member member) { - return Objects.equals(this.member, member); - } - - public Long getId() { - return id; - } - - public String getImage() { - return image; - } - - public Long getRating() { - return rating; - } - - public String getContent() { - return content; - } - - public Boolean getReBuy() { - return reBuy; - } - - public Product getProduct() { - return product; - } - - public Member getMember() { - return member; - } - - public List getReviewFavorites() { - return reviewFavorites; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public List getReviewTags() { - return reviewTags; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/review/domain/ReviewTag.java b/backend/src/main/java/com/funeat/review/domain/ReviewTag.java deleted file mode 100644 index 72b549743..000000000 --- a/backend/src/main/java/com/funeat/review/domain/ReviewTag.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.funeat.review.domain; - -import com.funeat.tag.domain.Tag; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; - -@Entity -public class ReviewTag { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "review_id") - private Review review; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "tag_id") - private Tag tag; - - protected ReviewTag() { - } - - private ReviewTag(final Review review, final Tag tag) { - this.review = review; - this.tag = tag; - } - - public static ReviewTag createReviewTag(final Review review, final Tag tag) { - final ReviewTag reviewTag = new ReviewTag(review, tag); - review.getReviewTags().add(reviewTag); - return reviewTag; - } - - public Long getId() { - return id; - } - - public Review getReview() { - return review; - } - - public Tag getTag() { - return tag; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/MostFavoriteReviewResponse.java b/backend/src/main/java/com/funeat/review/dto/MostFavoriteReviewResponse.java deleted file mode 100644 index 0d1352f80..000000000 --- a/backend/src/main/java/com/funeat/review/dto/MostFavoriteReviewResponse.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.funeat.review.dto; - -import com.funeat.review.domain.Review; -import com.funeat.review.domain.ReviewTag; -import com.funeat.tag.dto.TagDto; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -public class MostFavoriteReviewResponse { - - private final Long id; - private final String userName; - private final String profileImage; - private final String image; - private final Long rating; - private final List tags; - private final String content; - private final Boolean rebuy; - private final Long favoriteCount; - private final LocalDateTime createdAt; - - public MostFavoriteReviewResponse(final Long id, final String userName, final String profileImage, - final String image, final Long rating, final List tags, - final String content, final boolean rebuy, final Long favoriteCount, - final LocalDateTime createdAt) { - this.id = id; - this.userName = userName; - this.profileImage = profileImage; - this.image = image; - this.rating = rating; - this.tags = tags; - this.content = content; - this.rebuy = rebuy; - this.favoriteCount = favoriteCount; - this.createdAt = createdAt; - } - - public static Optional toResponse(final Optional nullableReview) { - if (nullableReview.isEmpty()) { - return Optional.empty(); - } - - final Review review = nullableReview.get(); - return Optional.of(new MostFavoriteReviewResponse( - review.getId(), - review.getMember().getNickname(), - review.getMember().getProfileImage(), - review.getImage(), - review.getRating(), - findTagDtos(review), - review.getContent(), - review.getReBuy(), - review.getFavoriteCount(), - review.getCreatedAt() - )); - } - - private static List findTagDtos(final Review review) { - return review.getReviewTags().stream() - .map(ReviewTag::getTag) - .map(TagDto::toDto) - .collect(Collectors.toList()); - } - - public Long getId() { - return id; - } - - public String getUserName() { - return userName; - } - - public String getProfileImage() { - return profileImage; - } - - public String getImage() { - return image; - } - - public Long getRating() { - return rating; - } - - public List getTags() { - return tags; - } - - public String getContent() { - return content; - } - - public Boolean isRebuy() { - return rebuy; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/RankingReviewDto.java b/backend/src/main/java/com/funeat/review/dto/RankingReviewDto.java deleted file mode 100644 index 5ac70bb59..000000000 --- a/backend/src/main/java/com/funeat/review/dto/RankingReviewDto.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.funeat.review.dto; - -import com.funeat.review.domain.Review; -import java.time.LocalDateTime; - -public class RankingReviewDto { - - private final Long reviewId; - private final Long productId; - private final String categoryType; - private final String productName; - private final String content; - private final Long rating; - private final Long favoriteCount; - private final LocalDateTime createdAt; - - private RankingReviewDto(final Long reviewId, final Long productId, final String categoryType, - final String productName, final String content, - final Long rating, final Long favoriteCount, final LocalDateTime createdAt) { - this.reviewId = reviewId; - this.productId = productId; - this.categoryType = categoryType; - this.productName = productName; - this.content = content; - this.rating = rating; - this.favoriteCount = favoriteCount; - this.createdAt = createdAt; - } - - public static RankingReviewDto toDto(final Review review) { - return new RankingReviewDto( - review.getId(), - review.getProduct().getId(), - review.getProduct().getCategory().getType().getName(), - review.getProduct().getName(), - review.getContent(), - review.getRating(), - review.getFavoriteCount(), - review.getCreatedAt()); - } - - public Long getReviewId() { - return reviewId; - } - - public Long getProductId() { - return productId; - } - - public String getProductName() { - return productName; - } - - public String getContent() { - return content; - } - - public Long getRating() { - return rating; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public String getCategoryType() { - return categoryType; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/RankingReviewsResponse.java b/backend/src/main/java/com/funeat/review/dto/RankingReviewsResponse.java deleted file mode 100644 index fd2befb0a..000000000 --- a/backend/src/main/java/com/funeat/review/dto/RankingReviewsResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.funeat.review.dto; - -import java.util.List; - -public class RankingReviewsResponse { - - private final List reviews; - - public RankingReviewsResponse(final List reviews) { - this.reviews = reviews; - } - - public static RankingReviewsResponse toResponse(final List reviews) { - return new RankingReviewsResponse(reviews); - } - - public List getReviews() { - return reviews; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/ReviewCreateRequest.java b/backend/src/main/java/com/funeat/review/dto/ReviewCreateRequest.java deleted file mode 100644 index ce1e9a717..000000000 --- a/backend/src/main/java/com/funeat/review/dto/ReviewCreateRequest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.funeat.review.dto; - -import java.util.List; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -public class ReviewCreateRequest { - - @NotNull(message = "평점을 확인해 μ£Όμ„Έμš”") - private final Long rating; - - @NotNull(message = "νƒœκ·Έ ID λͺ©λ‘μ„ 확인해 μ£Όμ„Έμš”") - @Size(min = 1, message = "적어도 1개의 νƒœκ·Έ IDκ°€ ν•„μš”ν•©λ‹ˆλ‹€") - private final List tagIds; - - @NotBlank(message = "리뷰 λ‚΄μš©μ„ 확인해 μ£Όμ„Έμš”") - @Size(max = 200, message = "리뷰 λ‚΄μš©μ€ μ΅œλŒ€ 200μžκΉŒμ§€ μž…λ ₯ κ°€λŠ₯ν•©λ‹ˆλ‹€") - private final String content; - - @NotNull(message = "재ꡬ맀 μ—¬λΆ€λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”") - private final Boolean rebuy; - - public ReviewCreateRequest(final Long rating, final List tagIds, final String content, final Boolean rebuy) { - this.rating = rating; - this.tagIds = tagIds; - this.content = content; - this.rebuy = rebuy; - } - - public Long getRating() { - return rating; - } - - public String getContent() { - return content; - } - - public Boolean getRebuy() { - return rebuy; - } - - public List getTagIds() { - return tagIds; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/ReviewDetailResponse.java b/backend/src/main/java/com/funeat/review/dto/ReviewDetailResponse.java deleted file mode 100644 index 7e0c9858b..000000000 --- a/backend/src/main/java/com/funeat/review/dto/ReviewDetailResponse.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.funeat.review.dto; - -import com.funeat.review.domain.Review; -import com.funeat.review.domain.ReviewTag; -import com.funeat.tag.dto.TagDto; -import java.time.LocalDateTime; -import java.util.List; -import java.util.stream.Collectors; - -public class ReviewDetailResponse { - - private final Long id; - private final String userName; - private final String profileImage; - private final String image; - private final Long rating; - private final List tags; - private final String content; - private final boolean rebuy; - private final Long favoriteCount; - private final LocalDateTime createdAt; - private final String categoryType; - private final Long productId; - private final String productName; - - public ReviewDetailResponse(final Long id, final String userName, final String profileImage, final String image, - final Long rating, final List tags, final String content, final boolean rebuy, - final Long favoriteCount, final LocalDateTime createdAt, final String categoryType, - final Long productId, final String productName) { - this.id = id; - this.userName = userName; - this.profileImage = profileImage; - this.image = image; - this.rating = rating; - this.tags = tags; - this.content = content; - this.rebuy = rebuy; - this.favoriteCount = favoriteCount; - this.createdAt = createdAt; - this.categoryType = categoryType; - this.productId = productId; - this.productName = productName; - } - - public static ReviewDetailResponse toResponse(final Review review) { - return new ReviewDetailResponse( - review.getId(), - review.getMember().getNickname(), - review.getMember().getProfileImage(), - review.getImage(), - review.getRating(), - findTagDtos(review), - review.getContent(), - review.getReBuy(), - review.getFavoriteCount(), - review.getCreatedAt(), - review.getProduct().getCategory().getType().getName(), - review.getProduct().getId(), - review.getProduct().getName() - ); - } - - private static List findTagDtos(final Review review) { - return review.getReviewTags().stream() - .map(ReviewTag::getTag) - .map(TagDto::toDto) - .collect(Collectors.toList()); - } - - public Long getId() { - return id; - } - - public String getUserName() { - return userName; - } - - public String getProfileImage() { - return profileImage; - } - - public String getImage() { - return image; - } - - public Long getRating() { - return rating; - } - - public List getTags() { - return tags; - } - - public String getContent() { - return content; - } - - public boolean isRebuy() { - return rebuy; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public String getCategoryType() { - return categoryType; - } - - public Long getProductId() { - return productId; - } - - public String getProductName() { - return productName; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/ReviewFavoriteRequest.java b/backend/src/main/java/com/funeat/review/dto/ReviewFavoriteRequest.java deleted file mode 100644 index ea3017304..000000000 --- a/backend/src/main/java/com/funeat/review/dto/ReviewFavoriteRequest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.funeat.review.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import javax.validation.constraints.NotNull; - -public class ReviewFavoriteRequest { - - @NotNull(message = "μ’‹μ•„μš”λ₯Ό ν™•μΈν•΄μ£Όμ„Έμš”") - private final Boolean favorite; - - @JsonCreator - public ReviewFavoriteRequest(@JsonProperty("favorite") final Boolean favorite) { - this.favorite = favorite; - } - - public Boolean getFavorite() { - return favorite; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/SortingReviewDto.java b/backend/src/main/java/com/funeat/review/dto/SortingReviewDto.java deleted file mode 100644 index 1231d0058..000000000 --- a/backend/src/main/java/com/funeat/review/dto/SortingReviewDto.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.funeat.review.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.ReviewFavorite; -import com.funeat.review.domain.Review; -import com.funeat.review.domain.ReviewTag; -import com.funeat.tag.domain.Tag; -import com.funeat.tag.dto.TagDto; -import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -public class SortingReviewDto { - - private final Long id; - private final String userName; - private final String profileImage; - private final String image; - private final Long rating; - private final List tags; - private final String content; - private final boolean rebuy; - private final Long favoriteCount; - private final boolean favorite; - private final LocalDateTime createdAt; - - @JsonCreator - public SortingReviewDto(final Long id, final String userName, final String profileImage, final String image, - final Long rating, final List tags, - final String content, final boolean rebuy, final Long favoriteCount, final boolean favorite, - final LocalDateTime createdAt) { - this.id = id; - this.userName = userName; - this.profileImage = profileImage; - this.image = image; - this.rating = rating; - this.tags = tags; - this.content = content; - this.rebuy = rebuy; - this.favoriteCount = favoriteCount; - this.favorite = favorite; - this.createdAt = createdAt; - } - - public static SortingReviewDto toDto(final SortingReviewDtoWithoutTag sortingReviewDto, final List tags) { - final List tagDtos = tags.stream() - .map(TagDto::toDto) - .collect(Collectors.toList()); - - return new SortingReviewDto( - sortingReviewDto.getId(), - sortingReviewDto.getUserName(), - sortingReviewDto.getProfileImage(), - sortingReviewDto.getImage(), - sortingReviewDto.getRating(), - tagDtos, - sortingReviewDto.getContent(), - sortingReviewDto.getRebuy(), - sortingReviewDto.getFavoriteCount(), - sortingReviewDto.getFavorite(), - sortingReviewDto.getCreatedAt()); - } - - public Long getId() { - return id; - } - - public String getUserName() { - return userName; - } - - public String getProfileImage() { - return profileImage; - } - - public String getImage() { - return image; - } - - public Long getRating() { - return rating; - } - - public List getTags() { - return tags; - } - - public String getContent() { - return content; - } - - public boolean getRebuy() { - return rebuy; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public boolean getFavorite() { - return favorite; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/SortingReviewDtoWithoutTag.java b/backend/src/main/java/com/funeat/review/dto/SortingReviewDtoWithoutTag.java deleted file mode 100644 index b58ac7165..000000000 --- a/backend/src/main/java/com/funeat/review/dto/SortingReviewDtoWithoutTag.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.funeat.review.dto; - -import java.time.LocalDateTime; -import java.util.Objects; - -public class SortingReviewDtoWithoutTag { - - private final Long id; - private final String userName; - private final String profileImage; - private final String image; - private final Long rating; - private final String content; - private final boolean rebuy; - private final Long favoriteCount; - private final boolean favorite; - private final LocalDateTime createdAt; - - public SortingReviewDtoWithoutTag(final Long id, final String userName, final String profileImage, - final String image, final Long rating, - final String content, final boolean rebuy, final Long favoriteCount, - final Boolean favorite, - final LocalDateTime createdAt) { - final Boolean isFavorite = checkingFavorite(favorite); - - this.id = id; - this.userName = userName; - this.profileImage = profileImage; - this.image = image; - this.rating = rating; - this.content = content; - this.rebuy = rebuy; - this.favoriteCount = favoriteCount; - this.favorite = isFavorite; - this.createdAt = createdAt; - } - - private static Boolean checkingFavorite(final Boolean favorite) { - if (Objects.isNull(favorite)) { - return Boolean.FALSE; - } - return favorite; - } - - public Long getId() { - return id; - } - - public String getUserName() { - return userName; - } - - public String getProfileImage() { - return profileImage; - } - - public String getImage() { - return image; - } - - public Long getRating() { - return rating; - } - - public String getContent() { - return content; - } - - public boolean getRebuy() { - return rebuy; - } - - public Long getFavoriteCount() { - return favoriteCount; - } - - public boolean getFavorite() { - return favorite; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/SortingReviewRequest.java b/backend/src/main/java/com/funeat/review/dto/SortingReviewRequest.java deleted file mode 100644 index b6bdeb1eb..000000000 --- a/backend/src/main/java/com/funeat/review/dto/SortingReviewRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.funeat.review.dto; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.PositiveOrZero; - -public class SortingReviewRequest { - - @NotNull(message = "μ •λ ¬ 쑰건을 ν™•μΈν•΄μ£Όμ„Έμš”") - private String sort; - - @NotNull(message = "λ§ˆμ§€λ§‰μœΌλ‘œ μ‘°νšŒν•œ 리뷰 IDλ₯Ό ν™•μΈν•΄μ£Όμ„Έμš”") - @PositiveOrZero(message = "λ§ˆμ§€λ§‰μœΌλ‘œ μ‘°νšŒν•œ IDλŠ” 0 이상이어야 ν•©λ‹ˆλ‹€. (처음 μ‘°νšŒν•˜λ©΄ 0)") - private Long lastReviewId; - - public SortingReviewRequest(final String sort, final Long lastReviewId) { - this.sort = sort; - this.lastReviewId = lastReviewId; - } - - public String getSort() { - return sort; - } - - public Long getLastReviewId() { - return lastReviewId; - } -} diff --git a/backend/src/main/java/com/funeat/review/dto/SortingReviewsResponse.java b/backend/src/main/java/com/funeat/review/dto/SortingReviewsResponse.java deleted file mode 100644 index 1dc082fe0..000000000 --- a/backend/src/main/java/com/funeat/review/dto/SortingReviewsResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.review.dto; - -import java.util.List; - -public class SortingReviewsResponse { - - private final List reviews; - private final Boolean hasNext; - - public SortingReviewsResponse(final List reviews, final Boolean hasNext) { - this.reviews = reviews; - this.hasNext = hasNext; - } - - public static SortingReviewsResponse toResponse(final List reviews, final Boolean hasNextReview) { - return new SortingReviewsResponse(reviews, hasNextReview); - } - - public List getReviews() { - return reviews; - } - - public Boolean getHasNext() { - return hasNext; - } -} diff --git a/backend/src/main/java/com/funeat/review/exception/ReviewErrorCode.java b/backend/src/main/java/com/funeat/review/exception/ReviewErrorCode.java deleted file mode 100644 index 2f5fb5c64..000000000 --- a/backend/src/main/java/com/funeat/review/exception/ReviewErrorCode.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.funeat.review.exception; - -import org.springframework.http.HttpStatus; - -public enum ReviewErrorCode { - - REVIEW_NOT_FOUND(HttpStatus.NOT_FOUND, "μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” λ¦¬λ·°μž…λ‹ˆλ‹€. 리뷰 idλ₯Ό ν™•μΈν•˜μ„Έμš”.", "3001"), - NOT_SUPPORTED_REVIEW_SORTING_CONDITION(HttpStatus.BAD_REQUEST, "μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” μ •λ ¬ μ˜΅μ…˜μž…λ‹ˆλ‹€. μ •λ ¬ μ˜΅μ…˜μ„ ν™•μΈν•˜μ„Έμš”.", "3002"), - NOT_AUTHOR_OF_REVIEW(HttpStatus.BAD_REQUEST, "ν•΄λ‹Ή 리뷰λ₯Ό μž‘μ„±ν•œ νšŒμ›μ΄ μ•„λ‹™λ‹ˆλ‹€", "3003") - ; - - private final HttpStatus status; - private final String message; - private final String code; - - ReviewErrorCode(final HttpStatus status, final String message, final String code) { - this.status = status; - this.message = message; - this.code = code; - } - - public HttpStatus getStatus() { - return status; - } - - public String getMessage() { - return message; - } - - public String getCode() { - return code; - } -} diff --git a/backend/src/main/java/com/funeat/review/exception/ReviewException.java b/backend/src/main/java/com/funeat/review/exception/ReviewException.java deleted file mode 100644 index 85fd3f666..000000000 --- a/backend/src/main/java/com/funeat/review/exception/ReviewException.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.funeat.review.exception; - -import com.funeat.exception.ErrorCode; -import com.funeat.exception.GlobalException; -import org.springframework.http.HttpStatus; - -public class ReviewException extends GlobalException { - - public ReviewException(final HttpStatus status, final ErrorCode errorCode) { - super(status, errorCode); - } - - public static class ReviewNotFoundException extends ReviewException { - public ReviewNotFoundException(final ReviewErrorCode errorCode, final Long reviewId) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), reviewId)); - } - } - - public static class NotSupportedReviewSortingConditionException extends ReviewException { - public NotSupportedReviewSortingConditionException(final ReviewErrorCode errorCode, final String sortFieldName) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), sortFieldName)); - } - } - - public static class NotAuthorOfReviewException extends ReviewException { - public NotAuthorOfReviewException(final ReviewErrorCode errorCode, final Long memberId) { - super(errorCode.getStatus(), new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), memberId)); - } - } -} diff --git a/backend/src/main/java/com/funeat/review/persistence/ReviewCustomRepository.java b/backend/src/main/java/com/funeat/review/persistence/ReviewCustomRepository.java deleted file mode 100644 index e2dd79992..000000000 --- a/backend/src/main/java/com/funeat/review/persistence/ReviewCustomRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.funeat.review.persistence; - -import com.funeat.member.domain.Member; -import com.funeat.review.domain.Review; -import com.funeat.review.dto.SortingReviewDtoWithoutTag; -import java.util.List; -import org.springframework.data.jpa.domain.Specification; - -public interface ReviewCustomRepository { - - List getSortingReview(final Member loginMember, - final Specification specification, - final String sortField); -} diff --git a/backend/src/main/java/com/funeat/review/persistence/ReviewRepository.java b/backend/src/main/java/com/funeat/review/persistence/ReviewRepository.java deleted file mode 100644 index 69d35018d..000000000 --- a/backend/src/main/java/com/funeat/review/persistence/ReviewRepository.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.funeat.review.persistence; - -import static javax.persistence.LockModeType.PESSIMISTIC_WRITE; - -import com.funeat.member.domain.Member; -import com.funeat.product.domain.Product; -import com.funeat.review.domain.Review; -import java.util.List; -import java.util.Optional; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Lock; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface ReviewRepository extends JpaRepository, ReviewCustomRepository { - - Long countByProduct(final Product product); - - Page findReviewsByMember(final Member findMember, final Pageable pageable); - - @Lock(PESSIMISTIC_WRITE) - @Query("SELECT r FROM Review r WHERE r.id=:id") - Optional findByIdForUpdate(final Long id); - - @Query("SELECT r " - + "FROM Review r " - + "LEFT JOIN r.product p " - + "WHERE p.id = :id AND r.image != '' " - + "ORDER BY r.favoriteCount DESC, r.id DESC") - List findPopularReviewWithImage(@Param("id") final Long productId, final Pageable pageable); - - Optional findTopByProductOrderByFavoriteCountDescIdDesc(final Product product); - - List findReviewsByFavoriteCountGreaterThanEqual(final Long favoriteCount); -} diff --git a/backend/src/main/java/com/funeat/review/persistence/ReviewRepositoryImpl.java b/backend/src/main/java/com/funeat/review/persistence/ReviewRepositoryImpl.java deleted file mode 100644 index ae47f7127..000000000 --- a/backend/src/main/java/com/funeat/review/persistence/ReviewRepositoryImpl.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.funeat.review.persistence; - -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.ReviewFavorite; -import com.funeat.review.domain.Review; -import com.funeat.review.dto.SortingReviewDtoWithoutTag; -import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CompoundSelection; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Order; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Repository; - -@Repository -public class ReviewRepositoryImpl implements ReviewCustomRepository { - - @PersistenceContext - private EntityManager em; - - @Override - public List getSortingReview(final Member loginMember, - final Specification specification, - final String sortOption) { - final CriteriaBuilder cb = em.getCriteriaBuilder(); - final CriteriaQuery cq = cb.createQuery(SortingReviewDtoWithoutTag.class); - final Root root = cq.from(Review.class); - - // sortField, sortOrder - final String[] sortOptionSplit = sortOption.split(","); - final String sortField = sortOptionSplit[0]; - final String sortOrder = sortOptionSplit[1]; - - // join - final Join joinMember = root.join("member", JoinType.INNER); - - // left join - final Join leftJoinReviewFavorite = root.join("reviewFavorites", JoinType.LEFT); - final Predicate condition = cb.equal(leftJoinReviewFavorite.get("member"), loginMember); - leftJoinReviewFavorite.on(condition); - - // select - from - where - order by - cq.select(getConstruct(root, cb, joinMember, leftJoinReviewFavorite)) - .where(specification.toPredicate(root, cq, cb)) - .orderBy(getOrderBy(root, cb, sortField, sortOrder)); - - // limit - final TypedQuery query = em.createQuery(cq); - query.setMaxResults(11); - - // result - return query.getResultList(); - } - - private CompoundSelection getConstruct(final Root root, - final CriteriaBuilder cb, - final Join joinMember, - final Join leftJoinReviewFavorite) { - - return cb.construct(SortingReviewDtoWithoutTag.class, - root.get("id"), - joinMember.get("nickname"), - joinMember.get("profileImage"), - root.get("image"), - root.get("rating"), - root.get("content"), - root.get("reBuy"), - root.get("favoriteCount"), - leftJoinReviewFavorite.get("favorite"), - root.get("createdAt")); - } - - private List getOrderBy(final Root root, - final CriteriaBuilder cb, - final String fieldName, - final String sortOption) { - if ("ASC".equalsIgnoreCase(sortOption)) { - final Order order = cb.asc(root.get(fieldName)); - return List.of(order, cb.desc(root.get("id"))); - } - final Order order = cb.desc(root.get(fieldName)); - return List.of(order, cb.desc(root.get("id"))); - } -} diff --git a/backend/src/main/java/com/funeat/review/persistence/ReviewTagRepository.java b/backend/src/main/java/com/funeat/review/persistence/ReviewTagRepository.java deleted file mode 100644 index cbdf3c3bf..000000000 --- a/backend/src/main/java/com/funeat/review/persistence/ReviewTagRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.funeat.review.persistence; - -import com.funeat.review.domain.Review; -import com.funeat.review.domain.ReviewTag; -import com.funeat.tag.domain.Tag; -import java.util.List; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -public interface ReviewTagRepository extends JpaRepository { - - @Query("SELECT rt.tag, COUNT(rt.tag) AS cnt " - + "FROM ReviewTag rt " - + "JOIN Review r ON rt.review.id = r.id " - + "WHERE r.product.id = :productId " - + "GROUP BY rt.tag " - + "ORDER BY cnt DESC") - List findTop3TagsByReviewIn(final Long productId, final Pageable pageable); - - void deleteByReview(final Review review); - - List findByReview(final Review review); -} diff --git a/backend/src/main/java/com/funeat/review/presentation/ReviewApiController.java b/backend/src/main/java/com/funeat/review/presentation/ReviewApiController.java deleted file mode 100644 index ff82ff499..000000000 --- a/backend/src/main/java/com/funeat/review/presentation/ReviewApiController.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.funeat.review.presentation; - -import com.funeat.auth.dto.LoginInfo; -import com.funeat.auth.util.AuthenticationPrincipal; -import com.funeat.common.logging.Logging; -import com.funeat.review.application.ReviewService; -import com.funeat.review.dto.MostFavoriteReviewResponse; -import com.funeat.review.dto.RankingReviewsResponse; -import com.funeat.review.dto.ReviewCreateRequest; -import com.funeat.review.dto.ReviewDetailResponse; -import com.funeat.review.dto.ReviewFavoriteRequest; -import com.funeat.review.dto.SortingReviewRequest; -import com.funeat.review.dto.SortingReviewsResponse; -import java.net.URI; -import java.util.Optional; -import javax.validation.Valid; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -@RestController -public class ReviewApiController implements ReviewController { - - private final ReviewService reviewService; - - public ReviewApiController(final ReviewService reviewService) { - this.reviewService = reviewService; - } - - @Logging - @PostMapping(value = "/api/products/{productId}/reviews", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, - MediaType.APPLICATION_JSON_VALUE}) - public ResponseEntity writeReview(@PathVariable final Long productId, - @AuthenticationPrincipal final LoginInfo loginInfo, - @RequestPart(required = false) final MultipartFile image, - @RequestPart @Valid final ReviewCreateRequest reviewRequest) { - reviewService.create(productId, loginInfo.getId(), image, reviewRequest); - - return ResponseEntity.created(URI.create("/api/products/" + productId)).build(); - } - - @Logging - @PatchMapping("/api/products/{productId}/reviews/{reviewId}") - public ResponseEntity toggleLikeReview(@PathVariable final Long productId, - @PathVariable final Long reviewId, - @AuthenticationPrincipal final LoginInfo loginInfo, - @RequestBody @Valid final ReviewFavoriteRequest request) { - reviewService.likeReview(reviewId, loginInfo.getId(), request); - reviewService.updateProductImage(productId); - - return ResponseEntity.noContent().build(); - } - - @GetMapping("/api/products/{productId}/reviews") - public ResponseEntity getSortingReviews(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long productId, - @ModelAttribute final SortingReviewRequest request) { - final SortingReviewsResponse response = reviewService.sortingReviews(productId, loginInfo.getId(), request); - - return ResponseEntity.ok(response); - } - - @GetMapping("/api/ranks/reviews") - public ResponseEntity getRankingReviews() { - final RankingReviewsResponse response = reviewService.getTopReviews(); - - return ResponseEntity.ok(response); - } - - @GetMapping("/api/ranks/products/{productId}/reviews") - public ResponseEntity> getMostFavoriteReview(@PathVariable final Long productId) { - final Optional response = reviewService.getMostFavoriteReview(productId); - - if (response.isEmpty()) { - return ResponseEntity.noContent().build(); - } - return ResponseEntity.ok(response); - } - - @GetMapping("/api/reviews/{reviewId}") - public ResponseEntity getReviewDetail(@PathVariable final Long reviewId) { - final ReviewDetailResponse response = reviewService.getReviewDetail(reviewId); - - return ResponseEntity.ok(response); - } -} diff --git a/backend/src/main/java/com/funeat/review/presentation/ReviewController.java b/backend/src/main/java/com/funeat/review/presentation/ReviewController.java deleted file mode 100644 index 13fb85e94..000000000 --- a/backend/src/main/java/com/funeat/review/presentation/ReviewController.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.funeat.review.presentation; - -import com.funeat.auth.dto.LoginInfo; -import com.funeat.auth.util.AuthenticationPrincipal; -import com.funeat.review.dto.MostFavoriteReviewResponse; -import com.funeat.review.dto.RankingReviewsResponse; -import com.funeat.review.dto.ReviewCreateRequest; -import com.funeat.review.dto.ReviewDetailResponse; -import com.funeat.review.dto.ReviewFavoriteRequest; -import com.funeat.review.dto.SortingReviewRequest; -import com.funeat.review.dto.SortingReviewsResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import java.util.Optional; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.multipart.MultipartFile; - -@Tag(name = "03.Review", description = "리뷰관련 API μž…λ‹ˆλ‹€.") -public interface ReviewController { - - @Operation(summary = "리뷰 μΆ”κ°€", description = "리뷰λ₯Ό μž‘μ„±ν•œλ‹€.") - @ApiResponse( - responseCode = "201", - description = "리뷰 μž‘μ„± 성곡." - ) - @PostMapping - ResponseEntity writeReview(@PathVariable final Long productId, - @AuthenticationPrincipal final LoginInfo loginInfo, - @RequestPart final MultipartFile image, - @RequestPart final ReviewCreateRequest reviewRequest); - - @Operation(summary = "리뷰 μ’‹μ•„μš”", description = "리뷰에 μ’‹μ•„μš” λ˜λŠ” μ·¨μ†Œλ₯Ό ν•œλ‹€.") - @ApiResponse( - responseCode = "204", - description = "리뷰 μ’‹μ•„μš”(μ·¨μ†Œ) 성곡." - ) - @PatchMapping - ResponseEntity toggleLikeReview(@PathVariable final Long productId, - @PathVariable final Long reviewId, - @AuthenticationPrincipal final LoginInfo loginInfo, - @RequestBody final ReviewFavoriteRequest request); - - @Operation(summary = "리뷰λ₯Ό μ •λ ¬ν›„ 쑰회", description = "리뷰λ₯Ό μ •λ ¬ν›„ μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "리뷰 μ •λ ¬ν›„ 쑰회 성곡." - ) - @GetMapping - ResponseEntity getSortingReviews(@AuthenticationPrincipal final LoginInfo loginInfo, - @PathVariable final Long productId, - @ModelAttribute final SortingReviewRequest request); - - @Operation(summary = "리뷰 λž­ν‚Ή Top3 쑰회", description = "리뷰 λž­ν‚Ή Top3 μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "리뷰 λž­ν‚Ή Top3 쑰회 성곡." - ) - @GetMapping - ResponseEntity getRankingReviews(); - - @Operation(summary = "μ’‹μ•„μš”λ₯Ό 제일 λ§Žμ€ 받은 리뷰 쑰회", description = "νŠΉμ • μƒν’ˆμ— λŒ€ν•΄ μ’‹μ•„μš”λ₯Ό 제일 많이 받은 리뷰λ₯Ό μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "μ’‹μ•„μš”λ₯Ό 제일 많이 받은 리뷰 쑰회 성곡." - ) - @GetMapping - ResponseEntity> getMostFavoriteReview(@PathVariable final Long productId); - - @Operation(summary = "리뷰 상세 쑰회", description = "리뷰의 상세 정보λ₯Ό μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "리뷰 상세 쑰회 성곡." - ) - @GetMapping - ResponseEntity getReviewDetail(@PathVariable final Long reviewId); -} diff --git a/backend/src/main/java/com/funeat/review/specification/LongTypeReviewSortSpec.java b/backend/src/main/java/com/funeat/review/specification/LongTypeReviewSortSpec.java deleted file mode 100644 index 23914e003..000000000 --- a/backend/src/main/java/com/funeat/review/specification/LongTypeReviewSortSpec.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.funeat.review.specification; - -import com.funeat.review.domain.Review; -import java.util.Arrays; -import java.util.function.Function; - -public enum LongTypeReviewSortSpec { - - FAVORITE_COUNT("favoriteCount", Review::getFavoriteCount), - RATING("rating", Review::getRating); - - private final String fieldName; - private final Function function; - - LongTypeReviewSortSpec(final String fieldName, final Function function) { - this.fieldName = fieldName; - this.function = function; - } - - public static Long find(final String fieldName, final Review lastReview) { - return Arrays.stream(LongTypeReviewSortSpec.values()) - .filter(reviewSortSpec -> reviewSortSpec.fieldName.equals(fieldName)) - .findFirst() - .orElseThrow(IllegalArgumentException::new) - .function.apply(lastReview); - } -} diff --git a/backend/src/main/java/com/funeat/review/specification/SortingReviewSpecification.java b/backend/src/main/java/com/funeat/review/specification/SortingReviewSpecification.java deleted file mode 100644 index 781032017..000000000 --- a/backend/src/main/java/com/funeat/review/specification/SortingReviewSpecification.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.funeat.review.specification; - -import static com.funeat.review.exception.ReviewErrorCode.NOT_SUPPORTED_REVIEW_SORTING_CONDITION; - -import com.funeat.product.domain.Product; -import com.funeat.review.domain.Review; -import com.funeat.review.exception.ReviewException.NotSupportedReviewSortingConditionException; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.Path; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; -import org.springframework.data.jpa.domain.Specification; - -public final class SortingReviewSpecification { - - private static final List LOCALDATETIME_TYPE_INCLUDE = List.of("createdAt"); - private static final List LONG_TYPE_INCLUDE = List.of("favoriteCount", "rating"); - private static final String DELIMITER = ","; - private static final String PRODUCT = "product"; - private static final String ID = "id"; - private static final String ASC = "ASC"; - - private SortingReviewSpecification() { - } - - public static Specification sortingFirstPageBy(final Product product) { - return (root, query, criteriaBuilder) -> Specification - .where(equalsProduct(product)) - .toPredicate(root, query, criteriaBuilder); - } - - public static Specification sortingBy(final Product product, final String sortOption, - final Review lastReview) { - return (root, query, criteriaBuilder) -> { - final String[] sortFieldSplit = sortOption.split(DELIMITER); - final String field = sortFieldSplit[0]; - final String sort = sortFieldSplit[1]; - - return Specification - .where((equalsProduct(product).and(equals(field, lastReview)).and(lessThanLastReviewId(lastReview))) - .or(equalsProduct(product).and(lessOrGreaterThan(field, sort, lastReview)))) - .toPredicate(root, query, criteriaBuilder); - }; - } - - private static Specification equalsProduct(final Product product) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(product)) { - return null; - } - - final Path productPath = root.get(PRODUCT); - - return criteriaBuilder.equal(productPath, product); - }; - } - - private static Specification lessThanLastReviewId(final Review lastReview) { - return (root, query, criteriaBuilder) -> { - if (Objects.isNull(lastReview)) { - return null; - } - - final Path reviewPath = root.get(ID); - - return criteriaBuilder.lessThan(reviewPath, lastReview.getId()); - }; - } - - private static Specification equals(final String fieldName, final Review lastReview) { - return (root, query, criteriaBuilder) -> { - if (validateNull(fieldName, lastReview)) { - return null; - } - - return checkEquals(fieldName, lastReview, root, criteriaBuilder); - }; - } - - private static Predicate checkEquals(final String fieldName, - final Review lastReview, - final Root root, - final CriteriaBuilder criteriaBuilder) { - if (LOCALDATETIME_TYPE_INCLUDE.contains(fieldName)) { - final Path createdAtPath = root.get(fieldName); - final LocalDateTime lastReviewCreatedAt = lastReview.getCreatedAt(); - return criteriaBuilder.equal(createdAtPath, lastReviewCreatedAt); - } - if (LONG_TYPE_INCLUDE.contains(fieldName)) { - final Path reviewPath = root.get(fieldName); - final Long lastReviewField = LongTypeReviewSortSpec.find(fieldName, lastReview); - return criteriaBuilder.equal(reviewPath, lastReviewField); - } - throw new NotSupportedReviewSortingConditionException(NOT_SUPPORTED_REVIEW_SORTING_CONDITION, fieldName); - } - - private static Specification lessOrGreaterThan(final String field, final String sort, - final Review lastReview) { - if (ASC.equalsIgnoreCase(sort)) { - return greaterThan(field, lastReview); - } - return lessThan(field, lastReview); - } - - private static Specification greaterThan(final String fieldName, final Review lastReview) { - return (root, query, criteriaBuilder) -> { - if (validateNull(fieldName, lastReview)) { - return null; - } - - return checkGreaterThan(fieldName, lastReview, root, criteriaBuilder); - }; - } - - private static Predicate checkGreaterThan(final String fieldName, final Review lastReview, final Root root, - final CriteriaBuilder criteriaBuilder) { - if (LOCALDATETIME_TYPE_INCLUDE.contains(fieldName)) { - final Path createdAtPath = root.get(fieldName); - final LocalDateTime lastReviewCreatedAt = lastReview.getCreatedAt(); - return criteriaBuilder.greaterThan(createdAtPath, lastReviewCreatedAt); - } - if (LONG_TYPE_INCLUDE.contains(fieldName)) { - final Path reviewPath = root.get(fieldName); - final Long lastReviewField = LongTypeReviewSortSpec.find(fieldName, lastReview); - return criteriaBuilder.greaterThan(reviewPath, lastReviewField); - } - throw new NotSupportedReviewSortingConditionException(NOT_SUPPORTED_REVIEW_SORTING_CONDITION, fieldName); - } - - private static Specification lessThan(final String fieldName, final Review lastReview) { - return (root, query, criteriaBuilder) -> { - if (validateNull(fieldName, lastReview)) { - return null; - } - - return checkLessThan(fieldName, lastReview, root, criteriaBuilder); - }; - } - - private static boolean validateNull(final String fieldName, final Review lastReview) { - return Objects.isNull(fieldName) || Objects.isNull(lastReview); - } - - private static Predicate checkLessThan(final String fieldName, final Review lastReview, final Root root, - final CriteriaBuilder criteriaBuilder) { - if (LOCALDATETIME_TYPE_INCLUDE.contains(fieldName)) { - final Path createdAtPath = root.get(fieldName); - final LocalDateTime lastReviewCreatedAt = lastReview.getCreatedAt(); - return criteriaBuilder.lessThan(createdAtPath, lastReviewCreatedAt); - } - if (LONG_TYPE_INCLUDE.contains(fieldName)) { - final Path reviewPath = root.get(fieldName); - final Long lastReviewField = LongTypeReviewSortSpec.find(fieldName, lastReview); - return criteriaBuilder.lessThan(reviewPath, lastReviewField); - } - throw new NotSupportedReviewSortingConditionException(NOT_SUPPORTED_REVIEW_SORTING_CONDITION, fieldName); - } -} diff --git a/backend/src/main/java/com/funeat/tag/application/TagService.java b/backend/src/main/java/com/funeat/tag/application/TagService.java deleted file mode 100644 index efb15849d..000000000 --- a/backend/src/main/java/com/funeat/tag/application/TagService.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.funeat.tag.application; - -import com.funeat.tag.domain.TagType; -import com.funeat.tag.dto.TagDto; -import com.funeat.tag.dto.TagsResponse; -import com.funeat.tag.persistence.TagRepository; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional(readOnly = true) -public class TagService { - - private final TagRepository tagRepository; - - public TagService(final TagRepository tagRepository) { - this.tagRepository = tagRepository; - } - - public List getAllTags() { - final List responses = new ArrayList<>(); - for (final TagType tagType : TagType.values()) { - responses.add(getTagsByTagType(tagType)); - } - return responses; - } - - private TagsResponse getTagsByTagType(final TagType tagType) { - final List tags = tagRepository.findTagsByTagType(tagType).stream() - .map(TagDto::toDto) - .collect(Collectors.toList()); - return TagsResponse.toResponse(tagType.name(), tags); - } -} diff --git a/backend/src/main/java/com/funeat/tag/domain/Tag.java b/backend/src/main/java/com/funeat/tag/domain/Tag.java deleted file mode 100644 index 554b8db6f..000000000 --- a/backend/src/main/java/com/funeat/tag/domain/Tag.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.funeat.tag.domain; - -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - -@Entity -public class Tag { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String name; - - @Enumerated(EnumType.STRING) - private TagType tagType; - - protected Tag() { - } - - public Tag(final String name, final TagType tagType) { - this.name = name; - this.tagType = tagType; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public TagType getTagType() { - return tagType; - } -} diff --git a/backend/src/main/java/com/funeat/tag/domain/TagType.java b/backend/src/main/java/com/funeat/tag/domain/TagType.java deleted file mode 100644 index 859526546..000000000 --- a/backend/src/main/java/com/funeat/tag/domain/TagType.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.funeat.tag.domain; - -public enum TagType { - - TASTE, QUANTITY, ETC -} diff --git a/backend/src/main/java/com/funeat/tag/dto/TagDto.java b/backend/src/main/java/com/funeat/tag/dto/TagDto.java deleted file mode 100644 index 45a09c5f1..000000000 --- a/backend/src/main/java/com/funeat/tag/dto/TagDto.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.funeat.tag.dto; - -import com.funeat.tag.domain.Tag; -import com.funeat.tag.domain.TagType; - -public class TagDto { - - private final Long id; - private final String name; - private final TagType tagType; - - public TagDto(final Long id, final String name, final TagType tagType) { - this.id = id; - this.name = name; - this.tagType = tagType; - } - - public static TagDto toDto(final Tag tag) { - return new TagDto(tag.getId(), tag.getName(), tag.getTagType()); - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public TagType getTagType() { - return tagType; - } -} diff --git a/backend/src/main/java/com/funeat/tag/dto/TagsResponse.java b/backend/src/main/java/com/funeat/tag/dto/TagsResponse.java deleted file mode 100644 index e81f29e10..000000000 --- a/backend/src/main/java/com/funeat/tag/dto/TagsResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.tag.dto; - -import java.util.List; - -public class TagsResponse { - - private final String tagType; - private final List tags; - - public TagsResponse(final String tagType, final List tags) { - this.tagType = tagType; - this.tags = tags; - } - - public static TagsResponse toResponse(final String tagType, final List tags) { - return new TagsResponse(tagType, tags); - } - - public String getTagType() { - return tagType; - } - - public List getTags() { - return tags; - } -} diff --git a/backend/src/main/java/com/funeat/tag/persistence/TagRepository.java b/backend/src/main/java/com/funeat/tag/persistence/TagRepository.java deleted file mode 100644 index 9ad319f7a..000000000 --- a/backend/src/main/java/com/funeat/tag/persistence/TagRepository.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.funeat.tag.persistence; - -import com.funeat.tag.domain.Tag; -import com.funeat.tag.domain.TagType; -import java.util.List; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -public interface TagRepository extends JpaRepository { - - List findTagsByIdIn(final List tagIds); - - List findTagsByTagType(final TagType tagType); - - @Query("SELECT t " - + "FROM ReviewTag rt " - + "JOIN rt.tag t " - + "WHERE rt.review.id = :reviewId") - List findTagsByReviewId(@Param("reviewId") final Long reviewId); -} diff --git a/backend/src/main/java/com/funeat/tag/presentation/TagApiController.java b/backend/src/main/java/com/funeat/tag/presentation/TagApiController.java deleted file mode 100644 index b8e5c6b69..000000000 --- a/backend/src/main/java/com/funeat/tag/presentation/TagApiController.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.funeat.tag.presentation; - -import com.funeat.tag.application.TagService; -import com.funeat.tag.dto.TagsResponse; -import java.util.List; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class TagApiController implements TagController { - - private final TagService tagService; - - public TagApiController(final TagService tagService) { - this.tagService = tagService; - } - - @GetMapping("/api/tags") - public ResponseEntity> getAllTags() { - final List responses = tagService.getAllTags(); - return ResponseEntity.ok(responses); - } -} diff --git a/backend/src/main/java/com/funeat/tag/presentation/TagController.java b/backend/src/main/java/com/funeat/tag/presentation/TagController.java deleted file mode 100644 index a0e2377c8..000000000 --- a/backend/src/main/java/com/funeat/tag/presentation/TagController.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.funeat.tag.presentation; - -import com.funeat.tag.dto.TagsResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import java.util.List; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; - -@Tag(name = "04.Tag", description = "νƒœκ·Έ κΈ°λŠ₯") -public interface TagController { - - @Operation(summary = "전체 νƒœκ·Έ λͺ©λ‘ 쑰회", description = "전체 νƒœκ·Έ λͺ©λ‘μ„ νƒœκ·Έ νƒ€μž… λ³„λ‘œ μ‘°νšŒν•œλ‹€.") - @ApiResponse( - responseCode = "200", - description = "전체 νƒœκ·Έ λͺ©λ‘ 쑰회 성곡." - ) - @GetMapping - ResponseEntity> getAllTags(); -} diff --git a/backend/src/main/resources/application-dev.yml b/backend/src/main/resources/application-dev.yml deleted file mode 100644 index 0c1a72220..000000000 --- a/backend/src/main/resources/application-dev.yml +++ /dev/null @@ -1,46 +0,0 @@ -spring: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: { DEV_DB_URL } - username: { DEV_DB_USERNAME } - password: { DEV_DB_PASSWORD } - - jpa: - hibernate: - ddl-auto: update - properties: - hibernate: - format_sql: true - show_sql: true - -kakao: - rest-api-key: { DEV_REST_API_KEY } - redirect-uri: { DEV_REDIRECT_URI } - admin-key: { DEV_ADMIN_KEY } - -management: - endpoints: - enabled-by-default: false - web: - exposure: - include: health, metrics, prometheus - base-path: { ACTUATOR_BASE_PATH } - jmx: - exposure: - exclude: "*" - endpoint: - health: - enabled: true - metrics: - enabled: true - prometheus: - enabled: true - -cloud: - aws: - region: - static: { S3_REGION } - s3: - bucket: { S3_BUCKET } - folder: { S3_DEV_FOLDER } - cloudfrontPath: { S3_DEV_CLOUDFRONT_PATH } diff --git a/backend/src/main/resources/application-local.yml b/backend/src/main/resources/application-local.yml deleted file mode 100644 index 27ba9bccb..000000000 --- a/backend/src/main/resources/application-local.yml +++ /dev/null @@ -1,31 +0,0 @@ -spring: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: - username: - password: - - jpa: - hibernate: - ddl-auto: create - properties: - hibernate: - format_sql: true - show_sql: true -logging: - level: - org.hibernate.type.descriptor.sql: trace - -kakao: - rest-api-key: { LOCAL_REST_API_KEY } - redirect-uri: { LOCAL_REDIRECT_URI } - admin-key: { LOCAL_ADMIN_KEY } - -cloud: - aws: - region: - static: { S3_REGION } - s3: - bucket: { S3_BUCKET } - folder: { S3_LOCAL_FOLDER } - cloudfrontPath: { S3_LOCAL_CLOUDFRONT_PATH } diff --git a/backend/src/main/resources/application-prod.yml b/backend/src/main/resources/application-prod.yml deleted file mode 100644 index 1943e2bf8..000000000 --- a/backend/src/main/resources/application-prod.yml +++ /dev/null @@ -1,45 +0,0 @@ -spring: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: { PROD_DB_URL } - username: { PROD_DB_USERNAME } - password: { PROD_DB_PASSWORD } - - jpa: - hibernate: - ddl-auto: none - properties: - hibernate: - show_sql: true - -kakao: - rest-api-key: { PROD_REST_API_KEY } - redirect-uri: { PROD_REDIRECT_URI } - admin-key: { PROD_ADMIN_KEY } - -management: - endpoints: - enabled-by-default: false - web: - exposure: - include: health, metrics, prometheus - base-path: { ACTUATOR_BASE_PATH } - jmx: - exposure: - exclude: "*" - endpoint: - health: - enabled: true - metrics: - enabled: true - prometheus: - enabled: true - -cloud: - aws: - region: - static: { S3_REGION } - s3: - bucket: { S3_BUCKET } - folder: { S3_PROD_FOLDER } - cloudfrontPath: { S3_PROD_CLOUDFRONT_PATH } diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml deleted file mode 100644 index 941adb9cf..000000000 --- a/backend/src/main/resources/application.yml +++ /dev/null @@ -1,42 +0,0 @@ -spring: - profiles: - active: { DEPLOY_ACTIVE } - servlet: - multipart: - enabled: true - maxFileSize: 10MB - maxRequestSize: 15MB - task: - execution: - pool: - core-size: { THREAD_CORE_SIZE } - max-size: { THREAD_MAX_SIZE } - session: - store-type: jdbc - jdbc: - initialize-schema: never - datasource: - hikari: - connection-timeout: { CONNECTION_TIMEOUT } - maximum-pool-size: { MAXIMUM_POOL_SIZE } - -springdoc: - swagger-ui: - path: /funeat-api - enabled: true - tags-sorter: alpha - -logging: - file: - path: { LOG_DIR } - -server: - tomcat: - threads: - max: { MAX_THREADS } - max-connections: { MAX_CONNECTIONS } - accept-count: { ACCEPT_COUNT } - -back-office: - id: { BACK_OFFICE_ID } - key: { BACK_OFFICE_KEY } diff --git a/backend/src/main/resources/logback-spring-dev.xml b/backend/src/main/resources/logback-spring-dev.xml deleted file mode 100644 index b86839da1..000000000 --- a/backend/src/main/resources/logback-spring-dev.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - ${dev_slack_webhook_uri} - - ${log_pattern} - - open-macbook - :face_with_symbols_on_mouth: - true - - - - - - WARN - - - - - - INFO - ACCEPT - DENY - - ${log_dir}/info.log - - - ${log_dir}/info/info.%d{yyyy-MM-dd}_%i.log - - ${dev_file_size} - ${dev_file_max_history} - - - - ${log_pattern} - - true - - - - - - WARN - ACCEPT - DENY - - ${log_dir}/warn.log - - - ${log_dir}/warn/%d{yyyy-MM-dd}_%i.log - - ${dev_file_size} - ${dev_file_max_history} - - - - ${log_pattern} - - true - - - - - - ERROR - ACCEPT - DENY - - ${log_dir}/error.log - - - ${log_dir}/error/%d{yyyy-MM-dd}_%i.log - - ${dev_file_size} - ${dev_file_max_history} - - - - ${log_pattern} - - true - - - - - ${log_dir}/query_log.log - - - ${log_dir}/query/%d{yyyy-MM-dd}_%i.log - - 10kb - 1 - - - - ${log_pattern} - - true - - - - - - - - - - - - - - - - - - diff --git a/backend/src/main/resources/logback-spring-prod.xml b/backend/src/main/resources/logback-spring-prod.xml deleted file mode 100644 index 101ba8d7f..000000000 --- a/backend/src/main/resources/logback-spring-prod.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - ${prod_slack_webhook_uri} - - ${log_pattern} - - open-macbook - :face_with_symbols_on_mouth: - true - - - - - - ERROR - - - - - - INFO - ACCEPT - DENY - - ${log_dir}/info.log - - - ${log_dir}/info/info.%d{yyyy-MM-dd}_%i.log - - ${prod_file_size} - ${prod_file_max_history} - - - - ${log_pattern} - - true - - - - - - WARN - ACCEPT - DENY - - ${log_dir}/warn.log - - - ${log_dir}/warn/%d{yyyy-MM-dd}_%i.log - - ${prod_file_size} - ${prod_file_max_history} - - - - ${log_pattern} - - true - - - - - - ERROR - ACCEPT - DENY - - ${log_dir}/error.log - - - ${log_dir}/error/%d{yyyy-MM-dd}_%i.log - - ${prod_file_size} - ${prod_file_max_history} - - - - ${log_pattern} - - true - - - - - - - - - - - diff --git a/backend/src/main/resources/logback-spring.xml b/backend/src/main/resources/logback-spring.xml deleted file mode 100644 index ccea7008c..000000000 --- a/backend/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/backend/src/main/resources/logback-variables.yml b/backend/src/main/resources/logback-variables.yml deleted file mode 100644 index 823342938..000000000 --- a/backend/src/main/resources/logback-variables.yml +++ /dev/null @@ -1,7 +0,0 @@ -log_pattern: { LOG_PATTERN } -dev_slack_webhook_uri: { DEV_SLACK_WEBHOOK_URI } -dev_file_size: { DEV_FILE_SIZE } -dev_file_max_history: { DEV_FILE_MAX_HISTORY } -prod_slack_webhook_uri: { PROD_SLACK_WEBHOOK_URI } -prod_file_size: { PROD_FILE_SIZE } -prod_file_max_history: { PROD_FILE_MAX_HISTORY } diff --git a/backend/src/test/java/com/funeat/FuneatApplicationTests.java b/backend/src/test/java/com/funeat/FuneatApplicationTests.java deleted file mode 100644 index 6648db315..000000000 --- a/backend/src/test/java/com/funeat/FuneatApplicationTests.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.funeat; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class FuneatApplicationTests { - - @Test - void contextLoads() { - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/auth/AuthAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/auth/AuthAcceptanceTest.java deleted file mode 100644 index 77270c589..000000000 --- a/backend/src/test/java/com/funeat/acceptance/auth/AuthAcceptanceTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.funeat.acceptance.auth; - -import static com.funeat.acceptance.auth.LoginSteps.λ‘œκ·Έμ•„μ›ƒ_μš”μ²­; -import static com.funeat.acceptance.auth.LoginSteps.둜그인_μ‹œλ„_μš”μ²­; -import static com.funeat.acceptance.auth.LoginSteps.둜그인_μΏ ν‚€_νšλ“; -import static com.funeat.acceptance.auth.LoginSteps.카카였_둜그인_λ²„νŠΌ_클릭; -import static com.funeat.acceptance.common.CommonSteps.LOCATION_ν—€λ”μ—μ„œ_λ¦¬λ‹€μ΄λ ‰νŠΈ_μ£Όμ†Œ_μΆ”μΆœ; -import static com.funeat.acceptance.common.CommonSteps.REDIRECT_URL을_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.λ¦¬λ‹€μ΄λ ‰μ…˜_영ꡬ_이동; -import static com.funeat.acceptance.common.CommonSteps.μΈμ¦λ˜μ§€_μ•ŠμŒ; -import static com.funeat.acceptance.common.CommonSteps.정상_처리; -import static com.funeat.fixture.MemberFixture.멀버1; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.acceptance.common.AcceptanceTest; -import com.funeat.auth.application.AuthService; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullAndEmptySource; -import org.springframework.beans.factory.annotation.Autowired; - -@SuppressWarnings("NonAsciiCharacters") -public class AuthAcceptanceTest extends AcceptanceTest { - - private static final String λ§ˆμ΄νŽ˜μ΄μ§€ = "/members"; - private static final String λ©”μΈνŽ˜μ΄μ§€ = "/"; - - @Autowired - private AuthService authService; - - @Nested - class login_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 멀버가_둜그인_λ²„νŠΌμ„_λˆ„λ₯΄λ©΄_OAUTH_둜그인_νŽ˜μ΄μ§€λ‘œ_λ¦¬λ‹€μ΄λ ‰νŠΈν• _수_μžˆλ‹€() { - // given - final var OAUTH_둜그인_νŽ˜μ΄μ§€ = authService.getLoginRedirectUri(); - - // when - final var 응닡 = 카카였_둜그인_λ²„νŠΌ_클릭(); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, λ¦¬λ‹€μ΄λ ‰μ…˜_영ꡬ_이동); - REDIRECT_URL을_κ²€μ¦ν•œλ‹€(응닡, OAUTH_둜그인_νŽ˜μ΄μ§€); - } - } - - @Nested - class loginAuthorizeUser_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‹ κ·œ_μœ μ €λΌλ©΄_λ§ˆμ΄νŽ˜μ΄μ§€_경둜λ₯Ό_헀더에_λ‹΄μ•„_응닡을_보낸닀() { - // given & when - final var 응닡 = 둜그인_μ‹œλ„_μš”μ²­(멀버1); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - 헀더에_λ¦¬λ‹€μ΄λ ‰νŠΈκ°€_μ‘΄μž¬ν•˜λŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ΄νŽ˜μ΄μ§€); - } - - @Test - void κΈ°μ‘΄_μœ μ €λΌλ©΄_λ©”μΈνŽ˜μ΄μ§€_경둜λ₯Ό_헀더에_λ‹΄μ•„_응닡을_보낸닀() { - // given - 둜그인_μΏ ν‚€_νšλ“(멀버1); - - // when - final var 응닡 = 둜그인_μ‹œλ„_μš”μ²­(멀버1); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - 헀더에_λ¦¬λ‹€μ΄λ ‰νŠΈκ°€_μ‘΄μž¬ν•˜λŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ©”μΈνŽ˜μ΄μ§€); - } - } - - @Nested - class logout_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ‘œκ·Έμ•„μ›ƒμ„_ν•˜λ‹€() { - // given & when - final var 응닡 = λ‘œκ·Έμ•„μ›ƒ_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, λ¦¬λ‹€μ΄λ ‰μ…˜_영ꡬ_이동); - REDIRECT_URL을_κ²€μ¦ν•œλ‹€(응닡, λ©”μΈνŽ˜μ΄μ§€); - } - } - - @Nested - class logout_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void μΏ ν‚€κ°€_μ‘΄μž¬ν•˜μ§€_μ•Šμ„_λ•Œ_λ‘œκ·Έμ•„μ›ƒμ„_ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given & when - final var 응닡 = λ‘œκ·Έμ•„μ›ƒ_μš”μ²­(cookie); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - } - } - - private void 헀더에_λ¦¬λ‹€μ΄λ ‰νŠΈκ°€_μ‘΄μž¬ν•˜λŠ”μ§€_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final String expected) { - final var actual = LOCATION_ν—€λ”μ—μ„œ_λ¦¬λ‹€μ΄λ ‰νŠΈ_μ£Όμ†Œ_μΆ”μΆœ(response); - - assertThat(actual).isEqualTo(expected); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/auth/LoginSteps.java b/backend/src/test/java/com/funeat/acceptance/auth/LoginSteps.java deleted file mode 100644 index 92d2f48c7..000000000 --- a/backend/src/test/java/com/funeat/acceptance/auth/LoginSteps.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.funeat.acceptance.auth; - -import static io.restassured.RestAssured.given; - -import io.restassured.RestAssured; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; - -@SuppressWarnings("NonAsciiCharacters") -public class LoginSteps { - - public static ExtractableResponse 카카였_둜그인_λ²„νŠΌ_클릭() { - return given() - .redirects().follow(false) - .when() - .get("/api/auth/kakao") - .then() - .extract(); - } - - public static ExtractableResponse 둜그인_μ‹œλ„_μš”μ²­(final Long memberId) { - return given() - .param("code", String.valueOf(memberId)) - .when() - .get("/api/login/oauth2/code/kakao") - .then() - .extract(); - } - - public static ExtractableResponse λ‘œκ·Έμ•„μ›ƒ_μš”μ²­(final String loginCookie) { - return given() - .cookie("SESSION", loginCookie) - .when() - .post("/api/logout") - .then() - .extract(); - } - - public static String 둜그인_μΏ ν‚€_νšλ“(final Long memberId) { - return RestAssured.given() - .queryParam("code", String.valueOf(memberId)) - .when() - .get("/api/login/oauth2/code/kakao") - .then() - .extract() - .response() - .getCookie("SESSION"); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/banner/BannerAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/banner/BannerAcceptanceTest.java deleted file mode 100644 index e5b3a39fd..000000000 --- a/backend/src/test/java/com/funeat/acceptance/banner/BannerAcceptanceTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.funeat.acceptance.banner; - -import static com.funeat.acceptance.banner.BannerSteps.λ°°λ„ˆ_λͺ©λ‘_쑰회_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.정상_처리; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ1_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ2_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ3_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ4_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ5_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.acceptance.common.AcceptanceTest; -import com.funeat.banner.domain.Banner; -import com.funeat.banner.dto.BannerResponse; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -public class BannerAcceptanceTest extends AcceptanceTest { - - @Nested - class getBanners_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ°°λ„ˆλ₯Ό_아이디_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_전체_μ‘°νšŒν•œλ‹€() { - // given - final var λ°°λ„ˆ1 = λ°°λ„ˆ1_생성(); - final var λ°°λ„ˆ2 = λ°°λ„ˆ2_생성(); - final var λ°°λ„ˆ3 = λ°°λ„ˆ3_생성(); - final var λ°°λ„ˆ4 = λ°°λ„ˆ4_생성(); - final var λ°°λ„ˆ5 = λ°°λ„ˆ5_생성(); - final var 생성할_λ°°λ„ˆ_리슀트 = Arrays.asList(λ°°λ„ˆ1, λ°°λ„ˆ2, λ°°λ„ˆ3, λ°°λ„ˆ4, λ°°λ„ˆ5); - bannerRepository.saveAll(생성할_λ°°λ„ˆ_리슀트); - - // when - final var 응닡 = λ°°λ„ˆ_λͺ©λ‘_쑰회_μš”μ²­(); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ°°λ„ˆ_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 생성할_λ°°λ„ˆ_리슀트); - } - } - - private void λ°°λ„ˆ_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, - final List expected) { - List expectedResponse = new ArrayList<>(); - for (int i = expected.size() - 1; i >= 0; i--) { - expectedResponse.add(BannerResponse.toResponse(expected.get(i))); - } - - final List result = response.jsonPath().getList("$", BannerResponse.class); - assertThat(result).usingRecursiveComparison() - .ignoringFields("id") - .isEqualTo(expectedResponse); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/banner/BannerSteps.java b/backend/src/test/java/com/funeat/acceptance/banner/BannerSteps.java deleted file mode 100644 index 6fbc155f9..000000000 --- a/backend/src/test/java/com/funeat/acceptance/banner/BannerSteps.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.funeat.acceptance.banner; - -import io.restassured.RestAssured; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; - -@SuppressWarnings("NonAsciiCharacters") -public class BannerSteps { - - public static ExtractableResponse λ°°λ„ˆ_λͺ©λ‘_쑰회_μš”μ²­() { - return RestAssured.given() - .when() - .get("/api/banners") - .then() - .extract(); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/common/AcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/common/AcceptanceTest.java deleted file mode 100644 index 2e5be6b6d..000000000 --- a/backend/src/test/java/com/funeat/acceptance/common/AcceptanceTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.funeat.acceptance.common; - -import com.funeat.banner.persistence.BannerRepository; -import com.funeat.comment.persistence.CommentRepository; -import com.funeat.common.DataClearExtension; -import com.funeat.member.domain.Member; -import com.funeat.member.persistence.MemberRepository; -import com.funeat.member.persistence.RecipeFavoriteRepository; -import com.funeat.member.persistence.ReviewFavoriteRepository; -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import com.funeat.product.persistence.CategoryRepository; -import com.funeat.product.persistence.ProductRecipeRepository; -import com.funeat.product.persistence.ProductRepository; -import com.funeat.recipe.persistence.RecipeImageRepository; -import com.funeat.recipe.persistence.RecipeRepository; -import com.funeat.review.persistence.ReviewRepository; -import com.funeat.review.persistence.ReviewTagRepository; -import com.funeat.tag.domain.Tag; -import com.funeat.tag.persistence.TagRepository; -import io.restassured.RestAssured; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; - -@ExtendWith(DataClearExtension.class) -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(ReplaceUnderscores.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -public abstract class AcceptanceTest { - - @LocalServerPort - private int port; - - @Autowired - protected ProductRepository productRepository; - - @Autowired - protected CategoryRepository categoryRepository; - - @Autowired - protected MemberRepository memberRepository; - - @Autowired - protected ReviewRepository reviewRepository; - - @Autowired - protected TagRepository tagRepository; - - @Autowired - protected ReviewTagRepository reviewTagRepository; - - @Autowired - protected ReviewFavoriteRepository reviewFavoriteRepository; - - @Autowired - protected RecipeRepository recipeRepository; - - @Autowired - protected RecipeImageRepository recipeImageRepository; - - @Autowired - protected ProductRecipeRepository productRecipeRepository; - - @Autowired - protected RecipeFavoriteRepository recipeFavoriteRepository; - - @Autowired - protected BannerRepository bannerRepository; - - @Autowired - protected CommentRepository commentRepository; - - @BeforeEach - void setUp() { - RestAssured.port = port; - } - - protected Long 단일_μƒν’ˆ_μ €μž₯(final Product product) { - return productRepository.save(product).getId(); - } - - protected Long 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(final Category category) { - return categoryRepository.save(category).getId(); - } - - protected Long 단일_멀버_μ €μž₯(final Member member) { - return memberRepository.save(member).getId(); - } - - protected Long 단일_νƒœκ·Έ_μ €μž₯(final Tag tag) { - return tagRepository.save(tag).getId(); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/common/CommonSteps.java b/backend/src/test/java/com/funeat/acceptance/common/CommonSteps.java deleted file mode 100644 index af33aa14f..000000000 --- a/backend/src/test/java/com/funeat/acceptance/common/CommonSteps.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.funeat.acceptance.common; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.dto.PageDto; -import io.restassured.builder.MultiPartSpecBuilder; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import io.restassured.specification.MultiPartSpecification; -import java.util.ArrayList; -import java.util.List; -import org.springframework.http.HttpStatus; - -@SuppressWarnings("NonAsciiCharacters") -public class CommonSteps { - - private static final String LOCATION = "Location"; - public static final HttpStatus 정상_처리 = HttpStatus.OK; - public static final HttpStatus 정상_생성 = HttpStatus.CREATED; - public static final HttpStatus 정상_처리_NO_CONTENT = HttpStatus.NO_CONTENT; - public static final HttpStatus λ¦¬λ‹€μ΄λ ‰μ…˜_영ꡬ_이동 = HttpStatus.FOUND; - public static final HttpStatus μΈμ¦λ˜μ§€_μ•ŠμŒ = HttpStatus.UNAUTHORIZED; - public static final HttpStatus 잘λͺ»λœ_μš”μ²­ = HttpStatus.BAD_REQUEST; - public static final HttpStatus μ°Ύμ„μˆ˜_μ—†μŒ = HttpStatus.NOT_FOUND; - - public static Long LOCATION_ν—€λ”μ—μ„œ_ID_μΆ”μΆœ(final ExtractableResponse response) { - return Long.parseLong(response.header(LOCATION).split("/")[2]); - } - - public static String LOCATION_ν—€λ”μ—μ„œ_λ¦¬λ‹€μ΄λ ‰νŠΈ_μ£Όμ†Œ_μΆ”μΆœ(final ExtractableResponse response) { - return response.header(LOCATION); - } - - public static void LOCATION_헀더λ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response) { - assertThat(response.header("Location")).isNotBlank(); - } - - public static void STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final HttpStatus httpStatus) { - assertThat(response.statusCode()).isEqualTo(httpStatus.value()); - } - - public static void REDIRECT_URL을_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final String expected) { - final var actual = LOCATION_ν—€λ”μ—μ„œ_λ¦¬λ‹€μ΄λ ‰νŠΈ_μ£Όμ†Œ_μΆ”μΆœ(response); - - assertThat(actual).isEqualTo(expected); - } - - public static MultiPartSpecification 사진_λͺ…μ„Έ_μš”μ²­(final String name) { - return new MultiPartSpecBuilder("image".getBytes()) - .fileName(String.format("%s.png", name)) - .controlName("image") - .mimeType("image/png") - .build(); - } - - public static List μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(final String... names) { - final var images = new ArrayList(); - - for (final String name : names) { - images.add(new MultiPartSpecBuilder("image".getBytes()) - .fileName(String.format("%s.png", name)) - .controlName("image") - .mimeType("image/png") - .build() - ); - } - - return images; - } - - public static void νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final PageDto expected) { - final var actual = response.jsonPath().getObject("page", PageDto.class); - - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - public static void λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final boolean expected) { - final var actual = response.jsonPath().getBoolean("hasNext"); - - assertThat(actual).isEqualTo(expected); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/common/TestPlatformUserProvider.java b/backend/src/test/java/com/funeat/acceptance/common/TestPlatformUserProvider.java deleted file mode 100644 index 269e27d55..000000000 --- a/backend/src/test/java/com/funeat/acceptance/common/TestPlatformUserProvider.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.acceptance.common; - -import com.funeat.auth.dto.UserInfoDto; -import com.funeat.auth.util.PlatformUserProvider; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; - -@Component -@Profile("test") -public class TestPlatformUserProvider implements PlatformUserProvider { - - @Override - public UserInfoDto getPlatformUser(final String code) { - return new UserInfoDto(Long.valueOf(code), String.format("member%s", code), - String.format("www.member%s.com", code)); - } - - @Override - public String getRedirectURI() { - return "www.test.com"; - } - - @Override - public void logout(final String platformId) { - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/member/MemberAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/member/MemberAcceptanceTest.java deleted file mode 100644 index b2a94b2c0..000000000 --- a/backend/src/test/java/com/funeat/acceptance/member/MemberAcceptanceTest.java +++ /dev/null @@ -1,431 +0,0 @@ -package com.funeat.acceptance.member; - -import static com.funeat.acceptance.auth.LoginSteps.둜그인_μΏ ν‚€_νšλ“; -import static com.funeat.acceptance.common.CommonSteps.STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.사진_λͺ…μ„Έ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.μΈμ¦λ˜μ§€_μ•ŠμŒ; -import static com.funeat.acceptance.common.CommonSteps.잘λͺ»λœ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.정상_처리; -import static com.funeat.acceptance.common.CommonSteps.정상_처리_NO_CONTENT; -import static com.funeat.acceptance.common.CommonSteps.μ°Ύμ„μˆ˜_μ—†μŒ; -import static com.funeat.acceptance.common.CommonSteps.νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.member.MemberSteps.리뷰_μ‚­μ œ_μš”μ²­; -import static com.funeat.acceptance.member.MemberSteps.μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_μš”μ²­; -import static com.funeat.acceptance.member.MemberSteps.μ‚¬μš©μž_리뷰_쑰회_μš”μ²­; -import static com.funeat.acceptance.member.MemberSteps.μ‚¬μš©μž_정보_μˆ˜μ •_μš”μ²­; -import static com.funeat.acceptance.member.MemberSteps.μ‚¬μš©μž_정보_쑰회_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.리뷰_μž‘μ„±_μš”μ²­; -import static com.funeat.auth.exception.AuthErrorCode.LOGIN_MEMBER_NOT_FOUND; -import static com.funeat.exception.CommonErrorCode.REQUEST_VALID_ERROR_CODE; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.ImageFixture.이미지1; -import static com.funeat.fixture.ImageFixture.이미지2; -import static com.funeat.fixture.ImageFixture.이미지3; -import static com.funeat.fixture.MemberFixture.멀버1; -import static com.funeat.fixture.MemberFixture.멀버2; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.μœ μ €λ‹‰λ„€μž„μˆ˜μ •μš”μ²­_생성; -import static com.funeat.fixture.PageFixture.FIRST_PAGE; -import static com.funeat.fixture.PageFixture.PAGE_SIZE; -import static com.funeat.fixture.PageFixture.λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O; -import static com.funeat.fixture.PageFixture.응닡_νŽ˜μ΄μ§€_생성; -import static com.funeat.fixture.PageFixture.μ²«νŽ˜μ΄μ§€O; -import static com.funeat.fixture.PageFixture.총_데이터_개수; -import static com.funeat.fixture.PageFixture.총_νŽ˜μ΄μ§€; -import static com.funeat.fixture.PageFixture.μ΅œμ‹ μˆœ; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό1; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό2; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성; -import static com.funeat.fixture.ReviewFixture.리뷰1; -import static com.funeat.fixture.ReviewFixture.리뷰2; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성; -import static com.funeat.fixture.ScoreFixture.점수_1점; -import static com.funeat.fixture.ScoreFixture.점수_2점; -import static com.funeat.fixture.ScoreFixture.점수_3점; -import static com.funeat.fixture.ScoreFixture.점수_4점; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성; -import static com.funeat.review.exception.ReviewErrorCode.REVIEW_NOT_FOUND; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.acceptance.common.AcceptanceTest; -import com.funeat.member.domain.Member; -import com.funeat.member.dto.MemberProfileResponse; -import com.funeat.member.dto.MemberRecipeDto; -import com.funeat.member.dto.MemberReviewDto; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullAndEmptySource; - -@SuppressWarnings("NonAsciiCharacters") -public class MemberAcceptanceTest extends AcceptanceTest { - - @Nested - class getMemberProfile_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μž_정보λ₯Ό_ν™•μΈν•˜λ‹€() { - // given & when - final var 응닡 = μ‚¬μš©μž_정보_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - μ‚¬μš©μž_정보_쑰회λ₯Ό_κ²€μ¦ν•˜λ‹€(응닡, 멀버_멀버1_생성()); - } - } - - @Nested - class getMemberProfile_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_μ‚¬μš©μž_정보λ₯Ό_ν™•μΈμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given & when - final var 응닡 = μ‚¬μš©μž_정보_쑰회_μš”μ²­(cookie); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - } - - @Nested - class putMemberProfile_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μž_정보λ₯Ό_μˆ˜μ •ν•˜λ‹€() { - // given & when - final var 응닡 = μ‚¬μš©μž_정보_μˆ˜μ •_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), 사진_λͺ…μ„Έ_μš”μ²­(이미지1), μœ μ €λ‹‰λ„€μž„μˆ˜μ •μš”μ²­_생성("after")); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - } - - @Test - void μ‚¬μš©μž_λ‹‰λ„€μž„μ„_μˆ˜μ •ν•˜λ‹€() { - // given & when - final var 응닡 = μ‚¬μš©μž_정보_μˆ˜μ •_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), 사진_λͺ…μ„Έ_μš”μ²­(이미지1), μœ μ €λ‹‰λ„€μž„μˆ˜μ •μš”μ²­_생성("member1")); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - } - - @Test - void μ‚¬μš©μž_이미지λ₯Ό_μˆ˜μ •ν•˜λ‹€() { - // given & when - final var 응닡 = μ‚¬μš©μž_정보_μˆ˜μ •_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), 사진_λͺ…μ„Έ_μš”μ²­(이미지2), μœ μ €λ‹‰λ„€μž„μˆ˜μ •μš”μ²­_생성("after")); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - } - } - - @Nested - class putMemberProfile_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_μ‚¬μš©μž_정보_μˆ˜μ •μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given & when - final var 응닡 = μ‚¬μš©μž_정보_μˆ˜μ •_μš”μ²­(cookie, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), μœ μ €λ‹‰λ„€μž„μˆ˜μ •μš”μ²­_생성("after")); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - - @ParameterizedTest - @NullAndEmptySource - void μ‚¬μš©μžκ°€_μ‚¬μš©μž_정보_μˆ˜μ •ν• λ•Œ_λ‹‰λ„€μž„_λ―ΈκΈ°μž…μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String nickname) { - // given & when - final var 응닡 = μ‚¬μš©μž_정보_μˆ˜μ •_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), 사진_λͺ…μ„Έ_μš”μ²­(이미지1), μœ μ €λ‹‰λ„€μž„μˆ˜μ •μš”μ²­_생성(nickname)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "λ‹‰λ„€μž„μ„ ν™•μΈν•΄μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - } - - @Nested - class getMemberReviews_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_리뷰λ₯Ό_μ‘°νšŒν•˜λ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_2점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_1점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(2L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μ‚¬μš©μž_리뷰_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μ‚¬μš©μž_리뷰_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 2); - } - - @Test - void μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_리뷰가_μ—†μ„λ•Œ_λ¦¬λ·°λŠ”_λΉˆμƒνƒœλ‘œ_μ‘°νšŒλœλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_2점, List.of(νƒœκ·Έ))); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(0L), 총_νŽ˜μ΄μ§€(0L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μ‚¬μš©μž_리뷰_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μ‚¬μš©μž_리뷰_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 0); - } - } - - @Nested - class getMemberReviews_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void λ‘œκ·ΈμΈν•˜μ§€_μ•Šμ€_μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_리뷰λ₯Ό_μ‘°νšŒν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given & when - final var 응닡 = μ‚¬μš©μž_리뷰_쑰회_μš”μ²­(cookie, μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - } - - @Nested - class getMemberRecipes_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_꿀쑰합을_μ‘°νšŒν•˜λ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(2L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό1)); - } - - @Test - void μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_꿀쑰합이_μ—†μ„λ•Œ_꿀쑰합은_λΉˆμƒνƒœλ‘œ_μ‘°νšŒλœλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(0L), 총_νŽ˜μ΄μ§€(0L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, Collections.emptyList()); - } - - @Test - void μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_꿀쑰합에_이미지가_μ—†μ„λ•Œ_꿀쑰합은_이미지없이_μ‘°νšŒλœλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), null, λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(1L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ ˆμ‹œν”Ό)); - μ‘°νšŒν•œ_κΏ€μ‘°ν•©μ˜_이미지가_μ—†λŠ”μ§€_ν™•μΈν•œλ‹€(응닡); - } - } - - @Nested - class getMemberRecipes_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void λ‘œκ·ΈμΈν•˜μ§€_μ•Šμ€_μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_꿀쑰합을_μ‘°νšŒν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given & when - final var 응닡 = μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_μš”μ²­(cookie, μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - } - - @Nested - class deleteReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μžμ‹ μ΄_μž‘μ„±ν•œ_리뷰λ₯Ό_μ‚­μ œν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = 리뷰_μ‚­μ œ_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), 리뷰1); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - } - } - - @Nested - class deleteReview_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void λ‘œκ·ΈμΈν•˜μ§€_μ•ŠλŠ”_μ‚¬μš©μžκ°€_리뷰_μ‚­μ œμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = 리뷰_μ‚­μ œ_μš”μ²­(cookie, 리뷰1); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰λ₯Ό_μ‚­μ œν• _수_μ—†λ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = 리뷰_μ‚­μ œ_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), 리뷰2); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REVIEW_NOT_FOUND.getCode(), REVIEW_NOT_FOUND.getMessage()); - } - - @Test - void μžμ‹ μ΄_μž‘μ„±ν•˜μ§€_μ•Šμ€_λ¦¬λ·°λŠ”_μ‚­μ œν• _수_μ—†λ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = 리뷰_μ‚­μ œ_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), 리뷰1); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - } - } - - private void μ‚¬μš©μž_리뷰_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final int expectedReviewSize) { - final var actual = response.jsonPath().getList("reviews", MemberReviewDto.class); - - assertThat(actual.size()).isEqualTo(expectedReviewSize); - } - - private void μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List recipeIds) { - final var actual = response.jsonPath() - .getList("recipes", MemberRecipeDto.class); - - assertThat(actual).extracting(MemberRecipeDto::getId) - .containsExactlyElementsOf(recipeIds); - } - - private void RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final String expectedCode, - final String expectedMessage) { - assertSoftly(soft -> { - soft.assertThat(response.jsonPath().getString("code")) - .isEqualTo(expectedCode); - soft.assertThat(response.jsonPath().getString("message")) - .isEqualTo(expectedMessage); - }); - } - - private void μ‚¬μš©μž_정보_쑰회λ₯Ό_κ²€μ¦ν•˜λ‹€(final ExtractableResponse response, final Member member) { - final var expected = MemberProfileResponse.toResponse(member); - final var expectedNickname = expected.getNickname(); - final var expectedProfileImage = expected.getProfileImage(); - - final var actualNickname = response.jsonPath().getString("nickname"); - final var actualProfileImage = response.jsonPath().getString("profileImage"); - - assertSoftly(soft -> { - soft.assertThat(actualNickname) - .isEqualTo(expectedNickname); - soft.assertThat(actualProfileImage) - .isEqualTo(expectedProfileImage); - }); - } - - private void μ‘°νšŒν•œ_κΏ€μ‘°ν•©μ˜_이미지가_μ—†λŠ”μ§€_ν™•μΈν•œλ‹€(final ExtractableResponse response) { - final var actual = response.jsonPath() - .getString("image"); - - assertThat(actual).isNull(); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/member/MemberSteps.java b/backend/src/test/java/com/funeat/acceptance/member/MemberSteps.java deleted file mode 100644 index 98cf4d6fa..000000000 --- a/backend/src/test/java/com/funeat/acceptance/member/MemberSteps.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.funeat.acceptance.member; - -import static io.restassured.RestAssured.given; - -import com.funeat.member.dto.MemberRequest; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import io.restassured.specification.MultiPartSpecification; -import java.util.Objects; - -@SuppressWarnings("NonAsciiCharacters") -public class MemberSteps { - - public static ExtractableResponse μ‚¬μš©μž_정보_쑰회_μš”μ²­(final String loginCookie) { - return given() - .cookie("SESSION", loginCookie) - .when() - .get("/api/members") - .then() - .extract(); - } - - public static ExtractableResponse μ‚¬μš©μž_정보_μˆ˜μ •_μš”μ²­(final String loginCookie, - final MultiPartSpecification image, - final MemberRequest request) { - final var requestSpec = given() - .cookie("SESSION", loginCookie); - - if (Objects.nonNull(image)) { - requestSpec.multiPart(image); - } - - return requestSpec - .multiPart("memberRequest", request, "application/json") - .body(request) - .when() - .put("/api/members") - .then() - .extract(); - } - - public static ExtractableResponse μ‚¬μš©μž_리뷰_쑰회_μš”μ²­(final String loginCookie, final String sort, - final Long page) { - return given() - .when() - .cookie("SESSION", loginCookie) - .queryParam("sort", sort) - .queryParam("page", page) - .get("/api/members/reviews") - .then() - .extract(); - } - - public static ExtractableResponse μ‚¬μš©μž_κΏ€μ‘°ν•©_쑰회_μš”μ²­(final String loginCookie, final String sort, - final Long page) { - return given() - .when() - .cookie("SESSION", loginCookie) - .queryParam("sort", sort) - .queryParam("page", page) - .get("/api/members/recipes") - .then() - .extract(); - } - - public static ExtractableResponse 리뷰_μ‚­μ œ_μš”μ²­(final String loginCookie, final Long reviewId) { - return given() - .cookie("SESSION", loginCookie) - .when() - .delete("/api/members/reviews/{reviewId}", reviewId) - .then() - .extract(); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/product/CategoryAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/product/CategoryAcceptanceTest.java deleted file mode 100644 index 3ee19b4f9..000000000 --- a/backend/src/test/java/com/funeat/acceptance/product/CategoryAcceptanceTest.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.funeat.acceptance.product; - -import static com.funeat.acceptance.common.CommonSteps.STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.잘λͺ»λœ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.정상_처리; -import static com.funeat.acceptance.product.CategorySteps.μΉ΄ν…Œκ³ λ¦¬_λͺ©λ‘_쑰회_μš”μ²­; -import static com.funeat.exception.CommonErrorCode.REQUEST_VALID_ERROR_CODE; -import static com.funeat.fixture.CategoryFixture.μŒμ‹; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_CU_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_과자λ₯˜_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.acceptance.common.AcceptanceTest; -import com.funeat.product.dto.CategoryResponse; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import java.util.List; -import org.assertj.core.api.SoftAssertions; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullAndEmptySource; -import org.junit.jupiter.params.provider.ValueSource; - -@SuppressWarnings("NonAsciiCharacters") -public class CategoryAcceptanceTest extends AcceptanceTest { - - - @Nested - class getAllCategoriesByType_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 곡톡_μƒν’ˆ_μΉ΄ν…Œκ³ λ¦¬μ˜_λͺ©λ‘μ„_μ‘°νšŒν•œλ‹€() { - // given - final var κ°„νŽΈμ‹μ‚¬ = 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성()); - final var 즉석쑰리 = 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성()); - final var 과자λ₯˜ = 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬_과자λ₯˜_생성()); - final var CU = 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬_CU_생성()); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬_λͺ©λ‘_쑰회_μš”μ²­(μŒμ‹); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - 곡톡_μƒν’ˆ_μΉ΄ν…Œκ³ λ¦¬_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(κ°„νŽΈμ‹μ‚¬, 즉석쑰리, 과자λ₯˜), List.of(CU)); - } - } - - @Nested - class getAllCategoriesByType_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - @ValueSource(strings = {"a", "foo"}) - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μΉ΄ν…Œκ³ λ¦¬μ˜_λͺ©λ‘μ„_μ‘°νšŒν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String type) { - // given & when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬_λͺ©λ‘_쑰회_μš”μ²­(type); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - REQUEST_VALID_ERROR_CODE.getMessage()); - } - } - - private void 곡톡_μƒν’ˆ_μΉ΄ν…Œκ³ λ¦¬_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, - final List includeCategoryIds, final List excludeCategoryIds) { - final var actual = response.jsonPath() - .getList("", CategoryResponse.class); - - assertThat(actual).extracting(CategoryResponse::getId) - .containsExactlyElementsOf(includeCategoryIds) - .doesNotContainAnyElementsOf(excludeCategoryIds); - } - - private void RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final String expectedCode, - final String expectedMessage) { - assertSoftly(soft -> { - soft.assertThat(response.jsonPath().getString("code")) - .isEqualTo(expectedCode); - soft.assertThat(response.jsonPath().getString("message")) - .isEqualTo(expectedMessage); - }); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/product/CategorySteps.java b/backend/src/test/java/com/funeat/acceptance/product/CategorySteps.java deleted file mode 100644 index 342beb2fc..000000000 --- a/backend/src/test/java/com/funeat/acceptance/product/CategorySteps.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.funeat.acceptance.product; - -import static io.restassured.RestAssured.given; - -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; - -@SuppressWarnings("NonAsciiCharacters") -public class CategorySteps { - - public static ExtractableResponse μΉ΄ν…Œκ³ λ¦¬_λͺ©λ‘_쑰회_μš”μ²­(final String type) { - return given() - .queryParam("type", type) - .when() - .get("/api/categories") - .then() - .extract(); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/product/ProductAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/product/ProductAcceptanceTest.java deleted file mode 100644 index 5a73e6554..000000000 --- a/backend/src/test/java/com/funeat/acceptance/product/ProductAcceptanceTest.java +++ /dev/null @@ -1,734 +0,0 @@ -package com.funeat.acceptance.product; - -import static com.funeat.acceptance.auth.LoginSteps.둜그인_μΏ ν‚€_νšλ“; -import static com.funeat.acceptance.common.CommonSteps.STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.사진_λͺ…μ„Έ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.정상_처리; -import static com.funeat.acceptance.common.CommonSteps.μ°Ύμ„μˆ˜_μ—†μŒ; -import static com.funeat.acceptance.common.CommonSteps.νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.product.ProductSteps.μƒν’ˆ_검색_κ²°κ³Ό_쑰회_μš”μ²­; -import static com.funeat.acceptance.product.ProductSteps.μƒν’ˆ_λž­ν‚Ή_쑰회_μš”μ²­; -import static com.funeat.acceptance.product.ProductSteps.μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­; -import static com.funeat.acceptance.product.ProductSteps.μƒν’ˆ_상세_쑰회_μš”μ²­; -import static com.funeat.acceptance.product.ProductSteps.μƒν’ˆ_μžλ™_μ™„μ„±_검색_μš”μ²­; -import static com.funeat.acceptance.product.ProductSteps.μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.리뷰_μž‘μ„±_μš”μ²­; -import static com.funeat.fixture.CategoryFixture.μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μΉ΄ν…Œκ³ λ¦¬; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.ImageFixture.이미지1; -import static com.funeat.fixture.ImageFixture.이미지2; -import static com.funeat.fixture.ImageFixture.이미지3; -import static com.funeat.fixture.ImageFixture.이미지4; -import static com.funeat.fixture.ImageFixture.이미지5; -import static com.funeat.fixture.ImageFixture.이미지6; -import static com.funeat.fixture.ImageFixture.이미지7; -import static com.funeat.fixture.MemberFixture.멀버1; -import static com.funeat.fixture.MemberFixture.멀버2; -import static com.funeat.fixture.MemberFixture.멀버3; -import static com.funeat.fixture.PageFixture.FIRST_PAGE; -import static com.funeat.fixture.PageFixture.PAGE_SIZE; -import static com.funeat.fixture.PageFixture.SECOND_PAGE; -import static com.funeat.fixture.PageFixture.가격_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.가격_μ˜€λ¦„μ°¨μˆœ; -import static com.funeat.fixture.PageFixture.과거순; -import static com.funeat.fixture.PageFixture.리뷰수_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O; -import static com.funeat.fixture.PageFixture.λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X; -import static com.funeat.fixture.PageFixture.응닡_νŽ˜μ΄μ§€_생성; -import static com.funeat.fixture.PageFixture.μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.μ²«νŽ˜μ΄μ§€O; -import static com.funeat.fixture.PageFixture.μ²«νŽ˜μ΄μ§€X; -import static com.funeat.fixture.PageFixture.총_데이터_개수; -import static com.funeat.fixture.PageFixture.총_νŽ˜μ΄μ§€; -import static com.funeat.fixture.PageFixture.μ΅œμ‹ μˆœ; -import static com.funeat.fixture.PageFixture.평균_평점_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.평균_평점_μ˜€λ¦„μ°¨μˆœ; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ1; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ10; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ11; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ2; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ3; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ4; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ5; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ6; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ7; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ8; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ9; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격3000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격3000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격4000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격5000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆ; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό1; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό2; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό3; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성; -import static com.funeat.fixture.RecipeFixture.μ’‹μ•„μš”O; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성; -import static com.funeat.fixture.ScoreFixture.점수_1점; -import static com.funeat.fixture.ScoreFixture.점수_2점; -import static com.funeat.fixture.ScoreFixture.점수_3점; -import static com.funeat.fixture.ScoreFixture.점수_4점; -import static com.funeat.fixture.ScoreFixture.점수_5점; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_단짠단짠_TASTE_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성; -import static com.funeat.product.exception.CategoryErrorCode.CATEGORY_NOT_FOUND; -import static com.funeat.product.exception.ProductErrorCode.PRODUCT_NOT_FOUND; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.acceptance.common.AcceptanceTest; -import com.funeat.product.domain.Category; -import com.funeat.product.dto.ProductInCategoryDto; -import com.funeat.product.dto.ProductResponse; -import com.funeat.product.dto.RankingProductDto; -import com.funeat.product.dto.SearchProductDto; -import com.funeat.product.dto.SearchProductResultDto; -import com.funeat.recipe.dto.RecipeDto; -import com.funeat.tag.dto.TagDto; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class ProductAcceptanceTest extends AcceptanceTest { - - @Nested - class getAllProductsInCategory_성곡_ν…ŒμŠ€νŠΈ { - - @Nested - class 가격_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회 { - - @Test - void μƒν’ˆ_가격이_μ„œλ‘œ_λ‹€λ₯΄λ©΄_가격_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격3000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ3 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격4000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(1L, 가격_λ‚΄λ¦Όμ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(μƒν’ˆ3, μƒν’ˆ1, μƒν’ˆ2)); - } - - @Test - void μƒν’ˆ_가격이_μ„œλ‘œ_κ°™μœΌλ©΄_ID_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var μΉ΄ν…Œκ³ λ¦¬_아이디 = 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ3 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(μΉ΄ν…Œκ³ λ¦¬_아이디, 가격_λ‚΄λ¦Όμ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(μƒν’ˆ3, μƒν’ˆ2, μƒν’ˆ1)); - } - } - - @Nested - class 가격_κΈ°μ€€_μ˜€λ¦„μ°¨μˆœμœΌλ‘œ_μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회 { - - @Test - void μƒν’ˆ_가격이_μ„œλ‘œ_λ‹€λ₯΄λ©΄_가격_κΈ°μ€€_μ˜€λ¦„μ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var μΉ΄ν…Œκ³ λ¦¬_아이디 = 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격4000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ3 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(μΉ΄ν…Œκ³ λ¦¬_아이디, 가격_μ˜€λ¦„μ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(μƒν’ˆ1, μƒν’ˆ3, μƒν’ˆ2)); - } - - @Test - void μƒν’ˆ_가격이_μ„œλ‘œ_κ°™μœΌλ©΄_ID_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(1L, 가격_μ˜€λ¦„μ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(3L, 2L, 1L)); - } - } - - @Nested - class 평점_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회 { - - @Test - void μƒν’ˆ_평점이_μ„œλ‘œ_λ‹€λ₯΄λ©΄_평점_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(1L, 평균_평점_λ‚΄λ¦Όμ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(2L, 1L, 3L)); - } - - @Test - void μƒν’ˆ_평점이_μ„œλ‘œ_κ°™μœΌλ©΄_ID_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(1L, 평균_평점_λ‚΄λ¦Όμ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(3L, 2L, 1L)); - } - } - - @Nested - class 평점_κΈ°μ€€_μ˜€λ¦„μ°¨μˆœμœΌλ‘œ_μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회 { - - @Test - void μƒν’ˆ_평점이_μ„œλ‘œ_λ‹€λ₯΄λ©΄_평점_κΈ°μ€€_μ˜€λ¦„μ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(1L, 평균_평점_μ˜€λ¦„μ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(1L, 3L, 2L)); - } - - @Test - void μƒν’ˆ_평점이_μ„œλ‘œ_κ°™μœΌλ©΄_ID_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(1L, 평균_평점_μ˜€λ¦„μ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(3L, 2L, 1L)); - } - } - - @Nested - class 리뷰수_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회 { - - @Test - void λ¦¬λ·°μˆ˜κ°€_μ„œλ‘œ_λ‹€λ₯΄λ©΄_리뷰수_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var μΉ΄ν…Œκ³ λ¦¬_아이디 = 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ3 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ1, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ2, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ2, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_2점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(μΉ΄ν…Œκ³ λ¦¬_아이디, 리뷰수_λ‚΄λ¦Όμ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(μƒν’ˆ2, μƒν’ˆ1, μƒν’ˆ3)); - } - - @Test - void λ¦¬λ·°μˆ˜κ°€_μ„œλ‘œ_κ°™μœΌλ©΄_ID_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var μΉ΄ν…Œκ³ λ¦¬_아이디 = 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격5000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ3 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격3000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(μΉ΄ν…Œκ³ λ¦¬_아이디, 리뷰수_λ‚΄λ¦Όμ°¨μˆœ, 0L); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X); - μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(μƒν’ˆ3, μƒν’ˆ2, μƒν’ˆ1)); - } - } - } - - @Nested - class getAllProductsInCategory_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μƒν’ˆμ„_μ •λ ¬ν• λ•Œ_μΉ΄ν…Œκ³ λ¦¬κ°€_μ‘΄μž¬ν•˜μ§€_μ•ŠμœΌλ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given & when - final var 응닡 = μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μΉ΄ν…Œκ³ λ¦¬, 가격_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - ERROR_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, CATEGORY_NOT_FOUND.getCode(), CATEGORY_NOT_FOUND.getMessage()); - } - } - - @Nested - class getProductDetail_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μƒν’ˆ_상세_정보λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ1 = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - final var νƒœκ·Έ2 = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_단짠단짠_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_4점, List.of(νƒœκ·Έ1, νƒœκ·Έ2))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_4점, List.of(νƒœκ·Έ2))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_1점, List.of(νƒœκ·Έ2))); - - // when - final var 응닡 = μƒν’ˆ_상세_쑰회_μš”μ²­(μƒν’ˆ); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - μƒν’ˆ_상세_정보_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡); - } - } - - @Nested - class getProductDetail_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆ_상세_정보λ₯Ό_μ‘°νšŒν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given & when - final var 응닡 = μƒν’ˆ_상세_쑰회_μš”μ²­(μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆ); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - ERROR_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, PRODUCT_NOT_FOUND.getCode(), PRODUCT_NOT_FOUND.getMessage()); - } - } - - @Nested - class getRankingProducts_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 전체_μƒν’ˆλ“€_μ€‘μ—μ„œ_λž­ν‚Ή_TOP3λ₯Ό_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ3 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ4 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ1, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ1, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ1, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ2, 사진_λͺ…μ„Έ_μš”μ²­(이미지4), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_5점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ2, 사진_λͺ…μ„Έ_μš”μ²­(이미지5), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_5점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ3, 사진_λͺ…μ„Έ_μš”μ²­(이미지6), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ3, 사진_λͺ…μ„Έ_μš”μ²­(이미지7), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_5점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μƒν’ˆ_λž­ν‚Ή_쑰회_μš”μ²­(); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - μƒν’ˆ_λž­ν‚Ή_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(μƒν’ˆ2, μƒν’ˆ3, μƒν’ˆ1)); - } - } - - @Nested - class searchProducts_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 검색어가_ν¬ν•¨λœ_μƒν’ˆλ“€μ„_κ²€μƒ‰ν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(2L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μƒν’ˆ_μžλ™_μ™„μ„±_검색_μš”μ²­("망고", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_μžλ™_μ™„μ„±_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(μƒν’ˆ2, μƒν’ˆ1)); - } - - @Test - void 검색어가_ν¬ν•¨λœ_μƒν’ˆμ΄_μ—†μœΌλ©΄_빈_리슀트λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 반볡_μ• ν”Œλ§κ³ _μƒν’ˆ_μ €μž₯(2, μΉ΄ν…Œκ³ λ¦¬); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(0L), 총_νŽ˜μ΄μ§€(0L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μƒν’ˆ_μžλ™_μ™„μ„±_검색_μš”μ²­("κΉ€λ°₯", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_μžλ™_μ™„μ„±_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, Collections.emptyList()); - } - - @Test - void νŽ˜μ΄μ§€κ°€_λ„˜μ–΄κ°€λ„_쀑볡없이_κ²°κ³Όλ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 반볡_μ• ν”Œλ§κ³ _μƒν’ˆ_μ €μž₯(10, μΉ΄ν…Œκ³ λ¦¬); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€1 = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(11L), 총_νŽ˜μ΄μ§€(2L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X, FIRST_PAGE, PAGE_SIZE); - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€2 = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(11L), 총_νŽ˜μ΄μ§€(2L), μ²«νŽ˜μ΄μ§€X, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, SECOND_PAGE, PAGE_SIZE); - - // when - final var 응닡1 = μƒν’ˆ_μžλ™_μ™„μ„±_검색_μš”μ²­("망고", FIRST_PAGE); - final var 응닡2 = μƒν’ˆ_μžλ™_μ™„μ„±_검색_μš”μ²­("망고", SECOND_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡1, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡1, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€1); - - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡2, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡2, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€2); - - 결과값이_이전_μš”μ²­_결과값에_μ€‘λ³΅λ˜λŠ”μ§€_검증(응닡1, 응닡2); - } - - @Test - void νŽ˜μ΄μ§€κ°€_λ„˜μ–΄κ°€λ„_μ‹œμž‘λ˜λŠ”_단어_μš°μ„ _μ‘°νšŒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 반볡_μ• ν”Œλ§κ³ _μƒν’ˆ_μ €μž₯(9, μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(11L), 총_νŽ˜μ΄μ§€(2L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μƒν’ˆ_μžλ™_μ™„μ„±_검색_μš”μ²­("망고", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_μžλ™_μ™„μ„±_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(μƒν’ˆ11, μƒν’ˆ1, μƒν’ˆ10, μƒν’ˆ9, μƒν’ˆ8, μƒν’ˆ7, μƒν’ˆ6, μƒν’ˆ5, μƒν’ˆ4, μƒν’ˆ3)); - } - } - - @Nested - class getSearchResults_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μƒν’ˆ_검색_결과듀을_μ‘°νšŒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(2L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var response = μƒν’ˆ_검색_κ²°κ³Ό_쑰회_μš”μ²­("망고", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(response, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(response, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(response, List.of(μƒν’ˆ2, μƒν’ˆ1)); - } - - @Test - void 검색_결과에_μƒν’ˆμ΄_μ—†μœΌλ©΄_빈_리슀트λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(0L), 총_νŽ˜μ΄μ§€(0L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μƒν’ˆ_검색_κ²°κ³Ό_쑰회_μš”μ²­("κΉ€λ°₯", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, Collections.emptyList()); - } - - @Test - void νŽ˜μ΄μ§€κ°€_λ„˜μ–΄κ°€λ„_쀑볡없이_μƒν’ˆ_κ²°κ³Όλ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 반볡_μ• ν”Œλ§κ³ _μƒν’ˆ_μ €μž₯(10, μΉ΄ν…Œκ³ λ¦¬); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€1 = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(11L), 총_νŽ˜μ΄μ§€(2L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X, FIRST_PAGE, PAGE_SIZE); - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€2 = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(11L), 총_νŽ˜μ΄μ§€(2L), μ²«νŽ˜μ΄μ§€X, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, SECOND_PAGE, PAGE_SIZE); - - // when - final var 응닡1 = μƒν’ˆ_검색_κ²°κ³Ό_쑰회_μš”μ²­("망고", FIRST_PAGE); - final var 응닡2 = μƒν’ˆ_검색_κ²°κ³Ό_쑰회_μš”μ²­("망고", SECOND_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡1, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡1, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€1); - - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡2, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡2, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€2); - - 결과값이_이전_μš”μ²­_결과값에_μ€‘λ³΅λ˜λŠ”μ§€_검증(응닡1, 응닡2); - } - - @Test - void νŽ˜μ΄μ§€κ°€_λ„˜μ–΄κ°€λ„_μ‹œμž‘λ˜λŠ”_단어_μš°μ„ _μ‘°νšŒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - 반볡_μ• ν”Œλ§κ³ _μƒν’ˆ_μ €μž₯(9, μΉ΄ν…Œκ³ λ¦¬); - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(11L), 총_νŽ˜μ΄μ§€(2L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X, FIRST_PAGE, PAGE_SIZE); - - // when - final var response = μƒν’ˆ_검색_κ²°κ³Ό_쑰회_μš”μ²­("망고", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(response, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(response, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(response, List.of(μƒν’ˆ11, μƒν’ˆ1, μƒν’ˆ10, μƒν’ˆ9, μƒν’ˆ8, μƒν’ˆ7, μƒν’ˆ6, μƒν’ˆ5, μƒν’ˆ4, μƒν’ˆ3)); - } - } - - @Nested - class getProductRecipes_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void ν•΄λ‹Ή_μƒν’ˆμ˜_κΏ€μ‘°ν•©_λͺ©λ‘μ„_μ’‹μ•„μš”κ°€_λ§Žμ€_순으둜_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1), λ ˆμ‹œν”Ό1, μ’‹μ•„μš”O); - μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(List.of(멀버2, 멀버3), λ ˆμ‹œν”Ό2, μ’‹μ•„μš”O); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(3L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var response = μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­(μƒν’ˆ, μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(response, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(response, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(response, List.of(λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό1, λ ˆμ‹œν”Ό3)); - } - - @Test - void ν•΄λ‹Ή_μƒν’ˆμ˜_κΏ€μ‘°ν•©_λͺ©λ‘μ„_μ΅œμ‹ μˆœμœΌλ‘œ_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(3L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var response = μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­(μƒν’ˆ, μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(response, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(response, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(response, List.of(λ ˆμ‹œν”Ό3, λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό1)); - } - - @Test - void ν•΄λ‹Ή_μƒν’ˆμ˜_κΏ€μ‘°ν•©_λͺ©λ‘μ„_였래된순으둜_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(3L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­(μƒν’ˆ, 과거순, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ ˆμ‹œν”Ό1, λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό3)); - } - } - - private void μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List productIds) { - final var actual = response.jsonPath() - .getList("products", ProductInCategoryDto.class); - - assertThat(actual).extracting(ProductInCategoryDto::getId) - .containsExactlyElementsOf(productIds); - } - - private void ERROR_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final String expectedCode, - final String expectedMessage) { - assertSoftly(soft -> { - soft.assertThat(response.jsonPath().getString("code")) - .isEqualTo(expectedCode); - soft.assertThat(response.jsonPath().getString("message")) - .isEqualTo(expectedMessage); - }); - } - - private void μƒν’ˆ_상세_정보_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response) { - final var actual = response.as(ProductResponse.class); - final var actualTags = response.jsonPath() - .getList("tags", TagDto.class); - - assertSoftly(soft -> { - soft.assertThat(actual.getId()).isEqualTo(1L); - soft.assertThat(actual.getName()).isEqualTo("삼각김λ°₯"); - soft.assertThat(actual.getPrice()).isEqualTo(1000L); - soft.assertThat(actual.getImage()).isEqualTo("image.png"); - soft.assertThat(actual.getContent()).isEqualTo("λ§›μžˆλŠ” 삼각김λ°₯"); - soft.assertThat(actual.getAverageRating()).isEqualTo(3.0); - soft.assertThat(actual.getReviewCount()).isEqualTo(3L); - soft.assertThat(actualTags).extracting("id").containsExactly(2L, 1L); - }); - } - - private void μƒν’ˆ_λž­ν‚Ή_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List productIds) { - final var actual = response.jsonPath() - .getList("products", RankingProductDto.class); - - assertThat(actual).extracting(RankingProductDto::getId) - .isEqualTo(productIds); - } - - private void μƒν’ˆ_μžλ™_μ™„μ„±_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List productIds) { - final var actual = response.jsonPath() - .getList("products", SearchProductDto.class); - - assertThat(actual).extracting(SearchProductDto::getId) - .isEqualTo(productIds); - } - - private void 결과값이_이전_μš”μ²­_결과값에_μ€‘λ³΅λ˜λŠ”μ§€_검증(final ExtractableResponse response1, - final ExtractableResponse response2) { - final var lastResponses = response1.jsonPath() - .getList("products", SearchProductResultDto.class); - final var currentResponse = response2.jsonPath() - .getList("products", SearchProductResultDto.class).get(0); - - assertThat(lastResponses).usingRecursiveFieldByFieldElementComparator() - .doesNotContain(currentResponse); - } - - private void μƒν’ˆ_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List productIds) { - final var actual = response.jsonPath() - .getList("products", SearchProductResultDto.class); - - assertThat(actual).extracting(SearchProductResultDto::getId) - .containsExactlyElementsOf(productIds); - } - - private void μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List recipeIds) { - final var actual = response.jsonPath().getList("recipes", RecipeDto.class); - - assertThat(actual).extracting(RecipeDto::getId) - .containsExactlyElementsOf(recipeIds); - } - - private void 반볡_μ• ν”Œλ§κ³ _μƒν’ˆ_μ €μž₯(final int repeat, final Category category) { - for (int i = 0; i < repeat; i++) { - 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(category)); - } - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/product/ProductSteps.java b/backend/src/test/java/com/funeat/acceptance/product/ProductSteps.java deleted file mode 100644 index d41bd5be1..000000000 --- a/backend/src/test/java/com/funeat/acceptance/product/ProductSteps.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.funeat.acceptance.product; - -import static io.restassured.RestAssured.given; - - -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; - -@SuppressWarnings("NonAsciiCharacters") -public class ProductSteps { - - public static ExtractableResponse μΉ΄ν…Œκ³ λ¦¬λ³„_μƒν’ˆ_λͺ©λ‘_쑰회_μš”μ²­(final Long categoryId, final String sort, - final Long lastProductId) { - return given() - .queryParam("sort", sort) - .queryParam("lastProductId", lastProductId) - .when() - .get("/api/categories/{category_id}/products", categoryId) - .then() - .extract(); - } - - public static ExtractableResponse μƒν’ˆ_상세_쑰회_μš”μ²­(final Long productId) { - return given() - .when() - .get("/api/products/{product_id}", productId) - .then() - .extract(); - } - - public static ExtractableResponse μƒν’ˆ_λž­ν‚Ή_쑰회_μš”μ²­() { - return given() - .when() - .get("/api/ranks/products") - .then() - .extract(); - } - - public static ExtractableResponse μƒν’ˆ_μžλ™_μ™„μ„±_검색_μš”μ²­(final String query, final Long page) { - return given() - .queryParam("query", query) - .queryParam("page", page) - .when() - .get("/api/search/products") - .then() - .extract(); - } - - public static ExtractableResponse μƒν’ˆ_검색_κ²°κ³Ό_쑰회_μš”μ²­(final String query, final Long page) { - return given() - .queryParam("query", query) - .queryParam("page", page) - .when() - .get("/api/search/products/results") - .then() - .extract(); - } - - public static ExtractableResponse μƒν’ˆ_λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­(final Long productId, final String sort, - final Long page) { - return given() - .queryParam("sort", sort) - .queryParam("page", page) - .when() - .get("/api/products/{productId}/recipes", productId) - .then() - .extract(); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java deleted file mode 100644 index bb388ea78..000000000 --- a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java +++ /dev/null @@ -1,806 +0,0 @@ -package com.funeat.acceptance.recipe; - -import static com.funeat.acceptance.auth.LoginSteps.둜그인_μΏ ν‚€_νšλ“; -import static com.funeat.acceptance.common.CommonSteps.STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.μΈμ¦λ˜μ§€_μ•ŠμŒ; -import static com.funeat.acceptance.common.CommonSteps.잘λͺ»λœ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.정상_생성; -import static com.funeat.acceptance.common.CommonSteps.정상_처리; -import static com.funeat.acceptance.common.CommonSteps.정상_처리_NO_CONTENT; -import static com.funeat.acceptance.common.CommonSteps.μ°Ύμ„μˆ˜_μ—†μŒ; -import static com.funeat.acceptance.common.CommonSteps.νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_검색_κ²°κ³Ό_쑰회_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_λŒ“κΈ€_쑰회_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_λž­ν‚Ή_쑰회_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_상세_정보_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­; -import static com.funeat.acceptance.recipe.RecipeSteps.μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­; -import static com.funeat.auth.exception.AuthErrorCode.LOGIN_MEMBER_NOT_FOUND; -import static com.funeat.exception.CommonErrorCode.REQUEST_VALID_ERROR_CODE; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.ImageFixture.이미지1; -import static com.funeat.fixture.ImageFixture.이미지2; -import static com.funeat.fixture.ImageFixture.이미지3; -import static com.funeat.fixture.ImageFixture.이미지4; -import static com.funeat.fixture.MemberFixture.멀버1; -import static com.funeat.fixture.MemberFixture.멀버2; -import static com.funeat.fixture.MemberFixture.멀버3; -import static com.funeat.fixture.PageFixture.FIRST_PAGE; -import static com.funeat.fixture.PageFixture.PAGE_SIZE; -import static com.funeat.fixture.PageFixture.과거순; -import static com.funeat.fixture.PageFixture.λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O; -import static com.funeat.fixture.PageFixture.응닡_νŽ˜μ΄μ§€_생성; -import static com.funeat.fixture.PageFixture.μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.μ²«νŽ˜μ΄μ§€O; -import static com.funeat.fixture.PageFixture.총_데이터_개수; -import static com.funeat.fixture.PageFixture.총_νŽ˜μ΄μ§€; -import static com.funeat.fixture.PageFixture.μ΅œμ‹ μˆœ; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격3000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό1; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό2; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό3; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό4; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_λ³Έλ¬Έ; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_제λͺ©; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성; -import static com.funeat.fixture.RecipeFixture.μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ ˆμ‹œν”Ό; -import static com.funeat.fixture.RecipeFixture.μ’‹μ•„μš”O; -import static com.funeat.fixture.RecipeFixture.μ’‹μ•„μš”X; -import static com.funeat.recipe.exception.RecipeErrorCode.RECIPE_NOT_FOUND; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.acceptance.common.AcceptanceTest; -import com.funeat.member.domain.Member; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.dto.ProductRecipeDto; -import com.funeat.recipe.dto.RankingRecipeDto; -import com.funeat.recipe.dto.RecipeAuthorDto; -import com.funeat.recipe.dto.RecipeCommentCondition; -import com.funeat.recipe.dto.RecipeCommentCreateRequest; -import com.funeat.recipe.dto.RecipeCommentResponse; -import com.funeat.recipe.dto.RecipeCreateRequest; -import com.funeat.recipe.dto.RecipeDetailResponse; -import com.funeat.recipe.dto.RecipeDto; -import com.funeat.recipe.dto.SearchRecipeResultDto; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullAndEmptySource; -import org.junit.jupiter.params.provider.NullSource; - -@SuppressWarnings("NonAsciiCharacters") -public class RecipeAcceptanceTest extends AcceptanceTest { - - @Nested - class writeRecipe_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ ˆμ‹œν”Όλ₯Ό_μž‘μ„±ν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_생성); - } - - @Test - void 이미지가_없어도_λ ˆμ‹œν”Όλ₯Ό_μž‘μ„±ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), null, λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_생성); - } - } - - @Nested - class writeRecipe_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_λ ˆμ‹œν”Ό_μž‘μ„±μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(cookie, μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - - @ParameterizedTest - @NullAndEmptySource - void μ‚¬μš©μžκ°€_λ ˆμ‹œν”Ό_μž‘μ„±ν• λ•Œ_λ ˆμ‹œν”Όμ΄λ¦„_λ―ΈκΈ°μž…μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String title) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - final var μš”μ²­ = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(title, List.of(μƒν’ˆ), λ ˆμ‹œν”Ό_λ³Έλ¬Έ); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "κΏ€μ‘°ν•© 이름을 확인해 μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @NullSource - @ParameterizedTest - void μ‚¬μš©μžκ°€_λ ˆμ‹œν”Ό_μž‘μ„±ν• λ•Œ_μƒν’ˆλ“€μ΄_NULLμΌμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final List productIds) { - // given - final var μš”μ²­ = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(λ ˆμ‹œν”Ό_제λͺ©, productIds, λ ˆμ‹œν”Ό_λ³Έλ¬Έ); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "μƒν’ˆ ID λͺ©λ‘μ„ 확인해 μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_λ ˆμ‹œν”Ό_μž‘μ„±ν• λ•Œ_μƒν’ˆλ“€μ΄_λΉ„μ–΄μžˆμ„μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μš”μ²­ = new RecipeCreateRequest(λ ˆμ‹œν”Ό_제λͺ©, Collections.emptyList(), λ ˆμ‹œν”Ό_λ³Έλ¬Έ); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "적어도 1개의 μƒν’ˆ IDκ°€ ν•„μš”ν•©λ‹ˆλ‹€. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @ParameterizedTest - @NullAndEmptySource - void μ‚¬μš©μžκ°€_λ ˆμ‹œν”Ό_μž‘μ„±ν• λ•Œ_λ‚΄μš©μ΄_λΉ„μ–΄μžˆμ„μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String content) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - final var μš”μ²­ = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(λ ˆμ‹œν”Ό_제λͺ©, List.of(μƒν’ˆ), content); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "κΏ€μ‘°ν•© λ‚΄μš©μ„ 확인해 μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_λ ˆμ‹œν”Ό_μž‘μ„±ν• λ•Œ_λ ˆμ‹œν”Όλ‚΄μš©μ΄_500자_μ΄ˆκ³Όμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - final var λ ˆμ‹œν”Όλ‚΄μš©_501자 = ".".repeat(500) + "a"; - final var μš”μ²­ = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성("title", List.of(μƒν’ˆ), λ ˆμ‹œν”Όλ‚΄μš©_501자); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "κΏ€μ‘°ν•© λ‚΄μš©μ€ μ΅œλŒ€ 500μžκΉŒμ§€ μž…λ ₯ κ°€λŠ₯ν•©λ‹ˆλ‹€. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - } - - @Nested - class getRecipeDetail_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ ˆμ‹œν”Όμ˜_상세_정보λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격3000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ1, μƒν’ˆ2)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_상세_정보_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), λ ˆμ‹œν”Ό); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ ˆμ‹œν”Ό_상세_정보_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡); - } - } - - @Nested - class getRecipeDetail_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_λ ˆμ‹œν”Ό_상세_μ‘°νšŒμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_상세_정보_μš”μ²­(cookie, λ ˆμ‹œν”Ό); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ ˆμ‹œν”Ό_μ‚¬μš©μžκ°€_λ ˆμ‹œν”Ό_상세_μ‘°νšŒμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given & when - final var 응닡 = λ ˆμ‹œν”Ό_상세_정보_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ ˆμ‹œν”Ό); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, RECIPE_NOT_FOUND.getCode(), RECIPE_NOT_FOUND.getMessage()); - } - } - - @Nested - class likeRecipe_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ ˆμ‹œν”Όμ—_μ’‹μ•„μš”λ₯Ό_ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), λ ˆμ‹œν”Ό, λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - } - - @Test - void λ ˆμ‹œν”Όμ—_μ’‹μ•„μš”λ₯Ό_μ·¨μ†Œν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), λ ˆμ‹œν”Ό, λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), λ ˆμ‹œν”Ό, λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”X)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - } - } - - @Nested - class likeRecipe_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_λ ˆμ‹œν”Όμ—_μ’‹μ•„μš”λ₯Ό_ν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(cookie, λ ˆμ‹œν”Ό, λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_λ ˆμ‹œν”Όμ—_μ’‹μ•„μš”λ₯Ό_ν• λ•Œ_μ’‹μ•„μš”_λ―ΈκΈ°μž…μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), λ ˆμ‹œν”Ό, λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(null)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "μ’‹μ•„μš”λ₯Ό ν™•μΈν•΄μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ ˆμ‹œν”Όμ—_μ‚¬μš©μžκ°€_μ’‹μ•„μš”λ₯Ό_ν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given & when - final var 응닡 = λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ ˆμ‹œν”Ό, λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, RECIPE_NOT_FOUND.getCode(), RECIPE_NOT_FOUND.getMessage()); - } - } - - @Nested - class getSearchResults_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 검색어에_ν•΄λ‹Ήν•˜λŠ”_μƒν’ˆμ΄_ν¬ν•¨λœ_λ ˆμ‹œν”Όκ°€_2개면_λ ˆμ‹œν”Ό_2개λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ1)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ1, μƒν’ˆ2)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ2)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(2L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_검색_κ²°κ³Ό_쑰회_μš”μ²­("망고", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - λ ˆμ‹œν”Ό_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό3)); - } - - @Test - void 검색어에_ν•΄λ‹Ήν•˜λŠ”_μƒν’ˆμ΄_2개고_μƒν’ˆμ΄_ν¬ν•¨λœ_λ ˆμ‹œν”Όκ°€_1개면_λ ˆμ‹œν”Ό_1개λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ1, μƒν’ˆ2)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(1L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_검색_κ²°κ³Ό_쑰회_μš”μ²­("망고", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - λ ˆμ‹œν”Ό_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ ˆμ‹œν”Ό)); - } - - @Test - void 검색_결과에_λ ˆμ‹œν”Όκ°€_μ—†μœΌλ©΄_빈_리슀트λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(0L), 총_νŽ˜μ΄μ§€(0L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_검색_κ²°κ³Ό_쑰회_μš”μ²­("참치", FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - λ ˆμ‹œν”Ό_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, Collections.emptyList()); - } - } - - @Nested - class getSortingRecipes_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 꿀쑰합을_μ’‹μ•„μš”κ°€_λ§Žμ€_순으둜_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1), λ ˆμ‹œν”Ό1, μ’‹μ•„μš”O); - μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1, 멀버2), λ ˆμ‹œν”Ό2, μ’‹μ•„μš”O); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(3L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­(μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - λ ˆμ‹œν”Ό_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό1, λ ˆμ‹œν”Ό3)); - } - - @Test - void 꿀쑰합을_μ΅œμ‹ μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(3L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­(μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - λ ˆμ‹œν”Ό_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ ˆμ‹œν”Ό3, λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό1)); - } - - @Test - void 꿀쑰합을_였래된순으둜_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€ = 응닡_νŽ˜μ΄μ§€_생성(총_데이터_개수(3L), 총_νŽ˜μ΄μ§€(1L), μ²«νŽ˜μ΄μ§€O, λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O, FIRST_PAGE, PAGE_SIZE); - - // when - final var response = λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­(과거순, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(response, 정상_처리); - νŽ˜μ΄μ§€λ₯Ό_κ²€μ¦ν•œλ‹€(response, μ˜ˆμƒ_응닡_νŽ˜μ΄μ§€); - λ ˆμ‹œν”Ό_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(response, List.of(λ ˆμ‹œν”Ό1, λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό3)); - } - } - - @Nested - class getRankingRecipes_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 전체_κΏ€μ‘°ν•©λ“€_μ€‘μ—μ„œ_λž­ν‚Ή_TOP3λ₯Ό_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지4), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1, 멀버2), λ ˆμ‹œν”Ό2, μ’‹μ•„μš”O); - μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1), λ ˆμ‹œν”Ό3, μ’‹μ•„μš”O); - μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1, 멀버2, 멀버3), λ ˆμ‹œν”Ό4, μ’‹μ•„μš”O); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_λž­ν‚Ή_쑰회_μš”μ²­(); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ ˆμ‹œν”Ό_λž­ν‚Ή_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ ˆμ‹œν”Ό4, λ ˆμ‹œν”Ό2, λ ˆμ‹œν”Ό3)); - } - } - - @Nested - class writeRecipeComment_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 꿀쑰합에_λŒ“κΈ€μ„_μž‘μ„±ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var κΏ€μ‘°ν•©_μž‘μ„±_응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // when - final var μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디 = μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디_μΆ”μΆœ(κΏ€μ‘°ν•©_μž‘μ„±_응닡); - final var λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“ = 둜그인_μΏ ν‚€_νšλ“(멀버2); - final var κΏ€μ‘°ν•©_λŒ“κΈ€ = new RecipeCommentCreateRequest("ν…ŒμŠ€νŠΈ μ½”λ©˜νŠΈ 1"); - - final var 응닡 = λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­(λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“, μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, κΏ€μ‘°ν•©_λŒ“κΈ€); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_생성); - κΏ€μ‘°ν•©_λŒ“κΈ€_μž‘μ„±_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 멀버2, κΏ€μ‘°ν•©_λŒ“κΈ€); - } - } - - @Nested - class writeRecipeComment_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 꿀쑰합에_λŒ“κΈ€μ„_μž‘μ„±ν• λ•Œ_λŒ“κΈ€μ΄_λΉ„μ–΄μžˆμ„μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String comment) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var κΏ€μ‘°ν•©_μž‘μ„±_응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // when - final var μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디 = μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디_μΆ”μΆœ(κΏ€μ‘°ν•©_μž‘μ„±_응닡); - final var λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“ = 둜그인_μΏ ν‚€_νšλ“(멀버2); - final var κΏ€μ‘°ν•©_λŒ“κΈ€ = new RecipeCommentCreateRequest(comment); - - final var λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­ = λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­(λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“, μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, κΏ€μ‘°ν•©_λŒ“κΈ€); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­, REQUEST_VALID_ERROR_CODE.getCode(), - "κΏ€μ‘°ν•© λŒ“κΈ€μ„ 확인해 μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void 꿀쑰합에_λŒ“κΈ€μ„_μž‘μ„±ν• λ•Œ_λŒ“κΈ€μ΄_200자_μ΄ˆκ³Όμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var κΏ€μ‘°ν•©_μž‘μ„±_응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // when - final var μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디 = μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디_μΆ”μΆœ(κΏ€μ‘°ν•©_μž‘μ„±_응닡); - final var λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“ = 둜그인_μΏ ν‚€_νšλ“(멀버2); - final var κΏ€μ‘°ν•©_λŒ“κΈ€ = new RecipeCommentCreateRequest("1" + "λŒ“κΈ€μž…λ‹ˆλ‹€".repeat(40)); - - final var 응닡 = λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­(λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“, μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, κΏ€μ‘°ν•©_λŒ“κΈ€); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "κΏ€μ‘°ν•© λŒ“κΈ€μ€ μ΅œλŒ€ 200μžκΉŒμ§€ μž…λ ₯ κ°€λŠ₯ν•©λ‹ˆλ‹€. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_κΏ€μ‘°ν•©_λŒ“κΈ€_μž‘μ„±μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var κΏ€μ‘°ν•©_μž‘μ„±_응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - // when - final var μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디 = μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디_μΆ”μΆœ(κΏ€μ‘°ν•©_μž‘μ„±_응닡); - final var κΏ€μ‘°ν•©_λŒ“κΈ€ = new RecipeCommentCreateRequest("ν…ŒμŠ€νŠΈ μ½”λ©˜νŠΈ 1"); - - final var 응닡 = λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­(cookie, μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, κΏ€μ‘°ν•©_λŒ“κΈ€); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - } - - @Nested - class getRecipeComment_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 꿀쑰합에_λŒ“κΈ€μ„_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var κΏ€μ‘°ν•©_μž‘μ„±_응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디 = μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디_μΆ”μΆœ(κΏ€μ‘°ν•©_μž‘μ„±_응닡); - final var λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“ = 둜그인_μΏ ν‚€_νšλ“(멀버2); - - for (int i = 1; i <= 15; i++) { - λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­(λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“, μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, - new RecipeCommentCreateRequest("ν…ŒμŠ€νŠΈ μ½”λ©˜νŠΈ" + i)); - } - - // when - final var 응닡 = λ ˆμ‹œν”Ό_λŒ“κΈ€_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, - new RecipeCommentCondition(null, null)); - - // then - final var expectedSize = 10; - final var expectedHasNext = true; - - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ ˆμ‹œν”Ό_λŒ“κΈ€_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, expectedSize, expectedHasNext); - } - - @Test - void 꿀쑰합에_λŒ“κΈ€μ„_λ§ˆμ§€λ§‰_νŽ˜μ΄μ§€λ₯Ό_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var κΏ€μ‘°ν•©_μž‘μ„±_응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디 = μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디_μΆ”μΆœ(κΏ€μ‘°ν•©_μž‘μ„±_응닡); - final var λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“ = 둜그인_μΏ ν‚€_νšλ“(멀버2); - - final var totalElements = 15L; - final var lastId = 6L; - - for (int i = 1; i <= totalElements; i++) { - λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­(λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“, μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, - new RecipeCommentCreateRequest("ν…ŒμŠ€νŠΈ μ½”λ©˜νŠΈ" + i)); - } - - // when - final var 응닡 = λ ˆμ‹œν”Ό_λŒ“κΈ€_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, new RecipeCommentCondition(lastId, totalElements)); - - // then - final var expectedSize = 5; - final var expectedHasNext = false; - - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ ˆμ‹œν”Ό_λŒ“κΈ€_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, expectedSize, expectedHasNext); - } - } - - @Nested - class getRecipeComment_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_κΏ€μ‘°ν•©_λŒ“κΈ€_μ‘°νšŒμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var κΏ€μ‘°ν•©_μž‘μ„±_응닡 = λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ—¬λŸ¬κ°œ_사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(μƒν’ˆ)); - - final var μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디 = μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디_μΆ”μΆœ(κΏ€μ‘°ν•©_μž‘μ„±_응닡); - final var λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“ = 둜그인_μΏ ν‚€_νšλ“(멀버2); - final var κΏ€μ‘°ν•©_λŒ“κΈ€ = new RecipeCommentCreateRequest("ν…ŒμŠ€νŠΈ μ½”λ©˜νŠΈ"); - - λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­(λŒ“κΈ€μž‘μ„±μž_둜그인_μΏ ν‚€_νšλ“, μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, κΏ€μ‘°ν•©_λŒ“κΈ€); - - // when - final var 응닡 = λ ˆμ‹œν”Ό_λŒ“κΈ€_쑰회_μš”μ²­(cookie, μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디, - new RecipeCommentCondition(6L, 15L)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - } - - private void λ ˆμ‹œν”Ό_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List recipeIds) { - final var actual = response.jsonPath().getList("recipes", RecipeDto.class); - - assertThat(actual).extracting(RecipeDto::getId) - .containsExactlyElementsOf(recipeIds); - } - - private void λ ˆμ‹œν”Ό_상세_정보_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response) { - final var actual = response.as(RecipeDetailResponse.class); - final var actualAuthor = response.jsonPath().getObject("author", RecipeAuthorDto.class); - final var actualProducts = response.jsonPath().getList("products", ProductRecipeDto.class); - - assertSoftly(soft -> { - soft.assertThat(actual.getId()).isEqualTo(1L); - soft.assertThat(actual.getImages()).hasSize(0); - soft.assertThat(actual.getTitle()).isEqualTo("The most delicious recipes"); - soft.assertThat(actual.getContent()).isEqualTo("More rice, more rice, more rice.. Done!!"); - soft.assertThat(actual.getTotalPrice()).isEqualTo(4000L); - soft.assertThat(actual.getFavoriteCount()).isEqualTo(0L); - soft.assertThat(actual.getFavorite()).isEqualTo(false); - soft.assertThat(actualAuthor.getNickname()).isEqualTo("member1"); - soft.assertThat(actualAuthor.getProfileImage()).isEqualTo("www.member1.com"); - soft.assertThat(actualProducts).extracting(ProductRecipeDto::getId) - .containsExactlyElementsOf(List.of(1L, 2L)); - }); - } - - private void RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final String expectedCode, - final String expectedMessage) { - assertSoftly(soft -> { - soft.assertThat(response.jsonPath().getString("code")) - .isEqualTo(expectedCode); - soft.assertThat(response.jsonPath().getString("message")) - .isEqualTo(expectedMessage); - }); - } - - private List μ˜ˆμƒ_λ ˆμ‹œν”Ό_λž­ν‚Ή_λ³€ν™˜(final List recipes, final Member member) { - return recipes.stream() - .map(it -> RankingRecipeDto.toDto(it, Collections.emptyList(), RecipeAuthorDto.toDto(member))) - .collect(Collectors.toList()); - } - - private void λ ˆμ‹œν”Ό_λž­ν‚Ή_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List recipeIds) { - final var actual = response.jsonPath() - .getList("recipes", RankingRecipeDto.class); - - assertThat(actual).extracting(RankingRecipeDto::getId) - .isEqualTo(recipeIds); - } - - private void λ ˆμ‹œν”Ό_검색_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List recipeIds) { - final var actual = response.jsonPath() - .getList("recipes", SearchRecipeResultDto.class); - - assertThat(actual).extracting(SearchRecipeResultDto::getId) - .containsExactlyElementsOf(recipeIds); - } - - private Long μž‘μ„±λœ_κΏ€μ‘°ν•©_아이디_μΆ”μΆœ(final ExtractableResponse response) { - return Long.parseLong(response.header("Location").split("/")[3]); - } - - private void κΏ€μ‘°ν•©_λŒ“κΈ€_μž‘μ„±_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final Long memberId, - final RecipeCommentCreateRequest request) { - final var savedCommentId = Long.parseLong(response.header("Location").split("/")[4]); - - final var findComments = commentRepository.findAll(); - - assertSoftly(soft -> { - soft.assertThat(savedCommentId).isEqualTo(findComments.get(0).getId()); - soft.assertThat(memberId).isEqualTo(findComments.get(0).getMember().getId()); - soft.assertThat(request.getComment()).isEqualTo(findComments.get(0).getComment()); - }); - } - - private void λ ˆμ‹œν”Ό_λŒ“κΈ€_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final int expectedSize, - final boolean expectedHasNext) { - final var actualComments = response.jsonPath().getList("comments", RecipeCommentResponse.class); - final var actualHasNext = response.jsonPath().getBoolean("hasNext"); - - assertThat(actualComments).hasSize(expectedSize); - assertThat(actualHasNext).isEqualTo(expectedHasNext); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java deleted file mode 100644 index 8d68fe7e9..000000000 --- a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.funeat.acceptance.recipe; - -import static com.funeat.acceptance.auth.LoginSteps.둜그인_μΏ ν‚€_νšλ“; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성; -import static io.restassured.RestAssured.given; - -import com.funeat.recipe.dto.RecipeCommentCondition; -import com.funeat.recipe.dto.RecipeCommentCreateRequest; -import com.funeat.recipe.dto.RecipeCreateRequest; -import com.funeat.recipe.dto.RecipeFavoriteRequest; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import io.restassured.specification.MultiPartSpecification; -import java.util.List; -import java.util.Objects; - -@SuppressWarnings("NonAsciiCharacters") -public class RecipeSteps { - - public static ExtractableResponse λ ˆμ‹œν”Ό_μž‘μ„±_μš”μ²­(final String loginCookie, - final List images, - final RecipeCreateRequest recipeRequest) { - final var requestSpec = given() - .cookie("SESSION", loginCookie); - - if (Objects.nonNull(images) && !images.isEmpty()) { - images.forEach(requestSpec::multiPart); - } - - return requestSpec - .multiPart("recipeRequest", recipeRequest, "application/json") - .when() - .post("/api/recipes") - .then() - .extract(); - } - - public static ExtractableResponse λ ˆμ‹œν”Ό_상세_정보_μš”μ²­(final String loginCookie, final Long recipeId) { - return given() - .cookie("SESSION", loginCookie) - .when() - .get("/api/recipes/{recipeId}", recipeId) - .then() - .extract(); - } - - public static ExtractableResponse λ ˆμ‹œν”Ό_λͺ©λ‘_μš”μ²­(final String sort, final Long page) { - return given() - .queryParam("sort", sort) - .queryParam("page", page) - .when() - .get("/api/recipes") - .then() - .extract(); - } - - public static ExtractableResponse λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(final String loginCookie, final Long recipeId, - final RecipeFavoriteRequest request) { - return given() - .cookie("SESSION", loginCookie) - .contentType("application/json") - .body(request) - .when() - .patch("/api/recipes/{recipeId}", recipeId) - .then() - .extract(); - } - - public static void μ—¬λŸ¬λͺ…이_λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(final List memberIds, final Long recipeId, - final Boolean favorite) { - final var request = λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(favorite); - - for (final var memberId : memberIds) { - λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(memberId), recipeId, request); - } - } - - public static ExtractableResponse λ ˆμ‹œν”Ό_λž­ν‚Ή_쑰회_μš”μ²­() { - return given() - .when() - .get("/api/ranks/recipes") - .then() - .extract(); - } - - public static ExtractableResponse λ ˆμ‹œν”Ό_검색_κ²°κ³Ό_쑰회_μš”μ²­(final String query, final Long page) { - return given() - .queryParam("query", query) - .queryParam("page", page) - .when() - .get("/api/search/recipes/results") - .then() - .extract(); - } - - public static ExtractableResponse λ ˆμ‹œν”Ό_λŒ“κΈ€_μž‘μ„±_μš”μ²­(final String loginCookie, - final Long recipeId, - final RecipeCommentCreateRequest request) { - return given() - .cookie("SESSION", loginCookie) - .contentType("application/json") - .body(request) - .when() - .post("/api/recipes/" + recipeId + "/comments") - .then() - .extract(); - } - - public static ExtractableResponse λ ˆμ‹œν”Ό_λŒ“κΈ€_쑰회_μš”μ²­(final String loginCookie, final Long recipeId, - final RecipeCommentCondition condition) { - return given() - .cookie("SESSION", loginCookie) - .contentType("application/json") - .param("lastId", condition.getLastId()) - .param("totalElements", condition.getTotalElements()) - .when() - .get("/api/recipes/" + recipeId + "/comments") - .then() - .extract(); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/review/ReviewAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/review/ReviewAcceptanceTest.java deleted file mode 100644 index 233cc4ca5..000000000 --- a/backend/src/test/java/com/funeat/acceptance/review/ReviewAcceptanceTest.java +++ /dev/null @@ -1,752 +0,0 @@ -package com.funeat.acceptance.review; - -import static com.funeat.acceptance.auth.LoginSteps.둜그인_μΏ ν‚€_νšλ“; -import static com.funeat.acceptance.common.CommonSteps.STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.사진_λͺ…μ„Έ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.μΈμ¦λ˜μ§€_μ•ŠμŒ; -import static com.funeat.acceptance.common.CommonSteps.잘λͺ»λœ_μš”μ²­; -import static com.funeat.acceptance.common.CommonSteps.정상_생성; -import static com.funeat.acceptance.common.CommonSteps.정상_처리; -import static com.funeat.acceptance.common.CommonSteps.정상_처리_NO_CONTENT; -import static com.funeat.acceptance.common.CommonSteps.μ°Ύμ„μˆ˜_μ—†μŒ; -import static com.funeat.acceptance.product.ProductSteps.μƒν’ˆ_상세_쑰회_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.리뷰_λž­ν‚Ή_쑰회_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.리뷰_상세_쑰회_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.리뷰_μž‘μ„±_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.리뷰_μ’‹μ•„μš”_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.μ—¬λŸ¬λͺ…이_리뷰_μ’‹μ•„μš”_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­; -import static com.funeat.acceptance.review.ReviewSteps.μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_쑰회_μš”μ²­; -import static com.funeat.auth.exception.AuthErrorCode.LOGIN_MEMBER_NOT_FOUND; -import static com.funeat.exception.CommonErrorCode.REQUEST_VALID_ERROR_CODE; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.ImageFixture.이미지1; -import static com.funeat.fixture.ImageFixture.이미지2; -import static com.funeat.fixture.ImageFixture.이미지3; -import static com.funeat.fixture.ImageFixture.이미지4; -import static com.funeat.fixture.ImageFixture.이미지5; -import static com.funeat.fixture.MemberFixture.멀버1; -import static com.funeat.fixture.MemberFixture.멀버2; -import static com.funeat.fixture.MemberFixture.멀버3; -import static com.funeat.fixture.PageFixture.FIRST_PAGE; -import static com.funeat.fixture.PageFixture.μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.μ΅œμ‹ μˆœ; -import static com.funeat.fixture.PageFixture.평점_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.평점_μ˜€λ¦„μ°¨μˆœ; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ1; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆ; -import static com.funeat.fixture.ReviewFixture.λ‹€μŒ_데이터_쑴재X; -import static com.funeat.fixture.ReviewFixture.리뷰; -import static com.funeat.fixture.ReviewFixture.리뷰1; -import static com.funeat.fixture.ReviewFixture.리뷰2; -import static com.funeat.fixture.ReviewFixture.리뷰3; -import static com.funeat.fixture.ReviewFixture.리뷰4; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μΆ”κ°€μš”μ²­_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.재ꡬ맀O; -import static com.funeat.fixture.ReviewFixture.μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰; -import static com.funeat.fixture.ReviewFixture.μ’‹μ•„μš”O; -import static com.funeat.fixture.ReviewFixture.μ’‹μ•„μš”X; -import static com.funeat.fixture.ReviewFixture.첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄; -import static com.funeat.fixture.ScoreFixture.점수_1점; -import static com.funeat.fixture.ScoreFixture.점수_2점; -import static com.funeat.fixture.ScoreFixture.점수_3점; -import static com.funeat.fixture.ScoreFixture.점수_4점; -import static com.funeat.fixture.ScoreFixture.점수_5점; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성; -import static com.funeat.product.exception.ProductErrorCode.PRODUCT_NOT_FOUND; -import static com.funeat.review.exception.ReviewErrorCode.REVIEW_NOT_FOUND; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.acceptance.common.AcceptanceTest; -import com.funeat.review.dto.RankingReviewDto; -import com.funeat.review.dto.ReviewCreateRequest; -import com.funeat.review.dto.ReviewDetailResponse; -import com.funeat.review.dto.SortingReviewDto; -import com.funeat.tag.dto.TagDto; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullAndEmptySource; - -@SuppressWarnings("NonAsciiCharacters") -class ReviewAcceptanceTest extends AcceptanceTest { - - @Nested - class writeReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 이미지λ₯Ό_ν¬ν•¨ν•˜μ—¬_리뷰λ₯Ό_μž‘μ„±ν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), - λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_1점, List.of(νƒœκ·Έ))); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_생성); - } - - @Test - void 이미지가_없어도_리뷰λ₯Ό_μž‘μ„±ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, null, - λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_1점, List.of(νƒœκ·Έ))); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_생성); - } - } - - @Nested - class writeReview_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_리뷰_μž‘μ„±μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(cookie, μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), - λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_리뷰_μž‘μ„±ν• λ•Œ_νƒœκ·Έλ“€μ΄_NULLμΌμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), - λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, null)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "νƒœκ·Έ ID λͺ©λ‘μ„ 확인해 μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_리뷰_μž‘μ„±ν• λ•Œ_νƒœκ·Έλ“€μ΄_λΉ„μ–΄μžˆμ„μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), - λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, Collections.emptyList())); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "적어도 1개의 νƒœκ·Έ IDκ°€ ν•„μš”ν•©λ‹ˆλ‹€. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_리뷰_μž‘μ„±ν• λ•Œ_평점이_λΉ„μ–΄μžˆμ„μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), - λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(null, List.of(νƒœκ·Έ))); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "평점을 확인해 μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @ParameterizedTest - @NullAndEmptySource - void μ‚¬μš©μžκ°€_리뷰_μž‘μ„±ν• λ•Œ_λ¦¬λ·°λ‚΄μš©μ΄_λΉ„μ–΄μžˆμ„μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String content) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - final var μš”μ²­ = λ¦¬λ·°μΆ”κ°€μš”μ²­_생성(점수_1점, List.of(νƒœκ·Έ), content, 재ꡬ맀O); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "리뷰 λ‚΄μš©μ„ 확인해 μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_리뷰_μž‘μ„±ν• λ•Œ_μž¬κ΅¬λ§€μ—¬λΆ€κ°€_λΉ„μ–΄μžˆμ„μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - final var μš”μ²­ = λ¦¬λ·°μΆ”κ°€μš”μ²­_생성(점수_1점, List.of(νƒœκ·Έ), "content", null); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "재ꡬ맀 μ—¬λΆ€λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_리뷰_μž‘μ„±ν• λ•Œ_λ¦¬λ·°λ‚΄μš©μ΄_200자_μ΄ˆκ³Όμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - final var λ¦¬λ·°λ‚΄μš©_201자 = "test".repeat(50) + "a"; - final var μš”μ²­ = new ReviewCreateRequest(점수_1점, List.of(νƒœκ·Έ), λ¦¬λ·°λ‚΄μš©_201자, 재ꡬ맀O); - - // when - final var 응닡 = 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "리뷰 λ‚΄μš©μ€ μ΅œλŒ€ 200μžκΉŒμ§€ μž…λ ₯ κ°€λŠ₯ν•©λ‹ˆλ‹€. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - } - - @Nested - class toggleLikeReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰에_μ’‹μ•„μš”λ₯Ό_ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = 리뷰_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 리뷰, λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - } - - @Test - void 리뷰에_μ’‹μ•„μš”λ₯Ό_μ·¨μ†Œν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 리뷰, λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // when - final var 응닡 = 리뷰_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 리뷰, λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”X)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - } - - @Test - void μƒν’ˆ_이미지가_μ‘΄μž¬ν•˜λŠ”_μ’‹μ•„μš”λ₯Ό_κ°€μž₯_많이_받은_리뷰둜_μƒν’ˆ_이미지가_바뀐닀() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_1점, List.of(νƒœκ·Έ))); - - 리뷰_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 리뷰2, λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // when - final var 응닡 = μƒν’ˆ_상세_쑰회_μš”μ²­(μƒν’ˆ); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - μƒν’ˆ_사진을_κ²€μ¦ν•œλ‹€(응닡, "2.png"); - } - } - - @Nested - class toggleLikeReview_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_리뷰에_μ’‹μ•„μš”λ₯Ό_ν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = 리뷰_μ’‹μ•„μš”_μš”μ²­(cookie, μƒν’ˆ, 리뷰, λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - - @Test - void μ‚¬μš©μžκ°€_리뷰에_μ’‹μ•„μš”λ₯Ό_ν• λ•Œ_μ’‹μ•„μš”_λ―ΈκΈ°μž…μ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = 리뷰_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 리뷰, λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(null)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 잘λͺ»λœ_μš”μ²­); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REQUEST_VALID_ERROR_CODE.getCode(), - "μ’‹μ•„μš”λ₯Ό ν™•μΈν•΄μ£Όμ„Έμš”. " + REQUEST_VALID_ERROR_CODE.getMessage()); - } - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰에_μ‚¬μš©μžκ°€_μ’‹μ•„μš”λ₯Ό_ν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = 리뷰_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰, λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(μ’‹μ•„μš”O)); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REVIEW_NOT_FOUND.getCode(), REVIEW_NOT_FOUND.getMessage()); - } - } - - @Nested - class getSortingReviews_성곡_ν…ŒμŠ€νŠΈ { - - @Nested - class μ’‹μ•„μš”_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_리뷰_λͺ©λ‘_쑰회 { - - @Test - void μ’‹μ•„μš”_μˆ˜κ°€_μ„œλ‘œ_λ‹€λ₯΄λ©΄_μ’‹μ•„μš”_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - μ—¬λŸ¬λͺ…이_리뷰_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1), μƒν’ˆ, 리뷰3, μ’‹μ•„μš”O); - μ—¬λŸ¬λͺ…이_리뷰_μ’‹μ•„μš”_μš”μ²­(List.of(멀버2, 멀버3), μƒν’ˆ, 리뷰2, μ’‹μ•„μš”O); - - // when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ‹€μŒ_데이터_쑴재X); - μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(리뷰2, 리뷰3, 리뷰1)); - } - - @Test - void μ’‹μ•„μš”_μˆ˜κ°€_μ„œλ‘œ_κ°™μœΌλ©΄_ID_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ‹€μŒ_데이터_쑴재X); - μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(리뷰3, 리뷰2, 리뷰1)); - } - } - - @Nested - class 평점_κΈ°μ€€_μ˜€λ¦„μ°¨μˆœμœΌλ‘œ_리뷰_λͺ©λ‘μ„_쑰회 { - - @Test - void 평점이_μ„œλ‘œ_λ‹€λ₯΄λ©΄_평점_κΈ°μ€€_μ˜€λ¦„μ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_2점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, 평점_μ˜€λ¦„μ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ‹€μŒ_데이터_쑴재X); - μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(리뷰1, 리뷰3, 리뷰2)); - } - - @Test - void 평점이_μ„œλ‘œ_κ°™μœΌλ©΄_ID_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, 평점_μ˜€λ¦„μ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ‹€μŒ_데이터_쑴재X); - μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(리뷰3, 리뷰2, 리뷰1)); - } - } - - @Nested - class 평점_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_리뷰_λͺ©λ‘_쑰회 { - - @Test - void 평점이_μ„œλ‘œ_λ‹€λ₯΄λ©΄_평점_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_2점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, 평점_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ‹€μŒ_데이터_쑴재X); - μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(리뷰2, 리뷰3, 리뷰1)); - } - - @Test - void 평점이_μ„œλ‘œ_κ°™μœΌλ©΄_ID_κΈ°μ€€_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, 평점_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ‹€μŒ_데이터_쑴재X); - μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(리뷰3, 리뷰2, 리뷰1)); - } - } - - @Nested - class μ΅œμ‹ μˆœμœΌλ‘œ_리뷰_λͺ©λ‘μ„_쑰회 { - - @Test - void 등둝_μ‹œκ°„μ΄_μ„œλ‘œ_λ‹€λ₯΄λ©΄_μ΅œμ‹ μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_2점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(점수_3점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, μ΅œμ‹ μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - λ‹€μŒ_데이터가_μžˆλŠ”μ§€_κ²€μ¦ν•œλ‹€(응닡, λ‹€μŒ_데이터_쑴재X); - μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(리뷰3, 리뷰2, 리뷰1)); - } - } - } - - @Nested - class getSortingReviews_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @ParameterizedTest - @NullAndEmptySource - void 둜그인_ν•˜μ§€μ•Šμ€_μ‚¬μš©μžκ°€_리뷰_λͺ©λ‘μ„_μ‘°νšŒμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€(final String cookie) { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_2점, List.of(νƒœκ·Έ))); - - // when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(cookie, μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μΈμ¦λ˜μ§€_μ•ŠμŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, LOGIN_MEMBER_NOT_FOUND.getCode(), - LOGIN_MEMBER_NOT_FOUND.getMessage()); - } - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆμ˜_리뷰_λͺ©λ‘μ„_μ‘°νšŒμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given && when - final var 응닡 = μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆ, 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄, μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ, FIRST_PAGE); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, PRODUCT_NOT_FOUND.getCode(), PRODUCT_NOT_FOUND.getMessage()); - } - } - - @Nested - class getRankingReviews_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰_λž­ν‚Ήμ„_μ‘°νšŒν•˜λ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ1 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var μƒν’ˆ2 = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ1, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ1, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버3), μƒν’ˆ1, 사진_λͺ…μ„Έ_μš”μ²­(이미지3), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ2, 사진_λͺ…μ„Έ_μš”μ²­(이미지4), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_5점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ2, 사진_λͺ…μ„Έ_μš”μ²­(이미지5), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_1점, List.of(νƒœκ·Έ))); - μ—¬λŸ¬λͺ…이_리뷰_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1, 멀버2, 멀버3), μƒν’ˆ1, 리뷰2, μ’‹μ•„μš”O); - μ—¬λŸ¬λͺ…이_리뷰_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1, 멀버2), μƒν’ˆ1, 리뷰3, μ’‹μ•„μš”O); - μ—¬λŸ¬λͺ…이_리뷰_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1), μƒν’ˆ1, 리뷰4, μ’‹μ•„μš”O); - - // when - final var 응닡 = 리뷰_λž­ν‚Ή_쑰회_μš”μ²­(); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - 리뷰_λž­ν‚Ή_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(리뷰2, 리뷰3, 리뷰4)); - } - } - - @Nested - class getMostFavoriteReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void νŠΉμ •_μƒν’ˆμ—μ„œ_μ’‹μ•„μš”λ₯Ό_κ°€μž₯_많이_받은_리뷰λ₯Ό_μ‘°νšŒν•˜λ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ))); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버2), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지2), λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_4점, List.of(νƒœκ·Έ))); - μ—¬λŸ¬λͺ…이_리뷰_μ’‹μ•„μš”_μš”μ²­(List.of(멀버1, 멀버2, 멀버3), μƒν’ˆ1, 리뷰2, μ’‹μ•„μš”O); - - // when - final var 응닡 = μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_쑰회_μš”μ²­(μƒν’ˆ); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 리뷰2); - } - - @Test - void νŠΉμ •_μƒν’ˆμ—μ„œ_리뷰가_μ—†λ‹€λ©΄_빈_응닡을_λ°˜ν™˜ν•˜λ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - - // when - final var 응닡 = μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_쑰회_μš”μ²­(μƒν’ˆ); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리_NO_CONTENT); - μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_κ²°κ³Όκ°€_빈_응닡인지_κ²€μ¦ν•œλ‹€(응닡); - } - } - - @Nested - class getMostFavoriteReview_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆμ˜_μ’‹μ•„μš”λ₯Ό_κ°€μž₯_많이_받은_리뷰_μ‘°νšŒμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given & when - final var 응닡 = μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_쑰회_μš”μ²­(μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆ); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, PRODUCT_NOT_FOUND.getCode(), PRODUCT_NOT_FOUND.getMessage()); - } - } - - @Nested - class getReviewDetail_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰_상세_정보λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var μΉ΄ν…Œκ³ λ¦¬ = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(μΉ΄ν…Œκ³ λ¦¬); - final var μƒν’ˆ = 단일_μƒν’ˆ_μ €μž₯(μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(μΉ΄ν…Œκ³ λ¦¬)); - final var νƒœκ·Έ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - - final var μš”μ²­ = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(점수_3점, List.of(νƒœκ·Έ)); - 리뷰_μž‘μ„±_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(멀버1), μƒν’ˆ, 사진_λͺ…μ„Έ_μš”μ²­(이미지1), μš”μ²­); - - // when - final var 응닡 = 리뷰_상세_쑰회_μš”μ²­(리뷰); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - 리뷰_상세_정보_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μš”μ²­); - } - } - - @Nested - class getReviewDetail_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰_μ‘°νšŒμ‹œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given & when - final var 응닡 = 리뷰_상세_쑰회_μš”μ²­(μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, μ°Ύμ„μˆ˜_μ—†μŒ); - RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, REVIEW_NOT_FOUND.getCode(), REVIEW_NOT_FOUND.getMessage()); - } - } - - private void RESPONSE_CODE와_MESSAGEλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final String expectedCode, - final String expectedMessage) { - assertSoftly(soft -> { - soft.assertThat(response.jsonPath().getString("code")) - .isEqualTo(expectedCode); - soft.assertThat(response.jsonPath().getString("message")) - .isEqualTo(expectedMessage); - }); - } - - private void μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List reviewIds) { - final var actual = response.jsonPath().getList("reviews", SortingReviewDto.class); - - assertThat(actual).extracting(SortingReviewDto::getId) - .containsExactlyElementsOf(reviewIds); - } - - private void 리뷰_λž­ν‚Ή_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List reviewIds) { - final var actual = response.jsonPath() - .getList("reviews", RankingReviewDto.class); - - assertThat(actual).extracting(RankingReviewDto::getReviewId) - .containsExactlyElementsOf(reviewIds); - } - - private void μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final Long reviewId) { - final var actual = response.jsonPath() - .getLong("id"); - - assertThat(actual).isEqualTo(reviewId); - } - - private void μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_κ²°κ³Όκ°€_빈_응닡인지_κ²€μ¦ν•œλ‹€(final ExtractableResponse response) { - final var actual = response.body() - .asString(); - - assertThat(actual).isEmpty(); - } - - private void μƒν’ˆ_사진을_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final String expected) { - final var actual = response.jsonPath() - .getString("image"); - - assertThat(actual).isEqualTo(expected); - } - - private void 리뷰_상세_정보_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final ReviewCreateRequest request) { - final var actual = response.as(ReviewDetailResponse.class); - final var actualTags = response.jsonPath().getList("tags", TagDto.class); - - assertSoftly(soft -> { - soft.assertThat(actual.getId()).isEqualTo(리뷰); - soft.assertThat(actual.getImage()).isEqualTo("1.png"); - soft.assertThat(actual.getRating()).isEqualTo(request.getRating()); - soft.assertThat(actual.getContent()).isEqualTo(request.getContent()); - soft.assertThat(actual.isRebuy()).isEqualTo(request.getRebuy()); - soft.assertThat(actual.getFavoriteCount()).isEqualTo(0L); - soft.assertThat(actualTags).extracting(TagDto::getId) - .containsExactlyElementsOf(request.getTagIds()); - }); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/review/ReviewSteps.java b/backend/src/test/java/com/funeat/acceptance/review/ReviewSteps.java deleted file mode 100644 index d1b556d7d..000000000 --- a/backend/src/test/java/com/funeat/acceptance/review/ReviewSteps.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.funeat.acceptance.review; - -import static com.funeat.acceptance.auth.LoginSteps.둜그인_μΏ ν‚€_νšλ“; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성; -import static io.restassured.RestAssured.given; - -import com.funeat.review.dto.ReviewCreateRequest; -import com.funeat.review.dto.ReviewFavoriteRequest; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import io.restassured.specification.MultiPartSpecification; -import java.util.List; -import java.util.Objects; - -@SuppressWarnings("NonAsciiCharacters") -public class ReviewSteps { - - public static ExtractableResponse 리뷰_μž‘μ„±_μš”μ²­(final String loginCookie, final Long productId, - final MultiPartSpecification image, - final ReviewCreateRequest request) { - final var requestSpec = given() - .cookie("SESSION", loginCookie); - - if (Objects.nonNull(image)) { - requestSpec.multiPart(image); - } - - return requestSpec - .multiPart("reviewRequest", request, "application/json") - .when() - .post("/api/products/{productId}/reviews", productId) - .then() - .extract(); - } - - public static ExtractableResponse 리뷰_μ’‹μ•„μš”_μš”μ²­(final String loginCookie, final Long productId, - final Long reviewId, final ReviewFavoriteRequest request) { - return given() - .cookie("SESSION", loginCookie) - .contentType("application/json") - .body(request) - .when() - .patch("/api/products/{productId}/reviews/{reviewId}", productId, reviewId) - .then() - .extract(); - } - - public static void μ—¬λŸ¬λͺ…이_리뷰_μ’‹μ•„μš”_μš”μ²­(final List memberIds, final Long productId, final Long reviewId, - final Boolean favorite) { - final var request = λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(favorite); - - for (final var memberId : memberIds) { - 리뷰_μ’‹μ•„μš”_μš”μ²­(둜그인_μΏ ν‚€_νšλ“(memberId), productId, reviewId, request); - } - } - - public static ExtractableResponse μ •λ ¬λœ_리뷰_λͺ©λ‘_쑰회_μš”μ²­(final String loginCookie, final Long productId, - final Long lastReviewId, - final String sort, final Long page) { - return given() - .cookie("SESSION", loginCookie) - .queryParam("sort", sort) - .queryParam("page", page) - .queryParam("lastReviewId", lastReviewId).log().all() - .when() - .get("/api/products/{product_id}/reviews", productId) - .then().log().all() - .extract(); - } - - public static ExtractableResponse 리뷰_λž­ν‚Ή_쑰회_μš”μ²­() { - return given() - .when() - .get("/api/ranks/reviews") - .then() - .extract(); - } - - public static ExtractableResponse μ’‹μ•„μš”λ₯Ό_제일_많이_받은_리뷰_쑰회_μš”μ²­(final Long productId) { - return given() - .when() - .get("/api/ranks/products/{product_id}/reviews", productId) - .then().log().all() - .extract(); - } - - public static ExtractableResponse 리뷰_상세_쑰회_μš”μ²­(final Long reviewId) { - return given() - .when() - .get("/api/reviews/{reviewId}", reviewId) - .then() - .extract(); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/tag/TagAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/tag/TagAcceptanceTest.java deleted file mode 100644 index 426c7508b..000000000 --- a/backend/src/test/java/com/funeat/acceptance/tag/TagAcceptanceTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.funeat.acceptance.tag; - -import static com.funeat.acceptance.common.CommonSteps.STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€; -import static com.funeat.acceptance.common.CommonSteps.정상_처리; -import static com.funeat.acceptance.tag.TagSteps.전체_νƒœκ·Έ_λͺ©λ‘_쑰회_μš”μ²­; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_간식_ETC_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_κ°“μ„±λΉ„_PRICE_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_단짠단짠_TASTE_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.acceptance.common.AcceptanceTest; -import com.funeat.tag.dto.TagDto; -import com.funeat.tag.dto.TagsResponse; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import java.util.List; -import java.util.stream.Collectors; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -public class TagAcceptanceTest extends AcceptanceTest { - - @Nested - class getAllTags_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 전체_νƒœκ·Έ_λͺ©λ‘μ„_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var λ§›μžˆμ–΄μš” = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성()); - final var 단짠단짠 = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_단짠단짠_TASTE_생성()); - final var κ°“μ„±λΉ„ = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_κ°“μ„±λΉ„_PRICE_생성()); - final var 간식 = 단일_νƒœκ·Έ_μ €μž₯(νƒœκ·Έ_간식_ETC_생성()); - - // when - final var 응닡 = 전체_νƒœκ·Έ_λͺ©λ‘_쑰회_μš”μ²­(); - - // then - STATUS_CODEλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, 정상_처리); - 전체_νƒœκ·Έ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(응닡, List.of(λ§›μžˆμ–΄μš”, 단짠단짠, κ°“μ„±λΉ„, 간식)); - } - } - - private void 전체_νƒœκ·Έ_λͺ©λ‘_쑰회_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final ExtractableResponse response, final List tagIds) { - final var actual = response.jsonPath() - .getList("", TagsResponse.class); - - final var actualTagIds = actual.stream() - .flatMap(tagsResponse -> tagsResponse.getTags().stream()) - .map(TagDto::getId) - .collect(Collectors.toList()); - - assertThat(actualTagIds).containsExactlyElementsOf(tagIds); - } -} diff --git a/backend/src/test/java/com/funeat/acceptance/tag/TagSteps.java b/backend/src/test/java/com/funeat/acceptance/tag/TagSteps.java deleted file mode 100644 index 53dae95a1..000000000 --- a/backend/src/test/java/com/funeat/acceptance/tag/TagSteps.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.funeat.acceptance.tag; - -import static io.restassured.RestAssured.given; - -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; - -@SuppressWarnings("NonAsciiCharacters") -public class TagSteps { - - public static ExtractableResponse 전체_νƒœκ·Έ_λͺ©λ‘_쑰회_μš”μ²­() { - return given() - .when() - .get("/api/tags") - .then() - .extract(); - } -} diff --git a/backend/src/test/java/com/funeat/auth/application/AuthServiceTest.java b/backend/src/test/java/com/funeat/auth/application/AuthServiceTest.java deleted file mode 100644 index 7f82ccb6a..000000000 --- a/backend/src/test/java/com/funeat/auth/application/AuthServiceTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.funeat.auth.application; - -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -import com.funeat.auth.dto.SignUserDto; -import com.funeat.common.ServiceTest; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -public class AuthServiceTest extends ServiceTest { - - @Nested - class loginWithKakao_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 카카였_λ‘œκ·ΈμΈμ„_ν•˜μ—¬_멀버_정보λ₯Ό_κ°€μ Έμ˜¨λ‹€() { - // given - final var code = "1"; - final var member = 멀버_멀버1_생성(); - final var expected = SignUserDto.of(true, member); - - // when - final var actual = authService.loginWithKakao(code); - - // then - assertThat(actual).usingRecursiveComparison() - .ignoringFields("member.id") - .isEqualTo(expected); - } - } - - @Nested - class logoutWithKakao_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 카카였_λ‘œκ·ΈμΈν•œ_멀버λ₯Ό_λ‘œκ·Έμ•„μ›ƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var memberId = member.getId(); - - // when & then - assertDoesNotThrow(() -> authService.logoutWithKakao(memberId)); - } - } -} diff --git a/backend/src/test/java/com/funeat/banner/application/BannerServiceTest.java b/backend/src/test/java/com/funeat/banner/application/BannerServiceTest.java deleted file mode 100644 index dad7292f4..000000000 --- a/backend/src/test/java/com/funeat/banner/application/BannerServiceTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.funeat.banner.application; - -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ1_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ2_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ3_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ4_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ5_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.banner.dto.BannerResponse; -import com.funeat.common.ServiceTest; -import java.util.List; -import java.util.stream.Collectors; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -public class BannerServiceTest extends ServiceTest { - - @Nested - class getBanners_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ°°λ„ˆλ₯Ό_아이디_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_전체_μ‘°νšŒν•œλ‹€() { - // given - final var λ°°λ„ˆ1 = λ°°λ„ˆ1_생성(); - final var λ°°λ„ˆ2 = λ°°λ„ˆ2_생성(); - final var λ°°λ„ˆ3 = λ°°λ„ˆ3_생성(); - final var λ°°λ„ˆ4 = λ°°λ„ˆ4_생성(); - final var λ°°λ„ˆ5 = λ°°λ„ˆ5_생성(); - 볡수_λ°°λ„ˆ_μ €μž₯(λ°°λ„ˆ1, λ°°λ„ˆ2, λ°°λ„ˆ3, λ°°λ„ˆ4, λ°°λ„ˆ5); - - // when - final var result = bannerService.getAllBanners(); - - // then - final var λ°°λ„ˆλ“€ = List.of(λ°°λ„ˆ5, λ°°λ„ˆ4, λ°°λ„ˆ3, λ°°λ„ˆ2, λ°°λ„ˆ1); - final var bannerResponses = λ°°λ„ˆλ“€.stream() - .map(BannerResponse::toResponse) - .collect(Collectors.toList()); - - assertThat(result).usingRecursiveComparison() - .ignoringFields("id") - .isEqualTo(bannerResponses); - } - } -} diff --git a/backend/src/test/java/com/funeat/banner/persistence/BannerRepositoryTest.java b/backend/src/test/java/com/funeat/banner/persistence/BannerRepositoryTest.java deleted file mode 100644 index 34ef6e6b9..000000000 --- a/backend/src/test/java/com/funeat/banner/persistence/BannerRepositoryTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.funeat.banner.persistence; - -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ1_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ2_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ3_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ4_생성; -import static com.funeat.fixture.BannerFixture.λ°°λ„ˆ5_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.RepositoryTest; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -public class BannerRepositoryTest extends RepositoryTest { - - @Nested - class findAllByOrderByIdDesc_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ°°λ„ˆλŠ”_아이디가_λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ_μ‘°νšŒλœλ‹€() { - // given - final var λ°°λ„ˆ1 = λ°°λ„ˆ1_생성(); - final var λ°°λ„ˆ2 = λ°°λ„ˆ2_생성(); - final var λ°°λ„ˆ3 = λ°°λ„ˆ3_생성(); - final var λ°°λ„ˆ4 = λ°°λ„ˆ4_생성(); - final var λ°°λ„ˆ5 = λ°°λ„ˆ5_생성(); - 볡수_λ°°λ„ˆ_μ €μž₯(λ°°λ„ˆ1, λ°°λ„ˆ2, λ°°λ„ˆ3, λ°°λ„ˆ4, λ°°λ„ˆ5); - - // when - final var bannersOrderByIdDesc = bannerRepository.findAllByOrderByIdDesc(); - - // then - assertThat(bannersOrderByIdDesc).usingRecursiveComparison() - .isEqualTo(List.of(λ°°λ„ˆ5, λ°°λ„ˆ4, λ°°λ„ˆ3, λ°°λ„ˆ2, λ°°λ„ˆ1)); - } - } -} diff --git a/backend/src/test/java/com/funeat/common/DataCleaner.java b/backend/src/test/java/com/funeat/common/DataCleaner.java deleted file mode 100644 index 9cefb2f36..000000000 --- a/backend/src/test/java/com/funeat/common/DataCleaner.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.funeat.common; - -import java.util.ArrayList; -import java.util.List; -import javax.annotation.PostConstruct; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.transaction.Transactional; -import org.springframework.stereotype.Component; - -@Component -public class DataCleaner { - - private static final String FOREIGN_KEY_CHECK_FORMAT = "SET REFERENTIAL_INTEGRITY %s"; - private static final String TRUNCATE_FORMAT = "TRUNCATE TABLE %s"; - private static final String AUTO_INCREMENT_FORMAT = "ALTER TABLE %s ALTER COLUMN id RESTART WITH 1"; - - private final List tableNames = new ArrayList<>(); - - @PersistenceContext - private EntityManager entityManager; - - @SuppressWarnings("unchecked") - @PostConstruct - public void findDatabaseTableNames() { - List tableInfos = entityManager.createNativeQuery("SHOW TABLES").getResultList(); - for (Object[] tableInfo : tableInfos) { - String tableName = (String) tableInfo[0]; - tableNames.add(tableName); - } - } - - @Transactional - public void clear() { - entityManager.clear(); - truncate(); - } - - private void truncate() { - entityManager.createNativeQuery(String.format(FOREIGN_KEY_CHECK_FORMAT, "FALSE")).executeUpdate(); - for (String tableName : tableNames) { - entityManager.createNativeQuery(String.format(TRUNCATE_FORMAT, tableName)).executeUpdate(); - entityManager.createNativeQuery(String.format(AUTO_INCREMENT_FORMAT, tableName)).executeUpdate(); - } - entityManager.createNativeQuery(String.format(FOREIGN_KEY_CHECK_FORMAT, "TRUE")).executeUpdate(); - } -} diff --git a/backend/src/test/java/com/funeat/common/DataClearExtension.java b/backend/src/test/java/com/funeat/common/DataClearExtension.java deleted file mode 100644 index 4c06f51f0..000000000 --- a/backend/src/test/java/com/funeat/common/DataClearExtension.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.funeat.common; - -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -public class DataClearExtension implements BeforeEachCallback { - - @Override - public void beforeEach(final ExtensionContext context) { - final DataCleaner dataCleaner = getDataCleaner(context); - dataCleaner.clear(); - } - - private DataCleaner getDataCleaner(final ExtensionContext extensionContext) { - return SpringExtension.getApplicationContext(extensionContext) - .getBean(DataCleaner.class); - } -} diff --git a/backend/src/test/java/com/funeat/common/EventTest.java b/backend/src/test/java/com/funeat/common/EventTest.java deleted file mode 100644 index aeb72d418..000000000 --- a/backend/src/test/java/com/funeat/common/EventTest.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.funeat.common; - -import com.funeat.member.domain.Member; -import com.funeat.member.persistence.MemberRepository; -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import com.funeat.product.persistence.CategoryRepository; -import com.funeat.product.persistence.ProductRepository; -import com.funeat.review.application.ReviewService; -import com.funeat.review.persistence.ReviewRepository; -import com.funeat.tag.persistence.TagRepository; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.event.ApplicationEvents; -import org.springframework.test.context.event.RecordApplicationEvents; - -@SpringBootTest -@RecordApplicationEvents -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(ReplaceUnderscores.class) -@ExtendWith({MockitoExtension.class, DataClearExtension.class}) -public class EventTest { - - @Autowired - protected ApplicationEvents events; - - @Autowired - protected ReviewService reviewService; - - @Autowired - protected ProductRepository productRepository; - - @Autowired - protected CategoryRepository categoryRepository; - - @Autowired - protected TagRepository tagRepository; - - @Autowired - protected MemberRepository memberRepository; - - @Autowired - protected ReviewRepository reviewRepository; - - @AfterEach - void tearDown() { - events.clear(); - } - - protected Long 단일_μƒν’ˆ_μ €μž₯(final Product product) { - return productRepository.save(product).getId(); - } - - protected Long 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(final Category category) { - return categoryRepository.save(category).getId(); - } - - protected Long 단일_멀버_μ €μž₯(final Member member) { - return memberRepository.save(member).getId(); - } -} diff --git a/backend/src/test/java/com/funeat/common/RepositoryTest.java b/backend/src/test/java/com/funeat/common/RepositoryTest.java deleted file mode 100644 index 1ae1fff62..000000000 --- a/backend/src/test/java/com/funeat/common/RepositoryTest.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.funeat.common; - -import com.funeat.banner.domain.Banner; -import com.funeat.banner.persistence.BannerRepository; -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.RecipeFavorite; -import com.funeat.member.domain.favorite.ReviewFavorite; -import com.funeat.member.persistence.MemberRepository; -import com.funeat.member.persistence.RecipeFavoriteRepository; -import com.funeat.member.persistence.ReviewFavoriteRepository; -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import com.funeat.product.domain.ProductRecipe; -import com.funeat.product.persistence.CategoryRepository; -import com.funeat.product.persistence.ProductRecipeRepository; -import com.funeat.product.persistence.ProductRepository; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import com.funeat.recipe.persistence.RecipeImageRepository; -import com.funeat.recipe.persistence.RecipeRepository; -import com.funeat.review.domain.Review; -import com.funeat.review.domain.ReviewTag; -import com.funeat.review.persistence.ReviewRepository; -import com.funeat.review.persistence.ReviewTagRepository; -import com.funeat.tag.domain.Tag; -import com.funeat.tag.persistence.TagRepository; -import java.util.List; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; - -@DataJpaTest -@Import(DataCleaner.class) -@ExtendWith(DataClearExtension.class) -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(ReplaceUnderscores.class) -public abstract class RepositoryTest { - - @Autowired - protected MemberRepository memberRepository; - - @Autowired - protected RecipeFavoriteRepository recipeFavoriteRepository; - - @Autowired - protected ReviewFavoriteRepository reviewFavoriteRepository; - - @Autowired - protected CategoryRepository categoryRepository; - - @Autowired - protected ProductRecipeRepository productRecipeRepository; - - @Autowired - protected ProductRepository productRepository; - - @Autowired - protected RecipeImageRepository recipeImageRepository; - - @Autowired - protected RecipeRepository recipeRepository; - - @Autowired - protected ReviewRepository reviewRepository; - - @Autowired - protected ReviewTagRepository reviewTagRepository; - - @Autowired - protected TagRepository tagRepository; - - @Autowired - protected BannerRepository bannerRepository; - - protected Long 단일_μƒν’ˆ_μ €μž₯(final Product product) { - return productRepository.save(product).getId(); - } - - protected void 볡수_μƒν’ˆ_μ €μž₯(final Product... productsToSave) { - final var products = List.of(productsToSave); - - productRepository.saveAll(products); - } - - protected Long 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(final Category category) { - return categoryRepository.save(category).getId(); - } - - protected void 볡수_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(final Category... categoriesToSave) { - final var categories = List.of(categoriesToSave); - - categoryRepository.saveAll(categories); - } - - protected Long 단일_멀버_μ €μž₯(final Member member) { - return memberRepository.save(member).getId(); - } - - protected void 볡수_멀버_μ €μž₯(final Member... membersToSave) { - final var members = List.of(membersToSave); - - memberRepository.saveAll(members); - } - - protected Long 단일_리뷰_μ €μž₯(final Review review) { - return reviewRepository.save(review).getId(); - } - - protected void 볡수_리뷰_μ €μž₯(final Review... reviewsToSave) { - final var reviews = List.of(reviewsToSave); - - reviewRepository.saveAll(reviews); - } - - protected Long 단일_κΏ€μ‘°ν•©_μ €μž₯(final Recipe recipe) { - return recipeRepository.save(recipe).getId(); - } - - protected void 볡수_κΏ€μ‘°ν•©_μ €μž₯(final Recipe... recipesToSave) { - final var recipes = List.of(recipesToSave); - - recipeRepository.saveAll(recipes); - } - - protected void 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(final RecipeImage... recipeImageToSave) { - final var recipeFavorites = List.of(recipeImageToSave); - - recipeImageRepository.saveAll(recipeFavorites); - } - - protected void 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(final ProductRecipe... productRecipeImageToSave) { - final var productRecipes = List.of(productRecipeImageToSave); - - productRecipeRepository.saveAll(productRecipes); - } - - protected Long 단일_νƒœκ·Έ_μ €μž₯(final Tag tag) { - return tagRepository.save(tag).getId(); - } - - protected void 볡수_νƒœκ·Έ_μ €μž₯(final Tag... tagsToSave) { - final var tags = List.of(tagsToSave); - - tagRepository.saveAll(tags); - } - - protected Long 단일_리뷰_νƒœκ·Έ_μ €μž₯(final ReviewTag reviewTag) { - return reviewTagRepository.save(reviewTag).getId(); - } - - protected void 볡수_리뷰_νƒœκ·Έ_μ €μž₯(final ReviewTag... reviewTagsToSave) { - final var reviewTags = List.of(reviewTagsToSave); - - reviewTagRepository.saveAll(reviewTags); - } - - protected Long 단일_리뷰_μ’‹μ•„μš”_μ €μž₯(final ReviewFavorite reviewFavorite) { - return reviewFavoriteRepository.save(reviewFavorite).getId(); - } - - protected void 볡수_리뷰_μ’‹μ•„μš”_μ €μž₯(final ReviewFavorite... reviewFavoritesToSave) { - final var reviewFavorites = List.of(reviewFavoritesToSave); - - reviewFavoriteRepository.saveAll(reviewFavorites); - } - - protected Long 단일_λ ˆμ‹œν”Ό_μ €μž₯(final Recipe recipe) { - return recipeRepository.save(recipe).getId(); - } - - protected void 볡수_λ ˆμ‹œν”Ό_μ €μž₯(final Recipe... recipeToSave) { - final var recipes = List.of(recipeToSave); - - recipeRepository.saveAll(recipes); - } - - protected void 볡수_λ ˆμ‹œν”Ό_이미지_μ €μž₯(final RecipeImage... recipeImageToSave) { - final var images = List.of(recipeImageToSave); - - recipeImageRepository.saveAll(images); - } - - protected void 볡수_λ ˆμ‹œν”Ό_μƒν’ˆ_μ €μž₯(final ProductRecipe... productRecipeToSave) { - final var productRecipes = List.of(productRecipeToSave); - - productRecipeRepository.saveAll(productRecipes); - } - - protected void λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μ €μž₯(final RecipeFavorite recipeFavorite) { - recipeFavoriteRepository.save(recipeFavorite); - } - - protected void 볡수_λ°°λ„ˆ_μ €μž₯(final Banner... bannerToSave) { - final List banners = List.of(bannerToSave); - - bannerRepository.saveAll(banners); - } -} diff --git a/backend/src/test/java/com/funeat/common/ServiceTest.java b/backend/src/test/java/com/funeat/common/ServiceTest.java deleted file mode 100644 index 23ee634f5..000000000 --- a/backend/src/test/java/com/funeat/common/ServiceTest.java +++ /dev/null @@ -1,214 +0,0 @@ -package com.funeat.common; - -import com.funeat.auth.application.AuthService; -import com.funeat.banner.application.BannerService; -import com.funeat.banner.domain.Banner; -import com.funeat.banner.persistence.BannerRepository; -import com.funeat.comment.persistence.CommentRepository; -import com.funeat.member.application.TestMemberService; -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.ReviewFavorite; -import com.funeat.member.persistence.MemberRepository; -import com.funeat.member.persistence.RecipeFavoriteRepository; -import com.funeat.member.persistence.ReviewFavoriteRepository; -import com.funeat.product.application.CategoryService; -import com.funeat.product.application.ProductService; -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import com.funeat.product.domain.ProductRecipe; -import com.funeat.product.persistence.CategoryRepository; -import com.funeat.product.persistence.ProductRecipeRepository; -import com.funeat.product.persistence.ProductRepository; -import com.funeat.recipe.application.RecipeService; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import com.funeat.recipe.persistence.RecipeImageRepository; -import com.funeat.recipe.persistence.RecipeRepository; -import com.funeat.review.application.ReviewService; -import com.funeat.review.domain.Review; -import com.funeat.review.domain.ReviewTag; -import com.funeat.review.persistence.ReviewRepository; -import com.funeat.review.persistence.ReviewTagRepository; -import com.funeat.tag.application.TagService; -import com.funeat.tag.domain.Tag; -import com.funeat.tag.persistence.TagRepository; -import java.util.List; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.transaction.annotation.Transactional; - -@Transactional -@SpringBootTest -@ExtendWith(DataClearExtension.class) -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(ReplaceUnderscores.class) -public abstract class ServiceTest { - - @Autowired - protected MemberRepository memberRepository; - - @Autowired - protected RecipeFavoriteRepository recipeFavoriteRepository; - - @Autowired - protected ReviewFavoriteRepository reviewFavoriteRepository; - - @Autowired - protected CategoryRepository categoryRepository; - - @Autowired - protected ProductRecipeRepository productRecipeRepository; - - @Autowired - protected ProductRepository productRepository; - - @Autowired - protected RecipeImageRepository recipeImageRepository; - - @Autowired - protected RecipeRepository recipeRepository; - - @Autowired - protected ReviewRepository reviewRepository; - - @Autowired - protected ReviewTagRepository reviewTagRepository; - - @Autowired - protected TagRepository tagRepository; - - @Autowired - protected BannerRepository bannerRepository; - - @Autowired - protected CommentRepository commentRepository; - - @Autowired - protected AuthService authService; - - @Autowired - protected TestMemberService memberService; - - @Autowired - protected CategoryService categoryService; - - @Autowired - protected RecipeService recipeService; - - @Autowired - protected ProductService productService; - - @Autowired - protected ReviewService reviewService; - - @Autowired - protected TagService tagService; - - @Autowired - protected BannerService bannerService; - - protected Long 단일_μƒν’ˆ_μ €μž₯(final Product product) { - return productRepository.save(product).getId(); - } - - protected void 볡수_μƒν’ˆ_μ €μž₯(final Product... productsToSave) { - final var products = List.of(productsToSave); - - productRepository.saveAll(products); - } - - protected Long 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(final Category category) { - return categoryRepository.save(category).getId(); - } - - protected void 볡수_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(final Category... categoriesToSave) { - final var categories = List.of(categoriesToSave); - - categoryRepository.saveAll(categories); - } - - protected Long 단일_멀버_μ €μž₯(final Member member) { - return memberRepository.save(member).getId(); - } - - protected void 볡수_멀버_μ €μž₯(final Member... membersToSave) { - final var members = List.of(membersToSave); - - memberRepository.saveAll(members); - } - - protected Long 단일_리뷰_μ €μž₯(final Review review) { - return reviewRepository.save(review).getId(); - } - - protected void 볡수_리뷰_μ €μž₯(final Review... reviewsToSave) { - final var reviews = List.of(reviewsToSave); - - reviewRepository.saveAll(reviews); - } - - protected Long 단일_νƒœκ·Έ_μ €μž₯(final Tag tag) { - return tagRepository.save(tag).getId(); - } - - protected void 볡수_νƒœκ·Έ_μ €μž₯(final Tag... tagsToSave) { - final var tags = List.of(tagsToSave); - - tagRepository.saveAll(tags); - } - - protected Long 단일_리뷰_νƒœκ·Έ_μ €μž₯(final ReviewTag reviewTag) { - return reviewTagRepository.save(reviewTag).getId(); - } - - protected void 볡수_리뷰_νƒœκ·Έ_μ €μž₯(final ReviewTag... reviewTagsToSave) { - final var reviewTags = List.of(reviewTagsToSave); - - reviewTagRepository.saveAll(reviewTags); - } - - protected Long 단일_리뷰_μ’‹μ•„μš”_μ €μž₯(final ReviewFavorite reviewFavorite) { - return reviewFavoriteRepository.save(reviewFavorite).getId(); - } - - protected void 볡수_리뷰_μ’‹μ•„μš”_μ €μž₯(final ReviewFavorite... reviewFavoritesToSave) { - final var reviewFavorites = List.of(reviewFavoritesToSave); - - reviewFavoriteRepository.saveAll(reviewFavorites); - } - - protected void 단일_κΏ€μ‘°ν•©_μ €μž₯(final Recipe recipe) { - recipeRepository.save(recipe); - } - - protected void 볡수_κΏ€μ‘°ν•©_μ €μž₯(final Recipe... recipesToSave) { - final var recipeFavorites = List.of(recipesToSave); - - recipeRepository.saveAll(recipeFavorites); - } - - protected void 단일_κΏ€μ‘°ν•©_이미지_μ €μž₯(final RecipeImage recipeImage) { - recipeImageRepository.save(recipeImage); - } - - protected void 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(final RecipeImage... recipeImageToSave) { - final var recipeFavorites = List.of(recipeImageToSave); - - recipeImageRepository.saveAll(recipeFavorites); - } - - protected void 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(final ProductRecipe... productRecipeImageToSave) { - final var productRecipes = List.of(productRecipeImageToSave); - - productRecipeRepository.saveAll(productRecipes); - } - - protected void 볡수_λ°°λ„ˆ_μ €μž₯(final Banner... bannerToSave) { - final List banners = List.of(bannerToSave); - - bannerRepository.saveAll(banners); - } -} diff --git a/backend/src/test/java/com/funeat/common/TestImageUploader.java b/backend/src/test/java/com/funeat/common/TestImageUploader.java deleted file mode 100644 index 642da2176..000000000 --- a/backend/src/test/java/com/funeat/common/TestImageUploader.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.funeat.common; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Comparator; -import java.util.stream.Stream; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; - -@Component -@Profile("test") -public class TestImageUploader implements ImageUploader { - - @Override - public String upload(final MultipartFile image) { - // μ‹€μ œλ‘œ IO μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” λŒ€μ‹ , μž„μ‹œ λ””λ ‰ν† λ¦¬λ‘œ λ³΅μ‚¬ν•˜λ„λ‘ μˆ˜μ • - try { - final String temporaryPath = String.valueOf(System.currentTimeMillis()); - final Path tempDirectoryPath = Files.createTempDirectory(temporaryPath); - final Path filePath = tempDirectoryPath.resolve(image.getOriginalFilename()); - Files.copy(image.getInputStream(), filePath); - - deleteDirectory(tempDirectoryPath); - return image.getOriginalFilename(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void delete(final String fileName) { - } - - private void deleteDirectory(Path directory) throws IOException { - // 디렉토리 λ‚΄λΆ€ 파일 및 디렉토리 μ‚­μ œ - try (Stream pathStream = Files.walk(directory)) { - pathStream.sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); - } - Files.deleteIfExists(directory); - } -} diff --git a/backend/src/test/java/com/funeat/fixture/BannerFixture.java b/backend/src/test/java/com/funeat/fixture/BannerFixture.java deleted file mode 100644 index 9ab4443f5..000000000 --- a/backend/src/test/java/com/funeat/fixture/BannerFixture.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.funeat.fixture; - -import com.funeat.banner.domain.Banner; - -public class BannerFixture { - - public static Banner λ°°λ„ˆ1_생성() { - return new Banner("λ°°λ„ˆ1링크", "λ°°λ„ˆ1.jpeg"); - } - - public static Banner λ°°λ„ˆ2_생성() { - return new Banner("λ°°λ„ˆ2링크", "λ°°λ„ˆ2.jpeg"); - } - - public static Banner λ°°λ„ˆ3_생성() { - return new Banner("λ°°λ„ˆ3링크", "λ°°λ„ˆ3.jpeg"); - } - - public static Banner λ°°λ„ˆ4_생성() { - return new Banner("λ°°λ„ˆ4링크", "λ°°λ„ˆ4.jpeg"); - } - - public static Banner λ°°λ„ˆ5_생성() { - return new Banner("λ°°λ„ˆ5링크", "λ°°λ„ˆ5.jpeg"); - } -} diff --git a/backend/src/test/java/com/funeat/fixture/CategoryFixture.java b/backend/src/test/java/com/funeat/fixture/CategoryFixture.java deleted file mode 100644 index 95ee4b056..000000000 --- a/backend/src/test/java/com/funeat/fixture/CategoryFixture.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.funeat.fixture; - -import com.funeat.product.domain.Category; -import com.funeat.product.domain.CategoryType; - -@SuppressWarnings("NonAsciiCharacters") -public class CategoryFixture { - - public static final String μŒμ‹ = "food"; - - public static final Long μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μΉ΄ν…Œκ³ λ¦¬ = 99999L; - - public static Category μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성() { - return new Category("κ°„νŽΈμ‹μ‚¬", CategoryType.FOOD, "siksa.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성() { - return new Category("즉석쑰리", CategoryType.FOOD, "direct.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_과자λ₯˜_생성() { - return new Category("과자λ₯˜", CategoryType.FOOD, "snack.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_μ•„μ΄μŠ€ν¬λ¦Ό_생성() { - return new Category("μ•„μ΄μŠ€ν¬λ¦Ό", CategoryType.FOOD, "ice.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_μ‹ν’ˆ_생성() { - return new Category("μ‹ν’ˆ", CategoryType.FOOD, "food.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_음료_생성() { - return new Category("음료", CategoryType.FOOD, "drink.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_CU_생성() { - return new Category("CU", CategoryType.STORE, "cu.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_GS25_생성() { - return new Category("GS25", CategoryType.STORE, "gs25.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_EMART24_생성() { - return new Category("EMART24", CategoryType.STORE, "emart.jpeg"); - } - - public static Category μΉ΄ν…Œκ³ λ¦¬_μ„ΈλΈμΌλ ˆλΈ_생성() { - return new Category("μ„ΈλΈμΌλ ˆλΈ", CategoryType.STORE, "seven.jpeg"); - } -} diff --git a/backend/src/test/java/com/funeat/fixture/ImageFixture.java b/backend/src/test/java/com/funeat/fixture/ImageFixture.java deleted file mode 100644 index 5e744727e..000000000 --- a/backend/src/test/java/com/funeat/fixture/ImageFixture.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.funeat.fixture; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.web.multipart.MultipartFile; - -@SuppressWarnings("NonAsciiCharacters") -public class ImageFixture { - - public static final String 이미지1 = "1"; - public static final String 이미지2 = "2"; - public static final String 이미지3 = "3"; - public static final String 이미지4 = "4"; - public static final String 이미지5 = "5"; - public static final String 이미지6 = "6"; - public static final String 이미지7 = "7"; - - public static MultipartFile 이미지_생성() { - return new MockMultipartFile("image", "image.jpg", "image/jpeg", new byte[]{1, 2, 3}); - } - - public static List μ—¬λŸ¬_이미지_생성(final int count) { - return IntStream.range(0, count) - .mapToObj(it -> 이미지_생성()) - .collect(Collectors.toList()); - } -} diff --git a/backend/src/test/java/com/funeat/fixture/MemberFixture.java b/backend/src/test/java/com/funeat/fixture/MemberFixture.java deleted file mode 100644 index b6d67798f..000000000 --- a/backend/src/test/java/com/funeat/fixture/MemberFixture.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.funeat.fixture; - -import com.funeat.member.domain.Member; -import com.funeat.member.dto.MemberRequest; - -@SuppressWarnings("NonAsciiCharacters") -public class MemberFixture { - - public static final Long 멀버1 = 1L; - public static final Long 멀버2 = 2L; - public static final Long 멀버3 = 3L; - - - public static Member 멀버_멀버1_생성() { - return new Member("member1", "www.member1.com", "1"); - } - - public static Member 멀버_멀버2_생성() { - return new Member("member2", "www.member2.com", "2"); - } - - public static Member 멀버_멀버3_생성() { - return new Member("member3", "www.member3.com", "3"); - } - - public static MemberRequest μœ μ €λ‹‰λ„€μž„μˆ˜μ •μš”μ²­_생성(final String modifyNickname) { - return new MemberRequest(modifyNickname); - } -} diff --git a/backend/src/test/java/com/funeat/fixture/PageFixture.java b/backend/src/test/java/com/funeat/fixture/PageFixture.java deleted file mode 100644 index 773658f48..000000000 --- a/backend/src/test/java/com/funeat/fixture/PageFixture.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.funeat.fixture; - -import com.funeat.common.dto.PageDto; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Direction; - -@SuppressWarnings("NonAsciiCharacters") -public class PageFixture { - - public static final String 평균_평점_μ˜€λ¦„μ°¨μˆœ = "averageRating,asc"; - public static final String 평균_평점_λ‚΄λ¦Όμ°¨μˆœ = "averageRating,desc"; - public static final String 가격_μ˜€λ¦„μ°¨μˆœ = "price,asc"; - public static final String 가격_λ‚΄λ¦Όμ°¨μˆœ = "price,desc"; - public static final String μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ = "favoriteCount,desc"; - public static final String 리뷰수_λ‚΄λ¦Όμ°¨μˆœ = "reviewCount,desc"; - public static final String 평점_μ˜€λ¦„μ°¨μˆœ = "rating,asc"; - public static final String 평점_λ‚΄λ¦Όμ°¨μˆœ = "rating,desc"; - public static final String 과거순 = "createdAt,asc"; - public static final String μ΅œμ‹ μˆœ = "createdAt,desc"; - public static final String 아이디_λ‚΄λ¦Όμ°¨μˆœ = "id,desc"; - - public static final Long PAGE_SIZE = 10L; - public static final Long FIRST_PAGE = 0L; - public static final Long SECOND_PAGE = 1L; - - public static final boolean μ²«νŽ˜μ΄μ§€O = true; - public static final boolean μ²«νŽ˜μ΄μ§€X = false; - public static final boolean λ§ˆμ§€λ§‰νŽ˜μ΄μ§€O = true; - public static final boolean λ§ˆμ§€λ§‰νŽ˜μ΄μ§€X = false; - - public static PageRequest νŽ˜μ΄μ§€μš”μ²­_κΈ°λ³Έ_생성(final int page, final int size) { - return PageRequest.of(page, size); - } - - public static PageRequest νŽ˜μ΄μ§€μš”μ²­_생성(final int page, final int size, final String sort) { - final String[] splitSort = sort.split(","); - final String order = splitSort[0]; - final Direction direction = Direction.fromString(splitSort[1]); - - return PageRequest.of(page, size, Sort.by(direction, order)); - } - - public static PageDto 응닡_νŽ˜μ΄μ§€_생성(final Long totalDataCount, final Long totalPages, final boolean firstPage, - final boolean lastPage, final Long requestPage, final Long requestSize) { - return new PageDto(totalDataCount, totalPages, firstPage, lastPage, requestPage, requestSize); - } - - public static Pageable νŽ˜μ΄μ§€μš”μ²­_μ’‹μ•„μš”_λ‚΄λ¦Όμ°¨μˆœ_생성(final int page, final int size) { - final var sort = Sort.by(Direction.DESC, "favoriteCount"); - - return PageRequest.of(page, size, sort); - } - - public static Pageable νŽ˜μ΄μ§€μš”μ²­_μ΅œμ‹ μˆœ_생성(final int page, final int size) { - final var sort = Sort.by(Direction.DESC, "createdAt"); - - return PageRequest.of(page, size, sort); - } - - public static Pageable νŽ˜μ΄μ§€μš”μ²­_평점_μ˜€λ¦„μ°¨μˆœ_생성(final int page, final int size) { - final var sort = Sort.by(Direction.ASC, "rating"); - - return PageRequest.of(page, size, sort); - } - - public static Pageable νŽ˜μ΄μ§€μš”μ²­_평점_λ‚΄λ¦Όμ°¨μˆœ_생성(final int page, final int size) { - final var sort = Sort.by(Direction.DESC, "rating"); - - return PageRequest.of(page, size, sort); - } - - public static Long 총_데이터_개수(final Long count) { - return count; - } - - public static Long 총_νŽ˜μ΄μ§€(final Long page) { - return page; - } -} diff --git a/backend/src/test/java/com/funeat/fixture/ProductFixture.java b/backend/src/test/java/com/funeat/fixture/ProductFixture.java deleted file mode 100644 index 6bb7da0d9..000000000 --- a/backend/src/test/java/com/funeat/fixture/ProductFixture.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.funeat.fixture; - -import com.funeat.product.domain.Category; -import com.funeat.product.domain.Product; -import com.funeat.product.domain.ProductRecipe; -import com.funeat.recipe.domain.Recipe; - -@SuppressWarnings("NonAsciiCharacters") -public class ProductFixture { - - public static final Long μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆ = 99999L; - public static final Long μƒν’ˆ = 1L; - public static final Long μƒν’ˆ1 = 1L; - public static final Long μƒν’ˆ2 = 2L; - public static final Long μƒν’ˆ3 = 3L; - public static final Long μƒν’ˆ4 = 4L; - public static final Long μƒν’ˆ5 = 5L; - public static final Long μƒν’ˆ6 = 6L; - public static final Long μƒν’ˆ7 = 7L; - public static final Long μƒν’ˆ8 = 8L; - public static final Long μƒν’ˆ9 = 9L; - public static final Long μƒν’ˆ10 = 10L; - public static final Long μƒν’ˆ11 = 11L; - - public static Product μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(final Category category) { - return new Product("삼각김λ°₯", 1000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 1.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(final Category category) { - return new Product("삼각김λ°₯", 1000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 2.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(final Category category) { - return new Product("삼각김λ°₯", 1000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 3.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성(final Category category) { - return new Product("삼각김λ°₯", 1000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 4.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(final Category category) { - return new Product("삼각김λ°₯", 1000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 5.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(final Category category) { - return new Product("삼각김λ°₯", 2000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 1.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격2000원_평점2점_생성(final Category category) { - return new Product("삼각김λ°₯", 2000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 2.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(final Category category) { - return new Product("삼각김λ°₯", 2000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 3.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격2000원_평점4점_생성(final Category category) { - return new Product("삼각김λ°₯", 2000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 4.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격2000원_평점5점_생성(final Category category) { - return new Product("삼각김λ°₯", 2000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 5.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격3000원_평점1점_생성(final Category category) { - return new Product("삼각김λ°₯", 3000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 1.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격3000원_평점2점_생성(final Category category) { - return new Product("삼각김λ°₯", 3000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 2.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격3000원_평점3점_생성(final Category category) { - return new Product("삼각김λ°₯", 3000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 3.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(final Category category) { - return new Product("삼각김λ°₯", 3000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 4.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격3000원_평점5점_생성(final Category category) { - return new Product("삼각김λ°₯", 3000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 5.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격4000원_평점1점_생성(final Category category) { - return new Product("삼각김λ°₯", 4000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 1.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격4000원_평점2점_생성(final Category category) { - return new Product("삼각김λ°₯", 4000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 2.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격4000원_평점3점_생성(final Category category) { - return new Product("삼각김λ°₯", 4000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 3.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격4000원_평점4점_생성(final Category category) { - return new Product("삼각김λ°₯", 4000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 4.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격4000원_평점5점_생성(final Category category) { - return new Product("삼각김λ°₯", 4000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 5.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격5000원_평점1점_생성(final Category category) { - return new Product("삼각김λ°₯", 5000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 1.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격5000원_평점2점_생성(final Category category) { - return new Product("삼각김λ°₯", 5000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 2.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격5000원_평점3점_생성(final Category category) { - return new Product("삼각김λ°₯", 5000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 3.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격5000원_평점4점_생성(final Category category) { - return new Product("삼각김λ°₯", 5000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 4.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격5000원_평점5점_생성(final Category category) { - return new Product("삼각김λ°₯", 5000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", 5.0, category); - } - - public static Product μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(final Category category) { - return new Product("λ§κ³ λΉ™μˆ˜", 5000L, "image.png", "λ§›μžˆλŠ” λ§κ³ λΉ™μˆ˜", 4.0, category); - } - - public static Product μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(final Category category) { - return new Product("μ• ν”Œλ§κ³ ", 3000L, "image.png", "λ§›μžˆλŠ” μ• ν”Œλ§κ³ ", 5.0, category); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격5000원_리뷰0개_생성(final Category category) { - return new Product("삼각김λ°₯", 5000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", category, 0L); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격2000원_리뷰1개_생성(final Category category) { - return new Product("삼각김λ°₯", 2000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", category, 1L); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격1000원_리뷰3개_생성(final Category category) { - return new Product("삼각김λ°₯", 1000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", category, 3L); - } - - public static Product μƒν’ˆ_삼각김λ°₯_가격3000원_리뷰5개_생성(final Category category) { - return new Product("삼각김λ°₯", 3000L, "image.png", "λ§›μžˆλŠ” 삼각김λ°₯", category, 5L); - } - - public static ProductRecipe λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(final Product product, final Recipe recipe) { - return new ProductRecipe(product, recipe); - } -} diff --git a/backend/src/test/java/com/funeat/fixture/RecipeFixture.java b/backend/src/test/java/com/funeat/fixture/RecipeFixture.java deleted file mode 100644 index 2d3bb3deb..000000000 --- a/backend/src/test/java/com/funeat/fixture/RecipeFixture.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.funeat.fixture; - -import com.funeat.member.domain.Member; -import com.funeat.member.domain.favorite.RecipeFavorite; -import com.funeat.recipe.domain.Recipe; -import com.funeat.recipe.domain.RecipeImage; -import com.funeat.recipe.dto.RecipeCreateRequest; -import com.funeat.recipe.dto.RecipeFavoriteRequest; -import java.time.LocalDateTime; -import java.util.List; - -@SuppressWarnings("NonAsciiCharacters") -public class RecipeFixture { - - public static final Long λ ˆμ‹œν”Ό = 1L; - public static final Long μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ ˆμ‹œν”Ό = 99999L; - public static final Long λ ˆμ‹œν”Ό1 = 1L; - public static final Long λ ˆμ‹œν”Ό2 = 2L; - public static final Long λ ˆμ‹œν”Ό3 = 3L; - public static final Long λ ˆμ‹œν”Ό4 = 4L; - - public static final boolean μ’‹μ•„μš”O = true; - public static final boolean μ’‹μ•„μš”X = false; - - public static final String λ ˆμ‹œν”Ό_제λͺ© = "The most delicious recipes"; - public static final String λ ˆμ‹œν”Ό_λ³Έλ¬Έ = "More rice, more rice, more rice.. Done!!"; - - - public static Recipe λ ˆμ‹œν”Ό_생성(final Member member) { - return new Recipe("The most delicious recipes", "More rice, more rice, more rice.. Done!!", member); - } - - public static Recipe λ ˆμ‹œν”Ό_생성(final Member member, final Long favoriteCount) { - return new Recipe("The most delicious recipes", "More rice, more rice, more rice.. Done!!", member, favoriteCount); - } - - public static Recipe λ ˆμ‹œν”Ό_생성(final Member member, final Long favoriteCount, final LocalDateTime createdAt) { - return new Recipe("The most delicious recipes", "More rice, more rice, more rice.. Done!!", - member, favoriteCount, createdAt); - } - - public static RecipeFavorite λ ˆμ‹œν”Ό_μ’‹μ•„μš”_생성(final Member member, final Recipe recipe, final Boolean favorite) { - return new RecipeFavorite(member, recipe, favorite); - } - - public static RecipeCreateRequest λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(final String title, final List productIds, final String content) { - return new RecipeCreateRequest(title, productIds, content); - } - - public static RecipeCreateRequest λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(final Long... productIds) { - return new RecipeCreateRequest("The most delicious recipes", List.of(productIds), "More rice, more rice, more rice.. Done!!"); - } - - public static RecipeCreateRequest λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(final List productIds) { - return new RecipeCreateRequest("The most delicious recipes", productIds, "More rice, more rice, more rice.. Done!!"); - } - - public static RecipeFavoriteRequest λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(final Boolean favorite) { - return new RecipeFavoriteRequest(favorite); - } - - public static RecipeImage λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(final Recipe recipe) { - return new RecipeImage("제일둜 λ§›μ—†λŠ” 사진", recipe); - } -} diff --git a/backend/src/test/java/com/funeat/fixture/ReviewFixture.java b/backend/src/test/java/com/funeat/fixture/ReviewFixture.java deleted file mode 100644 index fee2b0b7b..000000000 --- a/backend/src/test/java/com/funeat/fixture/ReviewFixture.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.funeat.fixture; - -import static com.funeat.fixture.PageFixture.μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.μ΅œμ‹ μˆœ; -import static com.funeat.fixture.PageFixture.평점_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.평점_μ˜€λ¦„μ°¨μˆœ; - -import com.funeat.member.domain.Member; -import com.funeat.product.domain.Product; -import com.funeat.review.domain.Review; -import com.funeat.review.dto.ReviewCreateRequest; -import com.funeat.review.dto.ReviewFavoriteRequest; -import com.funeat.review.dto.SortingReviewRequest; -import java.time.LocalDateTime; -import java.util.List; - -@SuppressWarnings("NonAsciiCharacters") -public class ReviewFixture { - - public static final Long 리뷰 = 1L; - public static final Long μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰 = 99999L; - public static final Long 리뷰1 = 1L; - public static final Long 리뷰2 = 2L; - public static final Long 리뷰3 = 3L; - public static final Long 리뷰4 = 4L; - public static final boolean μ’‹μ•„μš”O = true; - public static final boolean μ’‹μ•„μš”X = false; - public static final boolean 재ꡬ맀O = true; - public static final boolean 재ꡬ맀X = false; - - public static final Long 첫_λͺ©λ‘μ„_κ°€μ Έμ˜΄ = 0L; - public static final boolean λ‹€μŒ_데이터_쑴재O = true; - public static final boolean λ‹€μŒ_데이터_쑴재X = false; - - public static Review 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test1", 1L, "test", true, count); - } - - public static Review 리뷰_μ΄λ―Έμ§€μ—†μŒ_평점1점_재ꡬ맀O_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "", 1L, "test", true, count); - } - - public static Review 리뷰_이미지test1_평점1점_재ꡬ맀X_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test1", 1L, "test", false, count); - } - - public static Review 리뷰_이미지test2_평점2점_재ꡬ맀O_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test2", 2L, "test", true, count); - } - - public static Review 리뷰_이미지test2_평점2점_재ꡬ맀X_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test2", 2L, "test", false, count); - } - - public static Review 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test3", 3L, "test", true, count); - } - - public static Review 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test3", 3L, "test", false, count); - } - - public static Review 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test4", 4L, "test", true, count); - } - - public static Review 리뷰_이미지test4_평점4점_재ꡬ맀X_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test4", 4L, "test", false, count); - } - - public static Review 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test5", 5L, "test", true, count); - } - - public static Review 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "test5", 5L, "test", false, count); - } - - public static Review 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(final Member member, final Product product, final Long count, - final LocalDateTime createdAt) { - return new Review(member, product, "test5", 5L, "test", false, count, createdAt); - } - - public static Review 리뷰_μ΄λ―Έμ§€μ—†μŒ_평점1점_재ꡬ맀X_생성(final Member member, final Product product, final Long count) { - return new Review(member, product, "", 1L, "test", false, count); - } - - public static ReviewCreateRequest λ¦¬λ·°μΆ”κ°€μš”μ²­_생성(final Long rating, final List tagIds, final String content, - final Boolean rebuy) { - return new ReviewCreateRequest(rating, tagIds, content, rebuy); - } - - public static ReviewCreateRequest λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(final Long rating, final List tagIds) { - return new ReviewCreateRequest(rating, tagIds, "test", true); - } - - public static ReviewCreateRequest λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀X_생성(final Long rating, final List tagIds) { - return new ReviewCreateRequest(rating, tagIds, "test", false); - } - - public static ReviewFavoriteRequest λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(final Boolean favorite) { - return new ReviewFavoriteRequest(favorite); - } - - public static SortingReviewRequest λ¦¬λ·°μ •λ ¬μš”μ²­_μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ_생성(final Long lastReviewId) { - return new SortingReviewRequest(μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ, lastReviewId); - } - - public static SortingReviewRequest λ¦¬λ·°μ •λ ¬μš”μ²­_μ΅œμ‹ μˆœ_생성(final Long lastReviewId) { - return new SortingReviewRequest(μ΅œμ‹ μˆœ, lastReviewId); - } - - public static SortingReviewRequest λ¦¬λ·°μ •λ ¬μš”μ²­_평점_μ˜€λ¦„μ°¨μˆœ_생성(final Long lastReviewId) { - return new SortingReviewRequest(평점_μ˜€λ¦„μ°¨μˆœ, lastReviewId); - } - - public static SortingReviewRequest λ¦¬λ·°μ •λ ¬μš”μ²­_평점_λ‚΄λ¦Όμ°¨μˆœ_생성(final Long lastReviewId) { - return new SortingReviewRequest(평점_λ‚΄λ¦Όμ°¨μˆœ, lastReviewId); - } - - public static SortingReviewRequest λ¦¬λ·°μ •λ ¬μš”μ²­_μ‘΄μž¬ν•˜μ§€μ•ŠλŠ”μ •λ ¬_생성() { - return new SortingReviewRequest("test,test", 1L); - } -} diff --git a/backend/src/test/java/com/funeat/fixture/ScoreFixture.java b/backend/src/test/java/com/funeat/fixture/ScoreFixture.java deleted file mode 100644 index 3f9ce8ece..000000000 --- a/backend/src/test/java/com/funeat/fixture/ScoreFixture.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.funeat.fixture; - -@SuppressWarnings("NonAsciiCharacters") -public class ScoreFixture { - - public static final Long 점수_1점 = 1L; - public static final Long 점수_2점 = 2L; - public static final Long 점수_3점 = 3L; - public static final Long 점수_4점 = 4L; - public static final Long 점수_5점 = 5L; -} diff --git a/backend/src/test/java/com/funeat/fixture/TagFixture.java b/backend/src/test/java/com/funeat/fixture/TagFixture.java deleted file mode 100644 index 2aa4da188..000000000 --- a/backend/src/test/java/com/funeat/fixture/TagFixture.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.funeat.fixture; - -import static com.funeat.tag.domain.TagType.ETC; -import static com.funeat.tag.domain.TagType.QUANTITY; -import static com.funeat.tag.domain.TagType.TASTE; - -import com.funeat.tag.domain.Tag; - -@SuppressWarnings("NonAsciiCharacters") -public class TagFixture { - - public static Tag νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성() { - return new Tag("λ§›μžˆμ–΄μš”", TASTE); - } - - public static Tag νƒœκ·Έ_단짠단짠_TASTE_생성() { - return new Tag("단짠딴짠", TASTE); - } - - public static Tag νƒœκ·Έ_κ°“μ„±λΉ„_PRICE_생성() { - return new Tag("κ°“μ„±λΉ„", QUANTITY); - } - - public static Tag νƒœκ·Έ_ν‘Έμ§ν•΄μš”_PRICE_생성() { - return new Tag("ν‘Έμ§ν•΄μš”", QUANTITY); - } - - public static Tag νƒœκ·Έ_간식_ETC_생성() { - return new Tag("간식", ETC); - } - - public static Tag νƒœκ·Έ_아침식사_ETC_생성() { - return new Tag("아침식사", ETC); - } -} diff --git a/backend/src/test/java/com/funeat/member/application/MemberServiceTest.java b/backend/src/test/java/com/funeat/member/application/MemberServiceTest.java deleted file mode 100644 index e67eb942d..000000000 --- a/backend/src/test/java/com/funeat/member/application/MemberServiceTest.java +++ /dev/null @@ -1,309 +0,0 @@ -package com.funeat.member.application; - -import static com.funeat.fixture.ImageFixture.이미지_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.auth.dto.UserInfoDto; -import com.funeat.common.ServiceTest; -import com.funeat.member.dto.MemberProfileResponse; -import com.funeat.member.dto.MemberRequest; -import com.funeat.member.exception.MemberException.MemberNotFoundException; -import com.funeat.member.exception.MemberException.MemberUpdateException; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.mock.web.MockMultipartFile; - -@SuppressWarnings("NonAsciiCharacters") -class MemberServiceTest extends ServiceTest { - - @Nested - class findOrCreateMember_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 이미_κ°€μž…λœ_μ‚¬μš©μžλ©΄_κ°€μž…ν•˜μ§€_μ•Šκ³ _λ°˜ν™˜ν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var userInfoDto = new UserInfoDto(1L, "test", "www.test.com"); - - final var expected = memberRepository.findAll(); - - // when - final var actual = memberService.findOrCreateMember(userInfoDto); - - // then - assertSoftly(soft -> { - soft.assertThat(actual.isSignUp()) - .isFalse(); - soft.assertThat(expected) - .containsExactly(actual.getMember()); - }); - } - - @Test - void κ°€μž…λ˜μ§€_μ•Šμ€_μ‚¬μš©μžλ©΄_κ°€μž…ν•˜κ³ _λ°˜ν™˜ν•˜λ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var userInfoDto = new UserInfoDto(2L, "test", "www.test.com"); - - final var expected = memberRepository.findAll(); - - // when - final var actual = memberService.findOrCreateMember(userInfoDto); - - // then - assertSoftly(soft -> { - soft.assertThat(actual.isSignUp()) - .isTrue(); - soft.assertThat(expected) - .doesNotContain(actual.getMember()); - }); - } - } - - @Nested - class findOrCreateMember_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void platformIdκ°€_null이면_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var userInfoDto = new UserInfoDto(null, "test", "www.test.com"); - - // when & then - assertThatThrownBy(() -> memberService.findOrCreateMember(userInfoDto)) - .isInstanceOf(NullPointerException.class); - } - } - - @Nested - class getMemberProfile_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μž_정보λ₯Ό_ν™•μΈν•˜λ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var expected = MemberProfileResponse.toResponse(member); - - // when - final var actual = memberService.getMemberProfile(memberId); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class getMemberProfile_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μ‚¬μš©μž_정보λ₯Ό_μ‘°νšŒν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var wrongMemberId = 단일_멀버_μ €μž₯(member) + 1L; - - // when & then - assertThatThrownBy(() -> memberService.getMemberProfile(wrongMemberId)) - .isInstanceOf(MemberNotFoundException.class); - } - } - - @Nested - class modify_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ‹‰λ„€μž„κ³Ό_ν”„λ‘œν•„_사진이_κ·ΈλŒ€λ‘œλ©΄_μ‚¬μš©μž_μ •λ³΄λŠ”_λ°”λ€Œμ§€_μ•ŠλŠ”λ‹€() { - // given - final var nickname = "member1"; - final var image = new MockMultipartFile("image", "www.member1.com", "image/jpeg", new byte[]{1, 2, 3}); - final var request = new MemberRequest(nickname); - - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var expected = memberRepository.findById(memberId).get(); - final var expectedNickname = expected.getNickname(); - final var expectedProfileImage = expected.getProfileImage(); - - // when - memberService.modify(memberId, image, request); - final var actual = memberRepository.findById(memberId).get(); - final var actualNickname = actual.getNickname(); - final var actualProfileImage = actual.getProfileImage(); - - // then - assertSoftly(soft -> { - soft.assertThat(actualNickname) - .isEqualTo(expectedNickname); - soft.assertThat(actualProfileImage) - .isEqualTo(expectedProfileImage); - }); - } - - @Test - void λ‹‰λ„€μž„λ§Œ_λ°”λ€Œκ³ _ν”„λ‘œν•„_사진은_κ·ΈλŒ€λ‘œλ©΄_λ‹‰λ„€μž„λ§Œ_바뀐닀() { - // given - final var profileImage = new MockMultipartFile("image", "www.member1.com", "image/jpeg", - new byte[]{1, 2, 3}); - final var afterNickname = "after"; - final var request = new MemberRequest(afterNickname); - - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var expected = memberRepository.findById(memberId).get(); - final var expectedNickname = expected.getNickname(); - final var expectedProfileImage = expected.getProfileImage(); - - // when - memberService.modify(memberId, profileImage, request); - final var actual = memberRepository.findById(memberId).get(); - final var actualNickname = actual.getNickname(); - final var actualProfileImage = actual.getProfileImage(); - - // then - assertSoftly(soft -> { - soft.assertThat(actualNickname) - .isNotEqualTo(expectedNickname); - soft.assertThat(actualProfileImage) - .isEqualTo(expectedProfileImage); - }); - } - - @Test - void λ‹‰λ„€μž„μ€_κ·ΈλŒ€λ‘œμ΄κ³ _ν”„λ‘œν•„_사진이_λ°”λ€Œλ©΄_ν”„λ‘œν•„_μ‚¬μ§„λ§Œ_바뀐닀() { - // given - final var nickname = "member1"; - final var afterProfileImage = 이미지_생성(); - final var request = new MemberRequest(nickname); - - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var expected = memberRepository.findById(memberId).get(); - final var expectedNickname = expected.getNickname(); - final var expectedProfileImage = expected.getProfileImage(); - - // when - memberService.modify(memberId, afterProfileImage, request); - final var actual = memberRepository.findById(memberId).get(); - final var actualNickname = actual.getNickname(); - final var actualProfileImage = actual.getProfileImage(); - - // then - assertSoftly(soft -> { - soft.assertThat(actualNickname) - .isEqualTo(expectedNickname); - soft.assertThat(actualProfileImage) - .isNotEqualTo(expectedProfileImage); - }); - } - - @Test - void λ‹‰λ„€μž„κ³Ό_ν”„λ‘œν•„_사진_λͺ¨λ‘_λ°”λ€Œλ©΄_λͺ¨λ‘_바뀐닀() { - // given - final var afterNickname = "after"; - final var afterProfileImage = 이미지_생성(); - - final var request = new MemberRequest(afterNickname); - - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var expected = memberRepository.findById(memberId).get(); - final var expectedNickname = expected.getNickname(); - final var expectedProfileImage = expected.getProfileImage(); - - // when - memberService.modify(memberId, afterProfileImage, request); - final var actual = memberRepository.findById(memberId).get(); - final var actualNickname = actual.getNickname(); - final var actualProfileImage = actual.getProfileImage(); - - // then - assertSoftly(soft -> { - soft.assertThat(actualNickname) - .isNotEqualTo(expectedNickname); - soft.assertThat(actualProfileImage) - .isNotEqualTo(expectedProfileImage); - }); - } - } - - @Nested - class modify_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€μ•ŠλŠ”_멀버λ₯Ό_μˆ˜μ •ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var afterNickname = "after"; - final var afterProfileImage = 이미지_생성(); - - final var member = 멀버_멀버1_생성(); - final var wrongMemberId = 단일_멀버_μ €μž₯(member) + 1L; - - final var request = new MemberRequest(afterNickname); - - // when - assertThatThrownBy(() -> memberService.modify(wrongMemberId, afterProfileImage, request)) - .isInstanceOf(MemberNotFoundException.class); - } - - @Test - void λ‹‰λ„€μž„_μˆ˜μ •_μš”μ²­_값을_null둜_μ„€μ •ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var request = new MemberRequest(null); - final var image = 이미지_생성(); - - // when & then - assertThatThrownBy(() -> memberService.modify(memberId, image, request)) - .isInstanceOf(MemberUpdateException.class); - } - } - - @Nested - class findPlatformId_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μžμ˜_OAUTH_νšŒμ›λ²ˆν˜Έλ₯Ό_ν™•μΈν•˜λ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var expected = member.getPlatformId(); - - // when - final String actual = memberService.findPlatformId(memberId); - - // then - assertThat(actual).isEqualTo(expected); - } - - } - - @Nested - class findPlatformId_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μ‚¬μš©μžμ˜_OAUTH_νšŒμ›λ²ˆν˜Έλ₯Ό_ν™•μΈν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var wrongMemberId = 단일_멀버_μ €μž₯(member) + 1L; - - // when & then - assertThatThrownBy(() -> memberService.findPlatformId(wrongMemberId)) - .isInstanceOf(MemberNotFoundException.class); - } - } -} diff --git a/backend/src/test/java/com/funeat/member/application/TestMemberService.java b/backend/src/test/java/com/funeat/member/application/TestMemberService.java deleted file mode 100644 index f0bb441b5..000000000 --- a/backend/src/test/java/com/funeat/member/application/TestMemberService.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.funeat.member.application; - -import com.funeat.auth.dto.SignUserDto; -import com.funeat.auth.dto.UserInfoDto; -import com.funeat.common.ImageUploader; -import com.funeat.member.persistence.MemberRepository; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class TestMemberService extends MemberService { - - public TestMemberService(final MemberRepository memberRepository, final ImageUploader imageUploader) { - super(memberRepository, imageUploader); - } - - @Override - @Transactional - public SignUserDto findOrCreateMember(final UserInfoDto userInfoDto) { - return super.findOrCreateMember(userInfoDto); - } -} diff --git a/backend/src/test/java/com/funeat/member/domain/MemberTest.java b/backend/src/test/java/com/funeat/member/domain/MemberTest.java deleted file mode 100644 index 25bbda6dc..000000000 --- a/backend/src/test/java/com/funeat/member/domain/MemberTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.funeat.member.domain; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.member.exception.MemberException.MemberUpdateException; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(ReplaceUnderscores.class) -public class MemberTest { - - @Nested - class modifyProfile_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μžμ˜_λ‹‰λ„€μž„κ³Ό_이미지_μ£Όμ†Œλ₯Ό_λ³€κ²½ν• _수_μžˆλ‹€() { - // given - final var member = new Member("before", "http://www.before.com", "1"); - - final var expectedNickname = "after"; - final var expectedProfileImage = "http://www.after.com"; - - // when - member.modifyProfile(expectedNickname, expectedProfileImage); - final var actualNickname = member.getNickname(); - final var actualProfileImage = member.getProfileImage(); - - // then - assertSoftly(soft -> { - soft.assertThat(actualNickname) - .isEqualTo(expectedNickname); - soft.assertThat(actualProfileImage) - .isEqualTo(expectedProfileImage); - }); - } - } - - @Nested - class modifyProfile_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μžμ˜_λ‹‰λ„€μž„_λ³€κ²½_값이_null이면_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = new Member("test", "http://www.before.com", "1"); - - final var expectedProfileImage = "http://www.after.com"; - - // when & then - assertThatThrownBy(() -> member.modifyProfile(null, expectedProfileImage)) - .isInstanceOf(MemberUpdateException.class); - } - - @Test - void μ‚¬μš©μžμ˜_ν”„λ‘œν•„_이미지_λ³€κ²½_값이_null이면_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = new Member("test", "http://www.before.com", "1"); - - final var expectedNickname = "after"; - - // when & then - assertThatThrownBy(() -> member.modifyProfile(expectedNickname, null)) - .isInstanceOf(MemberUpdateException.class); - } - } -} diff --git a/backend/src/test/java/com/funeat/member/domain/favorite/RecipeFavoriteTest.java b/backend/src/test/java/com/funeat/member/domain/favorite/RecipeFavoriteTest.java deleted file mode 100644 index 4b2cc940b..000000000 --- a/backend/src/test/java/com/funeat/member/domain/favorite/RecipeFavoriteTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.funeat.member.domain.favorite; - -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -class RecipeFavoriteTest { - - @Nested - class updateFavorite_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void κΈ°μ‘΄_false_μ‹ κ·œ_true_경우_recipe의_favoriteCountλŠ”_1_증가() { - // given - final var member = 멀버_멀버1_생성(); - final var recipe = λ ˆμ‹œν”Ό_생성(member); - final var recipeFavorite = RecipeFavorite.create(member, recipe, false); - - // when - recipeFavorite.updateFavorite(true); - - // then - assertSoftly(soft -> { - soft.assertThat(recipeFavorite.getRecipe().getFavoriteCount()) - .isOne(); - soft.assertThat(recipeFavorite.getFavorite()) - .isTrue(); - }); - } - - @Test - void κΈ°μ‘΄_true_μ‹ κ·œ_false_경우_recipe의_favoriteCountλŠ”_1_κ°μ†Œ() { - // given - final var member = 멀버_멀버1_생성(); - final var recipe = λ ˆμ‹œν”Ό_생성(member); - - final var recipeFavorite = RecipeFavorite.create(member, recipe, true); - - // when - recipeFavorite.updateFavorite(false); - - // then - assertSoftly(soft -> { - soft.assertThat(recipeFavorite.getRecipe().getFavoriteCount()) - .isZero(); - soft.assertThat(recipeFavorite.getFavorite()) - .isFalse(); - }); - } - - @Test - void κΈ°μ‘΄_true_μ‹ κ·œ_true_경우_recipe의_favoriteCountλŠ”_μœ μ§€() { - // given - final var member = 멀버_멀버1_생성(); - final var recipe = λ ˆμ‹œν”Ό_생성(member); - - final var recipeFavorite = RecipeFavorite.create(member, recipe, true); - - // when - recipeFavorite.updateFavorite(true); - - // then - assertSoftly(soft -> { - soft.assertThat(recipeFavorite.getRecipe().getFavoriteCount()) - .isOne(); - soft.assertThat(recipeFavorite.getFavorite()) - .isTrue(); - }); - } - - @Test - void κΈ°μ‘΄_false_μ‹ κ·œ_false_경우_recipe의_favoriteCountλŠ”_μœ μ§€() { - // given - final var member = 멀버_멀버1_생성(); - final var recipe = λ ˆμ‹œν”Ό_생성(member); - - final var recipeFavorite = RecipeFavorite.create(member, recipe, false); - - // when - recipeFavorite.updateFavorite(false); - - // then - assertSoftly(soft -> { - soft.assertThat(recipeFavorite.getRecipe().getFavoriteCount()) - .isZero(); - soft.assertThat(recipeFavorite.getFavorite()) - .isFalse(); - }); - } - } -} diff --git a/backend/src/test/java/com/funeat/member/persistence/MemberRepositoryTest.java b/backend/src/test/java/com/funeat/member/persistence/MemberRepositoryTest.java deleted file mode 100644 index 21b890137..000000000 --- a/backend/src/test/java/com/funeat/member/persistence/MemberRepositoryTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.funeat.member.persistence; - -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.funeat.common.RepositoryTest; -import java.util.NoSuchElementException; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -public class MemberRepositoryTest extends RepositoryTest { - - @Nested - class findByPlatformId_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void platformIdλ₯Ό_톡해_멀버λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var platformId = "1"; - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - // when - final var actual = memberRepository.findByPlatformId(platformId).get(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(member); - } - } - - @Nested - class findByPlatformId_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void platform_idκ°€_잘λͺ»λœ_κ°’μœΌλ‘œ_멀버λ₯Ό_μ‘°νšŒν• _λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var wrongPlatformId = "2"; - - // when & then - assertThatThrownBy(() -> memberRepository.findByPlatformId(wrongPlatformId).get()) - .isInstanceOf(NoSuchElementException.class); - } - } -} diff --git a/backend/src/test/java/com/funeat/member/persistence/RecipeFavoriteRepositoryTest.java b/backend/src/test/java/com/funeat/member/persistence/RecipeFavoriteRepositoryTest.java deleted file mode 100644 index 1d87dd531..000000000 --- a/backend/src/test/java/com/funeat/member/persistence/RecipeFavoriteRepositoryTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.funeat.member.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버3_생성; -import static com.funeat.fixture.ProductFixture.λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격3000원_평점2점_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_μ’‹μ•„μš”_생성; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.common.DataCleaner; -import com.funeat.common.DataClearExtension; -import com.funeat.common.RepositoryTest; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.context.annotation.Import; - -@DataJpaTest -@Import(DataCleaner.class) -@ExtendWith(DataClearExtension.class) -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(ReplaceUnderscores.class) -class RecipeFavoriteRepositoryTest extends RepositoryTest { - - @Nested - class findByMemberAndRecipe_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void ν•΄λ‹Ή_μ‚¬μš©μžμ˜_ν•΄λ‹Ή_λ ˆμ‹œν”Όμ—_λŒ€ν•œ_μ’‹μ•„μš”_ν˜„ν™©μ„_λ°˜ν™˜ν• _수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점2점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipeAuthor = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(recipeAuthor); - - final var recipe = λ ˆμ‹œν”Ό_생성(recipeAuthor); - 단일_λ ˆμ‹œν”Ό_μ €μž₯(recipe); - - final var productRecipe1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe); - final var productRecipe2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe); - final var productRecipe3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe); - 볡수_λ ˆμ‹œν”Ό_μƒν’ˆ_μ €μž₯(productRecipe1, productRecipe2, productRecipe3); - - final var realMember = 멀버_멀버2_생성(); - final var fakeMember = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(realMember, fakeMember); - - final var recipeFavorite = λ ˆμ‹œν”Ό_μ’‹μ•„μš”_생성(realMember, recipe, true); - λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μ €μž₯(recipeFavorite); - - // when - final var realMemberActual = recipeFavoriteRepository.findByMemberAndRecipe(realMember, recipe); - final var fakeMemberActual = recipeFavoriteRepository.findByMemberAndRecipe(fakeMember, recipe); - - // then - assertSoftly(soft -> { - soft.assertThat(realMemberActual) - .isNotEmpty(); - soft.assertThat(fakeMemberActual) - .isEmpty(); - }); - } - } - - @Nested - class existsByMemberAndRecipeAndFavoriteTrue_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void ν•΄λ‹Ή_μ‚¬μš©μžκ°€_ν•΄λ‹Ή_λ ˆμ‹œν”Όμ—_μ’‹μ•„μš”λ₯Ό_λˆŒλ €λŠ”μ§€_μ•Œ_수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점2점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipeAuthor = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(recipeAuthor); - - final var recipe = λ ˆμ‹œν”Ό_생성(recipeAuthor); - 단일_λ ˆμ‹œν”Ό_μ €μž₯(recipe); - - final var productRecipe1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe); - final var productRecipe2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe); - final var productRecipe3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe); - 볡수_λ ˆμ‹œν”Ό_μƒν’ˆ_μ €μž₯(productRecipe1, productRecipe2, productRecipe3); - - final var realMember = 멀버_멀버2_생성(); - final var fakeMember = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(realMember, fakeMember); - - final var recipeFavorite = λ ˆμ‹œν”Ό_μ’‹μ•„μš”_생성(realMember, recipe, true); - λ ˆμ‹œν”Ό_μ’‹μ•„μš”_μ €μž₯(recipeFavorite); - - // when - final var realMemberActual = recipeFavoriteRepository.existsByMemberAndRecipeAndFavoriteTrue(realMember, - recipe); - final var fakeMemberActual = recipeFavoriteRepository.existsByMemberAndRecipeAndFavoriteTrue(fakeMember, - recipe); - - // then - assertSoftly(soft -> { - soft.assertThat(realMemberActual) - .isTrue(); - soft.assertThat(fakeMemberActual) - .isFalse(); - }); - } - } -} diff --git a/backend/src/test/java/com/funeat/member/persistence/ReviewFavoriteRepositoryTest.java b/backend/src/test/java/com/funeat/member/persistence/ReviewFavoriteRepositoryTest.java deleted file mode 100644 index fcb190d28..000000000 --- a/backend/src/test/java/com/funeat/member/persistence/ReviewFavoriteRepositoryTest.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.funeat.member.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버3_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test4_평점4점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test5_평점5점_재ꡬ맀O_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.funeat.common.RepositoryTest; -import com.funeat.member.domain.favorite.ReviewFavorite; -import java.util.List; -import java.util.NoSuchElementException; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class ReviewFavoriteRepositoryTest extends RepositoryTest { - - @Nested - class findByMemberAndReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 멀버와_리뷰둜_리뷰_μ’‹μ•„μš”λ₯Ό_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 0L); - 단일_리뷰_μ €μž₯(review); - - final var reviewFavorite = ReviewFavorite.create(member, review, true); - 단일_리뷰_μ’‹μ•„μš”_μ €μž₯(reviewFavorite); - - final var expected = ReviewFavorite.create(member, review, true); - - // when - final var actual = reviewFavoriteRepository.findByMemberAndReview(member, review).get(); - - // then - assertThat(actual).usingRecursiveComparison() - .ignoringExpectedNullFields() - .isEqualTo(expected); - } - } - - @Nested - class findByMemberAndReview_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void 잘λͺ»λœ_λ©€λ²„λ‘œ_μ’‹μ•„μš”λ₯Ό_μ‘°νšŒν•˜λ©΄_μ—λŸ¬κ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 0L); - 단일_리뷰_μ €μž₯(review); - - final var wrongMember = 멀버_멀버2_생성(); - 단일_멀버_μ €μž₯(wrongMember); - - // when & then - assertThatThrownBy(() -> reviewFavoriteRepository.findByMemberAndReview(wrongMember, review).get()) - .isInstanceOf(NoSuchElementException.class); - } - - @Test - void 잘λͺ»λœ_리뷰둜_μ’‹μ•„μš”λ₯Ό_μ‘°νšŒν•˜λ©΄_μ—λŸ¬κ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var anotherMember = 멀버_멀버2_생성(); - 단일_멀버_μ €μž₯(anotherMember); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 0L); - 단일_리뷰_μ €μž₯(review); - - final var reviewFavorite = ReviewFavorite.create(member, review, true); - 단일_리뷰_μ’‹μ•„μš”_μ €μž₯(reviewFavorite); - - final var wrongReview = 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(member, product, 0L); - 단일_리뷰_μ €μž₯(wrongReview); - - // when & then - assertThatThrownBy(() -> reviewFavoriteRepository.findByMemberAndReview(member, wrongReview).get()) - .isInstanceOf(NoSuchElementException.class); - } - } - - @Nested - class deleteByReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void ν•΄λ‹Ή_리뷰에_달린_μ’‹μ•„μš”λ₯Ό_μ‚­μ œν• _수_μžˆλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member1, product, 0L); - final var review2 = 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(member1, product, 0L); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var reviewFavorite1_1 = ReviewFavorite.create(member1, review1, true); - final var reviewFavorite1_2 = ReviewFavorite.create(member2, review1, true); - final var reviewFavorite1_3 = ReviewFavorite.create(member3, review1, true); - final var reviewFavorite2_1 = ReviewFavorite.create(member1, review2, true); - final var reviewFavorite2_2 = ReviewFavorite.create(member2, review2, true); - 볡수_리뷰_μ’‹μ•„μš”_μ €μž₯(reviewFavorite1_1, reviewFavorite1_2, reviewFavorite1_3, reviewFavorite2_1, reviewFavorite2_2); - - final var expected = List.of(reviewFavorite2_1, reviewFavorite2_2); - - // when - reviewFavoriteRepository.deleteByReview(review1); - - // then - final var remainings = reviewFavoriteRepository.findAll(); - assertThat(remainings).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class findByReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰둜_ν•΄λ‹Ή_리뷰에_달린_μ’‹μ•„μš”λ₯Ό_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 0L); - 단일_리뷰_μ €μž₯(review); - - final var reviewFavorite = ReviewFavorite.create(member, review, true); - 단일_리뷰_μ’‹μ•„μš”_μ €μž₯(reviewFavorite); - - final var expected = List.of(reviewFavorite); - - // when - final var actual = reviewFavoriteRepository.findByReview(review); - - // then - assertThat(actual).usingRecursiveComparison() - .ignoringExpectedNullFields() - .isEqualTo(expected); - } - } -} diff --git a/backend/src/test/java/com/funeat/product/application/ProductServiceTest.java b/backend/src/test/java/com/funeat/product/application/ProductServiceTest.java deleted file mode 100644 index 9f5b88c5b..000000000 --- a/backend/src/test/java/com/funeat/product/application/ProductServiceTest.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.funeat.product.application; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버3_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격4000원_평점4점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test1_평점1점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test2_평점2점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test3_평점3점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test3_평점3점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test4_평점4점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test4_평점4점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test5_평점5점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test5_평점5점_재ꡬ맀X_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.ServiceTest; -import com.funeat.product.dto.RankingProductDto; -import com.funeat.product.dto.RankingProductsResponse; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class ProductServiceTest extends ServiceTest { - - @Nested - class getTop3Products_성곡_ν…ŒμŠ€νŠΈ { - - @Nested - class μƒν’ˆ_κ°œμˆ˜μ—_λŒ€ν•œ_ν…ŒμŠ€νŠΈ { - - @Test - void 전체_μƒν’ˆμ΄_ν•˜λ‚˜λ„_없어도_λ°˜ν™˜κ°’μ€_μžˆμ–΄μ•Όν•œλ‹€() { - // given - final var expected = RankingProductsResponse.toResponse(Collections.emptyList()); - - // when - final var actual = productService.getTop3Products(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 전체_μƒν’ˆμ΄_1개_이상_3개_λ―Έλ§Œμ΄λΌλ„_μƒν’ˆμ΄_λ‚˜μ™€μ•Όν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점5점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var review1_1 = 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(member, product1, 0L); - final var review1_2 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product1, 0L); - final var review1_3 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product1, 0L); - final var review1_4 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product1, 0L); - final var review2_1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product2, 0L); - final var review2_2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product2, 0L); - 볡수_리뷰_μ €μž₯(review1_1, review1_2, review1_3, review1_4, review2_1, review2_2); - - final var rankingProductDto1 = RankingProductDto.toDto(product2); - final var rankingProductDto2 = RankingProductDto.toDto(product1); - final var rankingProductDtos = List.of(rankingProductDto1, rankingProductDto2); - final var expected = RankingProductsResponse.toResponse(rankingProductDtos); - - // when - final var actual = productService.getTop3Products(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 전체_μƒν’ˆ_쀑_λž­ν‚Ήμ΄_높은_μƒμœ„_3개_μƒν’ˆμ„_ꡬ할_수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product4 = μƒν’ˆ_삼각김λ°₯_가격4000원_평점4점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3, product4); - - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var review1_1 = 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(member1, product1, 0L); - final var review1_2 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member2, product1, 0L); - final var review1_3 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member3, product1, 0L); - final var review1_4 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member1, product1, 0L); - final var review2_1 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member1, product2, 0L); - final var review2_2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member1, product2, 0L); - final var review3_1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member1, product3, 0L); - final var review4_1 = 리뷰_이미지test4_평점4점_재ꡬ맀X_생성(member1, product4, 0L); - final var review4_2 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member1, product4, 0L); - final var review4_3 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member1, product4, 0L); - 볡수_리뷰_μ €μž₯(review1_1, review1_2, review1_3, review1_4, review2_1, review2_2, review3_1, review4_1, - review4_2, review4_3); - - final var rankingProductDto1 = RankingProductDto.toDto(product3); - final var rankingProductDto2 = RankingProductDto.toDto(product4); - final var rankingProductDto3 = RankingProductDto.toDto(product2); - final var rankingProductDtos = List.of(rankingProductDto1, rankingProductDto2, rankingProductDto3); - final var expected = RankingProductsResponse.toResponse(rankingProductDtos); - - // when - final var actual = productService.getTop3Products(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class μƒν’ˆ_μ μˆ˜μ—_λŒ€ν•œ_ν…ŒμŠ€νŠΈ { - - @Test - void λͺ¨λ“ _μƒν’ˆμ˜_평점이_3점_미만이면_빈_배열을_λ°˜ν™˜ν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2); - - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var review1_1 = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member1, product1, 0L); - final var review1_2 = 리뷰_이미지test2_평점2점_재ꡬ맀O_생성(member2, product1, 0L); - final var review1_3 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member3, product1, 0L); - final var review2_1 = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member1, product2, 0L); - final var review2_2 = 리뷰_이미지test2_평점2점_재ꡬ맀O_생성(member2, product2, 0L); - 볡수_리뷰_μ €μž₯(review1_1, review1_2, review1_3, review2_1, review2_2); - - final var expected = RankingProductsResponse.toResponse(Collections.emptyList()); - - // when - final var actual = productService.getTop3Products(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 일뢀_μƒν’ˆμ΄_평점_3점_이상이면_일뢀_μƒν’ˆλ§Œ_λ°˜ν™˜ν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점4점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2); - - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var review1_1 = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member1, product1, 0L); - final var review1_2 = 리뷰_이미지test2_평점2점_재ꡬ맀O_생성(member2, product1, 0L); - final var review1_3 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member3, product1, 0L); - final var review2_1 = 리뷰_이미지test4_평점4점_재ꡬ맀X_생성(member3, product2, 0L); - final var review2_2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member3, product2, 0L); - 볡수_리뷰_μ €μž₯(review1_1, review1_2, review1_3, review2_1, review2_2); - - final var rankingProductDtos = List.of(RankingProductDto.toDto(product2)); - - final var expected = RankingProductsResponse.toResponse(rankingProductDtos); - - // when - final var actual = productService.getTop3Products(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - } -} diff --git a/backend/src/test/java/com/funeat/product/domain/ProductTest.java b/backend/src/test/java/com/funeat/product/domain/ProductTest.java deleted file mode 100644 index 7e012dd22..000000000 --- a/backend/src/test/java/com/funeat/product/domain/ProductTest.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.funeat.product.domain; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(ReplaceUnderscores.class) -class ProductTest { - - @Nested - class updateAverageRatingForInsert_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 평균_평점을_μ—…λ°μ΄νŠΈ_ν• _수_μžˆλ‹€() { - // given - final var product = new Product("testName", 1000L, "testImage", "testContent", null); - final var reviewCount = 1L; - final var reviewRating = 4L; - - // when - product.updateAverageRatingForInsert(reviewCount, reviewRating); - final var actual = product.getAverageRating(); - - // then - assertThat(actual).isEqualTo(4.0); - } - - @Test - void 평균_평점을_μ—¬λŸ¬λ²ˆ_μ—…λ°μ΄νŠΈ_ν• _수_μžˆλ‹€() { - // given - final var product = new Product("testName", 1000L, "testImage", "testContent", null); - final var reviewCount1 = 1L; - final var reviewCount2 = 2L; - final var reviewRating1 = 4L; - final var reviewRating2 = 2L; - - // when - product.updateAverageRatingForInsert(reviewCount1, reviewRating1); - final var actual1 = product.getAverageRating(); - - product.updateAverageRatingForInsert(reviewCount2, reviewRating2); - final var actual2 = product.getAverageRating(); - - // then - assertSoftly(soft -> { - soft.assertThat(actual1) - .isEqualTo(4.0); - soft.assertThat(actual2) - .isEqualTo(3.0); - }); - } - } - - @Nested - class updateAverageRatingForDelete_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰가_ν•˜λ‚˜μΈ_μƒν’ˆμ˜_리뷰λ₯Ό_μ‚­μ œν•˜λ©΄_평균평점은_0점이_λœλ‹€() { - // given - final var product = new Product("testName", 1000L, "testImage", "testContent", 4.0, null, 1L); - final var reviewRating = 4L; - - // when - product.updateAverageRatingForDelete(reviewRating); - final var actual = product.getAverageRating(); - - // then - assertThat(actual).isEqualTo(0.0); - } - - @Test - void 리뷰가_μ—¬λŸ¬κ°œμΈ_μƒν’ˆμ˜_리뷰λ₯Ό_μ‚­μ œν•˜λ©΄_평균평점이_κ°±μ‹ λœλ‹€() { - // given - final var product = new Product("testName", 1000L, "testImage", "testContent", 4.0, null, 4L); - final var reviewRating = 5L; - - // when - product.updateAverageRatingForDelete(reviewRating); - final var actual = product.getAverageRating(); - - // then - assertThat(actual).isEqualTo(3.7); - } - } - - @Nested - class calculateRankingScore_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 평균_평점과_리뷰_수둜_ν•΄λ‹Ή_μƒν’ˆμ˜_λž­ν‚Ή_점수λ₯Ό_ꡬ할_수_μžˆλ‹€() { - // given - final var product = new Product("testName", 1000L, "testImage", "testContent", 4.0, null); - final var reviewCount = 9L; - - // when - final var rankingScore = product.calculateRankingScore(reviewCount); - - // then - assertThat(rankingScore).isEqualTo(3.5); - } - } - - @Nested - class calculateRankingScore_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰_μˆ˜κ°€_λ§ˆμ΄λ„ˆμŠ€_일둜_λ‚˜μ˜¨λ‹€λ©΄_λ¬΄ν•œλŒ€λ‘œ_λ‚˜μ™€μ„œ_μ˜ˆμ™Έκ°€_λ‚˜μ™€μ•Όν•˜λŠ”λ°_ν†΅κ³Όν•˜κ³ _μžˆλ‹€() { - // given - final var product = new Product("testName", 1000L, "testImage", "testContent", 4.0, null); - final var reviewCount = -1L; - - // when - final var rankingScore = product.calculateRankingScore(reviewCount); - - // then - assertThat(rankingScore).isInfinite(); - } - } -} diff --git a/backend/src/test/java/com/funeat/product/domain/favorite/ReviewFavoriteTest.java b/backend/src/test/java/com/funeat/product/domain/favorite/ReviewFavoriteTest.java deleted file mode 100644 index e38e256d6..000000000 --- a/backend/src/test/java/com/funeat/product/domain/favorite/ReviewFavoriteTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.funeat.product.domain.favorite; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test1_평점1점_재ꡬ맀O_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.member.domain.favorite.ReviewFavorite; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(ReplaceUnderscores.class) -public class ReviewFavoriteTest { - - @Nested - class updateChecked_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ’‹μ•„μš”κ°€_μžˆλŠ”_μƒνƒœμ—μ„œ_μ’‹μ•„μš”_μ·¨μ†Œν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - - final var member = 멀버_멀버1_생성(); - final var review = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 0L); - final var reviewFavorite = ReviewFavorite.create(member, review, true); - - // when - reviewFavorite.updateChecked(false); - final var actual = reviewFavorite.getFavorite(); - - // then - assertThat(actual).isFalse(); - } - - @Test - void μ’‹μ•„μš”κ°€_μ—†λŠ”_μƒνƒœμ—μ„œ_μ’‹μ•„μš”λ₯Ό_μ μš©ν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - - final var member = 멀버_멀버1_생성(); - final var review = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 0L); - final var reviewFavorite = ReviewFavorite.create(member, review, false); - - // when - reviewFavorite.updateChecked(true); - final var actual = reviewFavorite.getFavorite(); - - // then - assertThat(actual).isTrue(); - } - } - - @Nested - class updateChecked_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ’‹μ•„μš”κ°€_μžˆλŠ”_μƒνƒœμ—μ„œ_μ’‹μ•„μš”λ₯Ό_μ μš©ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•΄μ•Όν•˜λŠ”λ°_ν†΅κ³Όν•˜κ³ _μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - - final var member = 멀버_멀버1_생성(); - final var review = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 0L); - final var reviewFavorite = ReviewFavorite.create(member, review, true); - - // when - reviewFavorite.updateChecked(true); - final var actual = reviewFavorite.getFavorite(); - - // then - assertThat(actual).isTrue(); - } - - @Test - void μ’‹μ•„μš”κ°€_μ—†λŠ”_μƒνƒœμ—μ„œ_μ’‹μ•„μš”λ₯Ό_μ·¨μ†Œν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•΄μ•Όν•˜λŠ”λ°_ν†΅κ³Όν•˜κ³ _μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - - final var member = 멀버_멀버1_생성(); - final var review = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 0L); - final var reviewFavorite = ReviewFavorite.create(member, review, false); - - // when - reviewFavorite.updateChecked(false); - final var actual = reviewFavorite.getFavorite(); - - // then - assertThat(actual).isFalse(); - } - } -} diff --git a/backend/src/test/java/com/funeat/product/persistence/CategoryRepositoryTest.java b/backend/src/test/java/com/funeat/product/persistence/CategoryRepositoryTest.java deleted file mode 100644 index 5782fd8c9..000000000 --- a/backend/src/test/java/com/funeat/product/persistence/CategoryRepositoryTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.funeat.product.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_CU_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_EMART24_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_GS25_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_과자λ₯˜_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_μ„ΈλΈμΌλ ˆλΈ_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_μ‹ν’ˆ_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_μ•„μ΄μŠ€ν¬λ¦Ό_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_음료_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.RepositoryTest; -import com.funeat.product.domain.CategoryType; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -public class CategoryRepositoryTest extends RepositoryTest { - - @Nested - class findAllByType_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μΉ΄ν…Œκ³ λ¦¬_νƒ€μž…μ΄_FOOD인_λͺ¨λ“ _μΉ΄ν…Œκ³ λ¦¬λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var κ°„νŽΈμ‹μ‚¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var 즉석쑰리 = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - final var 과자λ₯˜ = μΉ΄ν…Œκ³ λ¦¬_과자λ₯˜_생성(); - final var μ•„μ΄μŠ€ν¬λ¦Ό = μΉ΄ν…Œκ³ λ¦¬_μ•„μ΄μŠ€ν¬λ¦Ό_생성(); - final var μ‹ν’ˆ = μΉ΄ν…Œκ³ λ¦¬_μ‹ν’ˆ_생성(); - final var 음료 = μΉ΄ν…Œκ³ λ¦¬_음료_생성(); - final var CU = μΉ΄ν…Œκ³ λ¦¬_CU_생성(); - final var GS25 = μΉ΄ν…Œκ³ λ¦¬_GS25_생성(); - final var EMART24 = μΉ΄ν…Œκ³ λ¦¬_EMART24_생성(); - final var μ„ΈλΈμΌλ ˆλΈ = μΉ΄ν…Œκ³ λ¦¬_μ„ΈλΈμΌλ ˆλΈ_생성(); - 볡수_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(κ°„νŽΈμ‹μ‚¬, 즉석쑰리, 과자λ₯˜, μ•„μ΄μŠ€ν¬λ¦Ό, μ‹ν’ˆ, 음료, CU, GS25, EMART24, μ„ΈλΈμΌλ ˆλΈ); - - final var expected = List.of(κ°„νŽΈμ‹μ‚¬, 즉석쑰리, 과자λ₯˜, μ•„μ΄μŠ€ν¬λ¦Ό, μ‹ν’ˆ, 음료); - - // when - final var actual = categoryRepository.findAllByType(CategoryType.FOOD); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void μΉ΄ν…Œκ³ λ¦¬_νƒ€μž…μ΄_STORE인_λͺ¨λ“ _μΉ΄ν…Œκ³ λ¦¬λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var κ°„νŽΈμ‹μ‚¬ = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var 즉석쑰리 = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - final var 과자λ₯˜ = μΉ΄ν…Œκ³ λ¦¬_과자λ₯˜_생성(); - final var μ•„μ΄μŠ€ν¬λ¦Ό = μΉ΄ν…Œκ³ λ¦¬_μ•„μ΄μŠ€ν¬λ¦Ό_생성(); - final var μ‹ν’ˆ = μΉ΄ν…Œκ³ λ¦¬_μ‹ν’ˆ_생성(); - final var 음료 = μΉ΄ν…Œκ³ λ¦¬_음료_생성(); - final var CU = μΉ΄ν…Œκ³ λ¦¬_CU_생성(); - final var GS25 = μΉ΄ν…Œκ³ λ¦¬_GS25_생성(); - final var EMART24 = μΉ΄ν…Œκ³ λ¦¬_EMART24_생성(); - final var μ„ΈλΈμΌλ ˆλΈ = μΉ΄ν…Œκ³ λ¦¬_μ„ΈλΈμΌλ ˆλΈ_생성(); - 볡수_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(κ°„νŽΈμ‹μ‚¬, 즉석쑰리, 과자λ₯˜, μ•„μ΄μŠ€ν¬λ¦Ό, μ‹ν’ˆ, 음료, CU, GS25, EMART24, μ„ΈλΈμΌλ ˆλΈ); - - final var expected = List.of(CU, GS25, EMART24, μ„ΈλΈμΌλ ˆλΈ); - - // when - final var actual = categoryRepository.findAllByType(CategoryType.STORE); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } -} diff --git a/backend/src/test/java/com/funeat/product/persistence/ProductRecipeRepositoryTest.java b/backend/src/test/java/com/funeat/product/persistence/ProductRecipeRepositoryTest.java deleted file mode 100644 index 612edad15..000000000 --- a/backend/src/test/java/com/funeat/product/persistence/ProductRecipeRepositoryTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.funeat.product.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.ProductFixture.λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.RepositoryTest; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -class ProductRecipeRepositoryTest extends RepositoryTest { - - @Nested - class findProductByRecipe_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ ˆμ‹œν”Όμ—_μ‚¬μš©λœ_μƒν’ˆλ“€μ„_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var recipe = λ ˆμ‹œν”Ό_생성(member, 1L); - 단일_κΏ€μ‘°ν•©_μ €μž₯(recipe); - - final var product_recipe_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe); - final var product_recipe_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1, product_recipe_2); - - final var expected = List.of(product1, product2); - - // when - final var actual = productRecipeRepository.findProductByRecipe(recipe); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } -} diff --git a/backend/src/test/java/com/funeat/product/persistence/ProductRepositoryTest.java b/backend/src/test/java/com/funeat/product/persistence/ProductRepositoryTest.java deleted file mode 100644 index 107585475..000000000 --- a/backend/src/test/java/com/funeat/product/persistence/ProductRepositoryTest.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.funeat.product.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버3_생성; -import static com.funeat.fixture.PageFixture.νŽ˜μ΄μ§€μš”μ²­_κΈ°λ³Έ_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격3000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격4000원_평점2점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test1_평점1점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test3_평점3점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test5_평점5점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test5_평점5점_재ꡬ맀X_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.RepositoryTest; -import com.funeat.product.dto.ProductReviewCountDto; -import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class ProductRepositoryTest extends RepositoryTest { - - @Nested - class findAllByAverageRatingGreaterThan3_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 평점이_3보닀_큰_λͺ¨λ“ _μƒν’ˆλ“€κ³Ό_리뷰_수λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점5점_생성(category); - final var product4 = μƒν’ˆ_삼각김λ°₯_가격4000원_평점2점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3, product4); - - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var review1_1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member1, product1, 0L, LocalDateTime.now().minusDays(2L)); - final var review1_2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member2, product1, 0L, LocalDateTime.now().minusDays(3L)); - final var review2_1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member3, product2, 0L, LocalDateTime.now().minusDays(10L)); - final var review2_2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member1, product2, 0L, LocalDateTime.now().minusDays(1L)); - final var review2_3 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member2, product2, 0L, LocalDateTime.now().minusDays(9L)); - final var review3_1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member1, product3, 0L, LocalDateTime.now().minusDays(8L)); - 볡수_리뷰_μ €μž₯(review1_1, review1_2, review2_1, review2_2, review2_3, review3_1); - - final var productReviewCountDto1 = new ProductReviewCountDto(product2, 3L); - final var productReviewCountDto2 = new ProductReviewCountDto(product3, 1L); - final var expected = List.of(productReviewCountDto1, productReviewCountDto2); - - // when - final var startDateTime = LocalDateTime.now().minusWeeks(2L); - final var endDateTime = LocalDateTime.now(); - final var actual = productRepository.findAllByAverageRatingGreaterThan3(startDateTime, endDateTime); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void κΈ°κ°„_μ•ˆμ—_리뷰가_μ‘΄μž¬ν•˜λŠ”_μƒν’ˆμ΄_μ—†μœΌλ©΄_빈_리슀트λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점4점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2); - - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - 볡수_멀버_μ €μž₯(member1, member2); - - final var review1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member1, product1, 0L, LocalDateTime.now().minusDays(15L)); - final var review2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member2, product2, 0L, LocalDateTime.now().minusWeeks(3L)); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var expected = Collections.emptyList(); - - // when - final var startDateTime = LocalDateTime.now().minusWeeks(2L); - final var endDateTime = LocalDateTime.now(); - final var actual = productRepository.findAllByAverageRatingGreaterThan3(startDateTime, endDateTime); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class findAllByNameContaining_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μƒν’ˆλͺ…에_검색어가_ν¬ν•¨λœ_μƒν’ˆλ“€μ„_μ‘°νšŒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2); - - final var page = νŽ˜μ΄μ§€μš”μ²­_κΈ°λ³Έ_생성(0, 10); - - final var expected = List.of(product2, product1); - - // when - final var actual = productRepository.findAllByNameContaining("망고", page).getContent(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class findAllWithReviewCountByNameContaining_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μƒν’ˆλͺ…에_검색어가_ν¬ν•¨λœ_μƒν’ˆλ“€κ³Ό_리뷰_수λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2); - - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - 볡수_멀버_μ €μž₯(member1, member2); - - final var review1_1 = 리뷰_이미지test1_평점1점_재ꡬ맀X_생성(member1, product1, 0L); - final var review1_2 = 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(member2, product1, 0L); - final var review2_1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member1, product2, 0L); - 볡수_리뷰_μ €μž₯(review1_1, review1_2, review2_1); - - final var page = νŽ˜μ΄μ§€μš”μ²­_κΈ°λ³Έ_생성(0, 10); - - final var expectedDto1 = new ProductReviewCountDto(product1, 2L); - final var expectedDto2 = new ProductReviewCountDto(product2, 1L); - final var expected = List.of(expectedDto2, expectedDto1); - - // when - final var actual = productRepository.findAllWithReviewCountByNameContaining("망고", page).getContent(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } -} diff --git a/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java b/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java deleted file mode 100644 index 81badf4f6..000000000 --- a/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java +++ /dev/null @@ -1,913 +0,0 @@ -package com.funeat.recipe.application; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.ImageFixture.μ—¬λŸ¬_이미지_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버3_생성; -import static com.funeat.fixture.PageFixture.과거순; -import static com.funeat.fixture.PageFixture.μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.μ΅œμ‹ μˆœ; -import static com.funeat.fixture.PageFixture.νŽ˜μ΄μ§€μš”μ²­_생성; -import static com.funeat.fixture.ProductFixture.λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.comment.domain.Comment; -import com.funeat.common.ServiceTest; -import com.funeat.common.dto.PageDto; -import com.funeat.member.domain.Member; -import com.funeat.member.dto.MemberRecipeDto; -import com.funeat.member.dto.MemberRecipeProductDto; -import com.funeat.member.dto.MemberRecipesResponse; -import com.funeat.member.exception.MemberException.MemberNotFoundException; -import com.funeat.product.domain.Category; -import com.funeat.product.domain.CategoryType; -import com.funeat.product.domain.Product; -import com.funeat.product.exception.ProductException.ProductNotFoundException; -import com.funeat.recipe.dto.RankingRecipeDto; -import com.funeat.recipe.dto.RankingRecipesResponse; -import com.funeat.recipe.dto.RecipeAuthorDto; -import com.funeat.recipe.dto.RecipeCommentCondition; -import com.funeat.recipe.dto.RecipeCommentCreateRequest; -import com.funeat.recipe.dto.RecipeCommentResponse; -import com.funeat.recipe.dto.RecipeCreateRequest; -import com.funeat.recipe.dto.RecipeDetailResponse; -import com.funeat.recipe.dto.RecipeDto; -import com.funeat.recipe.exception.RecipeException.RecipeNotFoundException; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class RecipeServiceTest extends ServiceTest { - - @Nested - class create_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ ˆμ‹œν”Όλ₯Ό_μΆ”κ°€ν• _수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var productIds = μƒν’ˆ_아이디_λ³€ν™˜(product1, product2, product3); - - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - // when - final var request = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(productIds); - - final var expected = λ ˆμ‹œν”Ό_생성(member); - - // when - final var recipeId = recipeService.create(memberId, images, request); - final var actual = recipeRepository.findById(recipeId).get(); - - // then - assertThat(actual).usingRecursiveComparison() - .ignoringFields("id", "createdAt") - .isEqualTo(expected); - assertThat(actual.getCreatedAt()).isNotNull(); - } - } - - @Test - void λ ˆμ‹œν”Όμ˜_상세_정보λ₯Ό_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_μΆ”κ°€_μš”μ²­(new Category("κ°„νŽΈμ‹μ‚¬", CategoryType.FOOD, "siksa.jpeg")); - final var product1 = new Product("λΆˆλ‹­λ³ΆμŒλ©΄", 1000L, "image.png", "μ—„μ²­ 맀운 λΆˆλ‹­", category); - final var product2 = new Product("참치 μ‚ΌκΉ€", 2000L, "image.png", "λ‹΄λ°±ν•œ μ°ΈμΉ˜λ§ˆμš” μ‚ΌκΉ€", category); - final var product3 = new Product("슀트링 치즈", 1500L, "image.png", "κ³ μ†Œν•œ 치즈", category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var products = List.of(product1, product2, product3); - final var author = new Member("author", "image.png", "1"); - 단일_멀버_μ €μž₯(author); - final var authorId = author.getId(); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var productIds = List.of(product1.getId(), product2.getId(), product3.getId()); - final var request = new RecipeCreateRequest("제일둜 λ§›μžˆλŠ” λ ˆμ‹œν”Ό", productIds, - "μš°μ„  λ°₯을 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μœΌλ©΄.. 끝!!"); - - final var recipeId = recipeService.create(authorId, images, request); - - // when - final var actual = recipeService.getRecipeDetail(authorId, recipeId); - - // then - final var recipe = recipeRepository.findById(recipeId).get(); - final var expected = RecipeDetailResponse.toResponse( - recipe, recipeImageRepository.findByRecipe(recipe), - products, 4500L, false); - - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Nested - class create_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_멀버가_λ ˆμ‹œν”Όλ₯Ό_μΆ”κ°€ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var productIds = μƒν’ˆ_아이디_λ³€ν™˜(product1, product2, product3); - - final var member = 멀버_멀버1_생성(); - final var wrongMemberId = 단일_멀버_μ €μž₯(member) + 1L; - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var request = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(productIds); - - // when & then - assertThatThrownBy(() -> recipeService.create(wrongMemberId, images, request)) - .isInstanceOf(MemberNotFoundException.class); - } - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆμ„_λ ˆμ‹œν”Όμ—_μΆ”κ°€ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var wrongProductIds = μƒν’ˆ_아이디_λ³€ν™˜(product1, product2, product3); - wrongProductIds.add(4L); - - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var request = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(wrongProductIds); - - // when & then - assertThatThrownBy(() -> recipeService.create(memberId, images, request)) - .isInstanceOf(ProductNotFoundException.class); - } - } - - @Nested - class findRecipeByMember_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_꿀쑰합을_μ‘°νšŒν•œλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - 볡수_멀버_μ €μž₯(member1); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipe1_1 = λ ˆμ‹œν”Ό_생성(member1); - final var recipe1_2 = λ ˆμ‹œν”Ό_생성(member1); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1_1, recipe1_2); - - final var product_recipe_1_1_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_1); - final var product_recipe_1_1_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1_1); - final var product_recipe_1_1_3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_1); - final var product_recipe_1_2_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_2); - final var product_recipe_1_2_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_2); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1_1_1, product_recipe_1_1_2, product_recipe_1_1_3, product_recipe_1_2_1, - product_recipe_1_2_2); - - final var recipeImage1_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_1); - final var recipeImage1_2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(recipeImage1_1, recipeImage1_2); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ΅œμ‹ μˆœ); - - // when - final var actual = recipeService.findRecipeByMember(member1.getId(), page); - - // then - final var expectedRecipes = List.of(recipe1_2, recipe1_1); - final var expectedRecipesDtos = expectedRecipes.stream() - .map(recipe -> { - final var findRecipeImages = recipeImageRepository.findByRecipe(recipe); - final var productsByRecipe = productRecipeRepository.findProductByRecipe(recipe); - final var memberRecipeProductDtos = productsByRecipe.stream() - .map(MemberRecipeProductDto::toDto) - .collect(Collectors.toList()); - return MemberRecipeDto.toDto(recipe, findRecipeImages, memberRecipeProductDtos); - }) - .collect(Collectors.toList()); - final var expectedPage = new PageDto(2L, 1L, true, true, 0L, 10L); - - ν•΄λ‹Ήλ©€λ²„μ˜_κΏ€μ‘°ν•©κ³Ό_νŽ˜μ΄μ§•_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(actual, expectedRecipesDtos, expectedPage); - } - - @Test - void μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_꿀쑰합이_μ—†μ„λ•Œ_꿀쑰합은_λΉˆμƒνƒœλ‘œ_μ‘°νšŒλœλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member1); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ΅œμ‹ μˆœ); - - // when - final var actual = recipeService.findRecipeByMember(member1.getId(), page); - - // then - final var expectedRecipes = Collections.emptyList(); - final var expectedPage = new PageDto(0L, 0L, true, true, 0L, 10L); - - ν•΄λ‹Ήλ©€λ²„μ˜_κΏ€μ‘°ν•©κ³Ό_νŽ˜μ΄μ§•_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(actual, expectedRecipes, expectedPage); - } - } - - @Nested - class findRecipeByMember_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_멀버가_ν•΄λ‹Ή_λ©€λ²„μ˜_λ ˆμ‹œν”Όλ₯Ό_μ‘°νšŒν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var notExistMemberId = 99999L; - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ΅œμ‹ μˆœ); - - // when & then - assertThatThrownBy(() -> recipeService.findRecipeByMember(notExistMemberId, page)) - .isInstanceOf(MemberNotFoundException.class); - } - } - - @Nested - class getSortingRecipes_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 꿀쑰합을_μ’‹μ•„μš”κ°€_λ§Žμ€_순으둜_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipe1_1 = λ ˆμ‹œν”Ό_생성(member1, 1L); - final var recipe1_2 = λ ˆμ‹œν”Ό_생성(member1, 3L); - final var recipe1_3 = λ ˆμ‹œν”Ό_생성(member1, 2L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1_1, recipe1_2, recipe1_3); - - final var product_recipe_1_1_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_1); - final var product_recipe_1_1_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1_1); - final var product_recipe_1_1_3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_1); - final var product_recipe_1_2_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_2); - final var product_recipe_1_2_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_2); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1_1_1, product_recipe_1_1_2, product_recipe_1_1_3, product_recipe_1_2_1, - product_recipe_1_2_2); - - final var recipeImage1_1_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_1); - final var recipeImage1_2_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - final var recipeImage1_2_2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(recipeImage1_1_1, recipeImage1_2_1); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ); - - // when - final var actual = recipeService.getSortingRecipes(page).getRecipes(); - final var expected = List.of( - RecipeDto.toDto(recipe1_2, List.of(recipeImage1_2_1, recipeImage1_2_2), - List.of(product1, product3)), - RecipeDto.toDto(recipe1_3, List.of(), List.of()), - RecipeDto.toDto(recipe1_1, List.of(recipeImage1_1_1), List.of(product1, product2, product3))); - - // then - assertThat(actual) - .usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 꿀쑰합을_μ΅œμ‹ μˆœμœΌλ‘œ_μ •λ ¬ν• _수_μžˆλ‹€() throws InterruptedException { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipe1_1 = λ ˆμ‹œν”Ό_생성(member1, 1L); - Thread.sleep(100); - final var recipe1_2 = λ ˆμ‹œν”Ό_생성(member1, 3L); - Thread.sleep(100); - final var recipe1_3 = λ ˆμ‹œν”Ό_생성(member1, 2L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1_1, recipe1_2, recipe1_3); - - final var product_recipe_1_1_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_1); - final var product_recipe_1_1_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1_1); - final var product_recipe_1_1_3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_1); - final var product_recipe_1_2_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_2); - final var product_recipe_1_2_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_2); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1_1_1, product_recipe_1_1_2, product_recipe_1_1_3, product_recipe_1_2_1, - product_recipe_1_2_2); - - final var recipeImage1_1_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_1); - final var recipeImage1_2_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - final var recipeImage1_2_2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(recipeImage1_1_1, recipeImage1_2_1); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ΅œμ‹ μˆœ); - - // when - final var actual = recipeService.getSortingRecipes(page).getRecipes(); - final var expected = List.of( - RecipeDto.toDto(recipe1_3, List.of(), List.of()), - RecipeDto.toDto(recipe1_2, List.of(recipeImage1_2_1, recipeImage1_2_2), - List.of(product1, product3)), - RecipeDto.toDto(recipe1_1, List.of(recipeImage1_1_1), List.of(product1, product2, product3))); - - // then - assertThat(actual) - .usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 꿀쑰합을_였래된순으둜_μ •λ ¬ν• _수_μžˆλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipe1_1 = λ ˆμ‹œν”Ό_생성(member1, 1L); - final var recipe1_2 = λ ˆμ‹œν”Ό_생성(member1, 3L); - final var recipe1_3 = λ ˆμ‹œν”Ό_생성(member1, 2L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1_1, recipe1_2, recipe1_3); - - final var product_recipe_1_1_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_1); - final var product_recipe_1_1_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1_1); - final var product_recipe_1_1_3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_1); - final var product_recipe_1_2_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_2); - final var product_recipe_1_2_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_2); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1_1_1, product_recipe_1_1_2, product_recipe_1_1_3, product_recipe_1_2_1, - product_recipe_1_2_2); - - final var recipeImage1_1_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_1); - final var recipeImage1_2_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - final var recipeImage1_2_2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(recipeImage1_1_1, recipeImage1_2_1); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, 과거순); - - // when - final var actual = recipeService.getSortingRecipes(page).getRecipes(); - final var expected = List.of( - RecipeDto.toDto(recipe1_1, List.of(recipeImage1_1_1), List.of(product1, product2, product3)), - RecipeDto.toDto(recipe1_2, List.of(recipeImage1_2_1, recipeImage1_2_2), - List.of(product1, product3)), - RecipeDto.toDto(recipe1_3, List.of(), List.of())); - - // then - assertThat(actual) - .usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class likeRecipe_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 꿀쑰합에_μ’‹μ•„μš”λ₯Ό_ν• _수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var productIds = μƒν’ˆ_아이디_λ³€ν™˜(product1, product2, product3); - - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - final var member = 멀버_멀버2_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var createRequest = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(productIds); - final var recipeId = recipeService.create(authorId, images, createRequest); - - // when - final var favoriteRequest = λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(true); - recipeService.likeRecipe(memberId, recipeId, favoriteRequest); - - final var actualRecipe = recipeRepository.findById(recipeId).get(); - final var actualRecipeFavorite = recipeFavoriteRepository.findByMemberAndRecipe(member, actualRecipe).get(); - - // then - assertSoftly(soft -> { - soft.assertThat(actualRecipe.getFavoriteCount()) - .isOne(); - soft.assertThat(actualRecipeFavorite.getFavorite()) - .isTrue(); - }); - } - - @Test - void 꿀쑰합에_μ’‹μ•„μš”λ₯Ό_μ·¨μ†Œ_ν• _수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var productIds = μƒν’ˆ_아이디_λ³€ν™˜(product1, product2, product3); - - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - final var member = 멀버_멀버2_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var createRequest = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(productIds); - final var recipeId = recipeService.create(authorId, images, createRequest); - - final var favoriteRequest = λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(true); - recipeService.likeRecipe(memberId, recipeId, favoriteRequest); - - // when - final var cancelFavoriteRequest = λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(false); - recipeService.likeRecipe(memberId, recipeId, cancelFavoriteRequest); - - final var actualRecipe = recipeRepository.findById(recipeId).get(); - final var actualRecipeFavorite = recipeFavoriteRepository.findByMemberAndRecipe(member, actualRecipe).get(); - - // then - assertSoftly(soft -> { - soft.assertThat(actualRecipe.getFavoriteCount()) - .isZero(); - soft.assertThat(actualRecipeFavorite.getFavorite()) - .isFalse(); - }); - } - } - - @Nested - class likeRecipe_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_멀버가_λ ˆμ‹œν”Όμ—_μ’‹μ•„μš”λ₯Ό_ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var productIds = μƒν’ˆ_아이디_λ³€ν™˜(product1, product2, product3); - - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - final var wrongMemberId = authorId + 1L; - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var createRequest = λ ˆμ‹œν”ΌμΆ”κ°€μš”μ²­_생성(productIds); - final var recipeId = recipeService.create(authorId, images, createRequest); - - // when & then - final var favoriteRequest = λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(true); - assertThatThrownBy(() -> recipeService.likeRecipe(wrongMemberId, recipeId, favoriteRequest)) - .isInstanceOf(MemberNotFoundException.class); - } - - @Test - void 멀버가_μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ ˆμ‹œν”Όμ—_μ’‹μ•„μš”λ₯Ό_ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var wrongRecipeId = 999L; - - // when & then - final var favoriteRequest = λ ˆμ‹œν”Όμ’‹μ•„μš”μš”μ²­_생성(true); - assertThatThrownBy(() -> recipeService.likeRecipe(memberId, wrongRecipeId, favoriteRequest)) - .isInstanceOf(RecipeNotFoundException.class); - } - } - - @Nested - class getTop3Recipes_성곡_ν…ŒμŠ€νŠΈ { - - @Nested - class κΏ€μ‘°ν•©_κ°œμˆ˜μ—_λŒ€ν•œ_ν…ŒμŠ€νŠΈ { - - @Test - void 전체_꿀쑰합이_ν•˜λ‚˜λ„_없어도_λ°˜ν™˜κ°’μ€_μžˆμ–΄μ•Όν•œλ‹€() { - // given - final var expected = RankingRecipesResponse.toResponse(Collections.emptyList()); - - // when - final var actual = recipeService.getTop3Recipes(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void λž­ν‚Ή_쑰건에_λΆ€ν•©ν•˜λŠ”_꿀쑰합이_1개면_꿀쑰합이_1개_λ°˜ν™˜λœλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var recipe = λ ˆμ‹œν”Ό_생성(member, 2L, now); - 단일_κΏ€μ‘°ν•©_μ €μž₯(recipe); - - final var author = RecipeAuthorDto.toDto(member); - final var rankingRecipeDto = RankingRecipeDto.toDto(recipe, Collections.emptyList(), author); - final var rankingRecipesDtos = Collections.singletonList(rankingRecipeDto); - final var expected = RankingRecipesResponse.toResponse(rankingRecipesDtos); - - // when - final var actual = recipeService.getTop3Recipes(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void λž­ν‚Ή_쑰건에_λΆ€ν•©ν•˜λŠ”_꿀쑰합이_2개면_꿀쑰합이_2개_λ°˜ν™˜λœλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var recipe1 = λ ˆμ‹œν”Ό_생성(member, 2L, now.minusDays(1L)); - final var recipe2 = λ ˆμ‹œν”Ό_생성(member, 2L, now); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1, recipe2); - - final var author = RecipeAuthorDto.toDto(member); - final var rankingRecipeDto1 = RankingRecipeDto.toDto(recipe1, Collections.emptyList(), author); - final var rankingRecipeDto2 = RankingRecipeDto.toDto(recipe2, Collections.emptyList(), author); - final var rankingRecipesDtos = List.of(rankingRecipeDto2, rankingRecipeDto1); - final var expected = RankingRecipesResponse.toResponse(rankingRecipesDtos); - - // when - final var actual = recipeService.getTop3Recipes(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 전체_κΏ€μ‘°ν•©_쀑_λž­ν‚Ήμ΄_높은_μƒμœ„_3개_꿀쑰합을_ꡬ할_수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var recipe1 = λ ˆμ‹œν”Ό_생성(member, 4L, now.minusDays(10L)); - final var recipe2 = λ ˆμ‹œν”Ό_생성(member, 6L, now.minusDays(10L)); - final var recipe3 = λ ˆμ‹œν”Ό_생성(member, 5L, now); - final var recipe4 = λ ˆμ‹œν”Ό_생성(member, 6L, now); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1, recipe2, recipe3, recipe4); - - final var author = RecipeAuthorDto.toDto(member); - final var rankingRecipeDto1 = RankingRecipeDto.toDto(recipe1, Collections.emptyList(), author); - final var rankingRecipeDto2 = RankingRecipeDto.toDto(recipe2, Collections.emptyList(), author); - final var rankingRecipeDto3 = RankingRecipeDto.toDto(recipe3, Collections.emptyList(), author); - final var rankingRecipeDto4 = RankingRecipeDto.toDto(recipe4, Collections.emptyList(), author); - final var rankingRecipesDtos = List.of(rankingRecipeDto4, rankingRecipeDto3, rankingRecipeDto2); - final var expected = RankingRecipesResponse.toResponse(rankingRecipesDtos); - - // when - final var actual = recipeService.getTop3Recipes(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class κΏ€μ‘°ν•©_λž­ν‚Ή_μ μˆ˜μ—_λŒ€ν•œ_ν…ŒμŠ€νŠΈ { - - @Test - void κΏ€μ‘°ν•©_μ’‹μ•„μš”_μˆ˜κ°€_κ°™μœΌλ©΄_졜근_μƒμ„±λœ_κΏ€μ‘°ν•©μ˜_λž­ν‚Ήμ„_더_λ†’κ²Œ_λ°˜ν™˜ν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var recipe1 = λ ˆμ‹œν”Ό_생성(member, 10L, now.minusDays(9L)); - final var recipe2 = λ ˆμ‹œν”Ό_생성(member, 10L, now.minusDays(4L)); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1, recipe2); - - final var author = RecipeAuthorDto.toDto(member); - final var rankingRecipeDto1 = RankingRecipeDto.toDto(recipe1, Collections.emptyList(), author); - final var rankingRecipeDto2 = RankingRecipeDto.toDto(recipe2, Collections.emptyList(), author); - final var rankingRecipesDtos = List.of(rankingRecipeDto2, rankingRecipeDto1); - final var expected = RankingRecipesResponse.toResponse(rankingRecipesDtos); - - // when - final var actual = recipeService.getTop3Recipes(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void κΏ€μ‘°ν•©_생성_μΌμžκ°€_κ°™μœΌλ©΄_μ’‹μ•„μš”_μˆ˜κ°€_λ§Žμ€_κΏ€μ‘°ν•©μ˜_λž­ν‚Ήμ„_더_λ†’κ²Œ_λ°˜ν™˜ν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var recipe1 = λ ˆμ‹œν”Ό_생성(member, 2L, now.minusDays(1L)); - final var recipe2 = λ ˆμ‹œν”Ό_생성(member, 4L, now.minusDays(1L)); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1, recipe2); - - final var author = RecipeAuthorDto.toDto(member); - final var rankingRecipeDto1 = RankingRecipeDto.toDto(recipe1, Collections.emptyList(), author); - final var rankingRecipeDto2 = RankingRecipeDto.toDto(recipe2, Collections.emptyList(), author); - final var rankingRecipesDtos = List.of(rankingRecipeDto2, rankingRecipeDto1); - final var expected = RankingRecipesResponse.toResponse(rankingRecipesDtos); - - // when - final var actual = recipeService.getTop3Recipes(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - } - - @Nested - class writeCommentOfRecipe_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 꿀쑰합에_λŒ“κΈ€μ„_μž‘μ„±ν• _수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var author = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(author); - final var authorId = author.getId(); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var productIds = List.of(product1.getId(), product2.getId(), product3.getId()); - final var recipeCreateRequest = new RecipeCreateRequest("제일둜 λ§›μžˆλŠ” λ ˆμ‹œν”Ό", productIds, - "μš°μ„  λ°₯을 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μœΌλ©΄.. 끝!!"); - - final var savedMemberId = 단일_멀버_μ €μž₯(멀버_멀버1_생성()); - final var savedRecipeId = recipeService.create(authorId, images, recipeCreateRequest); - - // when - final var request = new RecipeCommentCreateRequest("κΏ€μ‘°ν•© λŒ“κΈ€μ΄μ—μš”"); - final var savedCommentId = recipeService.writeCommentOfRecipe(savedMemberId, savedRecipeId, request); - - // then - final var result = commentRepository.findById(savedCommentId).get(); - final var savedRecipe = recipeRepository.findById(savedRecipeId).get(); - final var savedMember = memberRepository.findById(savedMemberId).get(); - - assertThat(result).usingRecursiveComparison() - .ignoringFields("id", "createdAt") - .isEqualTo(new Comment(savedRecipe, savedMember, request.getComment())); - } - } - - @Nested - class writeCommentOfRecipe_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•Šμ€_멀버가_꿀쑰합에_λŒ“κΈ€μ„_μž‘μ„±ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var author = new Member("author", "image.png", "1"); - 단일_멀버_μ €μž₯(author); - final var authorId = author.getId(); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var productIds = List.of(product1.getId(), product2.getId(), product3.getId()); - final var recipeCreateRequest = new RecipeCreateRequest("제일둜 λ§›μžˆλŠ” λ ˆμ‹œν”Ό", productIds, - "μš°μ„  λ°₯을 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μœΌλ©΄.. 끝!!"); - - final var notExistMemberId = 999999999L; - final var savedRecipeId = recipeService.create(authorId, images, recipeCreateRequest); - final var request = new RecipeCommentCreateRequest("κΏ€μ‘°ν•© λŒ“κΈ€μ΄μ—μš”"); - - // when then - assertThatThrownBy(() -> recipeService.writeCommentOfRecipe(notExistMemberId, savedRecipeId, request)) - .isInstanceOf(MemberNotFoundException.class); - } - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•Šμ€_꿀쑰합에_λŒ“κΈ€μ„_μž‘μ„±ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var memberId = 단일_멀버_μ €μž₯(멀버_멀버1_생성()); - final var request = new RecipeCommentCreateRequest("κΏ€μ‘°ν•© λŒ“κΈ€μ΄μ—μš”"); - final var notExistRecipeId = 999999999L; - - // when then - assertThatThrownBy(() -> recipeService.writeCommentOfRecipe(memberId, notExistRecipeId, request)) - .isInstanceOf(RecipeNotFoundException.class); - } - } - - @Nested - class getCommentsOfRecipe_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 꿀쑰합에_달린_λŒ“κΈ€λ“€μ„_μ»€μ„œνŽ˜μ΄μ§•μ„_톡해_μ‘°νšŒν• _수_μžˆλ‹€_총_λŒ“κΈ€_15개_쀑_μ²«νŽ˜μ΄μ§€_λŒ“κΈ€_10개쑰회() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var author = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(author); - final var authorId = author.getId(); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var productIds = List.of(product1.getId(), product2.getId(), product3.getId()); - final var recipeCreateRequest = new RecipeCreateRequest("제일둜 λ§›μžˆλŠ” λ ˆμ‹œν”Ό", productIds, - "μš°μ„  λ°₯을 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μœΌλ©΄.. 끝!!"); - - final var savedMemberId = 단일_멀버_μ €μž₯(멀버_멀버1_생성()); - final var savedRecipeId = recipeService.create(authorId, images, recipeCreateRequest); - - for (int i = 1; i <= 15; i++) { - final var request = new RecipeCommentCreateRequest("κΏ€μ‘°ν•© λŒ“κΈ€μ΄μ—μš”" + i); - recipeService.writeCommentOfRecipe(savedMemberId, savedRecipeId, request); - } - - // when - final var result = recipeService.getCommentsOfRecipe(savedRecipeId, - new RecipeCommentCondition(null, null)); - - // - final var savedRecipe = recipeRepository.findById(savedRecipeId).get(); - final var savedMember = memberRepository.findById(savedMemberId).get(); - - final var expectedCommentResponses = new ArrayList<>(); - for (int i = 0; i < result.getComments().size(); i++) { - expectedCommentResponses.add(RecipeCommentResponse.toResponse( - new Comment(savedRecipe, savedMember, "κΏ€μ‘°ν•© λŒ“κΈ€μ΄μ—μš”" + (15 - i)))); - } - - assertThat(result.getHasNext()).isTrue(); - assertThat(result.getTotalElements()).isEqualTo(15); - assertThat(result.getComments()).hasSize(10); - assertThat(result.getComments()).usingRecursiveComparison() - .ignoringFields("id", "createdAt") - .isEqualTo(expectedCommentResponses); - } - - @Test - void 꿀쑰합에_달린_λŒ“κΈ€λ“€μ„_μ»€μ„œνŽ˜μ΄μ§•μ„_톡해_μ‘°νšŒν• _수_μžˆλ‹€_총_λŒ“κΈ€_15개_쀑_λ§ˆμ§€λ§‰νŽ˜μ΄μ§€_λŒ“κΈ€_5개쑰회() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - final var author = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(author); - final var authorId = author.getId(); - - final var images = μ—¬λŸ¬_이미지_생성(3); - - final var productIds = List.of(product1.getId(), product2.getId(), product3.getId()); - final var recipeCreateRequest = new RecipeCreateRequest("제일둜 λ§›μžˆλŠ” λ ˆμ‹œν”Ό", productIds, - "μš°μ„  λ°₯을 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μ–΄μš”. 그리고 λ°₯을 또 λ„£μœΌλ©΄.. 끝!!"); - - final var savedMemberId = 단일_멀버_μ €μž₯(멀버_멀버1_생성()); - final var savedRecipeId = recipeService.create(authorId, images, recipeCreateRequest); - - for (int i = 1; i <= 15; i++) { - final var request = new RecipeCommentCreateRequest("κΏ€μ‘°ν•© λŒ“κΈ€μ΄μ—μš”" + i); - recipeService.writeCommentOfRecipe(savedMemberId, savedRecipeId, request); - } - - // when - final var result = recipeService.getCommentsOfRecipe(savedRecipeId, - new RecipeCommentCondition(6L, 15L)); - - // - final var savedRecipe = recipeRepository.findById(savedRecipeId).get(); - final var savedMember = memberRepository.findById(savedMemberId).get(); - - final var expectedCommentResponses = new ArrayList<>(); - for (int i = 0; i < result.getComments().size(); i++) { - expectedCommentResponses.add(RecipeCommentResponse.toResponse( - new Comment(savedRecipe, savedMember, "κΏ€μ‘°ν•© λŒ“κΈ€μ΄μ—μš”" + (5 - i)))); - } - - assertThat(result.getHasNext()).isFalse(); - assertThat(result.getTotalElements()).isEqualTo(15); - assertThat(result.getComments()).hasSize(5); - assertThat(result.getComments()).usingRecursiveComparison() - .ignoringFields("id", "createdAt") - .isEqualTo(expectedCommentResponses); - } - } - - private void ν•΄λ‹Ήλ©€λ²„μ˜_κΏ€μ‘°ν•©κ³Ό_νŽ˜μ΄μ§•_κ²°κ³Όλ₯Ό_κ²€μ¦ν•œλ‹€(final MemberRecipesResponse actual, final List expectedRecipesDtos, - final PageDto expectedPage) { - assertSoftly(soft -> { - assertThat(actual.getRecipes()).usingRecursiveComparison() - .isEqualTo(expectedRecipesDtos); - assertThat(actual.getPage()).usingRecursiveComparison() - .isEqualTo(expectedPage); - }); - } - - private Category μΉ΄ν…Œκ³ λ¦¬_μΆ”κ°€_μš”μ²­(final Category category) { - return categoryRepository.save(category); - } - - private List μƒν’ˆ_아이디_λ³€ν™˜(final Product... products) { - return Stream.of(products) - .map(Product::getId) - .collect(Collectors.toList()); - } -} diff --git a/backend/src/test/java/com/funeat/recipe/domain/RecipeTest.java b/backend/src/test/java/com/funeat/recipe/domain/RecipeTest.java deleted file mode 100644 index 7a0d28030..000000000 --- a/backend/src/test/java/com/funeat/recipe/domain/RecipeTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.funeat.recipe.domain; - -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import java.time.LocalDateTime; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -class RecipeTest { - - @Nested - class calculateRankingScore_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void κΏ€μ‘°ν•©_μ’‹μ•„μš”_μˆ˜μ™€_κΏ€μ‘°ν•©_생성_μ‹œκ°„μœΌλ‘œ_ν•΄λ‹Ή_κΏ€μ‘°ν•©μ˜_λž­ν‚Ή_점수λ₯Ό_ꡬ할_수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var favoriteCount = 4L; - final var recipe = λ ˆμ‹œν”Ό_생성(member, favoriteCount, LocalDateTime.now().minusDays(1L)); - - final var expected = favoriteCount / Math.pow(2.0, 0.1); - - // when - final var actual = recipe.calculateRankingScore(); - - // then - assertThat(actual).isEqualTo(expected); - } - } -} diff --git a/backend/src/test/java/com/funeat/recipe/persistence/RecipeImageRepositoryTest.java b/backend/src/test/java/com/funeat/recipe/persistence/RecipeImageRepositoryTest.java deleted file mode 100644 index bb2c80923..000000000 --- a/backend/src/test/java/com/funeat/recipe/persistence/RecipeImageRepositoryTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.funeat.recipe.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.ProductFixture.λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격3000원_평점1점_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.RepositoryTest; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class RecipeImageRepositoryTest extends RepositoryTest { - - @Nested - class findByRecipe_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void λ ˆμ‹œν”Όμ—_μ‚¬μš©λœ_이미지듀을_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격3000원_평점1점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var recipe = λ ˆμ‹œν”Ό_생성(member); - 단일_λ ˆμ‹œν”Ό_μ €μž₯(recipe); - - final var productRecipe1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe); - final var productRecipe2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe); - final var productRecipe3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe); - 볡수_λ ˆμ‹œν”Ό_μƒν’ˆ_μ €μž₯(productRecipe1, productRecipe2, productRecipe3); - - final var image1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe); - final var image2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe); - final var image3 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe); - 볡수_λ ˆμ‹œν”Ό_이미지_μ €μž₯(image1, image2, image3); - - // when - final var images = recipeImageRepository.findByRecipe(recipe); - - // then - assertThat(images.size()).isEqualTo(3); - } - } -} diff --git a/backend/src/test/java/com/funeat/recipe/persistence/RecipeRepositoryTest.java b/backend/src/test/java/com/funeat/recipe/persistence/RecipeRepositoryTest.java deleted file mode 100644 index 9c53177db..000000000 --- a/backend/src/test/java/com/funeat/recipe/persistence/RecipeRepositoryTest.java +++ /dev/null @@ -1,307 +0,0 @@ -package com.funeat.recipe.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버3_생성; -import static com.funeat.fixture.PageFixture.과거순; -import static com.funeat.fixture.PageFixture.μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ; -import static com.funeat.fixture.PageFixture.μ΅œμ‹ μˆœ; -import static com.funeat.fixture.PageFixture.νŽ˜μ΄μ§€μš”μ²­_κΈ°λ³Έ_생성; -import static com.funeat.fixture.PageFixture.νŽ˜μ΄μ§€μš”μ²­_생성; -import static com.funeat.fixture.ProductFixture.λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Ό_생성; -import static com.funeat.fixture.RecipeFixture.λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.RepositoryTest; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class RecipeRepositoryTest extends RepositoryTest { - - @Nested - class findAllByProductNameContaining_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μƒν’ˆλͺ…에_검색어가_ν¬ν•¨λœ_μƒν’ˆμ΄_μžˆλŠ”_λ ˆμ‹œν”Όλ“€μ„_μ‘°νšŒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - final var product2 = μƒν’ˆ_λ§κ³ λΉ™μˆ˜_가격5000원_평점4점_생성(category); - final var product3 = μƒν’ˆ_μ• ν”Œλ§κ³ _가격3000원_평점5점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var recipe1 = λ ˆμ‹œν”Ό_생성(member); - final var recipe2 = λ ˆμ‹œν”Ό_생성(member); - 볡수_λ ˆμ‹œν”Ό_μ €μž₯(recipe1, recipe2); - - final var productRecipe1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1); - final var productRecipe2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1); - final var productRecipe3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe2); - 볡수_λ ˆμ‹œν”Ό_μƒν’ˆ_μ €μž₯(productRecipe1, productRecipe2, productRecipe3); - - final var image1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1); - final var image2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe2); - 볡수_λ ˆμ‹œν”Ό_이미지_μ €μž₯(image1, image2); - - final var page = νŽ˜μ΄μ§€μš”μ²­_κΈ°λ³Έ_생성(0, 10); - final var expected = List.of(recipe1, recipe2); - - // when - final var actual = recipeRepository.findAllByProductNameContaining("망고", page).getContent(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class findAllRecipes_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 꿀쑰합을_μ’‹μ•„μš”κ°€_λ§Žμ€_순으둜_μ •λ ¬ν•œλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipe1_1 = λ ˆμ‹œν”Ό_생성(member1, 1L); - final var recipe1_2 = λ ˆμ‹œν”Ό_생성(member1, 3L); - final var recipe1_3 = λ ˆμ‹œν”Ό_생성(member1, 2L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1_1, recipe1_2, recipe1_3); - - final var product_recipe_1_1_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_1); - final var product_recipe_1_1_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1_1); - final var product_recipe_1_1_3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_1); - final var product_recipe_1_2_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_2); - final var product_recipe_1_2_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_2); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1_1_1, product_recipe_1_1_2, product_recipe_1_1_3, product_recipe_1_2_1, - product_recipe_1_2_2); - - final var recipeImage1_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_1); - final var recipeImage1_2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(recipeImage1_1, recipeImage1_2); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ); - final var expected = List.of(recipe1_2, recipe1_3, recipe1_1); - - // when - final var actual = recipeRepository.findAll(page).getContent(); - - // then - assertThat(actual) - .usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 꿀쑰합을_μ΅œμ‹ μˆœμœΌλ‘œ_μ •λ ¬ν•œλ‹€() throws InterruptedException { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipe1_1 = λ ˆμ‹œν”Ό_생성(member1, 1L); - Thread.sleep(100); - final var recipe1_2 = λ ˆμ‹œν”Ό_생성(member1, 3L); - Thread.sleep(100); - final var recipe1_3 = λ ˆμ‹œν”Ό_생성(member1, 2L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1_1, recipe1_2, recipe1_3); - - final var product_recipe_1_1_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_1); - final var product_recipe_1_1_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1_1); - final var product_recipe_1_1_3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_1); - final var product_recipe_1_2_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_2); - final var product_recipe_1_2_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_2); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1_1_1, product_recipe_1_1_2, product_recipe_1_1_3, product_recipe_1_2_1, - product_recipe_1_2_2); - - final var recipeImage1_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_1); - final var recipeImage1_2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(recipeImage1_1, recipeImage1_2); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ΅œμ‹ μˆœ); - final var expected = List.of(recipe1_3, recipe1_2, recipe1_1); - - // when - final var actual = recipeRepository.findAll(page).getContent(); - - // then - assertThat(actual) - .usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 꿀쑰합을_였래된순으둜_μ •λ ¬ν•œλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipe1_1 = λ ˆμ‹œν”Ό_생성(member1, 1L); - final var recipe1_2 = λ ˆμ‹œν”Ό_생성(member1, 3L); - final var recipe1_3 = λ ˆμ‹œν”Ό_생성(member1, 2L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1_1, recipe1_2, recipe1_3); - - final var product_recipe_1_1_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_1); - final var product_recipe_1_1_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1_1); - final var product_recipe_1_1_3 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_1); - final var product_recipe_1_2_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1_2); - final var product_recipe_1_2_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1_2); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1_1_1, product_recipe_1_1_2, product_recipe_1_1_3, product_recipe_1_2_1, - product_recipe_1_2_2); - - final var recipeImage1_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_1); - final var recipeImage1_2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1_2); - 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(recipeImage1_1, recipeImage1_2); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, 과거순); - final var expected = List.of(recipe1_1, recipe1_2, recipe1_3); - - // when - final var actual = recipeRepository.findAll(page).getContent(); - - // then - assertThat(actual) - .usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class findRecipesByProduct_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μƒν’ˆμ΄_ν¬ν•¨λœ_λ ˆμ‹œν”Όλ“€μ„_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var recipe1 = λ ˆμ‹œν”Ό_생성(member, 1L); - final var recipe2 = λ ˆμ‹œν”Ό_생성(member, 3L); - final var recipe3 = λ ˆμ‹œν”Ό_생성(member, 2L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1, recipe2, recipe3); - - final var product_recipe_1_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe1); - final var product_recipe_1_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product1, recipe2); - final var product_recipe_2_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product2, recipe1); - final var product_recipe_3_1 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe1); - final var product_recipe_3_2 = λ ˆμ‹œν”Ό_μ•ˆμ—_λ“€μ–΄κ°€λŠ”_μƒν’ˆ_생성(product3, recipe2); - 볡수_κΏ€μ‘°ν•©_μƒν’ˆ_μ €μž₯(product_recipe_1_1, product_recipe_2_1, product_recipe_3_1, product_recipe_1_2, - product_recipe_3_2); - - final var recipeImage1_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe1); - final var recipeImage2_1 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe2); - final var recipeImage2_2 = λ ˆμ‹œν”Όμ΄λ―Έμ§€_생성(recipe2); - 볡수_κΏ€μ‘°ν•©_이미지_μ €μž₯(recipeImage1_1, recipeImage2_1, recipeImage2_2); - - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ); - final var expected = List.of(recipe2, recipe1); - - // when - final var actual = recipeRepository.findRecipesByProduct(product1, page).getContent(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class findRecipesByFavoriteCountGreaterThanEqual_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void νŠΉμ •_μ’‹μ•„μš”_수_이상인_λͺ¨λ“ _꿀쑰합듀을_μ‘°νšŒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var recipe1 = λ ˆμ‹œν”Ό_생성(member, 0L); - final var recipe2 = λ ˆμ‹œν”Ό_생성(member, 1L); - final var recipe3 = λ ˆμ‹œν”Ό_생성(member, 10L); - final var recipe4 = λ ˆμ‹œν”Ό_생성(member, 100L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1, recipe2, recipe3, recipe4); - - final var expected = List.of(recipe2, recipe3, recipe4); - - // when - final var actual = recipeRepository.findRecipesByFavoriteCountGreaterThanEqual(1L); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void νŠΉμ •_μ’‹μ•„μš”_수_이상인_꿀쑰합이_μ—†μœΌλ©΄_빈_리슀트λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var recipe1 = λ ˆμ‹œν”Ό_생성(member, 0L); - final var recipe2 = λ ˆμ‹œν”Ό_생성(member, 0L); - 볡수_κΏ€μ‘°ν•©_μ €μž₯(recipe1, recipe2); - - final var expected = Collections.emptyList(); - - // when - final var actual = recipeRepository.findRecipesByFavoriteCountGreaterThanEqual(1L); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } -} diff --git a/backend/src/test/java/com/funeat/review/application/ReviewDeleteEventListenerTest.java b/backend/src/test/java/com/funeat/review/application/ReviewDeleteEventListenerTest.java deleted file mode 100644 index 1349eaa37..000000000 --- a/backend/src/test/java/com/funeat/review/application/ReviewDeleteEventListenerTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.funeat.review.application; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test1_평점1점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test2_평점2점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test4_평점4점_재ꡬ맀O_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doThrow; - -import com.funeat.common.EventTest; -import com.funeat.common.ImageUploader; -import com.funeat.common.exception.CommonException.S3DeleteFailException; -import com.funeat.exception.CommonErrorCode; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; - -@SuppressWarnings("NonAsciiCharacters") -class ReviewDeleteEventListenerTest extends EventTest { - - @MockBean - private ImageUploader uploader; - - @Nested - class 리뷰_μ‚­μ œ_이벀트_λ°œν–‰ { - - @Test - void 리뷰_μž‘μ„±μžκ°€_리뷰_μ‚­μ œ_μ‹œλ„μ‹œ_리뷰_μ‚­μ œ_μ΄λ²€νŠΈκ°€_λ°œν–‰λœλ‹€() { - // given - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = reviewRepository.save(리뷰_이미지test1_평점1점_재ꡬ맀O_생성(author, product, 0L)); - - // when - reviewService.deleteReview(review.getId(), authorId); - - // then - final var count = events.stream(ReviewDeleteEvent.class).count(); - assertThat(count).isEqualTo(1); - } - - @Test - void 리뷰_μž‘μ„±μžκ°€_μ•„λ‹Œ_μ‚¬λžŒμ΄_리뷰_μ‚­μ œ_μ‹œλ„μ‹œ_리뷰_μ‚­μ œ_μ΄λ²€νŠΈκ°€_λ°œν–‰λ˜μ§€_μ•ŠλŠ”λ‹€() { - // given - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - - final var member = 멀버_멀버2_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = reviewRepository.save(리뷰_이미지test2_평점2점_재ꡬ맀O_생성(author, product, 0L)); - - // when - try { - reviewService.deleteReview(review.getId(), memberId); - } catch (Exception ignored) { - } - - // then - final var count = events.stream(ReviewDeleteEvent.class).count(); - assertThat(count).isEqualTo(0); - } - } - - @Nested - class 이미지_μ‚­μ œ_둜직_μž‘λ™ { - - @Test - void 이미지_μ‚­μ œ_둜직이_μ‹€νŒ¨ν•΄λ„_λ©”μΈλ‘œμ§κΉŒμ§€_λ‘€λ°±λ˜μ–΄μ„œλŠ”_μ•ˆλœλ‹€() { - // given - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = reviewRepository.save(리뷰_이미지test4_평점4점_재ꡬ맀O_생성(author, product, 0L)); - - doThrow(new S3DeleteFailException(CommonErrorCode.UNKNOWN_SERVER_ERROR_CODE)) - .when(uploader) - .delete(any()); - - // when - reviewService.deleteReview(review.getId(), authorId); - - // then - assertThat(reviewRepository.findById(review.getId())).isEmpty(); - } - } -} diff --git a/backend/src/test/java/com/funeat/review/application/ReviewServiceTest.java b/backend/src/test/java/com/funeat/review/application/ReviewServiceTest.java deleted file mode 100644 index 93fd0e046..000000000 --- a/backend/src/test/java/com/funeat/review/application/ReviewServiceTest.java +++ /dev/null @@ -1,1224 +0,0 @@ -package com.funeat.review.application; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.ImageFixture.이미지_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.PageFixture.μ΅œμ‹ μˆœ; -import static com.funeat.fixture.PageFixture.νŽ˜μ΄μ§€μš”μ²­_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test1_평점1점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test1_평점1점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test2_평점2점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test2_평점2점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test3_평점3점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test3_평점3점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test4_평점4점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test5_평점5점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_μ΄λ―Έμ§€μ—†μŒ_평점1점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μ •λ ¬μš”μ²­_μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μ •λ ¬μš”μ²­_μ΅œμ‹ μˆœ_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μ •λ ¬μš”μ²­_평점_λ‚΄λ¦Όμ°¨μˆœ_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μ •λ ¬μš”μ²­_평점_μ˜€λ¦„μ°¨μˆœ_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성; -import static com.funeat.fixture.ReviewFixture.λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_아침식사_ETC_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.common.ServiceTest; -import com.funeat.common.dto.PageDto; -import com.funeat.member.dto.MemberReviewDto; -import com.funeat.member.exception.MemberException.MemberNotFoundException; -import com.funeat.product.exception.ProductException.ProductNotFoundException; -import com.funeat.review.domain.Review; -import com.funeat.review.dto.MostFavoriteReviewResponse; -import com.funeat.review.dto.RankingReviewDto; -import com.funeat.review.dto.RankingReviewsResponse; -import com.funeat.review.dto.ReviewDetailResponse; -import com.funeat.review.dto.SortingReviewDto; -import com.funeat.review.exception.ReviewException.NotAuthorOfReviewException; -import com.funeat.review.exception.ReviewException.ReviewNotFoundException; -import com.funeat.tag.domain.Tag; -import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class ReviewServiceTest extends ServiceTest { - - @Nested - class create_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 이미지가_μ‘΄μž¬ν•˜λŠ”_리뷰λ₯Ό_μΆ”κ°€ν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var imageFileName = image.getOriginalFilename(); - - final var request = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - - final var expected = new Review(member, product, imageFileName, 4L, "test", true); - - // when - reviewService.create(productId, memberId, image, request); - final var actual = reviewRepository.findAll().get(0); - - // then - assertThat(actual).usingRecursiveComparison() - .comparingOnlyFields("member", "product", "image", "rating", "content", "reBuy") - .isEqualTo(expected); - } - - @Test - void 이미지가_μ—†λŠ”_리뷰λ₯Ό_μΆ”κ°€ν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - - final var request = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - - final var expected = new Review(member, product, "", 4L, "test", true); - - // when - reviewService.create(productId, memberId, null, request); - final var actual = reviewRepository.findAll().get(0); - - // then - assertThat(actual).usingRecursiveComparison() - .comparingOnlyFields("member", "product", "image", "rating", "content", "reBuy") - .isEqualTo(expected); - } - } - - @Nested - class create_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ©€λ²„λ‘œ_μƒν’ˆμ—_리뷰λ₯Ό_μΆ”κ°€ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var wrongMemberId = 단일_멀버_μ €μž₯(member) + 1L; - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - - final var request = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - - // when & then - assertThatThrownBy(() -> reviewService.create(productId, wrongMemberId, image, request)) - .isInstanceOf(MemberNotFoundException.class); - } - - @Test - void λ©€λ²„λ‘œ_μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆμ—_리뷰λ₯Ό_μΆ”κ°€ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var wrongProductId = 단일_μƒν’ˆ_μ €μž₯(product) + 1L; - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - - final var request = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - - // when & then - assertThatThrownBy(() -> reviewService.create(wrongProductId, memberId, image, request)) - .isInstanceOf(ProductNotFoundException.class); - } - } - - @Nested - class likeReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰에_μ’‹μ•„μš”λ₯Ό_ν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var reviewCreaterequest = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - reviewService.create(productId, memberId, image, reviewCreaterequest); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); - - final var favoriteRequest = λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(true); - - // when - reviewService.likeReview(reviewId, memberId, favoriteRequest); - - final var actualReview = reviewRepository.findAll().get(0); - final var actualReviewFavorite = reviewFavoriteRepository.findAll().get(0); - - // then - assertSoftly(soft -> { - soft.assertThat(actualReview.getFavoriteCount()) - .isOne(); - soft.assertThat(actualReviewFavorite.getFavorite()) - .isTrue(); - }); - } - - @Test - void 리뷰에_μ’‹μ•„μš”λ₯Ό_μ·¨μ†Œ_ν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var reviewCreaterequest = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - reviewService.create(productId, memberId, image, reviewCreaterequest); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); - - final var favoriteRequest = λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(true); - reviewService.likeReview(reviewId, memberId, favoriteRequest); - - // when - final var cancelFavoriteRequest = λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(false); - reviewService.likeReview(reviewId, memberId, cancelFavoriteRequest); - - final var actualReview = reviewRepository.findAll().get(0); - final var actualReviewFavorite = reviewFavoriteRepository.findAll().get(0); - - // then - assertSoftly(soft -> { - soft.assertThat(actualReview.getFavoriteCount()) - .isZero(); - soft.assertThat(actualReviewFavorite.getFavorite()) - .isFalse(); - }); - } - } - - @Nested - class likeReview_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_멀버가_리뷰에_μ’‹μ•„μš”λ₯Ό_ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - final var wrongMemberId = memberId + 1L; - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var reviewCreaterequest = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - reviewService.create(productId, memberId, image, reviewCreaterequest); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); - - final var favoriteRequest = λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(true); - - // when - assertThatThrownBy(() -> reviewService.likeReview(reviewId, wrongMemberId, favoriteRequest)) - .isInstanceOf(MemberNotFoundException.class); - } - - @Test - void 멀버가_μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰에_μ’‹μ•„μš”λ₯Ό_ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var reviewCreaterequest = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - reviewService.create(productId, memberId, image, reviewCreaterequest); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); - final var wrongReviewId = reviewId + 1L; - - final var favoriteRequest = λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(true); - - // when - assertThatThrownBy(() -> reviewService.likeReview(wrongReviewId, memberId, favoriteRequest)) - .isInstanceOf(ReviewNotFoundException.class); - } - } - - @Nested - class sortingReviews_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ’‹μ•„μš”_κΈ°μ€€μœΌλ‘œ_λ‚΄λ¦Όμ°¨μˆœ_정렬을_ν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 351L); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 24L); - final var review3 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 130L); - 볡수_리뷰_μ €μž₯(review1, review2, review3); - - final var request = λ¦¬λ·°μ •λ ¬μš”μ²­_μ’‹μ•„μš”μˆ˜_λ‚΄λ¦Όμ°¨μˆœ_생성(0L); - - final var expected = List.of(review1.getId(), review3.getId(), review2.getId()); - - // when - final var actual = reviewService.sortingReviews(productId, memberId, request).getReviews(); - - // then - assertThat(actual).extracting(SortingReviewDto::getId) - .containsExactlyElementsOf(expected); - } - - @Test - void μ΅œμ‹ μˆœμœΌλ‘œ_정렬을_ν• _수_μžˆλ‹€() throws InterruptedException { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 351L); - Thread.sleep(100); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 24L); - Thread.sleep(100); - final var review3 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 130L); - 볡수_리뷰_μ €μž₯(review1, review2, review3); - - final var request = λ¦¬λ·°μ •λ ¬μš”μ²­_μ΅œμ‹ μˆœ_생성(3L); - - final var expected = List.of(review2.getId(), review1.getId()); - - // when - final var actual = reviewService.sortingReviews(productId, memberId, request).getReviews(); - - // then - assertThat(actual).extracting(SortingReviewDto::getId) - .containsExactlyElementsOf(expected); - } - - @Test - void 평점_κΈ°μ€€μœΌλ‘œ_μ˜€λ¦„μ°¨μˆœ_정렬을_ν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test2_평점2점_재ꡬ맀O_생성(member, product, 351L); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 24L); - final var review3 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 130L); - 볡수_리뷰_μ €μž₯(review1, review2, review3); - - final var request = λ¦¬λ·°μ •λ ¬μš”μ²­_평점_μ˜€λ¦„μ°¨μˆœ_생성(0L); - - final var expected = List.of(review1.getId(), review3.getId(), review2.getId()); - - // when - final var actual = reviewService.sortingReviews(productId, memberId, request).getReviews(); - - // then - assertThat(actual).extracting(SortingReviewDto::getId) - .containsExactlyElementsOf(expected); - } - - @Test - void 평점_κΈ°μ€€μœΌλ‘œ_λ‚΄λ¦Όμ°¨μˆœ_정렬을_ν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 5L); - final var review2 = 리뷰_이미지test2_평점2점_재ꡬ맀O_생성(member, product, 24L); - final var review3 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 13L); - 볡수_리뷰_μ €μž₯(review1, review2, review3); - - final var request = λ¦¬λ·°μ •λ ¬μš”μ²­_평점_λ‚΄λ¦Όμ°¨μˆœ_생성(1L); - - final var expected = List.of(review3.getId(), review2.getId()); - - // when - final var actual = reviewService.sortingReviews(productId, memberId, request).getReviews(); - - // then - assertThat(actual).extracting(SortingReviewDto::getId) - .containsExactlyElementsOf(expected); - } - } - - @Nested - class sortingReviews_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_멀버가_μƒν’ˆμ—_μžˆλŠ”_리뷰듀을_μ •λ ¬ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var wrongMemberId = 단일_멀버_μ €μž₯(member) + 3L; - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 351L); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 24L); - final var review3 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 130L); - 볡수_리뷰_μ €μž₯(review1, review2, review3); - - final var request = λ¦¬λ·°μ •λ ¬μš”μ²­_평점_λ‚΄λ¦Όμ°¨μˆœ_생성(1L); - - // when & then - assertThatThrownBy(() -> reviewService.sortingReviews(productId, wrongMemberId, request)) - .isInstanceOf(MemberNotFoundException.class); - } - - @Test - void 멀버가_μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆμ—_μžˆλŠ”_리뷰듀을_μ •λ ¬ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var wrongProductId = 단일_μƒν’ˆ_μ €μž₯(product) + 1L; - - final var review1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 351L); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 24L); - final var review3 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 130L); - 볡수_리뷰_μ €μž₯(review1, review2, review3); - - final var request = λ¦¬λ·°μ •λ ¬μš”μ²­_평점_λ‚΄λ¦Όμ°¨μˆœ_생성(1L); - - // when & then - assertThatThrownBy(() -> reviewService.sortingReviews(wrongProductId, memberId, request)) - .isInstanceOf(ProductNotFoundException.class); - } - } - - @Nested - class findReviewByMember_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_리뷰λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - 볡수_멀버_μ €μž₯(member1, member2); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - final var product3 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점1점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2, product3); - - final var review1_1 = 리뷰_이미지test2_평점2점_재ꡬ맀X_생성(member1, product3, 0L); - - final var review2_1 = 리뷰_이미지test1_평점1점_재ꡬ맀X_생성(member1, product2, 0L); - final var review2_2 = 리뷰_이미지test1_평점1점_재ꡬ맀X_생성(member2, product2, 0L); - - final var review3_1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member1, product1, 0L); - final var review3_2 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member2, product1, 0L); - 볡수_리뷰_μ €μž₯(review1_1, review2_1, review2_2, review3_1, review3_2); - - // when - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ΅œμ‹ μˆœ); - final var member1Id = member1.getId(); - final var result = reviewService.findReviewByMember(member1Id, page); - - // then - final var expectedReviews = List.of(review3_1, review2_1, review1_1); - final var expectedReviewDtos = expectedReviews.stream() - .map(MemberReviewDto::toDto) - .collect(Collectors.toList()); - final var expectedPage = new PageDto(3L, 1L, true, true, 0L, 10L); - - assertThat(result.getReviews()).usingRecursiveComparison() - .isEqualTo(expectedReviewDtos); - assertThat(result.getPage()).usingRecursiveComparison() - .isEqualTo(expectedPage); - } - } - - @Nested - class findReviewByMember_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•Šμ€_μ‚¬μš©μžκ°€_μž‘μ„±ν•œ_리뷰λ₯Ό_μ‘°νšŒν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var notExistMemberId = 999999L; - final var page = νŽ˜μ΄μ§€μš”μ²­_생성(0, 10, μ΅œμ‹ μˆœ); - - // when & then - assertThatThrownBy(() -> reviewService.findReviewByMember(notExistMemberId, page)) - .isInstanceOf(MemberNotFoundException.class); - } - } - - @Nested - class updateProductImage_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 처음_리뷰가_λ“±λ‘λ˜λ©΄_ν•΄λ‹Ή_리뷰의_μ΄λ―Έμ§€λ‘œ_μƒν’ˆ_이미지가_λ³€κ²½λœλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 0L); - final var reviewId = 단일_리뷰_μ €μž₯(review); - - final var expected = review.getImage(); - - // when - reviewService.updateProductImage(product.getId()); - final var actual = product.getImage(); - - // then - assertThat(actual).isEqualTo(expected); - } - - @Test - void κ°€μž₯_λ§Žμ€_μ’‹μ•„μš”λ₯Ό_받은_리뷰가_λ°”λ€Œλ©΄_ν•΄λ‹Ή_리뷰의_μ΄λ―Έμ§€λ‘œ_μƒν’ˆ_이미지가_λ³€κ²½λœλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var firstReview = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 1L); - final var firstReviewId = 단일_리뷰_μ €μž₯(firstReview); - reviewService.updateProductImage(firstReviewId); - - final var secondReview = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 2L); - final var secondReviewId = 단일_리뷰_μ €μž₯(secondReview); - - final var expected = secondReview.getImage(); - - // when - reviewService.updateProductImage(product.getId()); - final var actual = product.getImage(); - - // then - assertThat(actual).isEqualTo(expected); - } - - @Test - void 리뷰에_μ’‹μ•„μš”λ₯Ό_ν–ˆμ§€λ§Œ_κ°€μž₯_λ§Žμ€_μ’‹μ•„μš”μΈ_리뷰가_λ°”λ€Œμ§€_μ•ŠμœΌλ©΄_μƒν’ˆ_μ΄λ―Έμ§€λŠ”_λ³€κ²½λ˜μ§€_μ•ŠλŠ”λ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var firstReview = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 100L); - final var firstReviewId = 단일_리뷰_μ €μž₯(firstReview); - reviewService.updateProductImage(firstReviewId); - - final var secondReview = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 0L); - final var secondReviewId = 단일_리뷰_μ €μž₯(secondReview); - - final var expected = firstReview.getImage(); - - // when - reviewService.updateProductImage(product.getId()); - final var actual = product.getImage(); - - // then - assertThat(actual).isEqualTo(expected); - } - - @Test - void 리뷰에_μ’‹μ•„μš”λ₯Ό_ν–ˆλŠ”λ°_κ°€μž₯_λ§Žμ€_μ’‹μ•„μš”κ°€_된_리뷰가_μ—¬λŸ¬κ°œλ©΄_μ΅œκ·Όμ—_κ°€μž₯_λ§Žμ€_μ’‹μ•„μš”_리뷰_μ΄λ―Έμ§€λ‘œ_바뀐닀() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var firstReview = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 0L); - final var firstReviewId = 단일_리뷰_μ €μž₯(firstReview); - reviewService.updateProductImage(firstReviewId); - - final var secondReview = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 0L); - final var secondReviewId = 단일_리뷰_μ €μž₯(secondReview); - - final var expected = secondReview.getImage(); - - // when - reviewService.updateProductImage(product.getId()); - final var actual = product.getImage(); - - // then - assertThat(actual).isEqualTo(expected); - } - - @Test - void κ°€μž₯_λ§Žμ€_μ’‹μ•„μš”λ₯Ό_받은_리뷰듀에_이미지가_μ—†μœΌλ©΄_이미지가_μ‘΄μž¬ν•˜λŠ”_μ’‹μ•„μš”λ₯Ό_많이_받은_리뷰_μ΄λ―Έμ§€λ‘œ_바뀐닀() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var firstReview = 리뷰_μ΄λ―Έμ§€μ—†μŒ_평점1점_재ꡬ맀O_생성(member, product, 3L); - final var firstReviewId = 단일_리뷰_μ €μž₯(firstReview); - reviewService.updateProductImage(product.getId()); - - final var secondReview = 리뷰_μ΄λ―Έμ§€μ—†μŒ_평점1점_재ꡬ맀O_생성(member, product, 2L); - final var secondReviewId = 단일_리뷰_μ €μž₯(secondReview); - reviewService.updateProductImage(product.getId()); - - final var thirdReview = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 1L); - final var thirdReviewId = 단일_리뷰_μ €μž₯(thirdReview); - - final var expected = thirdReview.getImage(); - - // when - reviewService.updateProductImage(product.getId()); - final var actual = product.getImage(); - - // then - assertThat(actual).isEqualTo(expected); - } - - @Test - void 이미지가_μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_λ¦¬λ·°λ“€λ§Œ_있으면_μƒν’ˆ_μ΄λ―Έμ§€λŠ”_λ°”λ€Œμ§€_μ•ŠλŠ”λ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var firstReview = 리뷰_μ΄λ―Έμ§€μ—†μŒ_평점1점_재ꡬ맀O_생성(member, product, 3L); - final var firstReviewId = 단일_리뷰_μ €μž₯(firstReview); - reviewService.updateProductImage(product.getId()); - - final var secondReview = 리뷰_μ΄λ―Έμ§€μ—†μŒ_평점1점_재ꡬ맀O_생성(member, product, 2L); - final var secondReviewId = 단일_리뷰_μ €μž₯(secondReview); - - final var expected = secondReview.getImage(); - - // when - reviewService.updateProductImage(product.getId()); - final var actual = product.getImage(); - - // then - assertThat(actual).isNotEqualTo(expected); - } - } - - @Nested - class updateProductImage_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆμœΌλ‘œ_μƒν’ˆ_μ—…λ°μ΄νŠΈλ₯Ό_μ‹œλ„ν•˜λ©΄_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var wrongProductId = 999L; - - // when & then - assertThatThrownBy(() -> reviewService.updateProductImage(wrongProductId)) - .isInstanceOf(ProductNotFoundException.class); - } - } - - @Nested - class deleteReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μžμ‹ μ΄_μž‘μ„±ν•œ_리뷰λ₯Ό_μ‚­μ œν• _수_μžˆλ‹€() { - // given - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - final var member = 멀버_멀버2_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var reviewCreateRequest1 = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(2L, tagIds); - final var reviewCreateRequest2 = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - - reviewService.create(productId, authorId, image, reviewCreateRequest1); - reviewService.create(productId, authorId, image, reviewCreateRequest2); - - final var reviews = reviewRepository.findAll(); - final var rating2_review = reviews.stream() - .filter(it -> it.getRating() == 2L) - .findFirst() - .get(); - - final var favoriteRequest = λ¦¬λ·°μ’‹μ•„μš”μš”μ²­_생성(true); - reviewService.likeReview(rating2_review.getId(), authorId, favoriteRequest); - reviewService.likeReview(rating2_review.getId(), memberId, favoriteRequest); - - // when - reviewService.deleteReview(rating2_review.getId(), authorId); - - // then - final var tags = reviewTagRepository.findByReview(rating2_review); - final var favorites = reviewFavoriteRepository.findByReview(rating2_review); - final var findReview = reviewRepository.findById(rating2_review.getId()); - final var findProduct = productRepository.findById(productId).get(); - - assertSoftly(soft -> { - soft.assertThat(tags).isEmpty(); - soft.assertThat(favorites).isEmpty(); - soft.assertThat(findReview).isEmpty(); - soft.assertThat(findProduct.getAverageRating()).isEqualTo(4.0); - soft.assertThat(findProduct.getReviewCount()).isEqualTo(1); - }); - } - } - - @Nested - class deleteReview_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μ‚¬μš©μžκ°€_리뷰λ₯Ό_μ‚­μ œν•˜λ €ν•˜λ©΄_μ—λŸ¬κ°€_λ°œμƒν•œλ‹€() { - // given - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var reviewCreateRequest = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - reviewService.create(productId, authorId, image, reviewCreateRequest); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); - - final var wrongMemberId = 999L; - - // when & then - assertThatThrownBy(() -> reviewService.deleteReview(reviewId, wrongMemberId)) - .isInstanceOf(MemberNotFoundException.class); - } - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰λ₯Ό_μ‚­μ œν•˜λ €ν•˜λ©΄_μ—λŸ¬κ°€_λ°œμƒν•œλ‹€() { - // given - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var reviewCreateRequest = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - reviewService.create(productId, authorId, image, reviewCreateRequest); - - final var wrongReviewId = 999L; - - // when & then - assertThatThrownBy(() -> reviewService.deleteReview(wrongReviewId, authorId)) - .isInstanceOf(ReviewNotFoundException.class); - } - - @Test - void μžμ‹ μ΄_μž‘μ„±ν•˜μ§€_μ•Šμ€_리뷰λ₯Ό_μ‚­μ œν•˜λ €ν•˜λ©΄_μ—λŸ¬κ°€_λ°œμƒν•œλ‹€() { - // given - final var author = 멀버_멀버1_생성(); - final var authorId = 단일_멀버_μ €μž₯(author); - final var member = 멀버_멀버2_생성(); - final var memberId = 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_아침식사_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - final var image = 이미지_생성(); - final var reviewCreateRequest = λ¦¬λ·°μΆ”κ°€μš”μ²­_재ꡬ맀O_생성(4L, tagIds); - reviewService.create(productId, authorId, image, reviewCreateRequest); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); - - // when & then - assertThatThrownBy(() -> reviewService.deleteReview(reviewId, memberId)) - .isInstanceOf(NotAuthorOfReviewException.class); - } - } - - @Nested - class getMostFavoriteReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰가_μ—¬λŸ¬κ°œ_μ‘΄μž¬ν•˜λ©΄_μ’‹μ•„μš”λ₯Ό_κ°€μž₯_많이_받은_리뷰λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 351L); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 24L); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var expected = MostFavoriteReviewResponse.toResponse(Optional.of(review1)); - - // when - final var actual = reviewService.getMostFavoriteReview(productId); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void μ’‹μ•„μš”_μˆ˜κ°€_같은_리뷰가_μ—¬λŸ¬κ°œ_μ‘΄μž¬ν•˜λ©΄_κ°€μž₯_졜근_μž‘μ„±λœ_리뷰λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 351L); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 351L); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var expected = MostFavoriteReviewResponse.toResponse(Optional.of(review2)); - - // when - final var actual = reviewService.getMostFavoriteReview(productId); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 리뷰가_μ‘΄μž¬ν•˜μ§€_μ•ŠμœΌλ©΄_Optional_emptyλ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점3점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var expected = Optional.empty(); - - // when - final var actual = reviewService.getMostFavoriteReview(productId); - - // then - assertThat(actual).isEqualTo(expected); - } - } - - @Nested - class getMostFavoriteReview_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_μƒν’ˆμ—_κ°€μž₯_λ§Žμ€_μ’‹μ•„μš”λ₯Ό_받은_리뷰λ₯Ό_찾으면_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var wrongProductId = 단일_μƒν’ˆ_μ €μž₯(product) + 1L; - - // when & then - assertThatThrownBy(() -> reviewService.getMostFavoriteReview(wrongProductId)) - .isInstanceOf(ProductNotFoundException.class); - } - } - - @Nested - class getReviewDetail_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰_상세_정보λ₯Ό_μ‘°νšŒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점5점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review = 리뷰_이미지test2_평점2점_재ꡬ맀X_생성(member, product, 0L); - 단일_리뷰_μ €μž₯(review); - - // when - final var actual = reviewService.getReviewDetail(review.getId()); - - // then - final var expected = ReviewDetailResponse.toResponse(review); - - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class getReviewDetail_μ‹€νŒ¨_ν…ŒμŠ€νŠΈ { - - @Test - void μ‘΄μž¬ν•˜μ§€_μ•ŠλŠ”_리뷰λ₯Ό_μ‘°νšŒν• λ•Œ_μ˜ˆμ™Έκ°€_λ°œμƒν•œλ‹€() { - // given - final var notExistReviewId = 999999L; - - // when & then - assertThatThrownBy(() -> reviewService.getReviewDetail(notExistReviewId)) - .isInstanceOf(ReviewNotFoundException.class); - } - } - - @Nested - class getTopReviews_성곡_ν…ŒμŠ€νŠΈ { - - @Nested - class 리뷰_κ°œμˆ˜μ—_λŒ€ν•œ_ν…ŒμŠ€νŠΈ { - - @Test - void 전체_리뷰가_ν•˜λ‚˜λ„_없어도_λ°˜ν™˜κ°’μ€_μžˆμ–΄μ•Όν•œλ‹€() { - // given - final var expected = RankingReviewsResponse.toResponse(Collections.emptyList()); - - // when - final var actual = reviewService.getTopReviews(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 전체_리뷰가_1개_이상_3개_λ―Έλ§Œμ΄λΌλ„_리뷰가_λ‚˜μ™€μ•Όν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var review1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 2L, now.minusDays(1L)); - final var review2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 2L, now); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var rankingReviewDto1 = RankingReviewDto.toDto(review1); - final var rankingReviewDto2 = RankingReviewDto.toDto(review2); - final var rankingReviewDtos = List.of(rankingReviewDto2, rankingReviewDto1); - final var expected = RankingReviewsResponse.toResponse(rankingReviewDtos); - - // when - final var actual = reviewService.getTopReviews(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 전체_리뷰_쀑_λž­ν‚Ήμ΄_높은_μƒμœ„_3개_리뷰λ₯Ό_ꡬ할_수_μžˆλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var review1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 4L, now.minusDays(3L)); - final var review2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 6L, now.minusDays(2L)); - final var review3 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 4L, now); - final var review4 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 5L, now); - 볡수_리뷰_μ €μž₯(review1, review2, review3, review4); - - final var rankingReviewDto1 = RankingReviewDto.toDto(review1); - final var rankingReviewDto2 = RankingReviewDto.toDto(review2); - final var rankingReviewDto3 = RankingReviewDto.toDto(review3); - final var rankingReviewDto4 = RankingReviewDto.toDto(review4); - final var rankingReviewDtos = List.of(rankingReviewDto4, rankingReviewDto3, rankingReviewDto2); - final var expected = RankingReviewsResponse.toResponse(rankingReviewDtos); - - // when - final var actual = reviewService.getTopReviews(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class 리뷰_λž­ν‚Ή_μ μˆ˜μ—_λŒ€ν•œ_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰_μ’‹μ•„μš”_μˆ˜κ°€_κ°™μœΌλ©΄_졜근_μƒμ„±λœ_리뷰의_λž­ν‚Ήμ„_더_λ†’κ²Œ_λ°˜ν™˜ν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var review1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 10L, now.minusDays(9L)); - final var review2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 10L, now.minusDays(4L)); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var rankingReviewDto1 = RankingReviewDto.toDto(review1); - final var rankingReviewDto2 = RankingReviewDto.toDto(review2); - final var rankingReviewDtos = List.of(rankingReviewDto2, rankingReviewDto1); - final var expected = RankingReviewsResponse.toResponse(rankingReviewDtos); - - // when - final var actual = reviewService.getTopReviews(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void 리뷰_생성_μΌμžκ°€_κ°™μœΌλ©΄_μ’‹μ•„μš”_μˆ˜κ°€_λ§Žμ€_리뷰의_λž­ν‚Ήμ„_더_λ†’κ²Œ_λ°˜ν™˜ν•œλ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점4점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var now = LocalDateTime.now(); - final var review1 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 2L, now.minusDays(1L)); - final var review2 = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, 4L, now.minusDays(1L)); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var rankingReviewDto1 = RankingReviewDto.toDto(review1); - final var rankingReviewDto2 = RankingReviewDto.toDto(review2); - final var rankingReviewDtos = List.of(rankingReviewDto2, rankingReviewDto1); - final var expected = RankingReviewsResponse.toResponse(rankingReviewDtos); - - // when - final var actual = reviewService.getTopReviews(); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - } - - private List νƒœκ·Έ_아이디_λ³€ν™˜(final Tag... tags) { - return Stream.of(tags) - .map(Tag::getId) - .collect(Collectors.toList()); - } -} diff --git a/backend/src/test/java/com/funeat/review/domain/ReviewTest.java b/backend/src/test/java/com/funeat/review/domain/ReviewTest.java deleted file mode 100644 index a9b02876b..000000000 --- a/backend/src/test/java/com/funeat/review/domain/ReviewTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.funeat.review.domain; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test5_평점5점_재ꡬ맀X_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import java.time.LocalDateTime; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -class ReviewTest { - - @Nested - class calculateRankingScore_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰_μ’‹μ•„μš”_μˆ˜μ™€_리뷰_생성_μ‹œκ°„μœΌλ‘œ_ν•΄λ‹Ή_리뷰의_λž­ν‚Ή_점수λ₯Ό_ꡬ할_수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - final var favoriteCount = 4L; - final var review = 리뷰_이미지test5_평점5점_재ꡬ맀X_생성(member, product, favoriteCount, LocalDateTime.now().minusDays(1L)); - - final var expected = favoriteCount / Math.pow(2.0, 0.5); - - // when - final var actual = review.calculateRankingScore(); - - // then - assertThat(actual).isEqualTo(expected); - } - } -} diff --git a/backend/src/test/java/com/funeat/review/persistence/ReviewRepositoryTest.java b/backend/src/test/java/com/funeat/review/persistence/ReviewRepositoryTest.java deleted file mode 100644 index 46e4645f4..000000000 --- a/backend/src/test/java/com/funeat/review/persistence/ReviewRepositoryTest.java +++ /dev/null @@ -1,221 +0,0 @@ -package com.funeat.review.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성; -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버2_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버3_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test1_평점1점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test3_평점3점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test3_평점3점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test4_평점4점_재ꡬ맀O_생성; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.funeat.common.RepositoryTest; -import java.util.Collections; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.data.domain.PageRequest; - -@SuppressWarnings("NonAsciiCharacters") -class ReviewRepositoryTest extends RepositoryTest { - - @Nested - class countByProduct_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μƒν’ˆμ˜_리뷰_수λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var member1 = 멀버_멀버1_생성(); - final var member2 = 멀버_멀버2_생성(); - final var member3 = 멀버_멀버3_생성(); - 볡수_멀버_μ €μž₯(member1, member2, member3); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product1 = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var product2 = μƒν’ˆ_삼각김λ°₯_가격2000원_평점3점_생성(category); - 볡수_μƒν’ˆ_μ €μž₯(product1, product2); - - final var review1_1 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member1, product1, 0L); - final var review1_2 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member2, product1, 0L); - final var review1_3 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member3, product1, 0L); - final var review2_1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member1, product2, 0L); - 볡수_리뷰_μ €μž₯(review1_1, review1_2, review1_3, review2_1); - - // when - final var actual1 = reviewRepository.countByProduct(product1); - final var actual2 = reviewRepository.countByProduct(product2); - - // then - assertSoftly(soft -> { - soft.assertThat(actual1) - .isEqualTo(3); - soft.assertThat(actual2) - .isEqualTo(1); - }); - } - } - - @Nested - class findPopularReviewWithImage_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰가_μ‘΄μž¬ν•˜μ§€_μ•ŠμœΌλ©΄_빈_값을_λ°˜ν™˜ν•˜λ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점1점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var pageable = PageRequest.of(0, 1); - - // when - final var actual = reviewRepository.findPopularReviewWithImage(productId, pageable); - - // then - assertThat(actual).isEmpty(); - } - - @Test - void 리뷰가_μ‘΄μž¬ν•˜λ©΄_μ’‹μ•„μš”_μˆ˜κ°€_λͺ‡κ°œμ΄λ“ _리뷰λ₯Ό_λ°˜ν™˜ν•˜λ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var review1 = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 2L); - final var review2 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 1L); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var pageable = PageRequest.of(0, 1); - - // when - final var actual = reviewRepository.findPopularReviewWithImage(productId, pageable).get(0); - - // then - assertThat(actual).usingRecursiveComparison().isEqualTo(review1); - } - - @Test - void μ’‹μ•„μš”_μˆ˜κ°€_κ°™μœΌλ©΄_μ΅œμ‹ _리뷰λ₯Ό_λ°˜ν™˜ν•˜λ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var review1 = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 0L); - final var review2 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 0L); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var pageable = PageRequest.of(0, 1); - - // when - final var actual = reviewRepository.findPopularReviewWithImage(productId, pageable).get(0); - - // then - assertThat(actual).usingRecursiveComparison().isEqualTo(review2); - } - } - - @Nested - class findTopByProductOrderByFavoriteCountDescIdDesc_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ’‹μ•„μš”κ°€_κ°€μž₯_λ§Žμ€_리뷰λ₯Ό_λ°˜ν™˜ν•˜λ‹€() { - // given - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var review1 = 리뷰_이미지test1_평점1점_재ꡬ맀O_생성(member, product, 0L); - final var review2 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 4L); - 볡수_리뷰_μ €μž₯(review1, review2); - - // when - final var actual = reviewRepository.findTopByProductOrderByFavoriteCountDescIdDesc(product); - - // then - assertThat(actual.get()).isEqualTo(review2); - } - } - - @Nested - class findReviewsByFavoriteCountGreaterThanEqual_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void νŠΉμ •_μ’‹μ•„μš”_수_이상인_λͺ¨λ“ _리뷰듀을_μ‘°νšŒν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 1L); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 0L); - final var review3 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 100L); - 볡수_리뷰_μ €μž₯(review1, review2, review3); - - final var expected = List.of(review1, review3); - - // when - final var actual = reviewRepository.findReviewsByFavoriteCountGreaterThanEqual(1L); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - - @Test - void νŠΉμ •_μ’‹μ•„μš”_수_이상인_리뷰가_μ—†μœΌλ©΄_빈_리슀트λ₯Ό_λ°˜ν™˜ν•œλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_κ°„νŽΈμ‹μ‚¬_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격1000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var review1 = 리뷰_이미지test3_평점3점_재ꡬ맀O_생성(member, product, 0L); - final var review2 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 0L); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var expected = Collections.emptyList(); - - // when - final var actual = reviewRepository.findReviewsByFavoriteCountGreaterThanEqual(1L); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } -} diff --git a/backend/src/test/java/com/funeat/review/persistence/ReviewTagRepositoryTest.java b/backend/src/test/java/com/funeat/review/persistence/ReviewTagRepositoryTest.java deleted file mode 100644 index 4f5bbf152..000000000 --- a/backend/src/test/java/com/funeat/review/persistence/ReviewTagRepositoryTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.funeat.review.persistence; - -import static com.funeat.fixture.CategoryFixture.μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성; -import static com.funeat.fixture.MemberFixture.멀버_멀버1_생성; -import static com.funeat.fixture.PageFixture.νŽ˜μ΄μ§€μš”μ²­_κΈ°λ³Έ_생성; -import static com.funeat.fixture.ProductFixture.μƒν’ˆ_삼각김λ°₯_가격3000원_평점2점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test3_평점3점_재ꡬ맀X_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test4_평점4점_재ꡬ맀O_생성; -import static com.funeat.fixture.ReviewFixture.리뷰_이미지test5_평점5점_재ꡬ맀O_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_간식_ETC_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_κ°“μ„±λΉ„_PRICE_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_단짠단짠_TASTE_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.RepositoryTest; -import com.funeat.review.domain.Review; -import com.funeat.review.domain.ReviewTag; -import com.funeat.tag.domain.Tag; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class ReviewTagRepositoryTest extends RepositoryTest { - - @Nested - class findTop3TagsByReviewIn_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void 리뷰_λͺ©λ‘μ—μ„œ_μƒμœ„_3κ°œμ—_ν•΄λ‹Ήν•˜λŠ”_νƒœκ·Έλ₯Ό_μ‘°νšŒν•œλ‹€() { - - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격3000원_평점2점_생성(category); - final var productId = 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_단짠단짠_TASTE_생성(); - final var tag3 = νƒœκ·Έ_κ°“μ„±λΉ„_PRICE_생성(); - final var tag4 = νƒœκ·Έ_간식_ETC_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2, tag3, tag4); - - final var review1 = 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(member, product, 0L); - final var review2 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 0L); - final var review3 = 리뷰_이미지test4_평점4점_재ꡬ맀O_생성(member, product, 0L); - 볡수_리뷰_μ €μž₯(review1, review2, review3); - - final var reviewTag1_1 = 리뷰_νƒœκ·Έ_생성(review1, tag1); - final var reviewTag1_2 = 리뷰_νƒœκ·Έ_생성(review1, tag2); - final var reviewTag2_1 = 리뷰_νƒœκ·Έ_생성(review2, tag1); - final var reviewTag2_2 = 리뷰_νƒœκ·Έ_생성(review2, tag2); - final var reviewTag2_3 = 리뷰_νƒœκ·Έ_생성(review2, tag3); - final var reviewTag3_1 = 리뷰_νƒœκ·Έ_생성(review3, tag1); - 볡수_리뷰_νƒœκ·Έ_μ €μž₯(reviewTag1_1, reviewTag1_2, reviewTag2_1, reviewTag2_2, reviewTag2_3, reviewTag3_1); - - final var page = νŽ˜μ΄μ§€μš”μ²­_κΈ°λ³Έ_생성(0, 3); - - final var expected = List.of(tag1, tag2, tag3); - - // when - final var top3Tags = reviewTagRepository.findTop3TagsByReviewIn(productId, page); - - // then - assertThat(top3Tags).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class deleteByReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void ν•΄λ‹Ή_리뷰에_달린_νƒœκ·Έλ₯Ό_μ‚­μ œν• _수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격3000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - 단일_νƒœκ·Έ_μ €μž₯(tag1); - - final var review1 = 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(member, product, 0L); - final var review2 = 리뷰_이미지test3_평점3점_재ꡬ맀X_생성(member, product, 0L); - 볡수_리뷰_μ €μž₯(review1, review2); - - final var reviewTag1_1 = 리뷰_νƒœκ·Έ_생성(review1, tag1); - final var reviewTag2_1 = 리뷰_νƒœκ·Έ_생성(review2, tag1); - 볡수_리뷰_νƒœκ·Έ_μ €μž₯(reviewTag1_1, reviewTag2_1); - - final var expected = List.of(reviewTag2_1); - - // when - reviewTagRepository.deleteByReview(review1); - - // then - final var remainings = reviewTagRepository.findAll(); - assertThat(remainings).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class findByReview_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void ν•΄λ‹Ή_리뷰에_달린_νƒœκ·Έλ₯Ό_확인할_수_μžˆλ‹€() { - // given - final var member = 멀버_멀버1_생성(); - 단일_멀버_μ €μž₯(member); - - final var category = μΉ΄ν…Œκ³ λ¦¬_즉석쑰리_생성(); - 단일_μΉ΄ν…Œκ³ λ¦¬_μ €μž₯(category); - - final var product = μƒν’ˆ_삼각김λ°₯_가격3000원_평점2점_생성(category); - 단일_μƒν’ˆ_μ €μž₯(product); - - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - 단일_νƒœκ·Έ_μ €μž₯(tag1); - - final var review = 리뷰_이미지test5_평점5점_재ꡬ맀O_생성(member, product, 0L); - 단일_리뷰_μ €μž₯(review); - - final var reviewTag = 리뷰_νƒœκ·Έ_생성(review, tag1); - 단일_리뷰_νƒœκ·Έ_μ €μž₯(reviewTag); - - final var expected = List.of(reviewTag); - - // when - final var actual = reviewTagRepository.findByReview(review); - - // then - assertThat(actual).usingRecursiveComparison() - .ignoringExpectedNullFields() - .isEqualTo(expected); - } - } - - private ReviewTag 리뷰_νƒœκ·Έ_생성(final Review review, final Tag tag) { - return ReviewTag.createReviewTag(review, tag); - } -} diff --git a/backend/src/test/java/com/funeat/tag/persistence/TagRepositoryTest.java b/backend/src/test/java/com/funeat/tag/persistence/TagRepositoryTest.java deleted file mode 100644 index 2b6dc178b..000000000 --- a/backend/src/test/java/com/funeat/tag/persistence/TagRepositoryTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.funeat.tag.persistence; - -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_κ°“μ„±λΉ„_PRICE_생성; -import static com.funeat.fixture.TagFixture.νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성; -import static com.funeat.tag.domain.TagType.TASTE; -import static org.assertj.core.api.Assertions.assertThat; - -import com.funeat.common.RepositoryTest; -import com.funeat.tag.domain.Tag; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("NonAsciiCharacters") -class TagRepositoryTest extends RepositoryTest { - - @Nested - class findTagsByIdIn_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void μ—¬λŸ¬_νƒœκ·Έ_μ•„μ΄λ””λ‘œ_νƒœκ·Έλ“€μ„_쑰회_ν• _수_μžˆλ‹€() { - // given - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_κ°“μ„±λΉ„_PRICE_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var tagIds = νƒœκ·Έ_아이디_λ³€ν™˜(tag1, tag2); - - final var expected = List.of(tag1, tag2); - - // then - final var actual = tagRepository.findTagsByIdIn(tagIds); - - // when - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - @Nested - class findTagsByTagType_성곡_ν…ŒμŠ€νŠΈ { - - @Test - void νƒœκ·Έ_νƒ€μž…μœΌλ‘œ_νƒœκ·Έλ“€μ„_μ‘°νšŒν• _수_μžˆλ‹€() { - // given - final var tag1 = νƒœκ·Έ_λ§›μžˆμ–΄μš”_TASTE_생성(); - final var tag2 = νƒœκ·Έ_κ°“μ„±λΉ„_PRICE_생성(); - 볡수_νƒœκ·Έ_μ €μž₯(tag1, tag2); - - final var expected = List.of(tag1); - - // when - final var actual = tagRepository.findTagsByTagType(TASTE); - - // then - assertThat(actual).usingRecursiveComparison() - .isEqualTo(expected); - } - } - - private List νƒœκ·Έ_아이디_λ³€ν™˜(final Tag... tags) { - return Stream.of(tags) - .map(Tag::getId) - .collect(Collectors.toList()); - } -} diff --git a/backend/src/test/resources/application.yml b/backend/src/test/resources/application.yml deleted file mode 100644 index 5d2dd0387..000000000 --- a/backend/src/test/resources/application.yml +++ /dev/null @@ -1,45 +0,0 @@ -spring: - profiles: - active: test - - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:test${random.uuid};MODE=MySQL - username: sa - - jpa: - hibernate: - ddl-auto: create - properties: - hibernate: - format_sql: true - show_sql: true - - session: - store-type: none - -logging: - level: - org.hibernate.type.descriptor.sql: trace - -cloud: - aws: - region: - static: testRegion - s3: - bucket: testBucket - folder: testFolder - cloudfrontPath: testCloudfrontPath - image: - food: foodimage - store: storeimage - -back-office: - id: test - key: test - -server: - servlet: - session: - cookie: - name: SESSION diff --git a/frontend/jest.config.js b/jest.config.js similarity index 100% rename from frontend/jest.config.js rename to jest.config.js diff --git a/frontend/package.json b/package.json similarity index 97% rename from frontend/package.json rename to package.json index 335158204..d448e7cfb 100644 --- a/frontend/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build": "webpack --config webpack.prod.js", "build-dev": "webpack --config webpack.dev.js", "storybook": "storybook dev -p 6006", - "lint:styled": "stylelint './src/**/*.tsx' --fix", + "lint:styled": "stylelint 'src/**/*.tsx' --fix", "test": "jest", "test:coverage": "jest --watchAll --coverage" }, diff --git a/frontend/public/assets/apple-icon-180x180.png b/public/assets/apple-icon-180x180.png similarity index 100% rename from frontend/public/assets/apple-icon-180x180.png rename to public/assets/apple-icon-180x180.png diff --git a/frontend/public/assets/favicon-16x16.png b/public/assets/favicon-16x16.png similarity index 100% rename from frontend/public/assets/favicon-16x16.png rename to public/assets/favicon-16x16.png diff --git a/frontend/public/assets/favicon-32x32.png b/public/assets/favicon-32x32.png similarity index 100% rename from frontend/public/assets/favicon-32x32.png rename to public/assets/favicon-32x32.png diff --git a/frontend/public/assets/favicon.ico b/public/assets/favicon.ico similarity index 100% rename from frontend/public/assets/favicon.ico rename to public/assets/favicon.ico diff --git a/frontend/public/assets/og-image.png b/public/assets/og-image.png similarity index 100% rename from frontend/public/assets/og-image.png rename to public/assets/og-image.png diff --git a/frontend/public/index.html b/public/index.html similarity index 100% rename from frontend/public/index.html rename to public/index.html diff --git a/frontend/public/manifest.json b/public/manifest.json similarity index 100% rename from frontend/public/manifest.json rename to public/manifest.json diff --git a/frontend/public/mockServiceWorker.js b/public/mockServiceWorker.js similarity index 100% rename from frontend/public/mockServiceWorker.js rename to public/mockServiceWorker.js diff --git a/frontend/public/robots.txt b/public/robots.txt similarity index 100% rename from frontend/public/robots.txt rename to public/robots.txt diff --git a/frontend/public/sitemap.xml b/public/sitemap.xml similarity index 100% rename from frontend/public/sitemap.xml rename to public/sitemap.xml diff --git a/frontend/src/apis/ApiClient.ts b/src/apis/ApiClient.ts similarity index 100% rename from frontend/src/apis/ApiClient.ts rename to src/apis/ApiClient.ts diff --git a/frontend/src/apis/fetch.ts b/src/apis/fetch.ts similarity index 100% rename from frontend/src/apis/fetch.ts rename to src/apis/fetch.ts diff --git a/frontend/src/apis/index.ts b/src/apis/index.ts similarity index 100% rename from frontend/src/apis/index.ts rename to src/apis/index.ts diff --git a/frontend/src/assets/characters.svg b/src/assets/characters.svg similarity index 100% rename from frontend/src/assets/characters.svg rename to src/assets/characters.svg diff --git a/frontend/src/assets/logo.svg b/src/assets/logo.svg similarity index 100% rename from frontend/src/assets/logo.svg rename to src/assets/logo.svg diff --git a/frontend/src/assets/plate.svg b/src/assets/plate.svg similarity index 100% rename from frontend/src/assets/plate.svg rename to src/assets/plate.svg diff --git a/frontend/src/assets/samgakgimbab.svg b/src/assets/samgakgimbab.svg similarity index 100% rename from frontend/src/assets/samgakgimbab.svg rename to src/assets/samgakgimbab.svg diff --git a/frontend/src/components/Common/Banner/Banner.tsx b/src/components/Common/Banner/Banner.tsx similarity index 100% rename from frontend/src/components/Common/Banner/Banner.tsx rename to src/components/Common/Banner/Banner.tsx diff --git a/frontend/src/components/Common/CategoryFoodList/CategoryFoodList.stories.tsx b/src/components/Common/CategoryFoodList/CategoryFoodList.stories.tsx similarity index 100% rename from frontend/src/components/Common/CategoryFoodList/CategoryFoodList.stories.tsx rename to src/components/Common/CategoryFoodList/CategoryFoodList.stories.tsx diff --git a/frontend/src/components/Common/CategoryFoodList/CategoryFoodList.tsx b/src/components/Common/CategoryFoodList/CategoryFoodList.tsx similarity index 100% rename from frontend/src/components/Common/CategoryFoodList/CategoryFoodList.tsx rename to src/components/Common/CategoryFoodList/CategoryFoodList.tsx diff --git a/frontend/src/components/Common/CategoryFoodTab/CategoryFoodTab.stories.tsx b/src/components/Common/CategoryFoodTab/CategoryFoodTab.stories.tsx similarity index 100% rename from frontend/src/components/Common/CategoryFoodTab/CategoryFoodTab.stories.tsx rename to src/components/Common/CategoryFoodTab/CategoryFoodTab.stories.tsx diff --git a/frontend/src/components/Common/CategoryFoodTab/CategoryFoodTab.tsx b/src/components/Common/CategoryFoodTab/CategoryFoodTab.tsx similarity index 100% rename from frontend/src/components/Common/CategoryFoodTab/CategoryFoodTab.tsx rename to src/components/Common/CategoryFoodTab/CategoryFoodTab.tsx diff --git a/frontend/src/components/Common/CategoryItem/CategoryItem.stories.tsx b/src/components/Common/CategoryItem/CategoryItem.stories.tsx similarity index 100% rename from frontend/src/components/Common/CategoryItem/CategoryItem.stories.tsx rename to src/components/Common/CategoryItem/CategoryItem.stories.tsx diff --git a/frontend/src/components/Common/CategoryItem/CategoryItem.tsx b/src/components/Common/CategoryItem/CategoryItem.tsx similarity index 100% rename from frontend/src/components/Common/CategoryItem/CategoryItem.tsx rename to src/components/Common/CategoryItem/CategoryItem.tsx diff --git a/frontend/src/components/Common/CategoryStoreList/CategoryStoreList.stories.tsx b/src/components/Common/CategoryStoreList/CategoryStoreList.stories.tsx similarity index 100% rename from frontend/src/components/Common/CategoryStoreList/CategoryStoreList.stories.tsx rename to src/components/Common/CategoryStoreList/CategoryStoreList.stories.tsx diff --git a/frontend/src/components/Common/CategoryStoreList/CategoryStoreList.tsx b/src/components/Common/CategoryStoreList/CategoryStoreList.tsx similarity index 100% rename from frontend/src/components/Common/CategoryStoreList/CategoryStoreList.tsx rename to src/components/Common/CategoryStoreList/CategoryStoreList.tsx diff --git a/frontend/src/components/Common/CategoryStoreTab/CategoryStoreTab.stories.tsx b/src/components/Common/CategoryStoreTab/CategoryStoreTab.stories.tsx similarity index 100% rename from frontend/src/components/Common/CategoryStoreTab/CategoryStoreTab.stories.tsx rename to src/components/Common/CategoryStoreTab/CategoryStoreTab.stories.tsx diff --git a/frontend/src/components/Common/CategoryStoreTab/CategoryStoreTab.tsx b/src/components/Common/CategoryStoreTab/CategoryStoreTab.tsx similarity index 100% rename from frontend/src/components/Common/CategoryStoreTab/CategoryStoreTab.tsx rename to src/components/Common/CategoryStoreTab/CategoryStoreTab.tsx diff --git a/frontend/src/components/Common/ErrorBoundary/ErrorBoundary.tsx b/src/components/Common/ErrorBoundary/ErrorBoundary.tsx similarity index 100% rename from frontend/src/components/Common/ErrorBoundary/ErrorBoundary.tsx rename to src/components/Common/ErrorBoundary/ErrorBoundary.tsx diff --git a/frontend/src/components/Common/ErrorComponent/ErrorComponent.stories.tsx b/src/components/Common/ErrorComponent/ErrorComponent.stories.tsx similarity index 100% rename from frontend/src/components/Common/ErrorComponent/ErrorComponent.stories.tsx rename to src/components/Common/ErrorComponent/ErrorComponent.stories.tsx diff --git a/frontend/src/components/Common/ErrorComponent/ErrorComponent.tsx b/src/components/Common/ErrorComponent/ErrorComponent.tsx similarity index 100% rename from frontend/src/components/Common/ErrorComponent/ErrorComponent.tsx rename to src/components/Common/ErrorComponent/ErrorComponent.tsx diff --git a/frontend/src/components/Common/Header/Header.stories.tsx b/src/components/Common/Header/Header.stories.tsx similarity index 100% rename from frontend/src/components/Common/Header/Header.stories.tsx rename to src/components/Common/Header/Header.stories.tsx diff --git a/frontend/src/components/Common/Header/Header.tsx b/src/components/Common/Header/Header.tsx similarity index 100% rename from frontend/src/components/Common/Header/Header.tsx rename to src/components/Common/Header/Header.tsx diff --git a/frontend/src/components/Common/ImageUploader/ImageUploader.stories.tsx b/src/components/Common/ImageUploader/ImageUploader.stories.tsx similarity index 100% rename from frontend/src/components/Common/ImageUploader/ImageUploader.stories.tsx rename to src/components/Common/ImageUploader/ImageUploader.stories.tsx diff --git a/frontend/src/components/Common/ImageUploader/ImageUploader.tsx b/src/components/Common/ImageUploader/ImageUploader.tsx similarity index 100% rename from frontend/src/components/Common/ImageUploader/ImageUploader.tsx rename to src/components/Common/ImageUploader/ImageUploader.tsx diff --git a/frontend/src/components/Common/Loading/Loading.stories.tsx b/src/components/Common/Loading/Loading.stories.tsx similarity index 100% rename from frontend/src/components/Common/Loading/Loading.stories.tsx rename to src/components/Common/Loading/Loading.stories.tsx diff --git a/frontend/src/components/Common/Loading/Loading.tsx b/src/components/Common/Loading/Loading.tsx similarity index 100% rename from frontend/src/components/Common/Loading/Loading.tsx rename to src/components/Common/Loading/Loading.tsx diff --git a/frontend/src/components/Common/MarkedText/MarkedText.tsx b/src/components/Common/MarkedText/MarkedText.tsx similarity index 100% rename from frontend/src/components/Common/MarkedText/MarkedText.tsx rename to src/components/Common/MarkedText/MarkedText.tsx diff --git a/frontend/src/components/Common/NavigableSectionTitle/NavigableSectionTitle.stories.tsx b/src/components/Common/NavigableSectionTitle/NavigableSectionTitle.stories.tsx similarity index 100% rename from frontend/src/components/Common/NavigableSectionTitle/NavigableSectionTitle.stories.tsx rename to src/components/Common/NavigableSectionTitle/NavigableSectionTitle.stories.tsx diff --git a/frontend/src/components/Common/NavigableSectionTitle/NavigableSectionTitle.tsx b/src/components/Common/NavigableSectionTitle/NavigableSectionTitle.tsx similarity index 100% rename from frontend/src/components/Common/NavigableSectionTitle/NavigableSectionTitle.tsx rename to src/components/Common/NavigableSectionTitle/NavigableSectionTitle.tsx diff --git a/frontend/src/components/Common/NavigationBar/NavigationBar.stories.tsx b/src/components/Common/NavigationBar/NavigationBar.stories.tsx similarity index 100% rename from frontend/src/components/Common/NavigationBar/NavigationBar.stories.tsx rename to src/components/Common/NavigationBar/NavigationBar.stories.tsx diff --git a/frontend/src/components/Common/NavigationBar/NavigationBar.tsx b/src/components/Common/NavigationBar/NavigationBar.tsx similarity index 100% rename from frontend/src/components/Common/NavigationBar/NavigationBar.tsx rename to src/components/Common/NavigationBar/NavigationBar.tsx diff --git a/frontend/src/components/Common/RegisterButton/RegisterButton.tsx b/src/components/Common/RegisterButton/RegisterButton.tsx similarity index 100% rename from frontend/src/components/Common/RegisterButton/RegisterButton.tsx rename to src/components/Common/RegisterButton/RegisterButton.tsx diff --git a/frontend/src/components/Common/ScrollButton/ScrollButton.stories.tsx b/src/components/Common/ScrollButton/ScrollButton.stories.tsx similarity index 100% rename from frontend/src/components/Common/ScrollButton/ScrollButton.stories.tsx rename to src/components/Common/ScrollButton/ScrollButton.stories.tsx diff --git a/frontend/src/components/Common/ScrollButton/ScrollButton.tsx b/src/components/Common/ScrollButton/ScrollButton.tsx similarity index 100% rename from frontend/src/components/Common/ScrollButton/ScrollButton.tsx rename to src/components/Common/ScrollButton/ScrollButton.tsx diff --git a/frontend/src/components/Common/SectionTitle/SectionTitle.stories.tsx b/src/components/Common/SectionTitle/SectionTitle.stories.tsx similarity index 100% rename from frontend/src/components/Common/SectionTitle/SectionTitle.stories.tsx rename to src/components/Common/SectionTitle/SectionTitle.stories.tsx diff --git a/frontend/src/components/Common/SectionTitle/SectionTitle.tsx b/src/components/Common/SectionTitle/SectionTitle.tsx similarity index 100% rename from frontend/src/components/Common/SectionTitle/SectionTitle.tsx rename to src/components/Common/SectionTitle/SectionTitle.tsx diff --git a/frontend/src/components/Common/SortButton/SortButton.stories.tsx b/src/components/Common/SortButton/SortButton.stories.tsx similarity index 100% rename from frontend/src/components/Common/SortButton/SortButton.stories.tsx rename to src/components/Common/SortButton/SortButton.stories.tsx diff --git a/frontend/src/components/Common/SortButton/SortButton.tsx b/src/components/Common/SortButton/SortButton.tsx similarity index 100% rename from frontend/src/components/Common/SortButton/SortButton.tsx rename to src/components/Common/SortButton/SortButton.tsx diff --git a/frontend/src/components/Common/SortOptionList/SortOptionList.stories.tsx b/src/components/Common/SortOptionList/SortOptionList.stories.tsx similarity index 100% rename from frontend/src/components/Common/SortOptionList/SortOptionList.stories.tsx rename to src/components/Common/SortOptionList/SortOptionList.stories.tsx diff --git a/frontend/src/components/Common/SortOptionList/SortOptionList.tsx b/src/components/Common/SortOptionList/SortOptionList.tsx similarity index 100% rename from frontend/src/components/Common/SortOptionList/SortOptionList.tsx rename to src/components/Common/SortOptionList/SortOptionList.tsx diff --git a/frontend/src/components/Common/Svg/SvgIcon.stories.tsx b/src/components/Common/Svg/SvgIcon.stories.tsx similarity index 100% rename from frontend/src/components/Common/Svg/SvgIcon.stories.tsx rename to src/components/Common/Svg/SvgIcon.stories.tsx diff --git a/frontend/src/components/Common/Svg/SvgIcon.tsx b/src/components/Common/Svg/SvgIcon.tsx similarity index 100% rename from frontend/src/components/Common/Svg/SvgIcon.tsx rename to src/components/Common/Svg/SvgIcon.tsx diff --git a/frontend/src/components/Common/Svg/SvgSprite.tsx b/src/components/Common/Svg/SvgSprite.tsx similarity index 100% rename from frontend/src/components/Common/Svg/SvgSprite.tsx rename to src/components/Common/Svg/SvgSprite.tsx diff --git a/frontend/src/components/Common/TabMenu/TabMenu.stories.tsx b/src/components/Common/TabMenu/TabMenu.stories.tsx similarity index 100% rename from frontend/src/components/Common/TabMenu/TabMenu.stories.tsx rename to src/components/Common/TabMenu/TabMenu.stories.tsx diff --git a/frontend/src/components/Common/TabMenu/TabMenu.tsx b/src/components/Common/TabMenu/TabMenu.tsx similarity index 100% rename from frontend/src/components/Common/TabMenu/TabMenu.tsx rename to src/components/Common/TabMenu/TabMenu.tsx diff --git a/frontend/src/components/Common/TagList/TagList.stories.tsx b/src/components/Common/TagList/TagList.stories.tsx similarity index 100% rename from frontend/src/components/Common/TagList/TagList.stories.tsx rename to src/components/Common/TagList/TagList.stories.tsx diff --git a/frontend/src/components/Common/TagList/TagList.tsx b/src/components/Common/TagList/TagList.tsx similarity index 100% rename from frontend/src/components/Common/TagList/TagList.tsx rename to src/components/Common/TagList/TagList.tsx diff --git a/frontend/src/components/Common/index.ts b/src/components/Common/index.ts similarity index 100% rename from frontend/src/components/Common/index.ts rename to src/components/Common/index.ts diff --git a/frontend/src/components/Layout/AuthLayout.tsx b/src/components/Layout/AuthLayout.tsx similarity index 100% rename from frontend/src/components/Layout/AuthLayout.tsx rename to src/components/Layout/AuthLayout.tsx diff --git a/frontend/src/components/Layout/DefaultLayout.tsx b/src/components/Layout/DefaultLayout.tsx similarity index 100% rename from frontend/src/components/Layout/DefaultLayout.tsx rename to src/components/Layout/DefaultLayout.tsx diff --git a/frontend/src/components/Layout/HeaderOnlyLayout.tsx b/src/components/Layout/HeaderOnlyLayout.tsx similarity index 100% rename from frontend/src/components/Layout/HeaderOnlyLayout.tsx rename to src/components/Layout/HeaderOnlyLayout.tsx diff --git a/frontend/src/components/Layout/MinimalLayout.tsx b/src/components/Layout/MinimalLayout.tsx similarity index 100% rename from frontend/src/components/Layout/MinimalLayout.tsx rename to src/components/Layout/MinimalLayout.tsx diff --git a/frontend/src/components/Layout/SimpleHeaderLayout.tsx b/src/components/Layout/SimpleHeaderLayout.tsx similarity index 100% rename from frontend/src/components/Layout/SimpleHeaderLayout.tsx rename to src/components/Layout/SimpleHeaderLayout.tsx diff --git a/frontend/src/components/Layout/index.ts b/src/components/Layout/index.ts similarity index 100% rename from frontend/src/components/Layout/index.ts rename to src/components/Layout/index.ts diff --git a/frontend/src/components/Members/MemberModifyInput/MemberModifyInput.tsx b/src/components/Members/MemberModifyInput/MemberModifyInput.tsx similarity index 100% rename from frontend/src/components/Members/MemberModifyInput/MemberModifyInput.tsx rename to src/components/Members/MemberModifyInput/MemberModifyInput.tsx diff --git a/frontend/src/components/Members/MemberRecipeList/MemberRecipeList.stories.tsx b/src/components/Members/MemberRecipeList/MemberRecipeList.stories.tsx similarity index 100% rename from frontend/src/components/Members/MemberRecipeList/MemberRecipeList.stories.tsx rename to src/components/Members/MemberRecipeList/MemberRecipeList.stories.tsx diff --git a/frontend/src/components/Members/MemberRecipeList/MemberRecipeList.tsx b/src/components/Members/MemberRecipeList/MemberRecipeList.tsx similarity index 100% rename from frontend/src/components/Members/MemberRecipeList/MemberRecipeList.tsx rename to src/components/Members/MemberRecipeList/MemberRecipeList.tsx diff --git a/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx b/src/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx similarity index 100% rename from frontend/src/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx rename to src/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx diff --git a/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.tsx b/src/components/Members/MemberReviewItem/MemberReviewItem.tsx similarity index 100% rename from frontend/src/components/Members/MemberReviewItem/MemberReviewItem.tsx rename to src/components/Members/MemberReviewItem/MemberReviewItem.tsx diff --git a/frontend/src/components/Members/MemberReviewList/MemberReviewList.stories.tsx b/src/components/Members/MemberReviewList/MemberReviewList.stories.tsx similarity index 100% rename from frontend/src/components/Members/MemberReviewList/MemberReviewList.stories.tsx rename to src/components/Members/MemberReviewList/MemberReviewList.stories.tsx diff --git a/frontend/src/components/Members/MemberReviewList/MemberReviewList.tsx b/src/components/Members/MemberReviewList/MemberReviewList.tsx similarity index 100% rename from frontend/src/components/Members/MemberReviewList/MemberReviewList.tsx rename to src/components/Members/MemberReviewList/MemberReviewList.tsx diff --git a/frontend/src/components/Members/MembersInfo/MembersInfo.tsx b/src/components/Members/MembersInfo/MembersInfo.tsx similarity index 100% rename from frontend/src/components/Members/MembersInfo/MembersInfo.tsx rename to src/components/Members/MembersInfo/MembersInfo.tsx diff --git a/frontend/src/components/Members/MembersInfo/MyPageInfo.stories.tsx b/src/components/Members/MembersInfo/MyPageInfo.stories.tsx similarity index 100% rename from frontend/src/components/Members/MembersInfo/MyPageInfo.stories.tsx rename to src/components/Members/MembersInfo/MyPageInfo.stories.tsx diff --git a/frontend/src/components/Members/index.ts b/src/components/Members/index.ts similarity index 100% rename from frontend/src/components/Members/index.ts rename to src/components/Members/index.ts diff --git a/frontend/src/components/Product/ProductDetailItem/ProductDetailItem.stories.tsx b/src/components/Product/ProductDetailItem/ProductDetailItem.stories.tsx similarity index 100% rename from frontend/src/components/Product/ProductDetailItem/ProductDetailItem.stories.tsx rename to src/components/Product/ProductDetailItem/ProductDetailItem.stories.tsx diff --git a/frontend/src/components/Product/ProductDetailItem/ProductDetailItem.tsx b/src/components/Product/ProductDetailItem/ProductDetailItem.tsx similarity index 100% rename from frontend/src/components/Product/ProductDetailItem/ProductDetailItem.tsx rename to src/components/Product/ProductDetailItem/ProductDetailItem.tsx diff --git a/frontend/src/components/Product/ProductItem/ProductItem.stories.tsx b/src/components/Product/ProductItem/ProductItem.stories.tsx similarity index 100% rename from frontend/src/components/Product/ProductItem/ProductItem.stories.tsx rename to src/components/Product/ProductItem/ProductItem.stories.tsx diff --git a/frontend/src/components/Product/ProductItem/ProductItem.tsx b/src/components/Product/ProductItem/ProductItem.tsx similarity index 100% rename from frontend/src/components/Product/ProductItem/ProductItem.tsx rename to src/components/Product/ProductItem/ProductItem.tsx diff --git a/frontend/src/components/Product/ProductList/ProductList.stories.tsx b/src/components/Product/ProductList/ProductList.stories.tsx similarity index 100% rename from frontend/src/components/Product/ProductList/ProductList.stories.tsx rename to src/components/Product/ProductList/ProductList.stories.tsx diff --git a/frontend/src/components/Product/ProductList/ProductList.tsx b/src/components/Product/ProductList/ProductList.tsx similarity index 100% rename from frontend/src/components/Product/ProductList/ProductList.tsx rename to src/components/Product/ProductList/ProductList.tsx diff --git a/frontend/src/components/Product/ProductOverviewItem/ProductOverviewItem.stories.tsx b/src/components/Product/ProductOverviewItem/ProductOverviewItem.stories.tsx similarity index 100% rename from frontend/src/components/Product/ProductOverviewItem/ProductOverviewItem.stories.tsx rename to src/components/Product/ProductOverviewItem/ProductOverviewItem.stories.tsx diff --git a/frontend/src/components/Product/ProductOverviewItem/ProductOverviewItem.tsx b/src/components/Product/ProductOverviewItem/ProductOverviewItem.tsx similarity index 100% rename from frontend/src/components/Product/ProductOverviewItem/ProductOverviewItem.tsx rename to src/components/Product/ProductOverviewItem/ProductOverviewItem.tsx diff --git a/frontend/src/components/Product/ProductRecipeList/ProductRecipeList.tsx b/src/components/Product/ProductRecipeList/ProductRecipeList.tsx similarity index 100% rename from frontend/src/components/Product/ProductRecipeList/ProductRecipeList.tsx rename to src/components/Product/ProductRecipeList/ProductRecipeList.tsx diff --git a/frontend/src/components/Product/ProductTitle/ProductTitle.stories.tsx b/src/components/Product/ProductTitle/ProductTitle.stories.tsx similarity index 100% rename from frontend/src/components/Product/ProductTitle/ProductTitle.stories.tsx rename to src/components/Product/ProductTitle/ProductTitle.stories.tsx diff --git a/frontend/src/components/Product/ProductTitle/ProductTitle.tsx b/src/components/Product/ProductTitle/ProductTitle.tsx similarity index 100% rename from frontend/src/components/Product/ProductTitle/ProductTitle.tsx rename to src/components/Product/ProductTitle/ProductTitle.tsx diff --git a/frontend/src/components/Product/index.ts b/src/components/Product/index.ts similarity index 100% rename from frontend/src/components/Product/index.ts rename to src/components/Product/index.ts diff --git a/frontend/src/components/Rank/ProductRankingList/ProductRankingList.stories.tsx b/src/components/Rank/ProductRankingList/ProductRankingList.stories.tsx similarity index 100% rename from frontend/src/components/Rank/ProductRankingList/ProductRankingList.stories.tsx rename to src/components/Rank/ProductRankingList/ProductRankingList.stories.tsx diff --git a/frontend/src/components/Rank/ProductRankingList/ProductRankingList.tsx b/src/components/Rank/ProductRankingList/ProductRankingList.tsx similarity index 100% rename from frontend/src/components/Rank/ProductRankingList/ProductRankingList.tsx rename to src/components/Rank/ProductRankingList/ProductRankingList.tsx diff --git a/frontend/src/components/Rank/RecipeRankingItem/RecipeRankingItem.stories.tsx b/src/components/Rank/RecipeRankingItem/RecipeRankingItem.stories.tsx similarity index 100% rename from frontend/src/components/Rank/RecipeRankingItem/RecipeRankingItem.stories.tsx rename to src/components/Rank/RecipeRankingItem/RecipeRankingItem.stories.tsx diff --git a/frontend/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx b/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx similarity index 100% rename from frontend/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx rename to src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx diff --git a/frontend/src/components/Rank/RecipeRankingList/RecipeRankingList.stories.tsx b/src/components/Rank/RecipeRankingList/RecipeRankingList.stories.tsx similarity index 100% rename from frontend/src/components/Rank/RecipeRankingList/RecipeRankingList.stories.tsx rename to src/components/Rank/RecipeRankingList/RecipeRankingList.stories.tsx diff --git a/frontend/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx b/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx similarity index 100% rename from frontend/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx rename to src/components/Rank/RecipeRankingList/RecipeRankingList.tsx diff --git a/frontend/src/components/Rank/ReviewRankingItem/ReviewRankingItem.stories.tsx b/src/components/Rank/ReviewRankingItem/ReviewRankingItem.stories.tsx similarity index 100% rename from frontend/src/components/Rank/ReviewRankingItem/ReviewRankingItem.stories.tsx rename to src/components/Rank/ReviewRankingItem/ReviewRankingItem.stories.tsx diff --git a/frontend/src/components/Rank/ReviewRankingItem/ReviewRankingItem.tsx b/src/components/Rank/ReviewRankingItem/ReviewRankingItem.tsx similarity index 100% rename from frontend/src/components/Rank/ReviewRankingItem/ReviewRankingItem.tsx rename to src/components/Rank/ReviewRankingItem/ReviewRankingItem.tsx diff --git a/frontend/src/components/Rank/ReviewRankingList/ReviewRankingList.stories.tsx b/src/components/Rank/ReviewRankingList/ReviewRankingList.stories.tsx similarity index 100% rename from frontend/src/components/Rank/ReviewRankingList/ReviewRankingList.stories.tsx rename to src/components/Rank/ReviewRankingList/ReviewRankingList.stories.tsx diff --git a/frontend/src/components/Rank/ReviewRankingList/ReviewRankingList.tsx b/src/components/Rank/ReviewRankingList/ReviewRankingList.tsx similarity index 100% rename from frontend/src/components/Rank/ReviewRankingList/ReviewRankingList.tsx rename to src/components/Rank/ReviewRankingList/ReviewRankingList.tsx diff --git a/frontend/src/components/Rank/index.ts b/src/components/Rank/index.ts similarity index 79% rename from frontend/src/components/Rank/index.ts rename to src/components/Rank/index.ts index 1b39a108e..4c2b8262b 100644 --- a/frontend/src/components/Rank/index.ts +++ b/src/components/Rank/index.ts @@ -1,4 +1,4 @@ -export { default as ReviewRankingItem } from '../Rank/ReviewRankingItem/ReviewRankingItem'; +export { default as ReviewRankingItem } from './ReviewRankingItem/ReviewRankingItem'; export { default as ReviewRankingList } from './ReviewRankingList/ReviewRankingList'; export { default as ProductRankingList } from './ProductRankingList/ProductRankingList'; export { default as RecipeRankingItem } from './RecipeRankingItem/RecipeRankingItem'; diff --git a/frontend/src/components/Recipe/CommentForm/CommentForm.stories.tsx b/src/components/Recipe/CommentForm/CommentForm.stories.tsx similarity index 100% rename from frontend/src/components/Recipe/CommentForm/CommentForm.stories.tsx rename to src/components/Recipe/CommentForm/CommentForm.stories.tsx diff --git a/frontend/src/components/Recipe/CommentForm/CommentForm.tsx b/src/components/Recipe/CommentForm/CommentForm.tsx similarity index 100% rename from frontend/src/components/Recipe/CommentForm/CommentForm.tsx rename to src/components/Recipe/CommentForm/CommentForm.tsx diff --git a/frontend/src/components/Recipe/CommentItem/CommentItem.stories.tsx b/src/components/Recipe/CommentItem/CommentItem.stories.tsx similarity index 100% rename from frontend/src/components/Recipe/CommentItem/CommentItem.stories.tsx rename to src/components/Recipe/CommentItem/CommentItem.stories.tsx diff --git a/frontend/src/components/Recipe/CommentItem/CommentItem.tsx b/src/components/Recipe/CommentItem/CommentItem.tsx similarity index 100% rename from frontend/src/components/Recipe/CommentItem/CommentItem.tsx rename to src/components/Recipe/CommentItem/CommentItem.tsx diff --git a/frontend/src/components/Recipe/CommentList/CommentList.stories.tsx b/src/components/Recipe/CommentList/CommentList.stories.tsx similarity index 100% rename from frontend/src/components/Recipe/CommentList/CommentList.stories.tsx rename to src/components/Recipe/CommentList/CommentList.stories.tsx diff --git a/frontend/src/components/Recipe/CommentList/CommentList.tsx b/src/components/Recipe/CommentList/CommentList.tsx similarity index 100% rename from frontend/src/components/Recipe/CommentList/CommentList.tsx rename to src/components/Recipe/CommentList/CommentList.tsx diff --git a/frontend/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx b/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx similarity index 91% rename from frontend/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx rename to src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx index eefc6267a..902bdde87 100644 --- a/frontend/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx +++ b/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { RecipeDetailTextarea } from '..'; +import { RecipeDetailTextarea } from '../index'; import RecipeFormProvider from '@/contexts/RecipeFormContext'; diff --git a/frontend/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.tsx b/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.tsx rename to src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.tsx diff --git a/frontend/src/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx b/src/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx rename to src/components/Recipe/RecipeFavoriteButton/RecipeFavoriteButton.tsx diff --git a/frontend/src/components/Recipe/RecipeItem/RecipeItem.stories.tsx b/src/components/Recipe/RecipeItem/RecipeItem.stories.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeItem/RecipeItem.stories.tsx rename to src/components/Recipe/RecipeItem/RecipeItem.stories.tsx diff --git a/frontend/src/components/Recipe/RecipeItem/RecipeItem.tsx b/src/components/Recipe/RecipeItem/RecipeItem.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeItem/RecipeItem.tsx rename to src/components/Recipe/RecipeItem/RecipeItem.tsx diff --git a/frontend/src/components/Recipe/RecipeList/RecipeList.stories.tsx b/src/components/Recipe/RecipeList/RecipeList.stories.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeList/RecipeList.stories.tsx rename to src/components/Recipe/RecipeList/RecipeList.stories.tsx diff --git a/frontend/src/components/Recipe/RecipeList/RecipeList.tsx b/src/components/Recipe/RecipeList/RecipeList.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeList/RecipeList.tsx rename to src/components/Recipe/RecipeList/RecipeList.tsx diff --git a/frontend/src/components/Recipe/RecipeNameInput/RecipeNameInput.stories.tsx b/src/components/Recipe/RecipeNameInput/RecipeNameInput.stories.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeNameInput/RecipeNameInput.stories.tsx rename to src/components/Recipe/RecipeNameInput/RecipeNameInput.stories.tsx diff --git a/frontend/src/components/Recipe/RecipeNameInput/RecipeNameInput.tsx b/src/components/Recipe/RecipeNameInput/RecipeNameInput.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeNameInput/RecipeNameInput.tsx rename to src/components/Recipe/RecipeNameInput/RecipeNameInput.tsx diff --git a/frontend/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.stories.tsx b/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.stories.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.stories.tsx rename to src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.stories.tsx diff --git a/frontend/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx b/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx rename to src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx diff --git a/frontend/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.stories.tsx b/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.stories.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.stories.tsx rename to src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.stories.tsx diff --git a/frontend/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx b/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx rename to src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx diff --git a/frontend/src/components/Recipe/RecipeUsedProducts/SearchedProductList.tsx b/src/components/Recipe/RecipeUsedProducts/SearchedProductList.tsx similarity index 100% rename from frontend/src/components/Recipe/RecipeUsedProducts/SearchedProductList.tsx rename to src/components/Recipe/RecipeUsedProducts/SearchedProductList.tsx diff --git a/frontend/src/components/Recipe/index.ts b/src/components/Recipe/index.ts similarity index 100% rename from frontend/src/components/Recipe/index.ts rename to src/components/Recipe/index.ts diff --git a/frontend/src/components/Review/BestReviewItem/BestReviewItem.stories.tsx b/src/components/Review/BestReviewItem/BestReviewItem.stories.tsx similarity index 100% rename from frontend/src/components/Review/BestReviewItem/BestReviewItem.stories.tsx rename to src/components/Review/BestReviewItem/BestReviewItem.stories.tsx diff --git a/frontend/src/components/Review/BestReviewItem/BestReviewItem.tsx b/src/components/Review/BestReviewItem/BestReviewItem.tsx similarity index 100% rename from frontend/src/components/Review/BestReviewItem/BestReviewItem.tsx rename to src/components/Review/BestReviewItem/BestReviewItem.tsx diff --git a/frontend/src/components/Review/RebuyCheckbox/RebuyCheckbox.tsx b/src/components/Review/RebuyCheckbox/RebuyCheckbox.tsx similarity index 100% rename from frontend/src/components/Review/RebuyCheckbox/RebuyCheckbox.tsx rename to src/components/Review/RebuyCheckbox/RebuyCheckbox.tsx diff --git a/frontend/src/components/Review/ReviewFavoriteButton/ReviewFavoriteButton.tsx b/src/components/Review/ReviewFavoriteButton/ReviewFavoriteButton.tsx similarity index 100% rename from frontend/src/components/Review/ReviewFavoriteButton/ReviewFavoriteButton.tsx rename to src/components/Review/ReviewFavoriteButton/ReviewFavoriteButton.tsx diff --git a/frontend/src/components/Review/ReviewItem/ReviewItem.stories.tsx b/src/components/Review/ReviewItem/ReviewItem.stories.tsx similarity index 100% rename from frontend/src/components/Review/ReviewItem/ReviewItem.stories.tsx rename to src/components/Review/ReviewItem/ReviewItem.stories.tsx diff --git a/frontend/src/components/Review/ReviewItem/ReviewItem.tsx b/src/components/Review/ReviewItem/ReviewItem.tsx similarity index 100% rename from frontend/src/components/Review/ReviewItem/ReviewItem.tsx rename to src/components/Review/ReviewItem/ReviewItem.tsx diff --git a/frontend/src/components/Review/ReviewList/ReviewList.tsx b/src/components/Review/ReviewList/ReviewList.tsx similarity index 100% rename from frontend/src/components/Review/ReviewList/ReviewList.tsx rename to src/components/Review/ReviewList/ReviewList.tsx diff --git a/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.stories.tsx b/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.stories.tsx similarity index 100% rename from frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.stories.tsx rename to src/components/Review/ReviewRegisterForm/ReviewRegisterForm.stories.tsx diff --git a/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx b/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx similarity index 100% rename from frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx rename to src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx diff --git a/frontend/src/components/Review/ReviewTagItem/ReviewTagItem.stories.tsx b/src/components/Review/ReviewTagItem/ReviewTagItem.stories.tsx similarity index 100% rename from frontend/src/components/Review/ReviewTagItem/ReviewTagItem.stories.tsx rename to src/components/Review/ReviewTagItem/ReviewTagItem.stories.tsx diff --git a/frontend/src/components/Review/ReviewTagItem/ReviewTagItem.tsx b/src/components/Review/ReviewTagItem/ReviewTagItem.tsx similarity index 100% rename from frontend/src/components/Review/ReviewTagItem/ReviewTagItem.tsx rename to src/components/Review/ReviewTagItem/ReviewTagItem.tsx diff --git a/frontend/src/components/Review/ReviewTagList/ReviewTagList.stories.tsx b/src/components/Review/ReviewTagList/ReviewTagList.stories.tsx similarity index 100% rename from frontend/src/components/Review/ReviewTagList/ReviewTagList.stories.tsx rename to src/components/Review/ReviewTagList/ReviewTagList.stories.tsx diff --git a/frontend/src/components/Review/ReviewTagList/ReviewTagList.tsx b/src/components/Review/ReviewTagList/ReviewTagList.tsx similarity index 100% rename from frontend/src/components/Review/ReviewTagList/ReviewTagList.tsx rename to src/components/Review/ReviewTagList/ReviewTagList.tsx diff --git a/frontend/src/components/Review/ReviewTextarea/ReviewTextarea.stories.tsx b/src/components/Review/ReviewTextarea/ReviewTextarea.stories.tsx similarity index 100% rename from frontend/src/components/Review/ReviewTextarea/ReviewTextarea.stories.tsx rename to src/components/Review/ReviewTextarea/ReviewTextarea.stories.tsx diff --git a/frontend/src/components/Review/ReviewTextarea/ReviewTextarea.tsx b/src/components/Review/ReviewTextarea/ReviewTextarea.tsx similarity index 100% rename from frontend/src/components/Review/ReviewTextarea/ReviewTextarea.tsx rename to src/components/Review/ReviewTextarea/ReviewTextarea.tsx diff --git a/frontend/src/components/Review/StarRate/StarRate.stories.tsx b/src/components/Review/StarRate/StarRate.stories.tsx similarity index 100% rename from frontend/src/components/Review/StarRate/StarRate.stories.tsx rename to src/components/Review/StarRate/StarRate.stories.tsx diff --git a/frontend/src/components/Review/StarRate/StarRate.tsx b/src/components/Review/StarRate/StarRate.tsx similarity index 100% rename from frontend/src/components/Review/StarRate/StarRate.tsx rename to src/components/Review/StarRate/StarRate.tsx diff --git a/frontend/src/components/Review/index.ts b/src/components/Review/index.ts similarity index 100% rename from frontend/src/components/Review/index.ts rename to src/components/Review/index.ts diff --git a/frontend/src/components/Search/ProductSearchResultList/ProductSearchResultList.tsx b/src/components/Search/ProductSearchResultList/ProductSearchResultList.tsx similarity index 100% rename from frontend/src/components/Search/ProductSearchResultList/ProductSearchResultList.tsx rename to src/components/Search/ProductSearchResultList/ProductSearchResultList.tsx diff --git a/frontend/src/components/Search/RecipeSearchResultList/RecipeSearchResultList.tsx b/src/components/Search/RecipeSearchResultList/RecipeSearchResultList.tsx similarity index 100% rename from frontend/src/components/Search/RecipeSearchResultList/RecipeSearchResultList.tsx rename to src/components/Search/RecipeSearchResultList/RecipeSearchResultList.tsx diff --git a/frontend/src/components/Search/RecommendList/RecommendList.tsx b/src/components/Search/RecommendList/RecommendList.tsx similarity index 100% rename from frontend/src/components/Search/RecommendList/RecommendList.tsx rename to src/components/Search/RecommendList/RecommendList.tsx diff --git a/frontend/src/components/Search/index.ts b/src/components/Search/index.ts similarity index 100% rename from frontend/src/components/Search/index.ts rename to src/components/Search/index.ts diff --git a/frontend/src/constants/index.ts b/src/constants/index.ts similarity index 100% rename from frontend/src/constants/index.ts rename to src/constants/index.ts diff --git a/frontend/src/constants/path.ts b/src/constants/path.ts similarity index 100% rename from frontend/src/constants/path.ts rename to src/constants/path.ts diff --git a/frontend/src/contexts/CategoryContext.tsx b/src/contexts/CategoryContext.tsx similarity index 100% rename from frontend/src/contexts/CategoryContext.tsx rename to src/contexts/CategoryContext.tsx diff --git a/frontend/src/contexts/RecipeFormContext.tsx b/src/contexts/RecipeFormContext.tsx similarity index 100% rename from frontend/src/contexts/RecipeFormContext.tsx rename to src/contexts/RecipeFormContext.tsx diff --git a/frontend/src/contexts/ReviewFormContext.tsx b/src/contexts/ReviewFormContext.tsx similarity index 100% rename from frontend/src/contexts/ReviewFormContext.tsx rename to src/contexts/ReviewFormContext.tsx diff --git a/frontend/src/hooks/common/index.ts b/src/hooks/common/index.ts similarity index 100% rename from frontend/src/hooks/common/index.ts rename to src/hooks/common/index.ts diff --git a/frontend/src/hooks/common/useDebounce.ts b/src/hooks/common/useDebounce.ts similarity index 100% rename from frontend/src/hooks/common/useDebounce.ts rename to src/hooks/common/useDebounce.ts diff --git a/frontend/src/hooks/common/useEnterKeyDown.ts b/src/hooks/common/useEnterKeyDown.ts similarity index 100% rename from frontend/src/hooks/common/useEnterKeyDown.ts rename to src/hooks/common/useEnterKeyDown.ts diff --git a/frontend/src/hooks/common/useFormData.ts b/src/hooks/common/useFormData.ts similarity index 100% rename from frontend/src/hooks/common/useFormData.ts rename to src/hooks/common/useFormData.ts diff --git a/frontend/src/hooks/common/useGA.ts b/src/hooks/common/useGA.ts similarity index 100% rename from frontend/src/hooks/common/useGA.ts rename to src/hooks/common/useGA.ts diff --git a/frontend/src/hooks/common/useImageUploader.ts b/src/hooks/common/useImageUploader.ts similarity index 100% rename from frontend/src/hooks/common/useImageUploader.ts rename to src/hooks/common/useImageUploader.ts diff --git a/frontend/src/hooks/common/useIntersectionObserver.ts b/src/hooks/common/useIntersectionObserver.ts similarity index 100% rename from frontend/src/hooks/common/useIntersectionObserver.ts rename to src/hooks/common/useIntersectionObserver.ts diff --git a/frontend/src/hooks/common/useRouteChangeTracker.ts b/src/hooks/common/useRouteChangeTracker.ts similarity index 100% rename from frontend/src/hooks/common/useRouteChangeTracker.ts rename to src/hooks/common/useRouteChangeTracker.ts diff --git a/frontend/src/hooks/common/useRoutePage.ts b/src/hooks/common/useRoutePage.ts similarity index 100% rename from frontend/src/hooks/common/useRoutePage.ts rename to src/hooks/common/useRoutePage.ts diff --git a/frontend/src/hooks/common/useScroll.ts b/src/hooks/common/useScroll.ts similarity index 100% rename from frontend/src/hooks/common/useScroll.ts rename to src/hooks/common/useScroll.ts diff --git a/frontend/src/hooks/common/useScrollRestoration.ts b/src/hooks/common/useScrollRestoration.ts similarity index 100% rename from frontend/src/hooks/common/useScrollRestoration.ts rename to src/hooks/common/useScrollRestoration.ts diff --git a/frontend/src/hooks/common/useSortOption.ts b/src/hooks/common/useSortOption.ts similarity index 100% rename from frontend/src/hooks/common/useSortOption.ts rename to src/hooks/common/useSortOption.ts diff --git a/frontend/src/hooks/common/useTabMenu.ts b/src/hooks/common/useTabMenu.ts similarity index 100% rename from frontend/src/hooks/common/useTabMenu.ts rename to src/hooks/common/useTabMenu.ts diff --git a/frontend/src/hooks/common/useTimeout.ts b/src/hooks/common/useTimeout.ts similarity index 100% rename from frontend/src/hooks/common/useTimeout.ts rename to src/hooks/common/useTimeout.ts diff --git a/frontend/src/hooks/context/index.ts b/src/hooks/context/index.ts similarity index 100% rename from frontend/src/hooks/context/index.ts rename to src/hooks/context/index.ts diff --git a/frontend/src/hooks/context/useCategoryActionContext.ts b/src/hooks/context/useCategoryActionContext.ts similarity index 100% rename from frontend/src/hooks/context/useCategoryActionContext.ts rename to src/hooks/context/useCategoryActionContext.ts diff --git a/frontend/src/hooks/context/useCategoryValueContext.ts b/src/hooks/context/useCategoryValueContext.ts similarity index 100% rename from frontend/src/hooks/context/useCategoryValueContext.ts rename to src/hooks/context/useCategoryValueContext.ts diff --git a/frontend/src/hooks/context/useRecipeFormActionContext.ts b/src/hooks/context/useRecipeFormActionContext.ts similarity index 100% rename from frontend/src/hooks/context/useRecipeFormActionContext.ts rename to src/hooks/context/useRecipeFormActionContext.ts diff --git a/frontend/src/hooks/context/useRecipeFormValueContext.ts b/src/hooks/context/useRecipeFormValueContext.ts similarity index 100% rename from frontend/src/hooks/context/useRecipeFormValueContext.ts rename to src/hooks/context/useRecipeFormValueContext.ts diff --git a/frontend/src/hooks/context/useReviewFormActionContext.ts b/src/hooks/context/useReviewFormActionContext.ts similarity index 100% rename from frontend/src/hooks/context/useReviewFormActionContext.ts rename to src/hooks/context/useReviewFormActionContext.ts diff --git a/frontend/src/hooks/context/useReviewFormValueContext.ts b/src/hooks/context/useReviewFormValueContext.ts similarity index 100% rename from frontend/src/hooks/context/useReviewFormValueContext.ts rename to src/hooks/context/useReviewFormValueContext.ts diff --git a/frontend/src/hooks/queries/banner/index.ts b/src/hooks/queries/banner/index.ts similarity index 100% rename from frontend/src/hooks/queries/banner/index.ts rename to src/hooks/queries/banner/index.ts diff --git a/frontend/src/hooks/queries/banner/useBannerQuery.ts b/src/hooks/queries/banner/useBannerQuery.ts similarity index 100% rename from frontend/src/hooks/queries/banner/useBannerQuery.ts rename to src/hooks/queries/banner/useBannerQuery.ts diff --git a/frontend/src/hooks/queries/index.ts b/src/hooks/queries/index.ts similarity index 100% rename from frontend/src/hooks/queries/index.ts rename to src/hooks/queries/index.ts diff --git a/frontend/src/hooks/queries/members/index.ts b/src/hooks/queries/members/index.ts similarity index 100% rename from frontend/src/hooks/queries/members/index.ts rename to src/hooks/queries/members/index.ts diff --git a/frontend/src/hooks/queries/members/useDeleteReview.ts b/src/hooks/queries/members/useDeleteReview.ts similarity index 100% rename from frontend/src/hooks/queries/members/useDeleteReview.ts rename to src/hooks/queries/members/useDeleteReview.ts diff --git a/frontend/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts b/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts similarity index 93% rename from frontend/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts rename to src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts index 1714fde8e..920e58a65 100644 --- a/frontend/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts +++ b/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '..'; +import { useSuspendedInfiniteQuery } from '../index'; import { memberApi } from '@/apis'; import type { MemberRecipeResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts b/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts similarity index 93% rename from frontend/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts rename to src/hooks/queries/members/useInfiniteMemberReviewQuery.ts index 556a24944..2f9336fe8 100644 --- a/frontend/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts +++ b/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '..'; +import { useSuspendedInfiniteQuery } from '../index'; import { memberApi } from '@/apis'; import type { MemberReviewResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/members/useLogoutMutation.ts b/src/hooks/queries/members/useLogoutMutation.ts similarity index 100% rename from frontend/src/hooks/queries/members/useLogoutMutation.ts rename to src/hooks/queries/members/useLogoutMutation.ts diff --git a/frontend/src/hooks/queries/members/useMemberModifyMutation.ts b/src/hooks/queries/members/useMemberModifyMutation.ts similarity index 100% rename from frontend/src/hooks/queries/members/useMemberModifyMutation.ts rename to src/hooks/queries/members/useMemberModifyMutation.ts diff --git a/frontend/src/hooks/queries/members/useMemberQuery.ts b/src/hooks/queries/members/useMemberQuery.ts similarity index 90% rename from frontend/src/hooks/queries/members/useMemberQuery.ts rename to src/hooks/queries/members/useMemberQuery.ts index f948cade1..a98cedd89 100644 --- a/frontend/src/hooks/queries/members/useMemberQuery.ts +++ b/src/hooks/queries/members/useMemberQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '..'; +import { useSuspendedQuery } from '../index'; import { memberApi } from '@/apis'; import type { Member } from '@/types/member'; diff --git a/frontend/src/hooks/queries/product/index.ts b/src/hooks/queries/product/index.ts similarity index 100% rename from frontend/src/hooks/queries/product/index.ts rename to src/hooks/queries/product/index.ts diff --git a/frontend/src/hooks/queries/product/useCategoryQuery.ts b/src/hooks/queries/product/useCategoryQuery.ts similarity index 93% rename from frontend/src/hooks/queries/product/useCategoryQuery.ts rename to src/hooks/queries/product/useCategoryQuery.ts index e79987d93..d4aa6a8e5 100644 --- a/frontend/src/hooks/queries/product/useCategoryQuery.ts +++ b/src/hooks/queries/product/useCategoryQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '..'; +import { useSuspendedQuery } from '../index'; import { categoryApi } from '@/apis'; import type { Category, CategoryVariant, Food, Store } from '@/types/common'; diff --git a/frontend/src/hooks/queries/product/useInfiniteProductRecipesQuery.ts b/src/hooks/queries/product/useInfiniteProductRecipesQuery.ts similarity index 100% rename from frontend/src/hooks/queries/product/useInfiniteProductRecipesQuery.ts rename to src/hooks/queries/product/useInfiniteProductRecipesQuery.ts diff --git a/frontend/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts b/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts similarity index 94% rename from frontend/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts rename to src/hooks/queries/product/useInfiniteProductReviewsQuery.ts index 8142c77e0..c203366c9 100644 --- a/frontend/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts +++ b/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '..'; +import { useSuspendedInfiniteQuery } from '../index'; import { productApi } from '@/apis'; import type { ProductReviewResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts b/src/hooks/queries/product/useInfiniteProductsQuery.ts similarity index 94% rename from frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts rename to src/hooks/queries/product/useInfiniteProductsQuery.ts index 1b9fdd57f..6c7736645 100644 --- a/frontend/src/hooks/queries/product/useInfiniteProductsQuery.ts +++ b/src/hooks/queries/product/useInfiniteProductsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '..'; +import { useSuspendedInfiniteQuery } from '../index'; import { categoryApi } from '@/apis'; import type { CategoryProductResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/product/useProductDetailQuery.ts b/src/hooks/queries/product/useProductDetailQuery.ts similarity index 91% rename from frontend/src/hooks/queries/product/useProductDetailQuery.ts rename to src/hooks/queries/product/useProductDetailQuery.ts index a0c3cd7c1..1b5cad01a 100644 --- a/frontend/src/hooks/queries/product/useProductDetailQuery.ts +++ b/src/hooks/queries/product/useProductDetailQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '..'; +import { useSuspendedQuery } from '../index'; import { productApi } from '@/apis'; import type { ProductDetail } from '@/types/product'; diff --git a/frontend/src/hooks/queries/rank/index.ts b/src/hooks/queries/rank/index.ts similarity index 100% rename from frontend/src/hooks/queries/rank/index.ts rename to src/hooks/queries/rank/index.ts diff --git a/frontend/src/hooks/queries/rank/useBestReviewQuery.ts b/src/hooks/queries/rank/useBestReviewQuery.ts similarity index 100% rename from frontend/src/hooks/queries/rank/useBestReviewQuery.ts rename to src/hooks/queries/rank/useBestReviewQuery.ts diff --git a/frontend/src/hooks/queries/rank/useProductRankingQuery.ts b/src/hooks/queries/rank/useProductRankingQuery.ts similarity index 90% rename from frontend/src/hooks/queries/rank/useProductRankingQuery.ts rename to src/hooks/queries/rank/useProductRankingQuery.ts index afc9b4f19..5ff800360 100644 --- a/frontend/src/hooks/queries/rank/useProductRankingQuery.ts +++ b/src/hooks/queries/rank/useProductRankingQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '..'; +import { useSuspendedQuery } from '../index'; import { rankApi } from '@/apis'; import type { ProductRankingResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/rank/useRecipeRankingQuery.ts b/src/hooks/queries/rank/useRecipeRankingQuery.ts similarity index 100% rename from frontend/src/hooks/queries/rank/useRecipeRankingQuery.ts rename to src/hooks/queries/rank/useRecipeRankingQuery.ts diff --git a/frontend/src/hooks/queries/rank/useReviewRankingQuery.ts b/src/hooks/queries/rank/useReviewRankingQuery.ts similarity index 90% rename from frontend/src/hooks/queries/rank/useReviewRankingQuery.ts rename to src/hooks/queries/rank/useReviewRankingQuery.ts index edacfaaf8..35dac87ef 100644 --- a/frontend/src/hooks/queries/rank/useReviewRankingQuery.ts +++ b/src/hooks/queries/rank/useReviewRankingQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '..'; +import { useSuspendedQuery } from '../index'; import { rankApi } from '@/apis'; import type { ReviewRankingResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/recipe/index.ts b/src/hooks/queries/recipe/index.ts similarity index 100% rename from frontend/src/hooks/queries/recipe/index.ts rename to src/hooks/queries/recipe/index.ts diff --git a/frontend/src/hooks/queries/recipe/useInfiniteRecipeCommentQuery.ts b/src/hooks/queries/recipe/useInfiniteRecipeCommentQuery.ts similarity index 100% rename from frontend/src/hooks/queries/recipe/useInfiniteRecipeCommentQuery.ts rename to src/hooks/queries/recipe/useInfiniteRecipeCommentQuery.ts diff --git a/frontend/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts b/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts similarity index 93% rename from frontend/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts rename to src/hooks/queries/recipe/useInfiniteRecipesQuery.ts index 117212c27..cd8638fe6 100644 --- a/frontend/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts +++ b/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '..'; +import { useSuspendedInfiniteQuery } from '../index'; import { recipeApi } from '@/apis'; import type { RecipeResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/recipe/useRecipeCommentMutation.ts b/src/hooks/queries/recipe/useRecipeCommentMutation.ts similarity index 100% rename from frontend/src/hooks/queries/recipe/useRecipeCommentMutation.ts rename to src/hooks/queries/recipe/useRecipeCommentMutation.ts diff --git a/frontend/src/hooks/queries/recipe/useRecipeDetailQuery.ts b/src/hooks/queries/recipe/useRecipeDetailQuery.ts similarity index 91% rename from frontend/src/hooks/queries/recipe/useRecipeDetailQuery.ts rename to src/hooks/queries/recipe/useRecipeDetailQuery.ts index 7bff2fe0d..8e76dbae0 100644 --- a/frontend/src/hooks/queries/recipe/useRecipeDetailQuery.ts +++ b/src/hooks/queries/recipe/useRecipeDetailQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '..'; +import { useSuspendedQuery } from '../index'; import { recipeApi } from '@/apis'; import type { RecipeDetail } from '@/types/recipe'; diff --git a/frontend/src/hooks/queries/recipe/useRecipeFavoriteMutation.ts b/src/hooks/queries/recipe/useRecipeFavoriteMutation.ts similarity index 100% rename from frontend/src/hooks/queries/recipe/useRecipeFavoriteMutation.ts rename to src/hooks/queries/recipe/useRecipeFavoriteMutation.ts diff --git a/frontend/src/hooks/queries/recipe/useRecipeRegisterFormMutation.ts b/src/hooks/queries/recipe/useRecipeRegisterFormMutation.ts similarity index 100% rename from frontend/src/hooks/queries/recipe/useRecipeRegisterFormMutation.ts rename to src/hooks/queries/recipe/useRecipeRegisterFormMutation.ts diff --git a/frontend/src/hooks/queries/review/index.ts b/src/hooks/queries/review/index.ts similarity index 100% rename from frontend/src/hooks/queries/review/index.ts rename to src/hooks/queries/review/index.ts diff --git a/frontend/src/hooks/queries/review/useReviewDetailQuery.ts b/src/hooks/queries/review/useReviewDetailQuery.ts similarity index 100% rename from frontend/src/hooks/queries/review/useReviewDetailQuery.ts rename to src/hooks/queries/review/useReviewDetailQuery.ts diff --git a/frontend/src/hooks/queries/review/useReviewFavoriteMutation.ts b/src/hooks/queries/review/useReviewFavoriteMutation.ts similarity index 100% rename from frontend/src/hooks/queries/review/useReviewFavoriteMutation.ts rename to src/hooks/queries/review/useReviewFavoriteMutation.ts diff --git a/frontend/src/hooks/queries/review/useReviewRegisterFormMutation.ts b/src/hooks/queries/review/useReviewRegisterFormMutation.ts similarity index 100% rename from frontend/src/hooks/queries/review/useReviewRegisterFormMutation.ts rename to src/hooks/queries/review/useReviewRegisterFormMutation.ts diff --git a/frontend/src/hooks/queries/review/useReviewTagsQuery.ts b/src/hooks/queries/review/useReviewTagsQuery.ts similarity index 89% rename from frontend/src/hooks/queries/review/useReviewTagsQuery.ts rename to src/hooks/queries/review/useReviewTagsQuery.ts index 3ba2b3409..2d8ced682 100644 --- a/frontend/src/hooks/queries/review/useReviewTagsQuery.ts +++ b/src/hooks/queries/review/useReviewTagsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '..'; +import { useSuspendedQuery } from '../index'; import { tagApi } from '@/apis'; import type { ReviewTag } from '@/types/review'; diff --git a/frontend/src/hooks/queries/search/index.ts b/src/hooks/queries/search/index.ts similarity index 100% rename from frontend/src/hooks/queries/search/index.ts rename to src/hooks/queries/search/index.ts diff --git a/frontend/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts b/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts similarity index 94% rename from frontend/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts rename to src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts index 492f3d96e..33bb275c0 100644 --- a/frontend/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts +++ b/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '..'; +import { useSuspendedInfiniteQuery } from '../index'; import { searchApi } from '@/apis'; import type { ProductSearchAutocompleteResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts b/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts similarity index 94% rename from frontend/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts rename to src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts index d49a07453..c9e06a2d8 100644 --- a/frontend/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts +++ b/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '..'; +import { useSuspendedInfiniteQuery } from '../index'; import { searchApi } from '@/apis'; import type { ProductSearchResultResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts b/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts similarity index 94% rename from frontend/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts rename to src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts index e473c405f..d1d6c21bf 100644 --- a/frontend/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts +++ b/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '..'; +import { useSuspendedInfiniteQuery } from '../index'; import { searchApi } from '@/apis'; import type { RecipeResponse } from '@/types/response'; diff --git a/frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts b/src/hooks/queries/useSuspendedInfiniteQuery.ts similarity index 100% rename from frontend/src/hooks/queries/useSuspendedInfiniteQuery.ts rename to src/hooks/queries/useSuspendedInfiniteQuery.ts diff --git a/frontend/src/hooks/queries/useSuspendedQuery.ts b/src/hooks/queries/useSuspendedQuery.ts similarity index 100% rename from frontend/src/hooks/queries/useSuspendedQuery.ts rename to src/hooks/queries/useSuspendedQuery.ts diff --git a/frontend/src/hooks/review/index.ts b/src/hooks/review/index.ts similarity index 100% rename from frontend/src/hooks/review/index.ts rename to src/hooks/review/index.ts diff --git a/frontend/src/hooks/review/useDisplayTag.ts b/src/hooks/review/useDisplayTag.ts similarity index 100% rename from frontend/src/hooks/review/useDisplayTag.ts rename to src/hooks/review/useDisplayTag.ts diff --git a/frontend/src/hooks/review/useStarRatingHover.ts b/src/hooks/review/useStarRatingHover.ts similarity index 100% rename from frontend/src/hooks/review/useStarRatingHover.ts rename to src/hooks/review/useStarRatingHover.ts diff --git a/frontend/src/hooks/search/index.ts b/src/hooks/search/index.ts similarity index 100% rename from frontend/src/hooks/search/index.ts rename to src/hooks/search/index.ts diff --git a/frontend/src/hooks/search/useSearch.ts b/src/hooks/search/useSearch.ts similarity index 100% rename from frontend/src/hooks/search/useSearch.ts rename to src/hooks/search/useSearch.ts diff --git a/frontend/src/index.tsx b/src/index.tsx similarity index 100% rename from frontend/src/index.tsx rename to src/index.tsx diff --git a/frontend/src/mocks/browser.ts b/src/mocks/browser.ts similarity index 100% rename from frontend/src/mocks/browser.ts rename to src/mocks/browser.ts diff --git a/frontend/src/mocks/data/banners.json b/src/mocks/data/banners.json similarity index 100% rename from frontend/src/mocks/data/banners.json rename to src/mocks/data/banners.json diff --git a/frontend/src/mocks/data/comments.json b/src/mocks/data/comments.json similarity index 100% rename from frontend/src/mocks/data/comments.json rename to src/mocks/data/comments.json diff --git a/frontend/src/mocks/data/foodCategory.json b/src/mocks/data/foodCategory.json similarity index 100% rename from frontend/src/mocks/data/foodCategory.json rename to src/mocks/data/foodCategory.json diff --git a/frontend/src/mocks/data/memberRecipes.json b/src/mocks/data/memberRecipes.json similarity index 100% rename from frontend/src/mocks/data/memberRecipes.json rename to src/mocks/data/memberRecipes.json diff --git a/frontend/src/mocks/data/memberReviews.json b/src/mocks/data/memberReviews.json similarity index 100% rename from frontend/src/mocks/data/memberReviews.json rename to src/mocks/data/memberReviews.json diff --git a/frontend/src/mocks/data/members.json b/src/mocks/data/members.json similarity index 100% rename from frontend/src/mocks/data/members.json rename to src/mocks/data/members.json diff --git a/frontend/src/mocks/data/pbProducts.json b/src/mocks/data/pbProducts.json similarity index 100% rename from frontend/src/mocks/data/pbProducts.json rename to src/mocks/data/pbProducts.json diff --git a/frontend/src/mocks/data/productDetail.json b/src/mocks/data/productDetail.json similarity index 100% rename from frontend/src/mocks/data/productDetail.json rename to src/mocks/data/productDetail.json diff --git a/frontend/src/mocks/data/productDetails.json b/src/mocks/data/productDetails.json similarity index 100% rename from frontend/src/mocks/data/productDetails.json rename to src/mocks/data/productDetails.json diff --git a/frontend/src/mocks/data/productRankingList.json b/src/mocks/data/productRankingList.json similarity index 100% rename from frontend/src/mocks/data/productRankingList.json rename to src/mocks/data/productRankingList.json diff --git a/frontend/src/mocks/data/productSearchResults.json b/src/mocks/data/productSearchResults.json similarity index 100% rename from frontend/src/mocks/data/productSearchResults.json rename to src/mocks/data/productSearchResults.json diff --git a/frontend/src/mocks/data/products.json b/src/mocks/data/products.json similarity index 100% rename from frontend/src/mocks/data/products.json rename to src/mocks/data/products.json diff --git a/frontend/src/mocks/data/recipeDetail.json b/src/mocks/data/recipeDetail.json similarity index 100% rename from frontend/src/mocks/data/recipeDetail.json rename to src/mocks/data/recipeDetail.json diff --git a/frontend/src/mocks/data/recipeRankingList.json b/src/mocks/data/recipeRankingList.json similarity index 100% rename from frontend/src/mocks/data/recipeRankingList.json rename to src/mocks/data/recipeRankingList.json diff --git a/frontend/src/mocks/data/recipes.json b/src/mocks/data/recipes.json similarity index 100% rename from frontend/src/mocks/data/recipes.json rename to src/mocks/data/recipes.json diff --git a/frontend/src/mocks/data/reviewDetail.json b/src/mocks/data/reviewDetail.json similarity index 100% rename from frontend/src/mocks/data/reviewDetail.json rename to src/mocks/data/reviewDetail.json diff --git a/frontend/src/mocks/data/reviewRankingList.json b/src/mocks/data/reviewRankingList.json similarity index 100% rename from frontend/src/mocks/data/reviewRankingList.json rename to src/mocks/data/reviewRankingList.json diff --git a/frontend/src/mocks/data/reviewTagList.json b/src/mocks/data/reviewTagList.json similarity index 100% rename from frontend/src/mocks/data/reviewTagList.json rename to src/mocks/data/reviewTagList.json diff --git a/frontend/src/mocks/data/reviews.json b/src/mocks/data/reviews.json similarity index 100% rename from frontend/src/mocks/data/reviews.json rename to src/mocks/data/reviews.json diff --git a/frontend/src/mocks/data/searchingProducts.json b/src/mocks/data/searchingProducts.json similarity index 100% rename from frontend/src/mocks/data/searchingProducts.json rename to src/mocks/data/searchingProducts.json diff --git a/frontend/src/mocks/data/storeCategory.json b/src/mocks/data/storeCategory.json similarity index 100% rename from frontend/src/mocks/data/storeCategory.json rename to src/mocks/data/storeCategory.json diff --git a/frontend/src/mocks/handlers/bannerHandlers.ts b/src/mocks/handlers/bannerHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/bannerHandlers.ts rename to src/mocks/handlers/bannerHandlers.ts diff --git a/frontend/src/mocks/handlers/index.ts b/src/mocks/handlers/index.ts similarity index 100% rename from frontend/src/mocks/handlers/index.ts rename to src/mocks/handlers/index.ts diff --git a/frontend/src/mocks/handlers/loginHandlers.ts b/src/mocks/handlers/loginHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/loginHandlers.ts rename to src/mocks/handlers/loginHandlers.ts diff --git a/frontend/src/mocks/handlers/logoutHandlers.ts b/src/mocks/handlers/logoutHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/logoutHandlers.ts rename to src/mocks/handlers/logoutHandlers.ts diff --git a/frontend/src/mocks/handlers/memberHandlers.ts b/src/mocks/handlers/memberHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/memberHandlers.ts rename to src/mocks/handlers/memberHandlers.ts diff --git a/frontend/src/mocks/handlers/productHandlers.ts b/src/mocks/handlers/productHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/productHandlers.ts rename to src/mocks/handlers/productHandlers.ts diff --git a/frontend/src/mocks/handlers/rankingHandlers.ts b/src/mocks/handlers/rankingHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/rankingHandlers.ts rename to src/mocks/handlers/rankingHandlers.ts diff --git a/frontend/src/mocks/handlers/recipeHandlers.ts b/src/mocks/handlers/recipeHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/recipeHandlers.ts rename to src/mocks/handlers/recipeHandlers.ts diff --git a/frontend/src/mocks/handlers/reviewHandlers.ts b/src/mocks/handlers/reviewHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/reviewHandlers.ts rename to src/mocks/handlers/reviewHandlers.ts diff --git a/frontend/src/mocks/handlers/searchHandlers.ts b/src/mocks/handlers/searchHandlers.ts similarity index 100% rename from frontend/src/mocks/handlers/searchHandlers.ts rename to src/mocks/handlers/searchHandlers.ts diff --git a/frontend/src/mocks/handlers/utils.ts b/src/mocks/handlers/utils.ts similarity index 100% rename from frontend/src/mocks/handlers/utils.ts rename to src/mocks/handlers/utils.ts diff --git a/frontend/src/pages/AuthPage.tsx b/src/pages/AuthPage.tsx similarity index 100% rename from frontend/src/pages/AuthPage.tsx rename to src/pages/AuthPage.tsx diff --git a/frontend/src/pages/HomePage.tsx b/src/pages/HomePage.tsx similarity index 100% rename from frontend/src/pages/HomePage.tsx rename to src/pages/HomePage.tsx diff --git a/frontend/src/pages/IntegratedSearchPage.tsx b/src/pages/IntegratedSearchPage.tsx similarity index 100% rename from frontend/src/pages/IntegratedSearchPage.tsx rename to src/pages/IntegratedSearchPage.tsx diff --git a/frontend/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx similarity index 100% rename from frontend/src/pages/LoginPage.tsx rename to src/pages/LoginPage.tsx diff --git a/frontend/src/pages/MemberModifyPage.tsx b/src/pages/MemberModifyPage.tsx similarity index 100% rename from frontend/src/pages/MemberModifyPage.tsx rename to src/pages/MemberModifyPage.tsx diff --git a/frontend/src/pages/MemberPage.tsx b/src/pages/MemberPage.tsx similarity index 100% rename from frontend/src/pages/MemberPage.tsx rename to src/pages/MemberPage.tsx diff --git a/frontend/src/pages/MemberRecipePage.tsx b/src/pages/MemberRecipePage.tsx similarity index 100% rename from frontend/src/pages/MemberRecipePage.tsx rename to src/pages/MemberRecipePage.tsx diff --git a/frontend/src/pages/MemberReviewPage.tsx b/src/pages/MemberReviewPage.tsx similarity index 100% rename from frontend/src/pages/MemberReviewPage.tsx rename to src/pages/MemberReviewPage.tsx diff --git a/frontend/src/pages/NotFoundPage.tsx b/src/pages/NotFoundPage.tsx similarity index 100% rename from frontend/src/pages/NotFoundPage.tsx rename to src/pages/NotFoundPage.tsx diff --git a/frontend/src/pages/ProductDetailPage.tsx b/src/pages/ProductDetailPage.tsx similarity index 100% rename from frontend/src/pages/ProductDetailPage.tsx rename to src/pages/ProductDetailPage.tsx diff --git a/frontend/src/pages/ProductListPage.tsx b/src/pages/ProductListPage.tsx similarity index 100% rename from frontend/src/pages/ProductListPage.tsx rename to src/pages/ProductListPage.tsx diff --git a/frontend/src/pages/RecipeDetailPage.tsx b/src/pages/RecipeDetailPage.tsx similarity index 100% rename from frontend/src/pages/RecipeDetailPage.tsx rename to src/pages/RecipeDetailPage.tsx diff --git a/frontend/src/pages/RecipePage.tsx b/src/pages/RecipePage.tsx similarity index 100% rename from frontend/src/pages/RecipePage.tsx rename to src/pages/RecipePage.tsx diff --git a/frontend/src/pages/ReviewDetailPage.tsx b/src/pages/ReviewDetailPage.tsx similarity index 100% rename from frontend/src/pages/ReviewDetailPage.tsx rename to src/pages/ReviewDetailPage.tsx diff --git a/frontend/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx similarity index 100% rename from frontend/src/pages/SearchPage.tsx rename to src/pages/SearchPage.tsx diff --git a/frontend/src/router/App.tsx b/src/router/App.tsx similarity index 100% rename from frontend/src/router/App.tsx rename to src/router/App.tsx diff --git a/frontend/src/router/index.tsx b/src/router/index.tsx similarity index 100% rename from frontend/src/router/index.tsx rename to src/router/index.tsx diff --git a/frontend/src/service/channelTalk.ts b/src/service/channelTalk.ts similarity index 100% rename from frontend/src/service/channelTalk.ts rename to src/service/channelTalk.ts diff --git a/frontend/src/styles/animations.ts b/src/styles/animations.ts similarity index 100% rename from frontend/src/styles/animations.ts rename to src/styles/animations.ts diff --git a/frontend/src/styles/font.ts b/src/styles/font.ts similarity index 100% rename from frontend/src/styles/font.ts rename to src/styles/font.ts diff --git a/frontend/src/styles/globalStyle.ts b/src/styles/globalStyle.ts similarity index 100% rename from frontend/src/styles/globalStyle.ts rename to src/styles/globalStyle.ts diff --git a/frontend/src/types/banner.ts b/src/types/banner.ts similarity index 100% rename from frontend/src/types/banner.ts rename to src/types/banner.ts diff --git a/frontend/src/types/common.ts b/src/types/common.ts similarity index 100% rename from frontend/src/types/common.ts rename to src/types/common.ts diff --git a/frontend/src/types/images.d.ts b/src/types/images.d.ts similarity index 100% rename from frontend/src/types/images.d.ts rename to src/types/images.d.ts diff --git a/frontend/src/types/member.ts b/src/types/member.ts similarity index 100% rename from frontend/src/types/member.ts rename to src/types/member.ts diff --git a/frontend/src/types/product.ts b/src/types/product.ts similarity index 100% rename from frontend/src/types/product.ts rename to src/types/product.ts diff --git a/frontend/src/types/ranking.ts b/src/types/ranking.ts similarity index 100% rename from frontend/src/types/ranking.ts rename to src/types/ranking.ts diff --git a/frontend/src/types/recipe.ts b/src/types/recipe.ts similarity index 100% rename from frontend/src/types/recipe.ts rename to src/types/recipe.ts diff --git a/frontend/src/types/response.ts b/src/types/response.ts similarity index 100% rename from frontend/src/types/response.ts rename to src/types/response.ts diff --git a/frontend/src/types/review.ts b/src/types/review.ts similarity index 100% rename from frontend/src/types/review.ts rename to src/types/review.ts diff --git a/frontend/src/types/search.ts b/src/types/search.ts similarity index 100% rename from frontend/src/types/search.ts rename to src/types/search.ts diff --git a/frontend/src/types/styled.d.ts b/src/types/styled.d.ts similarity index 100% rename from frontend/src/types/styled.d.ts rename to src/types/styled.d.ts diff --git a/frontend/src/utils/category.ts b/src/utils/category.ts similarity index 100% rename from frontend/src/utils/category.ts rename to src/utils/category.ts diff --git a/frontend/src/utils/convertTagColor.ts b/src/utils/convertTagColor.ts similarity index 100% rename from frontend/src/utils/convertTagColor.ts rename to src/utils/convertTagColor.ts diff --git a/frontend/src/utils/date.ts b/src/utils/date.ts similarity index 100% rename from frontend/src/utils/date.ts rename to src/utils/date.ts diff --git a/frontend/src/utils/displaySlice.ts b/src/utils/displaySlice.ts similarity index 100% rename from frontend/src/utils/displaySlice.ts rename to src/utils/displaySlice.ts diff --git a/frontend/src/utils/localStorage.ts b/src/utils/localStorage.ts similarity index 100% rename from frontend/src/utils/localStorage.ts rename to src/utils/localStorage.ts diff --git a/frontend/src/utils/uuid.ts b/src/utils/uuid.ts similarity index 100% rename from frontend/src/utils/uuid.ts rename to src/utils/uuid.ts diff --git a/frontend/tsconfig.json b/tsconfig.json similarity index 76% rename from frontend/tsconfig.json rename to tsconfig.json index 321f1c029..21f555674 100644 --- a/frontend/tsconfig.json +++ b/tsconfig.json @@ -11,13 +11,18 @@ "skipLibCheck": true, "jsx": "react-jsx", "outDir": "./dist", - "typeRoots": ["node_modules/@types", "src/types"], - "baseUrl": ".", + "typeRoots": ["node_modules/@types", + "src/types" + ], + "baseUrl": "./frontend", "paths": { "@/*": ["src/*"] }, "removeComments": false }, - "include": ["src", "__tests__"], + "include": [ + "src", + "__tests__" + ], "exclude": ["node_modules", "dist"] } diff --git a/frontend/webpack.common.js b/webpack.common.js similarity index 100% rename from frontend/webpack.common.js rename to webpack.common.js diff --git a/frontend/webpack.dev.js b/webpack.dev.js similarity index 100% rename from frontend/webpack.dev.js rename to webpack.dev.js diff --git a/frontend/webpack.prod.js b/webpack.prod.js similarity index 100% rename from frontend/webpack.prod.js rename to webpack.prod.js diff --git a/frontend/yarn.lock b/yarn.lock similarity index 100% rename from frontend/yarn.lock rename to yarn.lock From 251116fa93168c55ee167199d65ba3a9bb612c6c Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 27 Nov 2023 18:03:08 +0900 Subject: [PATCH 2/5] =?UTF-8?q?chore:=20tsconfig=20baseUrl=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.json | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 21f555674..321f1c029 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,18 +11,13 @@ "skipLibCheck": true, "jsx": "react-jsx", "outDir": "./dist", - "typeRoots": ["node_modules/@types", - "src/types" - ], - "baseUrl": "./frontend", + "typeRoots": ["node_modules/@types", "src/types"], + "baseUrl": ".", "paths": { "@/*": ["src/*"] }, "removeComments": false }, - "include": [ - "src", - "__tests__" - ], + "include": ["src", "__tests__"], "exclude": ["node_modules", "dist"] } From b09cee7ec18d9e47f85c84354e18670baae1aea4 Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 27 Nov 2023 18:03:31 +0900 Subject: [PATCH 3/5] =?UTF-8?q?style:=20index=20import=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx | 2 +- src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts | 2 +- src/hooks/queries/members/useInfiniteMemberReviewQuery.ts | 2 +- src/hooks/queries/members/useMemberQuery.ts | 2 +- src/hooks/queries/product/useCategoryQuery.ts | 2 +- src/hooks/queries/product/useInfiniteProductReviewsQuery.ts | 2 +- src/hooks/queries/product/useInfiniteProductsQuery.ts | 2 +- src/hooks/queries/product/useProductDetailQuery.ts | 2 +- src/hooks/queries/rank/useProductRankingQuery.ts | 2 +- src/hooks/queries/rank/useReviewRankingQuery.ts | 2 +- src/hooks/queries/recipe/useInfiniteRecipesQuery.ts | 2 +- src/hooks/queries/recipe/useRecipeDetailQuery.ts | 2 +- src/hooks/queries/review/useReviewTagsQuery.ts | 2 +- .../queries/search/useInfiniteProductSearchAutocompleteQuery.ts | 2 +- .../queries/search/useInfiniteProductSearchResultsQuery.ts | 2 +- src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx b/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx index 902bdde87..eefc6267a 100644 --- a/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx +++ b/src/components/Recipe/RecipeDetailTextarea/RecipeDetailTextarea.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { RecipeDetailTextarea } from '../index'; +import { RecipeDetailTextarea } from '..'; import RecipeFormProvider from '@/contexts/RecipeFormContext'; diff --git a/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts b/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts index 920e58a65..1714fde8e 100644 --- a/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts +++ b/src/hooks/queries/members/useInfiniteMemberRecipeQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '../index'; +import { useSuspendedInfiniteQuery } from '..'; import { memberApi } from '@/apis'; import type { MemberRecipeResponse } from '@/types/response'; diff --git a/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts b/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts index 2f9336fe8..556a24944 100644 --- a/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts +++ b/src/hooks/queries/members/useInfiniteMemberReviewQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '../index'; +import { useSuspendedInfiniteQuery } from '..'; import { memberApi } from '@/apis'; import type { MemberReviewResponse } from '@/types/response'; diff --git a/src/hooks/queries/members/useMemberQuery.ts b/src/hooks/queries/members/useMemberQuery.ts index a98cedd89..f948cade1 100644 --- a/src/hooks/queries/members/useMemberQuery.ts +++ b/src/hooks/queries/members/useMemberQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '../index'; +import { useSuspendedQuery } from '..'; import { memberApi } from '@/apis'; import type { Member } from '@/types/member'; diff --git a/src/hooks/queries/product/useCategoryQuery.ts b/src/hooks/queries/product/useCategoryQuery.ts index d4aa6a8e5..e79987d93 100644 --- a/src/hooks/queries/product/useCategoryQuery.ts +++ b/src/hooks/queries/product/useCategoryQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '../index'; +import { useSuspendedQuery } from '..'; import { categoryApi } from '@/apis'; import type { Category, CategoryVariant, Food, Store } from '@/types/common'; diff --git a/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts b/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts index c203366c9..8142c77e0 100644 --- a/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts +++ b/src/hooks/queries/product/useInfiniteProductReviewsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '../index'; +import { useSuspendedInfiniteQuery } from '..'; import { productApi } from '@/apis'; import type { ProductReviewResponse } from '@/types/response'; diff --git a/src/hooks/queries/product/useInfiniteProductsQuery.ts b/src/hooks/queries/product/useInfiniteProductsQuery.ts index 6c7736645..1b9fdd57f 100644 --- a/src/hooks/queries/product/useInfiniteProductsQuery.ts +++ b/src/hooks/queries/product/useInfiniteProductsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '../index'; +import { useSuspendedInfiniteQuery } from '..'; import { categoryApi } from '@/apis'; import type { CategoryProductResponse } from '@/types/response'; diff --git a/src/hooks/queries/product/useProductDetailQuery.ts b/src/hooks/queries/product/useProductDetailQuery.ts index 1b5cad01a..a0c3cd7c1 100644 --- a/src/hooks/queries/product/useProductDetailQuery.ts +++ b/src/hooks/queries/product/useProductDetailQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '../index'; +import { useSuspendedQuery } from '..'; import { productApi } from '@/apis'; import type { ProductDetail } from '@/types/product'; diff --git a/src/hooks/queries/rank/useProductRankingQuery.ts b/src/hooks/queries/rank/useProductRankingQuery.ts index 5ff800360..afc9b4f19 100644 --- a/src/hooks/queries/rank/useProductRankingQuery.ts +++ b/src/hooks/queries/rank/useProductRankingQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '../index'; +import { useSuspendedQuery } from '..'; import { rankApi } from '@/apis'; import type { ProductRankingResponse } from '@/types/response'; diff --git a/src/hooks/queries/rank/useReviewRankingQuery.ts b/src/hooks/queries/rank/useReviewRankingQuery.ts index 35dac87ef..edacfaaf8 100644 --- a/src/hooks/queries/rank/useReviewRankingQuery.ts +++ b/src/hooks/queries/rank/useReviewRankingQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '../index'; +import { useSuspendedQuery } from '..'; import { rankApi } from '@/apis'; import type { ReviewRankingResponse } from '@/types/response'; diff --git a/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts b/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts index cd8638fe6..117212c27 100644 --- a/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts +++ b/src/hooks/queries/recipe/useInfiniteRecipesQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '../index'; +import { useSuspendedInfiniteQuery } from '..'; import { recipeApi } from '@/apis'; import type { RecipeResponse } from '@/types/response'; diff --git a/src/hooks/queries/recipe/useRecipeDetailQuery.ts b/src/hooks/queries/recipe/useRecipeDetailQuery.ts index 8e76dbae0..7bff2fe0d 100644 --- a/src/hooks/queries/recipe/useRecipeDetailQuery.ts +++ b/src/hooks/queries/recipe/useRecipeDetailQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '../index'; +import { useSuspendedQuery } from '..'; import { recipeApi } from '@/apis'; import type { RecipeDetail } from '@/types/recipe'; diff --git a/src/hooks/queries/review/useReviewTagsQuery.ts b/src/hooks/queries/review/useReviewTagsQuery.ts index 2d8ced682..3ba2b3409 100644 --- a/src/hooks/queries/review/useReviewTagsQuery.ts +++ b/src/hooks/queries/review/useReviewTagsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedQuery } from '../index'; +import { useSuspendedQuery } from '..'; import { tagApi } from '@/apis'; import type { ReviewTag } from '@/types/review'; diff --git a/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts b/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts index 33bb275c0..492f3d96e 100644 --- a/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts +++ b/src/hooks/queries/search/useInfiniteProductSearchAutocompleteQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '../index'; +import { useSuspendedInfiniteQuery } from '..'; import { searchApi } from '@/apis'; import type { ProductSearchAutocompleteResponse } from '@/types/response'; diff --git a/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts b/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts index c9e06a2d8..d49a07453 100644 --- a/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts +++ b/src/hooks/queries/search/useInfiniteProductSearchResultsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '../index'; +import { useSuspendedInfiniteQuery } from '..'; import { searchApi } from '@/apis'; import type { ProductSearchResultResponse } from '@/types/response'; diff --git a/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts b/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts index d1d6c21bf..e473c405f 100644 --- a/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts +++ b/src/hooks/queries/search/useInfiniteRecipeSearchResultsQuery.ts @@ -1,4 +1,4 @@ -import { useSuspendedInfiniteQuery } from '../index'; +import { useSuspendedInfiniteQuery } from '..'; import { searchApi } from '@/apis'; import type { RecipeResponse } from '@/types/response'; From f8dfdd2e3e59ad4e730ee27a7df11f4870d0c80c Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 27 Nov 2023 18:05:42 +0900 Subject: [PATCH 4/5] =?UTF-8?q?chore:=20=EC=9D=B4=EC=8A=88=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=20=EC=A0=9C=EB=AA=A9=20prefix=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index bd61107e9..16cd7428c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,7 @@ --- name: πŸ› Bug Report about: 버그 리포트 이슈 ν…œν”Œλ¦Ώμž…λ‹ˆλ‹€ -title: '[ALL/FE/BE] ' +title: '' labels: '' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 904cf1acc..fdc3eec22 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: ✨ Feature request about: feature 이슈 ν…œν”Œλ¦Ώμž…λ‹ˆλ‹€ -title: '[ALL/FE/BE] ' +title: '' labels: '' assignees: '' --- From ae2a7923ab86394f456020d2a1552fc0ca49e13c Mon Sep 17 00:00:00 2001 From: Leejin-Yang Date: Mon, 27 Nov 2023 18:10:24 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20workflow=20working=20directory=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test-fe.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test-fe.yml b/.github/workflows/test-fe.yml index b8c436089..191c5cf2e 100644 --- a/.github/workflows/test-fe.yml +++ b/.github/workflows/test-fe.yml @@ -34,12 +34,10 @@ jobs: ${{ runner.os }}-node- - name: μ˜μ‘΄μ„± μ„€μΉ˜ - working-directory: frontend/ if: steps.cache.outputs.cache-hit != 'true' run: yarn install --pure-lockfile - name: ν…ŒμŠ€νŠΈ μ‹€ν–‰ - working-directory: frontend/ run: yarn test continue-on-error: true