From 1facfa4f99bece71d511f0f359bf68d0b3ab9b2e Mon Sep 17 00:00:00 2001 From: gugbab2 Date: Tue, 7 Jan 2025 01:11:40 +0900 Subject: [PATCH] =?UTF-8?q?[#5]=20=EC=9D=91=EB=AA=A8=20API=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 --- .../controller/DrawController.java | 42 ++++ .../productdraw/domain/entity/Draw.java | 25 +++ .../productdraw/domain/entity/Entrant.java | 22 ++ .../productdraw/domain/entity/Entry.java | 24 --- .../productdraw/domain/entity/Product.java | 8 +- .../domain/repository/DrawRepository.java | 13 ++ .../domain/repository/EntrantRepository.java | 8 + .../domain/repository/EntryRepository.java | 8 - .../inmemory/DrawRepositoryImpl.java | 63 ++++++ .../inmemory/EntrantRepositoryImpl.java | 18 ++ .../domain/service/DrawService.java | 118 +++++++++++ .../productdraw/domain/vo/WinnerStatus.java | 8 + .../com/gugbab2/productdraw/dto/DrawDto.java | 15 ++ .../exception/DrawNotFoundException.java | 7 + .../exception/EntrantNotFoundException.java | 7 + .../exception/ProductNotFoundException.java | 7 + .../domain/service/EntryServiceTest.java | 195 ------------------ 17 files changed, 359 insertions(+), 229 deletions(-) create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/controller/DrawController.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Draw.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Entrant.java delete mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Entry.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/DrawRepository.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/EntrantRepository.java delete mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/EntryRepository.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/inmemory/DrawRepositoryImpl.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/inmemory/EntrantRepositoryImpl.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/service/DrawService.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/domain/vo/WinnerStatus.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/dto/DrawDto.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/exception/DrawNotFoundException.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/exception/EntrantNotFoundException.java create mode 100644 product-draw/src/main/java/com/gugbab2/productdraw/exception/ProductNotFoundException.java delete mode 100644 product-draw/src/test/java/com/gugbab2/productdraw/domain/service/EntryServiceTest.java diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/controller/DrawController.java b/product-draw/src/main/java/com/gugbab2/productdraw/controller/DrawController.java new file mode 100644 index 0000000..36e45e0 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/controller/DrawController.java @@ -0,0 +1,42 @@ +package com.gugbab2.productdraw.controller; + +import com.gugbab2.productdraw.domain.entity.Draw; +import com.gugbab2.productdraw.domain.entity.Entrant; +import com.gugbab2.productdraw.domain.entity.Payment; +import com.gugbab2.productdraw.domain.service.DrawService; +import com.gugbab2.productdraw.dto.DrawDto; +import com.gugbab2.productdraw.dto.PaymentDto; +import com.gugbab2.productdraw.exception.EntrantNotFoundException; +import com.gugbab2.productdraw.exception.ProductNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/draws") +@RequiredArgsConstructor +public class DrawController { + + private final DrawService drawService; + + // 응모 제출 + @PostMapping("/submit") + public ResponseEntity createDraw(@RequestBody DrawDto.CreateDrawDto drawDto) { + try { + Draw entry = drawService.createDraw(drawDto.getEntrantId(), drawDto.getProductId()); + return new ResponseEntity<>(entry, HttpStatus.CREATED); + } catch (EntrantNotFoundException | ProductNotFoundException e) { + return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND); + } + } + + // 응모 결과 발표 + @PostMapping("/{productId}result") + public ResponseEntity> announceWinners(@PathVariable String productId) { + List entrants = drawService.announceResult(productId); + return new ResponseEntity<>(entrants, HttpStatus.OK); + } +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Draw.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Draw.java new file mode 100644 index 0000000..4f709ed --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Draw.java @@ -0,0 +1,25 @@ +package com.gugbab2.productdraw.domain.entity; + +import com.gugbab2.productdraw.domain.vo.WinnerStatus; +import lombok.Getter; +import lombok.Setter; + +import java.util.UUID; + +@Getter +@Setter +public class Draw { + private String id; + private String entrantId; + private String productId; + private boolean isPaid; + private WinnerStatus winnerStatus; + + public Draw(String entrantId, String productId) { + this.id = UUID.randomUUID().toString(); + this.entrantId = entrantId; + this.productId = productId; + this.isPaid = false; + this.winnerStatus = WinnerStatus.PENDING; // PENDING : 대기 + } +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Entrant.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Entrant.java new file mode 100644 index 0000000..865a1d4 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Entrant.java @@ -0,0 +1,22 @@ +package com.gugbab2.productdraw.domain.entity; + +import lombok.Getter; +import lombok.Setter; + +import java.util.UUID; + +@Getter +@Setter +public class Entrant { + private String id; + private String shippingAddress; + private String paymentMethod; + + public Entrant(String shippingAddress, String paymentMethod) { + this.id = UUID.randomUUID().toString(); + this.shippingAddress = shippingAddress; + this.paymentMethod = paymentMethod; + } + +} + diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Entry.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Entry.java deleted file mode 100644 index 3885c28..0000000 --- a/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Entry.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gugbab2.productdraw.domain.entity; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class Entry { - private String id; - private Product product; - private String shippingAddress; - private String paymentMethod; - private boolean isPaid; - private char isWinner; - - public Entry(String id, Product product, String shippingAddress, String paymentMethod) { - this.id = id; - this.product = product; - this.shippingAddress = shippingAddress; - this.paymentMethod = paymentMethod; - this.isPaid = false; - this.isWinner = '0'; // 0 : 대기, 1 : 당첨, 2 : 미당첨 - } -} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Product.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Product.java index ac02819..c340b9f 100644 --- a/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Product.java +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/entity/Product.java @@ -13,12 +13,16 @@ public class Product { private double price; private String size; private String category; + private boolean isDone; + private int stock; - public Product(String id, String name, double price, String size, String category) { - this.id = id; + public Product(String name, double price, String size, String category, int stock) { + this.id = UUID.randomUUID().toString(); this.name = name; this.price = price; this.size = size; this.category = category; + this.isDone = false; + this.stock = stock; } } diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/DrawRepository.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/DrawRepository.java new file mode 100644 index 0000000..179aed5 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/DrawRepository.java @@ -0,0 +1,13 @@ +package com.gugbab2.productdraw.domain.repository; + +import com.gugbab2.productdraw.domain.entity.Draw; + +import java.util.List; + +public interface DrawRepository { + Draw save(Draw entry); + Draw findById(String id); + List findByProductId(String productId); + List findByEntrantId(String entrantId); + void updateById(Draw draw); +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/EntrantRepository.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/EntrantRepository.java new file mode 100644 index 0000000..3bf9d06 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/EntrantRepository.java @@ -0,0 +1,8 @@ +package com.gugbab2.productdraw.domain.repository; + +import com.gugbab2.productdraw.domain.entity.Entrant; + +public interface EntrantRepository { + + Entrant findById(String id); +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/EntryRepository.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/EntryRepository.java deleted file mode 100644 index 6273160..0000000 --- a/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/EntryRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.gugbab2.productdraw.domain.repository; - -import com.gugbab2.productdraw.domain.entity.Entry; - -public interface EntryRepository { - Entry save(Entry entry); - Entry findById(String id); -} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/inmemory/DrawRepositoryImpl.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/inmemory/DrawRepositoryImpl.java new file mode 100644 index 0000000..0622422 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/inmemory/DrawRepositoryImpl.java @@ -0,0 +1,63 @@ +package com.gugbab2.productdraw.domain.repository.inmemory; + +import com.gugbab2.productdraw.domain.entity.Draw; +import com.gugbab2.productdraw.domain.entity.Entrant; +import com.gugbab2.productdraw.domain.repository.DrawRepository; +import com.gugbab2.productdraw.domain.vo.WinnerStatus; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Repository +public class DrawRepositoryImpl implements DrawRepository { + private final Map entryDatabase = new HashMap<>(); + + @Override + public Draw save(Draw draw) { + entryDatabase.put(draw.getId(), draw); + return draw; + } + + @Override + public Draw findById(String drawId) { + return entryDatabase.get(drawId); + } + + @Override + public List findByProductId(String productId) { + List result = new ArrayList<>(); + for (Draw draw : entryDatabase.values()) { + if (productId.equals(draw.getProductId())) { + result.add(draw); + } + } + return result; + } + + @Override + public List findByEntrantId(String entrantId) { + List result = new ArrayList<>(); + for (Draw draw : entryDatabase.values()) { + if (entrantId.equals(draw.getEntrantId())) { + result.add(draw); + } + } + return result; + } + + @Override + public void updateById(Draw draw) { + Draw existingDraw = entryDatabase.get(draw.getId()); + + if (existingDraw != null) { + existingDraw.setWinnerStatus(WinnerStatus.WINNER); + + entryDatabase.put(draw.getId(), existingDraw); + } else { + throw new IllegalArgumentException("Draw not found with id: " + draw.getId()); + } + } +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/inmemory/EntrantRepositoryImpl.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/inmemory/EntrantRepositoryImpl.java new file mode 100644 index 0000000..e7c04a4 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/repository/inmemory/EntrantRepositoryImpl.java @@ -0,0 +1,18 @@ +package com.gugbab2.productdraw.domain.repository.inmemory; + +import com.gugbab2.productdraw.domain.entity.Entrant; +import com.gugbab2.productdraw.domain.repository.EntrantRepository; +import org.springframework.stereotype.Repository; + +import java.util.HashMap; +import java.util.Map; + +@Repository +public class EntrantRepositoryImpl implements EntrantRepository { + private final Map entrantDatabase = new HashMap<>(); + + @Override + public Entrant findById(String id) { + return entrantDatabase.get(id); + } +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/service/DrawService.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/service/DrawService.java new file mode 100644 index 0000000..e1afb6c --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/service/DrawService.java @@ -0,0 +1,118 @@ +package com.gugbab2.productdraw.domain.service; + +import com.gugbab2.productdraw.domain.entity.Draw; +import com.gugbab2.productdraw.domain.entity.Entrant; +import com.gugbab2.productdraw.domain.entity.Product; +import com.gugbab2.productdraw.domain.repository.inmemory.DrawRepositoryImpl; +import com.gugbab2.productdraw.domain.repository.inmemory.EntrantRepositoryImpl; +import com.gugbab2.productdraw.domain.repository.inmemory.ProductRepositoryImpl; +import com.gugbab2.productdraw.exception.DrawNotFoundException; +import com.gugbab2.productdraw.exception.EntrantNotFoundException; +import com.gugbab2.productdraw.exception.ProductNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +@RequiredArgsConstructor +public class DrawService { + + private final DrawRepositoryImpl drawRepository; + private final EntrantRepositoryImpl entrantRepository; + private final ProductRepositoryImpl productRepository; + + /** + * 응모 생성 + * + * @param entrantId + * @param productId + * @return + */ + public Draw createDraw(String entrantId, String productId) { + + Entrant entrant = entrantRepository.findById(entrantId); + // 사용자 중복 요청 예외처리 + if(entrant == null) { + throw new EntrantNotFoundException(entrantId); + } + + Product product = productRepository.findById(productId); + // 상품 미조회 예외처리 + if(product == null) { + throw new ProductNotFoundException(productId); + } + + // 응모 생성 + Draw draw = new Draw(entrantId, productId); + return drawRepository.save(draw); + } + + /** + * 응모 당첨자 생성 + * + * @param productId + * @return + */ + public List announceResult(String productId) { + + Product product = productRepository.findById(productId); + // 상품 미조회 예외처리 + if (product == null) { + throw new ProductNotFoundException(productId); + } + + // 상품에 대한 모든 응모자 조회 + List draws = drawRepository.findByProductId(productId); + if (draws == null || draws.isEmpty()) { + throw new DrawNotFoundException(productId); + } + + // 응모자 목록에서 Entrant 객체 추출 + List entrants = new ArrayList<>(); + for (Draw draw : draws) { + Entrant entrant = entrantRepository.findById(draw.getEntrantId()); + if (entrant != null) { + entrants.add(entrant); + } + } + + // 응모자 중 재고 만큼 당첨자를 선정해 + int stockCount = product.getStock(); + int winnerCount = Math.min(entrants.size(), stockCount); + List winners = pickRandomWinners(entrants, winnerCount); + + // 당첨 결과를 업데이트 해줘 + for (Entrant winner : winners) { + List winnerDraws = drawRepository.findByEntrantId(winner.getId()); + for(Draw draw : winnerDraws) { + drawRepository.updateById(draw); + } + } + + return winners; + } + + /** + * 응모자 중 당첨자 생성 + * + * @param entrants + * @param winnerCount + * @return + */ + private List pickRandomWinners(List entrants, int winnerCount) { + List winners = new ArrayList<>(); + Random random = new Random(); + Set selectedIndices = new HashSet<>(); + + while (selectedIndices.size() < winnerCount) { + int index = random.nextInt(entrants.size()); + if (!selectedIndices.contains(index)) { + selectedIndices.add(index); + winners.add(entrants.get(index)); + } + } + return winners; + } + +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/domain/vo/WinnerStatus.java b/product-draw/src/main/java/com/gugbab2/productdraw/domain/vo/WinnerStatus.java new file mode 100644 index 0000000..b761b5d --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/domain/vo/WinnerStatus.java @@ -0,0 +1,8 @@ +package com.gugbab2.productdraw.domain.vo; + +public enum WinnerStatus { + + PENDING, // 대기 중 + WINNER, // 당첨 + NOT_WINNER; // 미당첨 +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/dto/DrawDto.java b/product-draw/src/main/java/com/gugbab2/productdraw/dto/DrawDto.java new file mode 100644 index 0000000..886b223 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/dto/DrawDto.java @@ -0,0 +1,15 @@ +package com.gugbab2.productdraw.dto; + +import lombok.Getter; +import lombok.Setter; + +public class DrawDto { + + @Getter + @Setter + public static class CreateDrawDto{ + private String entrantId; + private String productId; + } + +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/exception/DrawNotFoundException.java b/product-draw/src/main/java/com/gugbab2/productdraw/exception/DrawNotFoundException.java new file mode 100644 index 0000000..b252347 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/exception/DrawNotFoundException.java @@ -0,0 +1,7 @@ +package com.gugbab2.productdraw.exception; + +public class DrawNotFoundException extends RuntimeException { + public DrawNotFoundException(String productId) { + super("Draw not found with Product ID : " + productId); + } +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/exception/EntrantNotFoundException.java b/product-draw/src/main/java/com/gugbab2/productdraw/exception/EntrantNotFoundException.java new file mode 100644 index 0000000..5fd3167 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/exception/EntrantNotFoundException.java @@ -0,0 +1,7 @@ +package com.gugbab2.productdraw.exception; + +public class EntrantNotFoundException extends RuntimeException { + public EntrantNotFoundException(String entrantId) { + super("Entrant not found with ID : " + entrantId); + } +} diff --git a/product-draw/src/main/java/com/gugbab2/productdraw/exception/ProductNotFoundException.java b/product-draw/src/main/java/com/gugbab2/productdraw/exception/ProductNotFoundException.java new file mode 100644 index 0000000..94c9880 --- /dev/null +++ b/product-draw/src/main/java/com/gugbab2/productdraw/exception/ProductNotFoundException.java @@ -0,0 +1,7 @@ +package com.gugbab2.productdraw.exception; + +public class ProductNotFoundException extends RuntimeException { + public ProductNotFoundException(String productId) { + super("Product not found with ID : " + productId); + } +} diff --git a/product-draw/src/test/java/com/gugbab2/productdraw/domain/service/EntryServiceTest.java b/product-draw/src/test/java/com/gugbab2/productdraw/domain/service/EntryServiceTest.java deleted file mode 100644 index 13f3c47..0000000 --- a/product-draw/src/test/java/com/gugbab2/productdraw/domain/service/EntryServiceTest.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.gugbab2.productdraw.domain.service; - -import com.gugbab2.productdraw.domain.entity.Entry; -import com.gugbab2.productdraw.domain.entity.Payment; -import com.gugbab2.productdraw.domain.entity.Product; -import com.gugbab2.productdraw.domain.repository.inmemory.EntryRepositoryImpl; -import com.gugbab2.productdraw.domain.repository.inmemory.PaymentRepositoryImpl; -import com.gugbab2.productdraw.domain.repository.inmemory.ProductRepositoryImpl; -import com.gugbab2.productdraw.dto.PaymentDto; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -class EntryServiceTest { - - @Mock - private EntryRepositoryImpl entryRepository; - - @Mock - private PaymentRepositoryImpl paymentRepository; - - @Mock - private ProductRepositoryImpl productRepository; - - @InjectMocks - private EntryService entryService; - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - } - - @Test - @DisplayName("응모 생성") - void testCreateEntry() { - String productId = "product-123"; - String shippingAddress = "123 Main St"; - String paymentMethod = "Credit Card"; - String entryId = "entry-123"; - - /* - [given] - 1. 고정된 mockProduct, mockEntry 리턴 - */ - Product mockProduct = new Product(productId, "Test Product", 100.0, "L", "test"); - Entry mockEntry = new Entry(entryId, mockProduct, shippingAddress, paymentMethod); - - when(productRepository.findById(productId)).thenReturn(mockProduct); - when(entryRepository.save(any(Entry.class))).thenReturn(mockEntry); - - /* - [when] - 1. 응모 생성 - */ - Entry entry = entryService.createEntry(productId, shippingAddress, paymentMethod); - - /* - [then] - 1. 응모가 not null 이어야 한다. - 2. mockProduct 와 응모 내 product 는 동일해야 한다. - 3. shippingAddress 와 응모 내 shippingAddress 는 동일해야 한다. - 4. paymentMethod 와 응모 내 paymentMethod 는 동일해야 한다. - */ - assertNotNull(entry); - assertEquals(mockProduct, entry.getProduct()); - assertEquals(shippingAddress, entry.getShippingAddress()); - assertEquals(paymentMethod, entry.getPaymentMethod()); - -// verify(productRepository, times(1)).findById(productId); -// verify(entryRepository, times(1)).save(any(Entry.class)); - } - - @Test - @DisplayName("응모 후 결제") - void testProcessPayment() { - String entryId = "entry-123"; - String shippingAddress = "123 Main St"; - String paymentMethod = "Credit Card"; - PaymentDto paymentDto = new PaymentDto(shippingAddress, paymentMethod, 100.0); - - /* - [given] - 1. 결제 상태 변경 : 결제 성공 - 2. 고정된 mockEntry, mockPayment 리턴 - */ - Product mockProduct = new Product("product-123", "Test Product", 100.0, "L", "test"); - Entry mockEntry = new Entry(entryId, mockProduct, "123 Main St", "Credit Card"); - Payment mockPayment = new Payment("payment-123", mockEntry, paymentDto.getAmount()); - mockPayment.setSuccess(true); - - when(entryRepository.findById(entryId)).thenReturn(mockEntry); - when(paymentRepository.save(any(Payment.class))).thenReturn(mockPayment); - - /* - [when] - 1. 결제 진행 - */ - Payment payment = entryService.processPayment(entryId, paymentDto); - - /* - [then] - 1. 결제가 not null 이어야 한다. - 2. 결제가 성공해야 한다. - 3. paymentDto 내 금액은 결제 내 금액과 동일해야 한다. - */ - assertNotNull(payment); - assertTrue(payment.isSuccess()); - assertEquals(paymentDto.getAmount(), payment.getAmount()); - -// verify(entryRepository, times(1)).findById(entryId); -// verify(paymentRepository, times(1)).save(any(Payment.class)); - } - - @Test - @DisplayName("응모 확인 시 미당첨이라면 환불") - void testProcessWinnerWithRefund() { - String entryId = "entry-123"; - - /* - [given] - 1. 응모 상태 변경 : 미당첨 - 2. 고정된 mockEntry, mockPayment 리턴 - */ - Product mockProduct = new Product("product-123", "Test Product", 100.0, "L", "test"); - Entry mockEntry = new Entry(entryId, mockProduct, "123 Main St", "Credit Card"); - mockEntry.setIsWinner('2'); // 미당첨 - Payment mockPayment = new Payment("payment-123", mockEntry, 100.0); - mockPayment.setSuccess(true); - - when(entryRepository.findById(entryId)).thenReturn(mockEntry); - when(paymentRepository.findById(entryId)).thenReturn(mockPayment); - - /* - [when] - 1. 응모 상태 확인 - 2. 미당첨이라면 자동 환불 - */ - Entry entry = entryService.checkWinner(entryId); - - /* - [then] - 1. 응모가 not null 이어야 한다. - 2. 응모 결과가 미당첨이어야 한다. - 3. 결제는 성공 상태여야 한다. - */ - assertNotNull(entry); - assertEquals('2', entry.getIsWinner()); - assertFalse(mockPayment.isSuccess()); - -// verify(entryRepository, times(1)).findById(entryId); -// verify(paymentRepository, times(1)).findById(entryId); -// verify(paymentRepository, times(1)).save(mockPayment); - } - - @Test - @DisplayName("응모 확인 시 당첨이라면 상태 유지") - void testProcessWinnerWithoutRefund() { - String entryId = "entry-123"; - - /* - [given] - 1. 응모 상태 변경 : 당첨 - 2. 고정된 mockEntry, mockPayment 리턴 - */ - Product mockProduct = new Product("product-123", "Test Product", 100.0, "L", "test"); - Entry mockEntry = new Entry(entryId, mockProduct, "123 Main St", "Credit Card"); - mockEntry.setIsWinner('1'); // 당첨 - - when(entryRepository.findById(entryId)).thenReturn(mockEntry); - - /* - [when] - 1. 응모 상태 확인 - 2. 당첨이라면 상태 유지 - */ - Entry entry = entryService.checkWinner(entryId); - - /* - [then] - 1. 응모가 not null 이어야 한다. - 2. 응모 결과가 당첨이어야 한다. - */ - assertNotNull(entry); - assertEquals('1', entry.getIsWinner()); - - verify(entryRepository, times(1)).findById(entryId); - verifyNoInteractions(paymentRepository); - } -} \ No newline at end of file