diff --git a/backend/src/main/java/com/funeat/review/application/ReviewDeleteEventListener.java b/backend/src/main/java/com/funeat/review/application/ReviewDeleteEventListener.java index 2009e3936..a92c4f943 100644 --- a/backend/src/main/java/com/funeat/review/application/ReviewDeleteEventListener.java +++ b/backend/src/main/java/com/funeat/review/application/ReviewDeleteEventListener.java @@ -20,7 +20,7 @@ public ReviewDeleteEventListener(final ImageUploader imageUploader) { @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void deleteReviewImageInS3(final ReviewDeleteEvent event) { final String image = event.getImage(); - if (StringUtils.isBlank(image)) { + if (!StringUtils.isBlank(image)) { imageUploader.delete(image); } } diff --git a/backend/src/test/java/com/funeat/common/EventTest.java b/backend/src/test/java/com/funeat/common/EventTest.java index dec401bec..aeb72d418 100644 --- a/backend/src/test/java/com/funeat/common/EventTest.java +++ b/backend/src/test/java/com/funeat/common/EventTest.java @@ -8,9 +8,8 @@ import com.funeat.product.persistence.ProductRepository; import com.funeat.review.application.ReviewService; import com.funeat.review.persistence.ReviewRepository; -import com.funeat.tag.domain.Tag; import com.funeat.tag.persistence.TagRepository; -import java.util.List; +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; @@ -22,13 +21,17 @@ @SpringBootTest @RecordApplicationEvents -@ExtendWith(MockitoExtension.class) +@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; @@ -44,8 +47,10 @@ public class EventTest { @Autowired protected ReviewRepository reviewRepository; - @Autowired - protected ReviewService reviewService; + @AfterEach + void tearDown() { + events.clear(); + } protected Long 단일_상품_저장(final Product product) { return productRepository.save(product).getId(); @@ -55,11 +60,6 @@ public class EventTest { return categoryRepository.save(category).getId(); } - protected void 복수_태그_저장(final Tag... tagsToSave) { - final var tags = List.of(tagsToSave); - tagRepository.saveAll(tags); - } - protected Long 단일_멤버_저장(final Member member) { return memberRepository.save(member).getId(); } diff --git a/backend/src/test/java/com/funeat/fixture/ReviewFixture.java b/backend/src/test/java/com/funeat/fixture/ReviewFixture.java index 3ae53a3c7..12363d4cb 100644 --- a/backend/src/test/java/com/funeat/fixture/ReviewFixture.java +++ b/backend/src/test/java/com/funeat/fixture/ReviewFixture.java @@ -65,6 +65,10 @@ public class ReviewFixture { return new Review(member, product, "test5", 5L, "test", false, count); } + 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); diff --git a/backend/src/test/java/com/funeat/review/application/ReviewDeleteEventListenerTest.java b/backend/src/test/java/com/funeat/review/application/ReviewDeleteEventListenerTest.java index 5edf33f36..9f5dfb73b 100644 --- a/backend/src/test/java/com/funeat/review/application/ReviewDeleteEventListenerTest.java +++ b/backend/src/test/java/com/funeat/review/application/ReviewDeleteEventListenerTest.java @@ -1,13 +1,14 @@ package com.funeat.review.application; 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.ProductFixture.상품_삼각김밥_가격1000원_평점2점_생성; -import static com.funeat.fixture.ReviewFixture.리뷰추가요청_재구매O_생성; -import static com.funeat.fixture.TagFixture.태그_맛있어요_TASTE_생성; -import static com.funeat.fixture.TagFixture.태그_아침식사_ETC_생성; +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.리뷰_이미지test4_평점4점_재구매O_생성; +import static com.funeat.fixture.ReviewFixture.리뷰_이미지없음_평점1점_재구매X_생성; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doThrow; @@ -18,14 +19,11 @@ import com.funeat.common.ImageUploader; import com.funeat.common.exception.CommonException.S3DeleteFailException; import com.funeat.exception.CommonErrorCode; -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; import org.springframework.boot.test.mock.mockito.MockBean; +@SuppressWarnings("NonAsciiCharacters") class ReviewDeleteEventListenerTest extends EventTest { @MockBean @@ -37,30 +35,19 @@ class 리뷰_삭제_이벤트_발행 { @Test void 리뷰_작성자가_리뷰_삭제_시도시_리뷰_삭제_이벤트가_발행된다() { // given - final var member = 멤버_멤버1_생성(); - final var memberId = 단일_멤버_저장(member); + 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 = 이미지_생성(); + 단일_상품_저장(product); - final var request = 리뷰추가요청_재구매O_생성(4L, tagIds); - reviewService.create(productId, memberId, image, request); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); + final var review = reviewRepository.save(리뷰_이미지test1_평점1점_재구매O_생성(author, product, 0L)); // when - reviewService.deleteReview(reviewId, memberId); + reviewService.deleteReview(review.getId(), authorId); // then final var count = events.stream(ReviewDeleteEvent.class).count(); @@ -70,33 +57,23 @@ class 리뷰_삭제_이벤트_발행 { @Test void 리뷰_작성자가_아닌_사람이_리뷰_삭제_시도시_리뷰_삭제_이벤트가_발행되지_않는다() { // given - final var author = 멤버_멤버2_생성(); + final var author = 멤버_멤버1_생성(); final var authorId = 단일_멤버_저장(author); - final var member = 멤버_멤버1_생성(); + + 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); + 단일_상품_저장(product); - final var tagIds = 태그_아이디_변환(tag1, tag2); - final var image = 이미지_생성(); - - final var request = 리뷰추가요청_재구매O_생성(4L, tagIds); - reviewService.create(productId, authorId, image, request); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); + final var review = reviewRepository.save(리뷰_이미지test2_평점2점_재구매O_생성(author, product, 0L)); // when try { - reviewService.deleteReview(reviewId, memberId); + reviewService.deleteReview(review.getId(), memberId); } catch (Exception ignored) { } @@ -112,106 +89,68 @@ class 이미지_삭제_로직_작동 { @Test void 리뷰_삭제가_정상적으로_커밋되고_이미지가_존재하면_이미지_삭제_로직이_작동한다() { // given - final var member = 멤버_멤버1_생성(); - final var memberId = 단일_멤버_저장(member); + 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 = 이미지_생성(); + 단일_상품_저장(product); - final var request = 리뷰추가요청_재구매O_생성(4L, tagIds); - reviewService.create(productId, memberId, image, request); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); + final var review = reviewRepository.save(리뷰_이미지test3_평점3점_재구매O_생성(author, product, 0L)); // when - reviewService.deleteReview(reviewId, memberId); + reviewService.deleteReview(review.getId(), authorId); // then - verify(uploader, timeout(100).times(1)).delete(any()); + verify(uploader, timeout(1000).times(1)).delete(any()); } @Test void 리뷰_삭제가_정상적으로_커밋되었지만_이미지가_존재하지_않으면_이미지_삭제_로직이_작동하지않는다() { // given - final var member = 멤버_멤버1_생성(); - final var memberId = 단일_멤버_저장(member); + 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); + 단일_상품_저장(product); - final var tagIds = 태그_아이디_변환(tag1, tag2); - - final var request = 리뷰추가요청_재구매O_생성(4L, tagIds); - reviewService.create(productId, memberId, null, request); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); + final var review = reviewRepository.save(리뷰_이미지없음_평점1점_재구매X_생성(author, product, 0L)); // when - reviewService.deleteReview(reviewId, memberId); + reviewService.deleteReview(review.getId(), authorId); // then - verify(uploader, timeout(100).times(0)).delete(any()); + verify(uploader, timeout(1000).times(0)).delete(any()); } @Test void 이미지_삭제_로직이_실패해도_메인로직까지_롤백되어서는_안된다() { // given - final var member = 멤버_멤버1_생성(); - final var memberId = 단일_멤버_저장(member); + 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 = 이미지_생성(); + 단일_상품_저장(product); - final var request = 리뷰추가요청_재구매O_생성(4L, tagIds); - reviewService.create(productId, memberId, image, request); - - final var review = reviewRepository.findAll().get(0); - final var reviewId = review.getId(); + 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(reviewId, memberId); + reviewService.deleteReview(review.getId(), authorId); // then - assertThat(reviewRepository.findById(reviewId)).isEmpty(); + assertThat(reviewRepository.findById(review.getId())).isEmpty(); } } - - private List 태그_아이디_변환(final Tag... tags) { - return Stream.of(tags) - .map(Tag::getId) - .collect(Collectors.toList()); - } }