From b2c21b07876b090a674e346d1f902c4bb242de16 Mon Sep 17 00:00:00 2001 From: "Jungyo Yang(Window)" <2jungyo@naver.com> Date: Tue, 6 Jan 2026 14:49:21 +0900 Subject: [PATCH 1/3] Changes --- .../service/wishlist/WishlistServiceTest.java | 286 ++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 src/test/java/com/kt/service/wishlist/WishlistServiceTest.java diff --git a/src/test/java/com/kt/service/wishlist/WishlistServiceTest.java b/src/test/java/com/kt/service/wishlist/WishlistServiceTest.java new file mode 100644 index 0000000..88c89cd --- /dev/null +++ b/src/test/java/com/kt/service/wishlist/WishlistServiceTest.java @@ -0,0 +1,286 @@ +package com.kt.service.wishlist; + +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalDate; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +import com.kt.common.exception.CustomException; +import com.kt.common.exception.ErrorCode; +import com.kt.domain.category.Category; +import com.kt.domain.membership.Membership; +import com.kt.domain.product.Product; +import com.kt.domain.user.Gender; +import com.kt.domain.user.User; +import com.kt.dto.wishlist.WishlistResponse; +import com.kt.repository.category.CategoryRepository; +import com.kt.repository.membership.MembershipRepository; +import com.kt.repository.product.ProductRepository; +import com.kt.repository.user.UserRepository; +import com.kt.repository.wishlist.WishlistRepository; + +@Transactional +@ActiveProfiles("test") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class WishlistServiceTest { + + @Autowired + private WishlistService wishlistService; + + @Autowired + private WishlistRepository wishlistRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ProductRepository productRepository; + + @Autowired + private MembershipRepository membershipRepository; + + @Autowired + private CategoryRepository categoryRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + private User savedUser; + private Product savedProduct; + + @BeforeEach + void setUp() { + initWishlistTestData(); + } + + void initWishlistTestData() { + Membership membership = new Membership("BRONZE"); + membershipRepository.save(membership); + + savedUser = userRepository.saveAndFlush(User.normalUser( + "wishlist_user", + passwordEncoder.encode("password1234"), + "찜유저", + "wishlist@kttech.com", + "010-1234-5678", + Gender.FEMALE, + LocalDate.of(1999, 1, 10), + membership + )); + + Category category = categoryRepository.saveAndFlush(new Category("전자제품")); + + savedProduct = productRepository.saveAndFlush( + new Product("iPhone 15", "최신 아이폰", 1000000L, 50L, category) + ); + } + + @Test + @DisplayName("찜 추가 성공") + public void 찜_추가_성공() { + // when + Long wishlistId = wishlistService.addWishlist(savedUser.getId(), savedProduct.getId()); + + // then + assertThat(wishlistId).isNotNull(); + + var wishlists = wishlistRepository.findAll(); + assertThat(wishlists).hasSize(1); + + var savedWishlist = wishlists.getFirst(); + assertThat(savedWishlist.getUser().getId()).isEqualTo(savedUser.getId()); + assertThat(savedWishlist.getProduct().getId()).isEqualTo(savedProduct.getId()); + } + + @Test + @DisplayName("찜 추가 실패 - 존재하지 않는 사용자") + public void 찜_추가_실패_존재하지않는사용자() { + // given + Long nonExistUserId = 9999L; + + // when & then + assertThatThrownBy(() -> wishlistService.addWishlist(nonExistUserId, savedProduct.getId())) + .isInstanceOf(CustomException.class) + .hasMessageContaining(ErrorCode.NOT_FOUND_USER.getMessage()); + } + + @Test + @DisplayName("찜 추가 실패 - 존재하지 않는 상품") + public void 찜_추가_실패_존재하지않는상품() { + // given + Long nonExistProductId = 9999L; + + // when & then + assertThatThrownBy(() -> wishlistService.addWishlist(savedUser.getId(), nonExistProductId)) + .isInstanceOf(CustomException.class) + .hasMessageContaining(ErrorCode.NOT_FOUND_PRODUCT.getMessage()); + } + + @Test + @DisplayName("찜 추가 실패 - 이미 찜한 상품") + public void 찜_추가_실패_이미찜한상품() { + // given + wishlistService.addWishlist(savedUser.getId(), savedProduct.getId()); + + // when & then + assertThatThrownBy(() -> wishlistService.addWishlist(savedUser.getId(), savedProduct.getId())) + .isInstanceOf(CustomException.class) + .hasMessageContaining(ErrorCode.ALREADY_WISHLISTED.getMessage()); + } + + @Test + @DisplayName("찜 삭제 성공") + public void 찜_삭제_성공() { + // given + wishlistService.addWishlist(savedUser.getId(), savedProduct.getId()); + + // when + wishlistService.removeWishlist(savedUser.getId(), savedProduct.getId()); + + // then + boolean exists = wishlistRepository.existsByUserIdAndProductId(savedUser.getId(), savedProduct.getId()); + assertThat(exists).isFalse(); + } + + @Test + @DisplayName("찜 삭제 실패 - 존재하지 않는 찜") + public void 찜_삭제_실패_존재하지않는찜() { + // when & then + assertThatThrownBy(() -> wishlistService.removeWishlist(savedUser.getId(), savedProduct.getId())) + .isInstanceOf(CustomException.class) + .hasMessageContaining(ErrorCode.NOT_FOUND_WISHLIST.getMessage()); + } + + @Test + @DisplayName("전체 찜 삭제 성공") + public void 전체_찜_삭제_성공() { + // given + Category category2 = categoryRepository.saveAndFlush(new Category("의류")); + Product product2 = productRepository.saveAndFlush( + new Product("나이키 신발", "운동화", 150000L, 30L, category2) + ); + + wishlistService.addWishlist(savedUser.getId(), savedProduct.getId()); + wishlistService.addWishlist(savedUser.getId(), product2.getId()); + + // when + wishlistService.removeAllWishlist(savedUser.getId()); + + // then + List userWishlists = wishlistService.getWishlists(savedUser.getId()); + assertThat(userWishlists).isEmpty(); + } + + @Test + @DisplayName("찜 목록 조회 성공") + public void 찜_목록_조회_성공() { + // given + Category category2 = categoryRepository.saveAndFlush(new Category("의류")); + Product product2 = productRepository.saveAndFlush( + new Product("나이키 신발", "운동화", 150000L, 30L, category2) + ); + Product product3 = productRepository.saveAndFlush( + new Product("아디다스 신발", "운동화", 180000L, 25L, category2) + ); + + wishlistService.addWishlist(savedUser.getId(), savedProduct.getId()); + wishlistService.addWishlist(savedUser.getId(), product2.getId()); + wishlistService.addWishlist(savedUser.getId(), product3.getId()); + + // when + List wishlists = wishlistService.getWishlists(savedUser.getId()); + + // then + assertThat(wishlists).hasSize(3); + + var productIds = wishlists.stream() + .map(wishlistResponse -> wishlistResponse.productId()) + .toList(); + + assertThat(productIds).containsExactlyInAnyOrder( + savedProduct.getId(), + product2.getId(), + product3.getId() + ); + + var productNames = wishlists.stream() + .map(wishlistResponse -> wishlistResponse.productName()) + .toList(); + + assertThat(productNames).containsExactlyInAnyOrder( + "iPhone 15", + "나이키 신발", + "아디다스 신발" + ); + } + + @Test + @DisplayName("찜 목록 조회 성공 - 빈 목록") + public void 찜_목록_조회_성공_빈목록() { + // when + List wishlists = wishlistService.getWishlists(savedUser.getId()); + + // then + assertThat(wishlists).isEmpty(); + } + + @Test + @DisplayName("다른 사용자의 찜은 조회되지 않음") + public void 다른사용자_찜_조회안됨() { + // given + User anotherUser = userRepository.saveAndFlush(User.normalUser( + "another_user", + passwordEncoder.encode("password1234"), + "다른유저", + "another@kttech.com", + "010-9999-9999", + Gender.MALE, + LocalDate.of(1995, 5, 15), + savedUser.getMembership() + )); + + wishlistService.addWishlist(savedUser.getId(), savedProduct.getId()); + wishlistService.addWishlist(anotherUser.getId(), savedProduct.getId()); + + // when + List user1Wishlists = wishlistService.getWishlists(savedUser.getId()); + List user2Wishlists = wishlistService.getWishlists(anotherUser.getId()); + + // then + assertThat(user1Wishlists).hasSize(1); + assertThat(user2Wishlists).hasSize(1); + + // 각자 자신의 찜만 조회됨 + assertThat(user1Wishlists.get(0).productId()).isEqualTo(savedProduct.getId()); + assertThat(user2Wishlists.get(0).productId()).isEqualTo(savedProduct.getId()); + } + + @Test + @DisplayName("상품 삭제 후 찜 목록에서 조회 안됨") + public void 상품삭제후_찜목록_조회안됨() { + // given + wishlistService.addWishlist(savedUser.getId(), savedProduct.getId()); + + // 상품을 비활성화 (실제로는 소프트 삭제될 수 있음) + savedProduct.updateInActive(); + productRepository.saveAndFlush(savedProduct); + + // when + List wishlists = wishlistService.getWishlists(savedUser.getId()); + + // then + // 상품이 비활성화되어도 찜 목록에는 여전히 남아있어야 함 (비즈니스 로직에 따라) + // 만약 비활성화된 상품을 찜 목록에서 제외해야 한다면 서비스 로직 수정 필요 + assertThat(wishlists).hasSize(1); + } +} \ No newline at end of file From 4fb6618c462e889c9b6398485e01ad059b8c3409 Mon Sep 17 00:00:00 2001 From: "Jungyo Yang(Window)" <2jungyo@naver.com> Date: Tue, 6 Jan 2026 16:39:19 +0900 Subject: [PATCH 2/3] =?UTF-8?q?refactor:=20Payment=20=EC=97=B0=EA=B4=80?= =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EB=A7=A4=ED=95=91=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/kt/domain/payment/Payment.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/kt/domain/payment/Payment.java b/src/main/java/com/kt/domain/payment/Payment.java index d4e174d..bd3712c 100644 --- a/src/main/java/com/kt/domain/payment/Payment.java +++ b/src/main/java/com/kt/domain/payment/Payment.java @@ -15,10 +15,6 @@ @Table(name = "payment") public class Payment extends BaseEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - @Column(nullable = false) private Long totalPrice; // 총 상품 금액 From 788e48d2befae2b0c213004ddb71da68bca5bc68 Mon Sep 17 00:00:00 2001 From: "Jungyo Yang(Window)" <2jungyo@naver.com> Date: Tue, 6 Jan 2026 16:53:18 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20Payment=20=EC=97=B0=EA=B4=80?= =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EB=A7=A4=ED=95=91=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/kt/dto/wishlist/WishlistResponse.java | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/kt/dto/wishlist/WishlistResponse.java b/src/main/java/com/kt/dto/wishlist/WishlistResponse.java index d61a195..8239a7f 100644 --- a/src/main/java/com/kt/dto/wishlist/WishlistResponse.java +++ b/src/main/java/com/kt/dto/wishlist/WishlistResponse.java @@ -4,21 +4,15 @@ import com.kt.domain.wishlist.Wishlist; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; +public record WishlistResponse( + Long id, + Long productId, + String productName, + Long price, + LocalDateTime createdAt +) { -@Getter -@NoArgsConstructor -@AllArgsConstructor -public class WishlistResponse { - private Long id; - private Long productId; - private String productName; - private Long price; - private LocalDateTime createdAt; - - public static WishlistResponse from(Wishlist wishlist){ + public static WishlistResponse from(Wishlist wishlist) { return new WishlistResponse( wishlist.getId(), wishlist.getProduct().getId(),