From 6e4de92fb263d1d3fee388e56a382bdb54073955 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Mon, 7 Aug 2023 16:26:06 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20=EB=A0=88=EC=8B=9C=ED=94=BC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20API=20=ED=8B=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../recipe/dto/RecipeCreateRequest.java | 28 +++++++++++++++++ .../presentation/RecipeApiController.java | 31 +++++++++++++++++++ .../recipe/presentation/RecipeController.java | 27 ++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 backend/src/main/java/com/funeat/recipe/dto/RecipeCreateRequest.java create mode 100644 backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java create mode 100644 backend/src/main/java/com/funeat/recipe/presentation/RecipeController.java diff --git a/backend/src/main/java/com/funeat/recipe/dto/RecipeCreateRequest.java b/backend/src/main/java/com/funeat/recipe/dto/RecipeCreateRequest.java new file mode 100644 index 000000000..498236d76 --- /dev/null +++ b/backend/src/main/java/com/funeat/recipe/dto/RecipeCreateRequest.java @@ -0,0 +1,28 @@ +package com.funeat.recipe.dto; + +import java.util.List; + +public class RecipeCreateRequest { + + private final String name; + private final List productIds; + private final String content; + + public RecipeCreateRequest(final String name, final List productIds, final String content) { + this.name = name; + this.productIds = productIds; + this.content = content; + } + + public String getName() { + return name; + } + + public List getProductIds() { + return productIds; + } + + public String getContent() { + return content; + } +} diff --git a/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java b/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java new file mode 100644 index 000000000..f93fcddf7 --- /dev/null +++ b/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java @@ -0,0 +1,31 @@ +package com.funeat.recipe.presentation; + +import com.funeat.auth.dto.LoginInfo; +import com.funeat.auth.util.AuthenticationPrincipal; +import com.funeat.recipe.application.RecipeService; +import com.funeat.recipe.dto.RecipeCreateRequest; +import java.net.URI; +import java.util.List; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; + +public class RecipeApiController implements RecipeController{ + + private final RecipeService recipeService; + + public RecipeApiController(final RecipeService recipeService) { + this.recipeService = recipeService; + } + + @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 final RecipeCreateRequest recipeRequest) { + Long recipeId = recipeService.create(loginInfo.getId(), images, recipeRequest); + + return ResponseEntity.created(URI.create("/api/recipes/" + recipeId)).build(); + } +} diff --git a/backend/src/main/java/com/funeat/recipe/presentation/RecipeController.java b/backend/src/main/java/com/funeat/recipe/presentation/RecipeController.java new file mode 100644 index 000000000..dd6281eb0 --- /dev/null +++ b/backend/src/main/java/com/funeat/recipe/presentation/RecipeController.java @@ -0,0 +1,27 @@ +package com.funeat.recipe.presentation; + +import com.funeat.auth.dto.LoginInfo; +import com.funeat.auth.util.AuthenticationPrincipal; +import com.funeat.recipe.dto.RecipeCreateRequest; +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.PostMapping; +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 LoginInfo loginInfo, + @RequestPart List images, + @RequestPart RecipeCreateRequest recipeRequest); +} From 529fb175c29be5d1f97b2c16fe776864a51e7e64 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Mon, 7 Aug 2023 16:27:35 +0900 Subject: [PATCH 02/15] =?UTF-8?q?refactor:=20Recipe=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20=ED=95=84=EC=9A=94=20=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=EC=96=91=EB=B0=A9=ED=96=A5=20=EB=A7=A4=ED=95=91=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EB=B0=8F=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/funeat/recipe/domain/Recipe.java | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/backend/src/main/java/com/funeat/recipe/domain/Recipe.java b/backend/src/main/java/com/funeat/recipe/domain/Recipe.java index b52c125b4..8b3837777 100644 --- a/backend/src/main/java/com/funeat/recipe/domain/Recipe.java +++ b/backend/src/main/java/com/funeat/recipe/domain/Recipe.java @@ -1,17 +1,12 @@ package com.funeat.recipe.domain; import com.funeat.member.domain.Member; -import com.funeat.member.domain.bookmark.RecipeBookmark; -import com.funeat.member.domain.favorite.RecipeFavorite; -import com.funeat.product.domain.ProductRecipe; -import java.util.List; import javax.persistence.Entity; 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 Recipe { @@ -28,12 +23,28 @@ public class Recipe { @JoinColumn(name = "member_id") private Member member; - @OneToMany(mappedBy = "recipe") - private List productRecipes; + protected Recipe() { + } - @OneToMany(mappedBy = "recipe") - private List recipeFavorites; + public Recipe(final String name, final String content, final Member member) { + this.name = name; + this.content = content; + this.member = member; + } - @OneToMany(mappedBy = "recipe") - private List recipeBookmarks; + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getContent() { + return content; + } + + public Member getMember() { + return member; + } } From ba3e792feac485829c0fb6f6ae444c3d700a36b4 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Mon, 7 Aug 2023 16:28:26 +0900 Subject: [PATCH 03/15] =?UTF-8?q?refactor:=20ProductRecipe=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=EC=97=90=20=EC=83=9D=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/funeat/product/domain/ProductRecipe.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/src/main/java/com/funeat/product/domain/ProductRecipe.java b/backend/src/main/java/com/funeat/product/domain/ProductRecipe.java index 0d55845ed..dc68ee01e 100644 --- a/backend/src/main/java/com/funeat/product/domain/ProductRecipe.java +++ b/backend/src/main/java/com/funeat/product/domain/ProductRecipe.java @@ -22,4 +22,12 @@ public class ProductRecipe { @ManyToOne @JoinColumn(name = "recipe_id") private Recipe recipe; + + protected ProductRecipe() { + } + + public ProductRecipe(final Product product, final Recipe recipe) { + this.product = product; + this.recipe = recipe; + } } From ad42156716b49198a462815757260705dc5fec55 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Mon, 7 Aug 2023 16:28:46 +0900 Subject: [PATCH 04/15] =?UTF-8?q?refactor:=20RecipeImage=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=EC=97=90=20=EC=83=9D=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/funeat/recipe/domain/RecipeImage.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/backend/src/main/java/com/funeat/recipe/domain/RecipeImage.java b/backend/src/main/java/com/funeat/recipe/domain/RecipeImage.java index c3bf4ec0a..2dbb4ac34 100644 --- a/backend/src/main/java/com/funeat/recipe/domain/RecipeImage.java +++ b/backend/src/main/java/com/funeat/recipe/domain/RecipeImage.java @@ -19,4 +19,12 @@ public class RecipeImage { @ManyToOne @JoinColumn(name = "recipe_id") private Recipe recipe; + + protected RecipeImage() { + } + + public RecipeImage(final String image, final Recipe recipe) { + this.image = image; + this.recipe = recipe; + } } From 69a643776bf23c70f5c800784e6ca3b63f97acc9 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Mon, 7 Aug 2023 16:29:50 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20RecipeImageUploader=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/RecipeImageUploader.java | 30 +++++++++++++++++++ ...Uploader.java => ReviewImageUploader.java} | 4 +-- .../review/application/ReviewService.java | 13 ++++---- .../src/main/resources/application-dev.yml | 4 +++ 4 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 backend/src/main/java/com/funeat/recipe/application/RecipeImageUploader.java rename backend/src/main/java/com/funeat/review/application/{ImageUploader.java => ReviewImageUploader.java} (89%) diff --git a/backend/src/main/java/com/funeat/recipe/application/RecipeImageUploader.java b/backend/src/main/java/com/funeat/recipe/application/RecipeImageUploader.java new file mode 100644 index 000000000..03711fbdf --- /dev/null +++ b/backend/src/main/java/com/funeat/recipe/application/RecipeImageUploader.java @@ -0,0 +1,30 @@ +package com.funeat.recipe.application; + +import com.funeat.review.application.ImageService; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +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("recipeImageUploader") +@Profile("!test") +public class RecipeImageUploader implements ImageService { + + @Value("${recipe.image.path}") + private String imagePath; + + @Override + public void upload(final MultipartFile image) { + final String originalImageName = image.getOriginalFilename(); + final Path path = Paths.get(imagePath + originalImageName); + try { + Files.write(path, image.getBytes()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/backend/src/main/java/com/funeat/review/application/ImageUploader.java b/backend/src/main/java/com/funeat/review/application/ReviewImageUploader.java similarity index 89% rename from backend/src/main/java/com/funeat/review/application/ImageUploader.java rename to backend/src/main/java/com/funeat/review/application/ReviewImageUploader.java index f7958e3b3..162e7f100 100644 --- a/backend/src/main/java/com/funeat/review/application/ImageUploader.java +++ b/backend/src/main/java/com/funeat/review/application/ReviewImageUploader.java @@ -9,9 +9,9 @@ import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; -@Component +@Component("reviewImageUploader") @Profile("!test") -public class ImageUploader implements ImageService { +public class ReviewImageUploader implements ImageService { @Value("${review.image.path}") private String imagePath; diff --git a/backend/src/main/java/com/funeat/review/application/ReviewService.java b/backend/src/main/java/com/funeat/review/application/ReviewService.java index 0fb9e2472..732759aa3 100644 --- a/backend/src/main/java/com/funeat/review/application/ReviewService.java +++ b/backend/src/main/java/com/funeat/review/application/ReviewService.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -37,21 +38,23 @@ public class ReviewService { private final ReviewTagRepository reviewTagRepository; private final MemberRepository memberRepository; private final ProductRepository productRepository; - private final ImageService imageService; - private final ReviewFavoriteRepository reviewFavoriteRepository; + @Qualifier("reviewImageUploader") + private final ImageService imageService; + public ReviewService(final ReviewRepository reviewRepository, final TagRepository tagRepository, final ReviewTagRepository reviewTagRepository, final MemberRepository memberRepository, - final ProductRepository productRepository, final ImageService imageService, - final ReviewFavoriteRepository reviewFavoriteRepository) { + final ProductRepository productRepository, + final ReviewFavoriteRepository reviewFavoriteRepository, + final ImageService imageService) { this.reviewRepository = reviewRepository; this.tagRepository = tagRepository; this.reviewTagRepository = reviewTagRepository; this.memberRepository = memberRepository; this.productRepository = productRepository; - this.imageService = imageService; this.reviewFavoriteRepository = reviewFavoriteRepository; + this.imageService = imageService; } @Transactional diff --git a/backend/src/main/resources/application-dev.yml b/backend/src/main/resources/application-dev.yml index 80393be83..722772f25 100644 --- a/backend/src/main/resources/application-dev.yml +++ b/backend/src/main/resources/application-dev.yml @@ -16,3 +16,7 @@ spring: review: image: path: { DEV_IMAGE_PATH } + +recipe: + image: + path: { DEV_RECIPE_PATH } From 32c169dbb7749f6c1911f5e57fa2ecfdf67fab6e Mon Sep 17 00:00:00 2001 From: hanueleee Date: Mon, 7 Aug 2023 16:34:03 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20=EB=A0=88=EC=8B=9C=ED=94=BC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../recipe/application/RecipeService.java | 65 +++++++++++++++++++ .../presentation/RecipeApiController.java | 2 + .../review/application/ReviewService.java | 3 +- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 backend/src/main/java/com/funeat/recipe/application/RecipeService.java diff --git a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java new file mode 100644 index 000000000..14ed04f9b --- /dev/null +++ b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java @@ -0,0 +1,65 @@ +package com.funeat.recipe.application; + +import com.funeat.member.domain.Member; +import com.funeat.member.persistence.MemberRepository; +import com.funeat.product.domain.ProductRecipe; +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.RecipeCreateRequest; +import com.funeat.recipe.persistence.RecipeImageRepository; +import com.funeat.recipe.persistence.RecipeRepository; +import com.funeat.review.application.ImageService; +import java.util.List; +import org.springframework.beans.factory.annotation.Qualifier; +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 final MemberRepository memberRepository; + private final ProductRepository productRepository; + private final ProductRecipeRepository productRecipeRepository; + private final RecipeRepository recipeRepository; + private final RecipeImageRepository recipeImageRepository; + + private final ImageService imageService; + + public RecipeService(final MemberRepository memberRepository, final ProductRepository productRepository, + final ProductRecipeRepository productRecipeRepository, final RecipeRepository recipeRepository, + final RecipeImageRepository recipeImageRepository, + @Qualifier("recipeImageUploader") final ImageService imageService) { + this.memberRepository = memberRepository; + this.productRepository = productRepository; + this.productRecipeRepository = productRecipeRepository; + this.recipeRepository = recipeRepository; + this.recipeImageRepository = recipeImageRepository; + this.imageService = imageService; + } + + @Transactional + public Long create(final Long memberId, final List images, final RecipeCreateRequest request) { + final Member member = memberRepository.findById(memberId) + .orElseThrow(IllegalArgumentException::new); + + final Recipe savedRecipe = recipeRepository.save(new Recipe(request.getName(), request.getContent(), member)); + request.getProductIds() + .stream() + .map(it -> productRepository.findById(it) + .orElseThrow(IllegalArgumentException::new)) + .forEach(it -> productRecipeRepository.save( + new ProductRecipe(it, savedRecipe) + )); + + for (MultipartFile image : images) { + recipeImageRepository.save(new RecipeImage(image.getOriginalFilename(), savedRecipe)); + imageService.upload(image); + } + + return savedRecipe.getId(); + } +} diff --git a/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java b/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java index f93fcddf7..a63df13eb 100644 --- a/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java +++ b/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java @@ -10,8 +10,10 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; 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; diff --git a/backend/src/main/java/com/funeat/review/application/ReviewService.java b/backend/src/main/java/com/funeat/review/application/ReviewService.java index 732759aa3..154bc6989 100644 --- a/backend/src/main/java/com/funeat/review/application/ReviewService.java +++ b/backend/src/main/java/com/funeat/review/application/ReviewService.java @@ -40,14 +40,13 @@ public class ReviewService { private final ProductRepository productRepository; private final ReviewFavoriteRepository reviewFavoriteRepository; - @Qualifier("reviewImageUploader") private final ImageService imageService; public ReviewService(final ReviewRepository reviewRepository, final TagRepository tagRepository, final ReviewTagRepository reviewTagRepository, final MemberRepository memberRepository, final ProductRepository productRepository, final ReviewFavoriteRepository reviewFavoriteRepository, - final ImageService imageService) { + @Qualifier("reviewImageUploader") final ImageService imageService) { this.reviewRepository = reviewRepository; this.tagRepository = tagRepository; this.reviewTagRepository = reviewTagRepository; From 1a2c725714311513b6f79239f8f55e7d0471a700 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Mon, 7 Aug 2023 18:06:47 +0900 Subject: [PATCH 07/15] =?UTF-8?q?refactor:=20RecipeImageUploader=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20(recipe=20/=20review=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=A0=80=EC=9E=A5=20=EA=B2=BD=EB=A1=9C=20=EB=8F=99?= =?UTF-8?q?=EC=9D=BC=ED=95=98=EA=B2=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/RecipeImageUploader.java | 30 ------------------- .../recipe/application/RecipeService.java | 3 +- ...wImageUploader.java => ImageUploader.java} | 4 +-- .../review/application/ReviewService.java | 3 +- .../src/main/resources/application-dev.yml | 4 --- .../com/funeat/FuneatApplicationTests.java | 1 - .../TestImageUploader.java | 3 +- 7 files changed, 6 insertions(+), 42 deletions(-) delete mode 100644 backend/src/main/java/com/funeat/recipe/application/RecipeImageUploader.java rename backend/src/main/java/com/funeat/review/application/{ReviewImageUploader.java => ImageUploader.java} (89%) rename backend/src/test/java/com/funeat/{review/application => common}/TestImageUploader.java (94%) diff --git a/backend/src/main/java/com/funeat/recipe/application/RecipeImageUploader.java b/backend/src/main/java/com/funeat/recipe/application/RecipeImageUploader.java deleted file mode 100644 index 03711fbdf..000000000 --- a/backend/src/main/java/com/funeat/recipe/application/RecipeImageUploader.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.funeat.recipe.application; - -import com.funeat.review.application.ImageService; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -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("recipeImageUploader") -@Profile("!test") -public class RecipeImageUploader implements ImageService { - - @Value("${recipe.image.path}") - private String imagePath; - - @Override - public void upload(final MultipartFile image) { - final String originalImageName = image.getOriginalFilename(); - final Path path = Paths.get(imagePath + originalImageName); - try { - Files.write(path, image.getBytes()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java index 14ed04f9b..1d215fc93 100644 --- a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java +++ b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java @@ -12,7 +12,6 @@ import com.funeat.recipe.persistence.RecipeRepository; import com.funeat.review.application.ImageService; import java.util.List; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -32,7 +31,7 @@ public class RecipeService { public RecipeService(final MemberRepository memberRepository, final ProductRepository productRepository, final ProductRecipeRepository productRecipeRepository, final RecipeRepository recipeRepository, final RecipeImageRepository recipeImageRepository, - @Qualifier("recipeImageUploader") final ImageService imageService) { + final ImageService imageService) { this.memberRepository = memberRepository; this.productRepository = productRepository; this.productRecipeRepository = productRecipeRepository; diff --git a/backend/src/main/java/com/funeat/review/application/ReviewImageUploader.java b/backend/src/main/java/com/funeat/review/application/ImageUploader.java similarity index 89% rename from backend/src/main/java/com/funeat/review/application/ReviewImageUploader.java rename to backend/src/main/java/com/funeat/review/application/ImageUploader.java index 162e7f100..f7958e3b3 100644 --- a/backend/src/main/java/com/funeat/review/application/ReviewImageUploader.java +++ b/backend/src/main/java/com/funeat/review/application/ImageUploader.java @@ -9,9 +9,9 @@ import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; -@Component("reviewImageUploader") +@Component @Profile("!test") -public class ReviewImageUploader implements ImageService { +public class ImageUploader implements ImageService { @Value("${review.image.path}") private String imagePath; diff --git a/backend/src/main/java/com/funeat/review/application/ReviewService.java b/backend/src/main/java/com/funeat/review/application/ReviewService.java index 154bc6989..b4b6a239c 100644 --- a/backend/src/main/java/com/funeat/review/application/ReviewService.java +++ b/backend/src/main/java/com/funeat/review/application/ReviewService.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; @@ -46,7 +45,7 @@ public ReviewService(final ReviewRepository reviewRepository, final TagRepositor final ReviewTagRepository reviewTagRepository, final MemberRepository memberRepository, final ProductRepository productRepository, final ReviewFavoriteRepository reviewFavoriteRepository, - @Qualifier("reviewImageUploader") final ImageService imageService) { + final ImageService imageService) { this.reviewRepository = reviewRepository; this.tagRepository = tagRepository; this.reviewTagRepository = reviewTagRepository; diff --git a/backend/src/main/resources/application-dev.yml b/backend/src/main/resources/application-dev.yml index 722772f25..80393be83 100644 --- a/backend/src/main/resources/application-dev.yml +++ b/backend/src/main/resources/application-dev.yml @@ -16,7 +16,3 @@ spring: review: image: path: { DEV_IMAGE_PATH } - -recipe: - image: - path: { DEV_RECIPE_PATH } diff --git a/backend/src/test/java/com/funeat/FuneatApplicationTests.java b/backend/src/test/java/com/funeat/FuneatApplicationTests.java index 890bb2929..f8bc6d3e7 100644 --- a/backend/src/test/java/com/funeat/FuneatApplicationTests.java +++ b/backend/src/test/java/com/funeat/FuneatApplicationTests.java @@ -9,5 +9,4 @@ class FuneatApplicationTests { @Test void contextLoads() { } - } diff --git a/backend/src/test/java/com/funeat/review/application/TestImageUploader.java b/backend/src/test/java/com/funeat/common/TestImageUploader.java similarity index 94% rename from backend/src/test/java/com/funeat/review/application/TestImageUploader.java rename to backend/src/test/java/com/funeat/common/TestImageUploader.java index 49ca3ea65..c47fa6b4d 100644 --- a/backend/src/test/java/com/funeat/review/application/TestImageUploader.java +++ b/backend/src/test/java/com/funeat/common/TestImageUploader.java @@ -1,5 +1,6 @@ -package com.funeat.review.application; +package com.funeat.common; +import com.funeat.review.application.ImageService; import java.io.File; import java.io.IOException; import java.nio.file.Files; From f455c669a040543c01aea6c8b869b0b3536b8f0a Mon Sep 17 00:00:00 2001 From: hanueleee Date: Tue, 8 Aug 2023 13:50:08 +0900 Subject: [PATCH 08/15] =?UTF-8?q?refactor:=20=EB=A0=88=EC=8B=9C=ED=94=BC?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1=20=EA=B8=B0=EB=8A=A5=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=EA=B0=80=20null=EC=9D=BC=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/funeat/recipe/application/RecipeService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java index 1d215fc93..6b854e458 100644 --- a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java +++ b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java @@ -12,6 +12,7 @@ import com.funeat.recipe.persistence.RecipeRepository; import com.funeat.review.application.ImageService; import java.util.List; +import java.util.Objects; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -54,9 +55,10 @@ public Long create(final Long memberId, final List images, final new ProductRecipe(it, savedRecipe) )); - for (MultipartFile image : images) { - recipeImageRepository.save(new RecipeImage(image.getOriginalFilename(), savedRecipe)); - imageService.upload(image); + if (Objects.nonNull(images)) { + images.stream() + .peek(it -> recipeImageRepository.save(new RecipeImage(it.getOriginalFilename(), savedRecipe))) + .forEach(imageService::upload); } return savedRecipe.getId(); From cdce989c1b23303a6248215a4383235d6f79a707 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Tue, 8 Aug 2023 13:51:42 +0900 Subject: [PATCH 09/15] =?UTF-8?q?test:=20=EB=A0=88=EC=8B=9C=ED=94=BC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EA=B8=B0=EB=8A=A5=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EC=9D=B8=EC=88=98=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../recipe/RecipeAcceptanceTest.java | 48 +++++++++++++++++++ .../funeat/acceptance/recipe/RecipeSteps.java | 40 ++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java create mode 100644 backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java diff --git a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java new file mode 100644 index 000000000..b88b54124 --- /dev/null +++ b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java @@ -0,0 +1,48 @@ +package com.funeat.acceptance.recipe; + +import static com.funeat.acceptance.common.CommonSteps.STATUS_CODE를_검증한다; +import static com.funeat.acceptance.common.CommonSteps.정상_생성; +import static com.funeat.acceptance.product.ProductSteps.간편식사; +import static com.funeat.acceptance.recipe.RecipeSteps.레시피_추가_요청; +import static com.funeat.acceptance.recipe.RecipeSteps.여러_사진_요청; + +import com.funeat.acceptance.common.AcceptanceTest; +import com.funeat.acceptance.common.LoginSteps; +import com.funeat.product.domain.Category; +import com.funeat.product.domain.Product; +import com.funeat.recipe.dto.RecipeCreateRequest; +import io.restassured.specification.MultiPartSpecification; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class RecipeAcceptanceTest extends AcceptanceTest { + + @Test + void 레시피를_작성한다() { + // given + 카테고리_추가_요청(간편식사); + final var product1 = new Product("삼각김밥1", 1000L, "image.png", "맛있는 삼각김밥1", 간편식사); + final var product2 = new Product("삼각김밥2", 2000L, "image.png", "맛있는 삼각김밥2", 간편식사); + final var product3 = new Product("삼각김밥3", 1500L, "image.png", "맛있는 삼각김밥3", 간편식사); + 복수_상품_추가_요청(List.of(product1, product2, product3)); + final var loginCookie = LoginSteps.로그인_쿠키를_얻는다(); + + // when + final var request = new RecipeCreateRequest("제일로 맛있는 레시피", + List.of(product1.getId(), product2.getId(), product3.getId()), + "우선 밥을 넣어요. 그리고 밥을 또 넣어요. 그리고 밥을 또 넣으면.. 끝!!"); + final List images = 여러_사진_요청(3); + final var response = 레시피_추가_요청(request, images, loginCookie); + + // then + STATUS_CODE를_검증한다(response, 정상_생성); + } + + private Long 카테고리_추가_요청(final Category category) { + return categoryRepository.save(category).getId(); + } + + private void 복수_상품_추가_요청(final List products) { + productRepository.saveAll(products); + } +} diff --git a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java new file mode 100644 index 000000000..0e4486851 --- /dev/null +++ b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java @@ -0,0 +1,40 @@ +package com.funeat.acceptance.recipe; + +import static io.restassured.RestAssured.given; + +import com.funeat.recipe.dto.RecipeCreateRequest; +import io.restassured.builder.MultiPartSpecBuilder; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import io.restassured.specification.MultiPartSpecification; +import io.restassured.specification.RequestSpecification; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class RecipeSteps { + + public static ExtractableResponse 레시피_추가_요청(final RecipeCreateRequest recipeRequest, + List imageList, + final String loginCookie) { + RequestSpecification request = given() + .cookie("JSESSIONID", loginCookie); + imageList.forEach(request::multiPart); + return request + .multiPart("recipeRequest", recipeRequest, "application/json") + .when() + .post("/api/recipes") + .then() + .extract(); + } + + public static List 여러_사진_요청(int count) { + return IntStream.range(0, count) + .mapToObj(i -> new MultiPartSpecBuilder("image".getBytes()) + .fileName("testImage.png") + .controlName("images") + .mimeType("image/png") + .build()) + .collect(Collectors.toList()); + } +} From c21375e9d478905da8e63267ee0b9607627e16be Mon Sep 17 00:00:00 2001 From: hanueleee Date: Tue, 8 Aug 2023 16:11:14 +0900 Subject: [PATCH 10/15] =?UTF-8?q?test:=20=EB=A0=88=EC=8B=9C=ED=94=BC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EA=B8=B0=EB=8A=A5=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20service=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../recipe/application/RecipeServiceTest.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java diff --git a/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java b/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java new file mode 100644 index 000000000..92294783b --- /dev/null +++ b/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java @@ -0,0 +1,80 @@ +package com.funeat.recipe.application; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.funeat.common.DataClearExtension; +import com.funeat.member.domain.Member; +import com.funeat.member.persistence.MemberRepository; +import com.funeat.product.domain.Category; +import com.funeat.product.domain.CategoryType; +import com.funeat.product.domain.Product; +import com.funeat.product.persistence.CategoryRepository; +import com.funeat.product.persistence.ProductRepository; +import com.funeat.recipe.domain.Recipe; +import com.funeat.recipe.dto.RecipeCreateRequest; +import com.funeat.recipe.persistence.RecipeRepository; +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +@Transactional +@SpringBootTest +@ExtendWith(DataClearExtension.class) +@SuppressWarnings("NonAsciiCharacters") +@DisplayNameGeneration(ReplaceUnderscores.class) +class RecipeServiceTest { + + @Autowired + private RecipeService recipeService; + + @Autowired + private CategoryRepository categoryRepository; + + @Autowired + private ProductRepository productRepository; + + @Autowired + private MemberRepository memberRepository; + + @Autowired + private RecipeRepository recipeRepository; + + @Test + void 레시피를_추가할_수_있다() { + // given + Category category = categoryRepository.save(new Category("간편식사", CategoryType.FOOD)); + Product product1 = productRepository.save(new Product("불닭볶음면", 1000L, "image.png", "엄청 매운 불닭", category)); + Product product2 = productRepository.save(new Product("참치 삼김", 2000L, "image.png", "담백한 참치마요 삼김", category)); + Product product3 = productRepository.save(new Product("스트링 치즈", 1500L, "image.png", "고소한 치즈", category)); + Member member = memberRepository.save(new Member("test", "image.png", "1")); + + List images = List.of( + new MockMultipartFile("image", "image.jpg", "image/jpeg", new byte[]{1, 2, 3}), + new MockMultipartFile("image", "image.jpg", "image/jpeg", new byte[]{1, 2, 3}), + new MockMultipartFile("image", "image.jpg", "image/jpeg", new byte[]{1, 2, 3}) + ); + + RecipeCreateRequest request = new RecipeCreateRequest("제일로 맛있는 레시피", + List.of(product1.getId(), product2.getId(), product3.getId()), + "우선 밥을 넣어요. 그리고 밥을 또 넣어요. 그리고 밥을 또 넣으면.. 끝!!"); + + // when + Long recipeId = recipeService.create(member.getId(), images, request); + Recipe actual = recipeRepository.findById(recipeId).get(); + + // then + assertThat(actual).usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo( + new Recipe("제일로 맛있는 레시피", "우선 밥을 넣어요. 그리고 밥을 또 넣어요. 그리고 밥을 또 넣으면.. 끝!!", member) + ); + } + +} From 183343ab2b7d90cc3b87cd9bcec8609234da39fb Mon Sep 17 00:00:00 2001 From: hanueleee Date: Tue, 8 Aug 2023 17:24:14 +0900 Subject: [PATCH 11/15] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=A4=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/funeat/recipe/presentation/RecipeApiController.java | 2 +- .../com/funeat/acceptance/recipe/RecipeAcceptanceTest.java | 2 +- .../test/java/com/funeat/acceptance/recipe/RecipeSteps.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java b/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java index a63df13eb..87badbfd4 100644 --- a/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java +++ b/backend/src/main/java/com/funeat/recipe/presentation/RecipeApiController.java @@ -26,7 +26,7 @@ public RecipeApiController(final RecipeService recipeService) { public ResponseEntity writeRecipe(@AuthenticationPrincipal final LoginInfo loginInfo, @RequestPart(required = false) final List images, @RequestPart final RecipeCreateRequest recipeRequest) { - Long recipeId = recipeService.create(loginInfo.getId(), images, recipeRequest); + final Long recipeId = recipeService.create(loginInfo.getId(), images, recipeRequest); return ResponseEntity.created(URI.create("/api/recipes/" + recipeId)).build(); } diff --git a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java index b88b54124..026e54386 100644 --- a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java +++ b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java @@ -31,7 +31,7 @@ public class RecipeAcceptanceTest extends AcceptanceTest { final var request = new RecipeCreateRequest("제일로 맛있는 레시피", List.of(product1.getId(), product2.getId(), product3.getId()), "우선 밥을 넣어요. 그리고 밥을 또 넣어요. 그리고 밥을 또 넣으면.. 끝!!"); - final List images = 여러_사진_요청(3); + final var images = 여러_사진_요청(3); final var response = 레시피_추가_요청(request, images, loginCookie); // then diff --git a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java index 0e4486851..e41385bd2 100644 --- a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java +++ b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeSteps.java @@ -15,9 +15,9 @@ public class RecipeSteps { public static ExtractableResponse 레시피_추가_요청(final RecipeCreateRequest recipeRequest, - List imageList, + final List imageList, final String loginCookie) { - RequestSpecification request = given() + final var request = given() .cookie("JSESSIONID", loginCookie); imageList.forEach(request::multiPart); return request From f56ea775ea723e5ea02bb802af9a62b4c6bee3d4 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Tue, 8 Aug 2023 18:01:31 +0900 Subject: [PATCH 12/15] =?UTF-8?q?refactor:=20ImageService=EC=99=80=20Image?= =?UTF-8?q?Uploader=EC=9D=98=20=EC=9C=84=EC=B9=98=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../funeat/{review/application => common}/ImageService.java | 2 +- .../funeat/{review/application => common}/ImageUploader.java | 2 +- .../java/com/funeat/recipe/application/RecipeService.java | 2 +- .../java/com/funeat/review/application/ReviewService.java | 5 ++--- .../src/test/java/com/funeat/common/TestImageUploader.java | 1 - 5 files changed, 5 insertions(+), 7 deletions(-) rename backend/src/main/java/com/funeat/{review/application => common}/ImageService.java (77%) rename backend/src/main/java/com/funeat/{review/application => common}/ImageUploader.java (95%) diff --git a/backend/src/main/java/com/funeat/review/application/ImageService.java b/backend/src/main/java/com/funeat/common/ImageService.java similarity index 77% rename from backend/src/main/java/com/funeat/review/application/ImageService.java rename to backend/src/main/java/com/funeat/common/ImageService.java index 5b17a7565..3e8ad0cca 100644 --- a/backend/src/main/java/com/funeat/review/application/ImageService.java +++ b/backend/src/main/java/com/funeat/common/ImageService.java @@ -1,4 +1,4 @@ -package com.funeat.review.application; +package com.funeat.common; import org.springframework.web.multipart.MultipartFile; diff --git a/backend/src/main/java/com/funeat/review/application/ImageUploader.java b/backend/src/main/java/com/funeat/common/ImageUploader.java similarity index 95% rename from backend/src/main/java/com/funeat/review/application/ImageUploader.java rename to backend/src/main/java/com/funeat/common/ImageUploader.java index f7958e3b3..d3e26156e 100644 --- a/backend/src/main/java/com/funeat/review/application/ImageUploader.java +++ b/backend/src/main/java/com/funeat/common/ImageUploader.java @@ -1,4 +1,4 @@ -package com.funeat.review.application; +package com.funeat.common; import java.io.IOException; import java.nio.file.Files; diff --git a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java index 6b854e458..7da1e0bd3 100644 --- a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java +++ b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java @@ -10,7 +10,7 @@ import com.funeat.recipe.dto.RecipeCreateRequest; import com.funeat.recipe.persistence.RecipeImageRepository; import com.funeat.recipe.persistence.RecipeRepository; -import com.funeat.review.application.ImageService; +import com.funeat.common.ImageService; import java.util.List; import java.util.Objects; import org.springframework.stereotype.Service; diff --git a/backend/src/main/java/com/funeat/review/application/ReviewService.java b/backend/src/main/java/com/funeat/review/application/ReviewService.java index b4b6a239c..6b9500c28 100644 --- a/backend/src/main/java/com/funeat/review/application/ReviewService.java +++ b/backend/src/main/java/com/funeat/review/application/ReviewService.java @@ -1,5 +1,6 @@ package com.funeat.review.application; +import com.funeat.common.ImageService; import com.funeat.member.domain.Member; import com.funeat.member.domain.favorite.ReviewFavorite; import com.funeat.member.persistence.MemberRepository; @@ -38,14 +39,12 @@ public class ReviewService { private final MemberRepository memberRepository; private final ProductRepository productRepository; private final ReviewFavoriteRepository reviewFavoriteRepository; - private final ImageService imageService; public ReviewService(final ReviewRepository reviewRepository, final TagRepository tagRepository, final ReviewTagRepository reviewTagRepository, final MemberRepository memberRepository, final ProductRepository productRepository, - final ReviewFavoriteRepository reviewFavoriteRepository, - final ImageService imageService) { + final ReviewFavoriteRepository reviewFavoriteRepository, final ImageService imageService) { this.reviewRepository = reviewRepository; this.tagRepository = tagRepository; this.reviewTagRepository = reviewTagRepository; diff --git a/backend/src/test/java/com/funeat/common/TestImageUploader.java b/backend/src/test/java/com/funeat/common/TestImageUploader.java index c47fa6b4d..c34c6cf99 100644 --- a/backend/src/test/java/com/funeat/common/TestImageUploader.java +++ b/backend/src/test/java/com/funeat/common/TestImageUploader.java @@ -1,6 +1,5 @@ package com.funeat.common; -import com.funeat.review.application.ImageService; import java.io.File; import java.io.IOException; import java.nio.file.Files; From 557f74bf9cb1870ad19beda1acad9ff0c4ac2b3a Mon Sep 17 00:00:00 2001 From: hanueleee Date: Tue, 8 Aug 2023 18:08:38 +0900 Subject: [PATCH 13/15] =?UTF-8?q?refactor:=20image=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/java/com/funeat/common/ImageUploader.java | 2 +- backend/src/main/resources/application-dev.yml | 5 ++--- backend/src/main/resources/application-local.yml | 5 ++--- backend/src/main/resources/application-prod.yml | 5 ++--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/backend/src/main/java/com/funeat/common/ImageUploader.java b/backend/src/main/java/com/funeat/common/ImageUploader.java index d3e26156e..98af67960 100644 --- a/backend/src/main/java/com/funeat/common/ImageUploader.java +++ b/backend/src/main/java/com/funeat/common/ImageUploader.java @@ -13,7 +13,7 @@ @Profile("!test") public class ImageUploader implements ImageService { - @Value("${review.image.path}") + @Value("${image.path}") private String imagePath; @Override diff --git a/backend/src/main/resources/application-dev.yml b/backend/src/main/resources/application-dev.yml index 80393be83..0e9f65d2c 100644 --- a/backend/src/main/resources/application-dev.yml +++ b/backend/src/main/resources/application-dev.yml @@ -13,6 +13,5 @@ spring: format_sql: true show_sql: true -review: - image: - path: { DEV_IMAGE_PATH } +image: + path: { DEV_IMAGE_PATH } diff --git a/backend/src/main/resources/application-local.yml b/backend/src/main/resources/application-local.yml index d4f8d0592..f5942cf3a 100644 --- a/backend/src/main/resources/application-local.yml +++ b/backend/src/main/resources/application-local.yml @@ -17,6 +17,5 @@ logging: level: org.hibernate.type.descriptor.sql: trace -review: - image: - path: +image: + path: diff --git a/backend/src/main/resources/application-prod.yml b/backend/src/main/resources/application-prod.yml index 1aa7a6800..36d9d60aa 100644 --- a/backend/src/main/resources/application-prod.yml +++ b/backend/src/main/resources/application-prod.yml @@ -12,6 +12,5 @@ spring: hibernate: show_sql: true -review: - image: - path: { PROD_IMAGE_PATH } +image: + path: { PROD_IMAGE_PATH } From 47a14824e41e8edb340136f4192ae1b2a2693b32 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Tue, 8 Aug 2023 18:32:19 +0900 Subject: [PATCH 14/15] =?UTF-8?q?feat:=20Recipe=EC=9A=A9=20interceptor=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/funeat/common/WebConfig.java | 8 ++++++- .../utill/RecipeHandlerInterceptor.java | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/com/funeat/recipe/utill/RecipeHandlerInterceptor.java diff --git a/backend/src/main/java/com/funeat/common/WebConfig.java b/backend/src/main/java/com/funeat/common/WebConfig.java index 59a87fdc2..8c43fdeab 100644 --- a/backend/src/main/java/com/funeat/common/WebConfig.java +++ b/backend/src/main/java/com/funeat/common/WebConfig.java @@ -2,6 +2,7 @@ import com.funeat.auth.util.AuthArgumentResolver; import com.funeat.auth.util.AuthHandlerInterceptor; +import com.funeat.recipe.utill.RecipeHandlerInterceptor; import java.util.List; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; @@ -15,13 +16,16 @@ public class WebConfig implements WebMvcConfigurer { private final CustomPageableHandlerMethodArgumentResolver customPageableHandlerMethodArgumentResolver; private final AuthArgumentResolver authArgumentResolver; private final AuthHandlerInterceptor authHandlerInterceptor; + private final RecipeHandlerInterceptor recipeHandlerInterceptor; public WebConfig(final CustomPageableHandlerMethodArgumentResolver customPageableHandlerMethodArgumentResolver, final AuthArgumentResolver authArgumentResolver, - final AuthHandlerInterceptor authHandlerInterceptor) { + final AuthHandlerInterceptor authHandlerInterceptor, + final RecipeHandlerInterceptor recipeHandlerInterceptor) { this.customPageableHandlerMethodArgumentResolver = customPageableHandlerMethodArgumentResolver; this.authArgumentResolver = authArgumentResolver; this.authHandlerInterceptor = authHandlerInterceptor; + this.recipeHandlerInterceptor = recipeHandlerInterceptor; } @Override @@ -29,6 +33,8 @@ public void addInterceptors(final InterceptorRegistry registry) { registry.addInterceptor(authHandlerInterceptor) .addPathPatterns("/api/products/**/reviews/**") .addPathPatterns("/api/members"); + registry.addInterceptor(recipeHandlerInterceptor) + .addPathPatterns("/api/recipes"); } @Override diff --git a/backend/src/main/java/com/funeat/recipe/utill/RecipeHandlerInterceptor.java b/backend/src/main/java/com/funeat/recipe/utill/RecipeHandlerInterceptor.java new file mode 100644 index 000000000..03f2f712f --- /dev/null +++ b/backend/src/main/java/com/funeat/recipe/utill/RecipeHandlerInterceptor.java @@ -0,0 +1,24 @@ +package com.funeat.recipe.utill; + +import com.funeat.auth.exception.LoginException; +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 { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + if ("GET".equals(request.getMethod())) { + return true; + } + final HttpSession session = request.getSession(); + if (session.getAttribute("member") == null) { + throw new LoginException("login error"); + } + return true; + } +} From c72300683ed0867d9effb3b3f866a4da29e17469 Mon Sep 17 00:00:00 2001 From: hanueleee Date: Wed, 9 Aug 2023 10:03:53 +0900 Subject: [PATCH 15/15] =?UTF-8?q?test:=20=EC=BB=A8=EB=B2=A4=EC=85=98=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../recipe/application/RecipeService.java | 4 +- .../recipe/RecipeAcceptanceTest.java | 5 ++- .../recipe/application/RecipeServiceTest.java | 45 +++++++++++-------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java index 7da1e0bd3..0afca70e7 100644 --- a/backend/src/main/java/com/funeat/recipe/application/RecipeService.java +++ b/backend/src/main/java/com/funeat/recipe/application/RecipeService.java @@ -51,9 +51,7 @@ public Long create(final Long memberId, final List images, final .stream() .map(it -> productRepository.findById(it) .orElseThrow(IllegalArgumentException::new)) - .forEach(it -> productRecipeRepository.save( - new ProductRecipe(it, savedRecipe) - )); + .forEach(it -> productRecipeRepository.save(new ProductRecipe(it, savedRecipe))); if (Objects.nonNull(images)) { images.stream() diff --git a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java index 026e54386..a492f8ddb 100644 --- a/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java +++ b/backend/src/test/java/com/funeat/acceptance/recipe/RecipeAcceptanceTest.java @@ -11,10 +11,10 @@ import com.funeat.product.domain.Category; import com.funeat.product.domain.Product; import com.funeat.recipe.dto.RecipeCreateRequest; -import io.restassured.specification.MultiPartSpecification; import java.util.List; import org.junit.jupiter.api.Test; +@SuppressWarnings("NonAsciiCharacters") public class RecipeAcceptanceTest extends AcceptanceTest { @Test @@ -24,7 +24,8 @@ public class RecipeAcceptanceTest extends AcceptanceTest { final var product1 = new Product("삼각김밥1", 1000L, "image.png", "맛있는 삼각김밥1", 간편식사); final var product2 = new Product("삼각김밥2", 2000L, "image.png", "맛있는 삼각김밥2", 간편식사); final var product3 = new Product("삼각김밥3", 1500L, "image.png", "맛있는 삼각김밥3", 간편식사); - 복수_상품_추가_요청(List.of(product1, product2, product3)); + final var products = List.of(product1, product2, product3); + 복수_상품_추가_요청(products); final var loginCookie = LoginSteps.로그인_쿠키를_얻는다(); // when diff --git a/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java b/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java index 92294783b..b93a15098 100644 --- a/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java +++ b/backend/src/test/java/com/funeat/recipe/application/RecipeServiceTest.java @@ -22,7 +22,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mock.web.MockMultipartFile; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; @Transactional @SpringBootTest @@ -49,32 +48,40 @@ class RecipeServiceTest { @Test void 레시피를_추가할_수_있다() { // given - Category category = categoryRepository.save(new Category("간편식사", CategoryType.FOOD)); - Product product1 = productRepository.save(new Product("불닭볶음면", 1000L, "image.png", "엄청 매운 불닭", category)); - Product product2 = productRepository.save(new Product("참치 삼김", 2000L, "image.png", "담백한 참치마요 삼김", category)); - Product product3 = productRepository.save(new Product("스트링 치즈", 1500L, "image.png", "고소한 치즈", category)); - Member member = memberRepository.save(new Member("test", "image.png", "1")); - - List images = List.of( - new MockMultipartFile("image", "image.jpg", "image/jpeg", new byte[]{1, 2, 3}), - new MockMultipartFile("image", "image.jpg", "image/jpeg", new byte[]{1, 2, 3}), - new MockMultipartFile("image", "image.jpg", "image/jpeg", new byte[]{1, 2, 3}) - ); - - RecipeCreateRequest request = new RecipeCreateRequest("제일로 맛있는 레시피", + final var category = 카테고리_추가_요청(new Category("간편식사", CategoryType.FOOD)); + 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)); + final var member = 멤버_추가_요청(new Member("test", "image.png", "1")); + + final var image1 = new MockMultipartFile("image1", "image1.jpg", "image/jpeg", new byte[]{1, 2, 3}); + final var image2 = new MockMultipartFile("image2", "image2.jpg", "image/jpeg", new byte[]{1, 2, 3}); + final var image3 = new MockMultipartFile("image3", "image3.jpg", "image/jpeg", new byte[]{1, 2, 3}); + + final var request = new RecipeCreateRequest("제일로 맛있는 레시피", List.of(product1.getId(), product2.getId(), product3.getId()), "우선 밥을 넣어요. 그리고 밥을 또 넣어요. 그리고 밥을 또 넣으면.. 끝!!"); // when - Long recipeId = recipeService.create(member.getId(), images, request); - Recipe actual = recipeRepository.findById(recipeId).get(); + final var recipeId = recipeService.create(member.getId(), List.of(image1, image2, image3), request); + final var actual = recipeRepository.findById(recipeId).get(); // then + final var expected = new Recipe("제일로 맛있는 레시피", "우선 밥을 넣어요. 그리고 밥을 또 넣어요. 그리고 밥을 또 넣으면.. 끝!!", member); assertThat(actual).usingRecursiveComparison() .ignoringFields("id") - .isEqualTo( - new Recipe("제일로 맛있는 레시피", "우선 밥을 넣어요. 그리고 밥을 또 넣어요. 그리고 밥을 또 넣으면.. 끝!!", member) - ); + .isEqualTo(expected); + } + + private Category 카테고리_추가_요청(final Category category) { + return categoryRepository.save(category); } + private Product 상품_추가_요청(final Product product) { + return productRepository.save(product); + } + + private Member 멤버_추가_요청(final Member member) { + return memberRepository.save(member); + } }