diff --git a/src/main/java/site/goldenticket/domain/payment/model/Order.java b/src/main/java/site/goldenticket/domain/payment/model/Order.java index c84745f3..44ab758d 100644 --- a/src/main/java/site/goldenticket/domain/payment/model/Order.java +++ b/src/main/java/site/goldenticket/domain/payment/model/Order.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import site.goldenticket.common.constants.OrderStatus; @@ -27,6 +28,7 @@ public class Order extends BaseTimeEntity { private Integer price; private boolean customerViewCheck; + @Builder private Order(Long productId, Long userId, OrderStatus status, NegotiationStatus negoStatus, Integer price) { this.productId = productId; this.userId = userId; diff --git a/src/test/java/site/goldenticket/common/utils/ChatRoomUtils.java b/src/test/java/site/goldenticket/common/utils/ChatRoomUtils.java new file mode 100644 index 00000000..4ca348ef --- /dev/null +++ b/src/test/java/site/goldenticket/common/utils/ChatRoomUtils.java @@ -0,0 +1,17 @@ +package site.goldenticket.common.utils; + +import site.goldenticket.domain.chat.entity.ChatRoom; +import site.goldenticket.domain.product.model.Product; +import site.goldenticket.domain.user.entity.User; + +public class ChatRoomUtils { + + private ChatRoomUtils() {} + + public static ChatRoom createChatRoom(Product product, User user) { + return ChatRoom.builder() + .productId(product.getId()) + .buyerId(user.getId()) + .build(); + } +} diff --git a/src/test/java/site/goldenticket/common/utils/ChatUtils.java b/src/test/java/site/goldenticket/common/utils/ChatUtils.java new file mode 100644 index 00000000..d9accbd7 --- /dev/null +++ b/src/test/java/site/goldenticket/common/utils/ChatUtils.java @@ -0,0 +1,31 @@ +package site.goldenticket.common.utils; + +import site.goldenticket.domain.chat.entity.Chat; +import site.goldenticket.domain.chat.entity.ChatRoom; +import site.goldenticket.domain.chat.entity.SenderType; +import site.goldenticket.domain.user.entity.User; + +import static site.goldenticket.domain.chat.entity.SenderType.BUYER; + +public class ChatUtils { + private static final SenderType senderType = BUYER; + public static final String content = "채팅 메시지 내용"; + private static final Boolean viewedBySeller = false; + private static final Boolean viewedByBuyer = true; + + private ChatUtils() {} + + public static Chat createChat(ChatRoom chatRoom, User user) { + Long chatRoomId = chatRoom.getId(); + Long userId = user.getId(); + + return Chat.builder() + .chatRoomId(chatRoomId) + .senderType(senderType) + .userId(userId) + .content(content) + .viewedBySeller(viewedBySeller) + .viewedByBuyer(viewedByBuyer) + .build(); + } +} diff --git a/src/test/java/site/goldenticket/common/utils/NegoUtils.java b/src/test/java/site/goldenticket/common/utils/NegoUtils.java new file mode 100644 index 00000000..e488257a --- /dev/null +++ b/src/test/java/site/goldenticket/common/utils/NegoUtils.java @@ -0,0 +1,39 @@ +package site.goldenticket.common.utils; + +import site.goldenticket.domain.nego.entity.Nego; +import site.goldenticket.domain.nego.status.NegotiationStatus; +import site.goldenticket.domain.product.model.Product; +import site.goldenticket.domain.user.entity.User; + +import java.time.LocalDateTime; + +import static site.goldenticket.domain.nego.status.NegotiationStatus.NEGOTIATING; + +public class NegoUtils { + private static final Integer price = 50000; + private static final Integer count = 1; + private static final NegotiationStatus status = NEGOTIATING; + private static final boolean consent = false; + private static final LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(20); + private static final LocalDateTime createdAt = LocalDateTime.now(); + private static final LocalDateTime updatedAt = LocalDateTime.now(); + + private NegoUtils() {} + + public static Nego createNego(Product product, User user) { + Nego nego = Nego.builder() + .price(price) + .count(count) + .status(NEGOTIATING) + .consent(false) + .expirationTime(expirationTime) + .createdAt(createdAt) + .updatedAt(updatedAt) + .build(); + + nego.setProduct(product); + nego.setUser(user); + + return nego; + } +} diff --git a/src/test/java/site/goldenticket/common/utils/OrderUtils.java b/src/test/java/site/goldenticket/common/utils/OrderUtils.java new file mode 100644 index 00000000..a407c5d2 --- /dev/null +++ b/src/test/java/site/goldenticket/common/utils/OrderUtils.java @@ -0,0 +1,31 @@ +package site.goldenticket.common.utils; + +import site.goldenticket.common.constants.OrderStatus; +import site.goldenticket.domain.nego.status.NegotiationStatus; +import site.goldenticket.domain.payment.model.Order; +import site.goldenticket.domain.product.model.Product; +import site.goldenticket.domain.user.entity.User; + +import static site.goldenticket.common.constants.OrderStatus.COMPLETED_TRANSFER; +import static site.goldenticket.domain.nego.status.NegotiationStatus.TRANSFER_PENDING; + +public class OrderUtils { + private static final OrderStatus status = COMPLETED_TRANSFER; + private static final NegotiationStatus negoStatus = TRANSFER_PENDING; + private static final Integer price = 50000; + + private OrderUtils() {} + + public static Order createOrder(Product product, User user){ + Long productId = product.getId(); + Long userId = user.getId(); + + return Order.builder() + .productId(productId) + .userId(userId) + .status(status) + .negoStatus(negoStatus) + .price(price) + .build(); + } +} diff --git a/src/test/java/site/goldenticket/domain/product/controller/ProductControllerTest.java b/src/test/java/site/goldenticket/domain/product/controller/ProductControllerTest.java new file mode 100644 index 00000000..d5497e9a --- /dev/null +++ b/src/test/java/site/goldenticket/domain/product/controller/ProductControllerTest.java @@ -0,0 +1,234 @@ +package site.goldenticket.domain.product.controller; + +import io.restassured.RestAssured; +import io.restassured.path.json.JsonPath; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import io.restassured.specification.RequestSpecification; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import site.goldenticket.common.config.ApiTest; +import site.goldenticket.domain.chat.entity.Chat; +import site.goldenticket.domain.chat.entity.ChatRoom; +import site.goldenticket.domain.chat.repository.ChatRepository; +import site.goldenticket.domain.chat.repository.ChatRoomRepository; +import site.goldenticket.domain.nego.entity.Nego; +import site.goldenticket.domain.nego.repository.NegoRepository; +import site.goldenticket.domain.payment.model.Order; +import site.goldenticket.domain.payment.repository.OrderRepository; +import site.goldenticket.domain.product.model.Product; +import site.goldenticket.domain.product.repository.ProductRepository; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static site.goldenticket.common.utils.ChatRoomUtils.createChatRoom; +import static site.goldenticket.common.utils.ChatUtils.createChat; +import static site.goldenticket.common.utils.NegoUtils.createNego; +import static site.goldenticket.common.utils.OrderUtils.createOrder; +import static site.goldenticket.common.utils.ProductUtils.createProduct; +import static site.goldenticket.domain.product.constants.ProductStatus.EXPIRED; +import static site.goldenticket.domain.product.constants.ProductStatus.SOLD_OUT; + +public class ProductControllerTest extends ApiTest { + + @Autowired + private ProductRepository productRepository; + + @Autowired + private ChatRoomRepository chatRoomRepository; + + @Autowired + private ChatRepository chatRepository; + + @Autowired + private NegoRepository negoRepository; + + @Autowired + private OrderRepository orderRepository; + + @Test + void getProduct() { + // given + Product product = saveProduct(); + + String url = "/products/" + product.getId(); + + // when + final ExtractableResponse response = performGetRequest(url, false); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + @Test + void deleteProduct() { + // given + Product product = saveProduct(); + + String url = "/products/" + product.getId(); + + // when + final ExtractableResponse response = performDeleteRequest(url); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + @Test + void getProgressProducts() { + // given + Product product = saveProduct(); + ChatRoom chatRoom = saveChatRoom(product); + saveChat(chatRoom); + saveNego(product); + + String url = "/products/history/progress"; + + // when + final ExtractableResponse response = performGetRequest(url, true); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + final JsonPath result = response.jsonPath(); + assertAll( + () -> assertThat(result.getList("data.productId", Long.class)).contains(product.getId()), + () -> assertThat(result.getList("data.chats[0].chatRoomId", Long.class)).contains(chatRoom.getId()) + ); + } + + @Test + void getAllCompletedProducts() { + // given + List products = createCompletedProductsList(); + + String url = "/products/history/completed"; + + // when + final ExtractableResponse response = performGetRequest(url, true); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + final JsonPath result = response.jsonPath(); + assertAll( + () -> assertThat(result.getLong("data[0].productId")).isEqualTo(products.get(0).getId().intValue()), + () -> assertThat(result.getLong("data[1].productId")).isEqualTo(products.get(1).getId().intValue()) + ); + } + + @Test + void getCompletedProductDetails() { + // given + Product product = saveSoldOutProduct(); + ChatRoom chatRoom = saveChatRoom(product); + saveChat(chatRoom); + saveOrder(product); + + String url = "/products/history/completed/" + product.getId(); + String parameterName = "productStatus"; + String parameterValues = product.getProductStatus().toString(); + + // when + final ExtractableResponse response = performGetRequestWithQueryParam(url, parameterName, parameterValues, true); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + final JsonPath result = response.jsonPath(); + assertThat(result.getLong("data.productId")).isEqualTo(product.getId()); + } + + @Test + void deleteCompletedProduct(){ + // given + Product product = saveSoldOutProduct(); + + String url = "/products/history/completed/" + product.getId(); + + // when + final ExtractableResponse response = performDeleteRequest(url); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + private Product saveProduct() { + Product product = createProduct(); + return productRepository.save(product); + } + + private Product saveSoldOutProduct() { + Product product = createProduct(); + product.setProductStatus(SOLD_OUT); + return productRepository.save(product); + } + + private Product saveExpiredProduct() { + Product product = createProduct(); + product.setProductStatus(EXPIRED); + return productRepository.save(product); + } + + private List createCompletedProductsList() { + return List.of(saveSoldOutProduct(), saveExpiredProduct()); + } + + private ChatRoom saveChatRoom(Product product) { + ChatRoom chatRoom = createChatRoom(product, user); + return chatRoomRepository.save(chatRoom); + } + + private void saveChat(ChatRoom chatRoom) { + Chat chat = createChat(chatRoom, user); + chatRepository.save(chat); + } + + private void saveNego(Product product) { + Nego nego = createNego(product, user); + negoRepository.save(nego); + } + + private void saveOrder(Product product) { + Order order = createOrder(product, user); + orderRepository.save(order); + } + + private RequestSpecification setupRequestSpecification(boolean needsAuthentication) { + RequestSpecification requestSpecification = RestAssured.given().log().all(); + + if (needsAuthentication) { + requestSpecification.header("Authorization", "Bearer " + accessToken); + } + + return requestSpecification; + } + + private ExtractableResponse performGetRequest(String url, boolean needsAuthentication) { + RequestSpecification requestSpecification = setupRequestSpecification(needsAuthentication); + + return requestSpecification + .when().get(url) + .then().log().all() + .extract(); + } + + private ExtractableResponse performGetRequestWithQueryParam(String url, String parameterName, String parameterValues, boolean needsAuthentication) { + RequestSpecification requestSpecification = setupRequestSpecification(needsAuthentication); + + return requestSpecification + .queryParam(parameterName, parameterValues) + .when().get(url) + .then().log().all() + .extract(); + } + + private ExtractableResponse performDeleteRequest(String url) { + RequestSpecification requestSpecification = setupRequestSpecification(true); + + return requestSpecification + .when().delete(url) + .then().log().all() + .extract(); + } +}