diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/CheckAvailableRoomsResultDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/CheckAvailableRoomsResultDto.java index 149b0e65..0ba6b8a8 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/CheckAvailableRoomsResultDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/CheckAvailableRoomsResultDto.java @@ -1,8 +1,11 @@ package com.fc.shimpyo_be.domain.reservation.dto; +import lombok.Builder; + import java.util.List; import java.util.Map; +@Builder public record CheckAvailableRoomsResultDto( boolean isAvailable, List unavailableIds, diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/PreoccupyRoomItemRequestDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/PreoccupyRoomItemRequestDto.java index 1c001d79..5bde7af1 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/PreoccupyRoomItemRequestDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/PreoccupyRoomItemRequestDto.java @@ -2,7 +2,9 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; +import lombok.Builder; +@Builder public record PreoccupyRoomItemRequestDto( @NotNull Long roomId, diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/PreoccupyRoomsRequestDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/PreoccupyRoomsRequestDto.java index 251b1c6a..c8e0b97e 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/PreoccupyRoomsRequestDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/PreoccupyRoomsRequestDto.java @@ -2,9 +2,11 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.Size; +import lombok.Builder; import java.util.List; +@Builder public record PreoccupyRoomsRequestDto( @Valid diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/ReleaseRoomItemRequestDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/ReleaseRoomItemRequestDto.java index 448aac87..5c46bb16 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/ReleaseRoomItemRequestDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/ReleaseRoomItemRequestDto.java @@ -2,7 +2,9 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; +import lombok.Builder; +@Builder public record ReleaseRoomItemRequestDto( @NotNull Long roomId, diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/ReleaseRoomsRequestDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/ReleaseRoomsRequestDto.java index 00a295f9..ca1d809a 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/ReleaseRoomsRequestDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/ReleaseRoomsRequestDto.java @@ -2,9 +2,11 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.Size; +import lombok.Builder; import java.util.List; +@Builder public record ReleaseRoomsRequestDto( @Valid @Size(min = 1, max = 3, message = "최소 1개, 최대 3개의 객실 요청 정보가 필요합니다.") diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/SaveReservationRequestDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/SaveReservationRequestDto.java index 93fde17e..458d1340 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/SaveReservationRequestDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/request/SaveReservationRequestDto.java @@ -6,9 +6,11 @@ import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import lombok.Builder; import java.util.List; +@Builder public record SaveReservationRequestDto( @Valid @Size(min = 1, max = 3, message = "최소 1개, 최대 3개의 객실 예약이 가능합니다.") diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/ReservationInfoResponseDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/ReservationInfoResponseDto.java index 373696f3..ecb80459 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/ReservationInfoResponseDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/ReservationInfoResponseDto.java @@ -1,5 +1,8 @@ package com.fc.shimpyo_be.domain.reservation.dto.response; +import lombok.Builder; + +@Builder public record ReservationInfoResponseDto( Long reservationId, Long reservationProductId, @@ -7,6 +10,7 @@ public record ReservationInfoResponseDto( String productName, String productImageUrl, String productAddress, + String productDetailAddress, Long roomId, String roomName, String startDate, @@ -14,6 +18,7 @@ public record ReservationInfoResponseDto( String checkIn, String checkOut, Integer price, - String payMethod + String payMethod, + String createdAt ) { } diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/SaveReservationResponseDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/SaveReservationResponseDto.java index e679dbed..531b47ba 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/SaveReservationResponseDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/SaveReservationResponseDto.java @@ -1,25 +1,17 @@ package com.fc.shimpyo_be.domain.reservation.dto.response; -import com.fc.shimpyo_be.domain.reservation.dto.request.SaveReservationRequestDto; import com.fc.shimpyo_be.domain.reservation.entity.PayMethod; import com.fc.shimpyo_be.domain.reservationproduct.dto.response.ReservationProductResponseDto; +import lombok.Builder; import java.util.List; +@Builder public record SaveReservationResponseDto( Long reservationId, List reservationProducts, PayMethod payMethod, - Integer totalPrice + Integer totalPrice, + String createdAt ) { - public SaveReservationResponseDto(Long reservationId, SaveReservationRequestDto requestDto) { - this( - reservationId, - requestDto.reservationProducts() - .stream() - .map(ReservationProductResponseDto::new).toList(), - requestDto.payMethod(), - requestDto.totalPrice() - ); - } } diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/ValidationResultResponseDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/ValidationResultResponseDto.java index 516d2815..dd9c76b7 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/ValidationResultResponseDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/dto/response/ValidationResultResponseDto.java @@ -1,7 +1,10 @@ package com.fc.shimpyo_be.domain.reservation.dto.response; +import lombok.Builder; + import java.util.List; +@Builder public record ValidationResultResponseDto( boolean isAvailable, List unavailableIds diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/service/ReservationService.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/service/ReservationService.java index 3e633fcc..acdb193a 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservation/service/ReservationService.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/service/ReservationService.java @@ -3,7 +3,6 @@ import com.fc.shimpyo_be.domain.member.entity.Member; import com.fc.shimpyo_be.domain.member.exception.MemberNotFoundException; import com.fc.shimpyo_be.domain.member.repository.MemberRepository; -import com.fc.shimpyo_be.domain.product.entity.Product; import com.fc.shimpyo_be.domain.product.exception.RoomNotFoundException; import com.fc.shimpyo_be.domain.reservation.dto.request.ReleaseRoomItemRequestDto; import com.fc.shimpyo_be.domain.reservation.dto.request.ReleaseRoomsRequestDto; @@ -14,6 +13,7 @@ import com.fc.shimpyo_be.domain.reservation.entity.Reservation; import com.fc.shimpyo_be.domain.reservation.exception.InvalidRequestException; import com.fc.shimpyo_be.domain.reservation.repository.ReservationRepository; +import com.fc.shimpyo_be.domain.reservation.util.ReservationMapper; import com.fc.shimpyo_be.domain.reservationproduct.dto.request.ReservationProductRequestDto; import com.fc.shimpyo_be.domain.reservationproduct.entity.ReservationProduct; import com.fc.shimpyo_be.domain.reservationproduct.repository.ReservationProductRepository; @@ -32,7 +32,6 @@ import org.springframework.util.ObjectUtils; import java.time.LocalDate; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -77,16 +76,16 @@ public SaveReservationResponseDto saveReservation(Long memberId, SaveReservation } // 예약 저장 - Long reservationId - = reservationRepository.save( - Reservation.builder() - .member(member) - .reservationProducts(reservationProducts) - .payMethod(request.payMethod()) - .totalPrice(request.totalPrice()) - .build()).getId(); - - return new SaveReservationResponseDto(reservationId, request); + Reservation reservation = reservationRepository.save( + Reservation.builder() + .member(member) + .reservationProducts(reservationProducts) + .payMethod(request.payMethod()) + .totalPrice(request.totalPrice()) + .build() + ); + + return ReservationMapper.from(reservation); } @Transactional(readOnly = true) @@ -94,35 +93,10 @@ public Page getReservationInfoList(Long memberId, Pa log.info("{} ::: {}", getClass().getSimpleName(), "getReservationInfoList"); List reservationIds = reservationRepository.findIdsByMemberId(memberId); - DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm"); return reservationProductRepository .findAllInReservationIds(reservationIds, pageable) - .map( - reservationProduct -> { - Reservation reservation = reservationProduct.getReservation(); - Room room = reservationProduct.getRoom(); - Product product = room.getProduct(); - - return new ReservationInfoResponseDto( - reservation.getId(), - reservationProduct.getId(), - product.getId(), - product.getName(), - product.getThumbnail(), - product.getAddress().getAddress() + " " + product.getAddress().getDetailAddress(), - room.getId(), - room.getName(), - dateFormatter.format(reservationProduct.getStartDate()), - dateFormatter.format(reservationProduct.getEndDate()), - timeFormatter.format(room.getCheckIn()), - timeFormatter.format(room.getCheckOut()), - reservationProduct.getPrice(), - reservation.getPayMethod().name() - ); - } - ); + .map(ReservationMapper::from); } public ValidationResultResponseDto validate(Long memberId, List reservationProducts) { @@ -137,7 +111,7 @@ public ValidationResultResponseDto validate(Long memberId, List keys = new LinkedList<>(); - while(targetDate.isBefore(endDate)) { + while (targetDate.isBefore(endDate)) { keys.add(String.format(REDIS_ROOM_KEY_FORMAT, reservationProduct.roomId(), targetDate)); targetDate = targetDate.plusDays(1); } @@ -145,12 +119,12 @@ public ValidationResultResponseDto validate(Long memberId, List values = opsForValue.multiGet(keys); String memberIdValue = String.valueOf(memberId); - if(ObjectUtils.isEmpty(values)) { + if (ObjectUtils.isEmpty(values)) { throw new InvalidRequestException(ErrorCode.INVALID_RESERVATION_REQUEST); } for (Object value : values) { - if(!memberIdValue.equals(value)) { + if (!memberIdValue.equals(value)) { isValid = false; invalidRoomIds.add(Long.valueOf((String) value)); break; diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservation/util/ReservationMapper.java b/src/main/java/com/fc/shimpyo_be/domain/reservation/util/ReservationMapper.java new file mode 100644 index 00000000..df48a80f --- /dev/null +++ b/src/main/java/com/fc/shimpyo_be/domain/reservation/util/ReservationMapper.java @@ -0,0 +1,75 @@ +package com.fc.shimpyo_be.domain.reservation.util; + +import com.fc.shimpyo_be.domain.product.entity.Product; +import com.fc.shimpyo_be.domain.reservation.dto.response.ReservationInfoResponseDto; +import com.fc.shimpyo_be.domain.reservation.dto.response.SaveReservationResponseDto; +import com.fc.shimpyo_be.domain.reservation.entity.Reservation; +import com.fc.shimpyo_be.domain.reservationproduct.dto.response.ReservationProductResponseDto; +import com.fc.shimpyo_be.domain.reservationproduct.entity.ReservationProduct; +import com.fc.shimpyo_be.domain.room.entity.Room; +import com.fc.shimpyo_be.global.util.DateTimeUtil; + +import java.util.ArrayList; +import java.util.List; + +public class ReservationMapper { + + public static ReservationInfoResponseDto from(ReservationProduct reservationProduct) { + Reservation reservation = reservationProduct.getReservation(); + Room room = reservationProduct.getRoom(); + Product product = room.getProduct(); + + return ReservationInfoResponseDto.builder() + .reservationId(reservation.getId()) + .reservationProductId(reservationProduct.getId()) + .productId(product.getId()) + .productName(product.getName()) + .productImageUrl(product.getThumbnail()) + .productAddress(product.getAddress().getAddress()) + .productDetailAddress(product.getAddress().getDetailAddress()) + .roomId(room.getId()) + .roomName(room.getName()) + .startDate(DateTimeUtil.toString(reservationProduct.getStartDate())) + .endDate(DateTimeUtil.toString(reservationProduct.getEndDate())) + .checkIn(DateTimeUtil.toString(room.getCheckIn())) + .checkOut(DateTimeUtil.toString(room.getCheckOut())) + .price(reservationProduct.getPrice()) + .payMethod(reservation.getPayMethod().name()) + .createdAt(DateTimeUtil.toString(reservation.getCreatedAt())) + .build(); + } + + public static SaveReservationResponseDto from(Reservation reservation) { + List reservationProductDtos = new ArrayList<>(); + for (ReservationProduct reservationProduct : reservation.getReservationProducts()) { + + Room room = reservationProduct.getRoom(); + Product product = room.getProduct(); + + reservationProductDtos.add( + ReservationProductResponseDto.builder() + .productName(product.getName()) + .roomId(room.getId()) + .roomName(room.getName()) + .standard(room.getStandard()) + .capacity(room.getCapacity()) + .startDate(DateTimeUtil.toString(reservationProduct.getStartDate())) + .endDate(DateTimeUtil.toString(reservationProduct.getEndDate())) + .checkIn(DateTimeUtil.toString(room.getCheckIn())) + .checkOut(DateTimeUtil.toString(room.getCheckOut())) + .visitorName(reservationProduct.getVisitorName()) + .visitorPhone(reservationProduct.getVisitorPhone()) + .price(reservationProduct.getPrice()) + .build() + ); + } + + return SaveReservationResponseDto.builder() + .reservationId(reservation.getId()) + .reservationProducts(reservationProductDtos) + .payMethod(reservation.getPayMethod()) + .totalPrice(reservation.getTotalPrice()) + .createdAt(DateTimeUtil.toString(reservation.getCreatedAt())) + .build(); + } +} diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservationproduct/dto/request/ReservationProductRequestDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservationproduct/dto/request/ReservationProductRequestDto.java index dce3fe8a..3d4b90cc 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservationproduct/dto/request/ReservationProductRequestDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservationproduct/dto/request/ReservationProductRequestDto.java @@ -1,29 +1,18 @@ package com.fc.shimpyo_be.domain.reservationproduct.dto.request; import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; +import lombok.Builder; +@Builder public record ReservationProductRequestDto( @NotNull Long roomId, - @NotBlank - String productName, - @NotBlank - String roomName, - @NotNull - Integer standard, - @NotNull - Integer max, @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "올바른 날짜 형식이 아닙니다.(yyyy-MM-dd 형식으로 입력하세요.)") String startDate, @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "올바른 날짜 형식이 아닙니다.(yyyy-MM-dd 형식으로 입력하세요.)") String endDate, - @Pattern(regexp = "^\\d{2}:\\d{2}$", message = "올바른 시간 형식이 아닙니다.(HH:mm 형식으로 입력하세요.)") - String checkIn, - @Pattern(regexp = "^\\d{2}:\\d{2}$", message = "올바른 시간 형식이 아닙니다.(HH:mm 형식으로 입력하세요.)") - String checkOut, String visitorName, String visitorPhone, @Min(value = 0, message = "객실 이용 금액은 음수일 수 없습니다.") diff --git a/src/main/java/com/fc/shimpyo_be/domain/reservationproduct/dto/response/ReservationProductResponseDto.java b/src/main/java/com/fc/shimpyo_be/domain/reservationproduct/dto/response/ReservationProductResponseDto.java index 7452a5ff..41861df5 100644 --- a/src/main/java/com/fc/shimpyo_be/domain/reservationproduct/dto/response/ReservationProductResponseDto.java +++ b/src/main/java/com/fc/shimpyo_be/domain/reservationproduct/dto/response/ReservationProductResponseDto.java @@ -1,13 +1,14 @@ package com.fc.shimpyo_be.domain.reservationproduct.dto.response; -import com.fc.shimpyo_be.domain.reservationproduct.dto.request.ReservationProductRequestDto; +import lombok.Builder; +@Builder public record ReservationProductResponseDto( - Long roomId, String productName, + Long roomId, String roomName, Integer standard, - Integer max, + Integer capacity, String startDate, String endDate, String checkIn, @@ -16,20 +17,4 @@ public record ReservationProductResponseDto( String visitorPhone, Integer price ) { - public ReservationProductResponseDto(ReservationProductRequestDto requestDto) { - this( - requestDto.roomId(), - requestDto.productName(), - requestDto.roomName(), - requestDto.standard(), - requestDto.max(), - requestDto.startDate(), - requestDto.endDate(), - requestDto.checkIn(), - requestDto.checkOut(), - requestDto.visitorName(), - requestDto.visitorPhone(), - requestDto.price() - ); - } } diff --git a/src/main/java/com/fc/shimpyo_be/global/util/DateTimeUtil.java b/src/main/java/com/fc/shimpyo_be/global/util/DateTimeUtil.java index dfe0921c..5c1c9069 100644 --- a/src/main/java/com/fc/shimpyo_be/global/util/DateTimeUtil.java +++ b/src/main/java/com/fc/shimpyo_be/global/util/DateTimeUtil.java @@ -1,6 +1,7 @@ package com.fc.shimpyo_be.global.util; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; @@ -8,6 +9,7 @@ public class DateTimeUtil { public final static String LOCAL_DATE_PATTERN = "yyyy-MM-dd"; public final static String LOCAL_TIME_PATTERN = "HH:mm"; + public final static String LOCAL_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; public final static String LOCAL_DATE_REGEX_PATTERN = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])"; @@ -24,6 +26,10 @@ public static String toString(LocalTime timeObject) { return timeObject.format(DateTimeFormatter.ofPattern(LOCAL_TIME_PATTERN)); } + public static String toString(LocalDateTime dateTimeObject) { + return dateTimeObject.format(DateTimeFormatter.ofPattern(LOCAL_DATETIME_PATTERN)); + } + public static LocalDate toLocalDate(String dateString) { return LocalDate.parse(dateString, DateTimeFormatter.ofPattern(LOCAL_DATE_PATTERN)); } diff --git a/src/test/java/com/fc/shimpyo_be/config/TestDBCleanerConfig.java b/src/test/java/com/fc/shimpyo_be/config/TestDBCleanerConfig.java index 3dea5b23..31925369 100644 --- a/src/test/java/com/fc/shimpyo_be/config/TestDBCleanerConfig.java +++ b/src/test/java/com/fc/shimpyo_be/config/TestDBCleanerConfig.java @@ -1,9 +1,9 @@ package com.fc.shimpyo_be.config; +import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -@Configuration +@TestConfiguration public class TestDBCleanerConfig { @Bean diff --git a/src/test/java/com/fc/shimpyo_be/domain/reservation/docs/ReservationRestControllerDocsTest.java b/src/test/java/com/fc/shimpyo_be/domain/reservation/docs/ReservationRestControllerDocsTest.java index 4b0c0968..e43d0921 100644 --- a/src/test/java/com/fc/shimpyo_be/domain/reservation/docs/ReservationRestControllerDocsTest.java +++ b/src/test/java/com/fc/shimpyo_be/domain/reservation/docs/ReservationRestControllerDocsTest.java @@ -1,38 +1,16 @@ package com.fc.shimpyo_be.domain.reservation.docs; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.willDoNothing; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; -import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; -import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; -import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; -import static org.springframework.restdocs.snippet.Attributes.key; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - import com.fc.shimpyo_be.config.RestDocsSupport; -import com.fc.shimpyo_be.domain.reservation.dto.request.PreoccupyRoomItemRequestDto; -import com.fc.shimpyo_be.domain.reservation.dto.request.PreoccupyRoomsRequestDto; -import com.fc.shimpyo_be.domain.reservation.dto.request.ReleaseRoomItemRequestDto; -import com.fc.shimpyo_be.domain.reservation.dto.request.ReleaseRoomsRequestDto; -import com.fc.shimpyo_be.domain.reservation.dto.request.SaveReservationRequestDto; +import com.fc.shimpyo_be.domain.reservation.dto.request.*; import com.fc.shimpyo_be.domain.reservation.dto.response.ReservationInfoResponseDto; import com.fc.shimpyo_be.domain.reservation.dto.response.SaveReservationResponseDto; -import com.fc.shimpyo_be.domain.reservation.dto.response.ValidationResultResponseDto; import com.fc.shimpyo_be.domain.reservation.entity.PayMethod; import com.fc.shimpyo_be.domain.reservation.facade.PreoccupyRoomsLockFacade; import com.fc.shimpyo_be.domain.reservation.facade.ReservationLockFacade; import com.fc.shimpyo_be.domain.reservation.service.ReservationService; import com.fc.shimpyo_be.domain.reservationproduct.dto.request.ReservationProductRequestDto; +import com.fc.shimpyo_be.domain.reservationproduct.dto.response.ReservationProductResponseDto; import com.fc.shimpyo_be.global.util.SecurityUtil; -import java.util.ArrayList; -import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; @@ -44,6 +22,22 @@ import org.springframework.restdocs.payload.JsonFieldType; import org.springframework.security.test.context.support.WithMockUser; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; +import static org.springframework.restdocs.snippet.Attributes.key; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + public class ReservationRestControllerDocsTest extends RestDocsSupport { @MockBean @@ -84,24 +78,70 @@ void saveReservation() throws Exception { String requestUrl = "/api/reservations"; SaveReservationRequestDto requestDto - = new SaveReservationRequestDto( - List.of( - new ReservationProductRequestDto( - 1L, "신라호텔", "디럭스 더블1", - 2, 4, "2023-11-20", "2023-11-23", - "13:00", "12:00", - "홍길동", "010-1111-1111", 300000 - ), - new ReservationProductRequestDto( - 3L, "강릉 고즈넉한 펜션", "숲의 방", - 6, 9, "2023-12-10", "2023-12-12", - "13:00", "12:00", - "김갑돌", "010-2222-2222", 150000 + = SaveReservationRequestDto.builder() + .reservationProducts( + List.of( + ReservationProductRequestDto.builder() + .roomId(1L) + .startDate("2023-11-20") + .endDate("2023-11-23") + .visitorName("visitor1") + .visitorPhone("010-1111-1111") + .price(300000) + .build(), + ReservationProductRequestDto.builder() + .roomId(2L) + .startDate("2023-12-10") + .endDate("2023-12-12") + .visitorName("visitor2") + .visitorPhone("010-2222-2222") + .price(150000) + .build() ) - ), PayMethod.CREDIT_CARD, 450000 - ); - - SaveReservationResponseDto responseDto = new SaveReservationResponseDto(1L, requestDto); + ) + .payMethod(PayMethod.CREDIT_CARD) + .totalPrice(450000) + .build(); + + SaveReservationResponseDto responseDto + = SaveReservationResponseDto.builder() + .reservationId(1L) + .reservationProducts( + List.of( + ReservationProductResponseDto.builder() + .productName("숙소1") + .roomId(1L) + .roomName("객실1") + .standard(2) + .capacity(3) + .startDate("2023-11-20") + .endDate("2023-11-23") + .checkIn("13:00") + .checkOut("12:00") + .visitorName("visitor1") + .visitorPhone("010-1111-1111") + .price(300000) + .build(), + ReservationProductResponseDto.builder() + .productName("숙소2") + .roomId(2L) + .roomName("객실2") + .standard(2) + .capacity(3) + .startDate("2023-12-10") + .endDate("2023-12-1") + .checkIn("13:00") + .checkOut("12:00") + .visitorName("visitor2") + .visitorPhone("010-2222-2222") + .price(150000) + .build() + ) + ) + .payMethod(requestDto.payMethod()) + .totalPrice(requestDto.totalPrice()) + .createdAt("2023-12-06 10:30:35") + .build(); given(securityUtil.getCurrentMemberId()).willReturn(1L); given(reservationLockFacade.saveReservation(anyLong(), any(SaveReservationRequestDto.class))) @@ -120,30 +160,12 @@ void saveReservation() throws Exception { fieldWithPath("reservationProducts[].roomId").type(JsonFieldType.NUMBER).description("예약할 객실 식별자") .attributes(key("constraints").value( reservationProductDescriptions.descriptionsForProperty("roomId"))), - fieldWithPath("reservationProducts[].productName").type(JsonFieldType.STRING).description("예약할 숙소명") - .attributes(key("constraints").value( - reservationProductDescriptions.descriptionsForProperty("productName"))), - fieldWithPath("reservationProducts[].roomName").type(JsonFieldType.STRING).description("예약할 객실명") - .attributes(key("constraints").value( - reservationProductDescriptions.descriptionsForProperty("roomName"))), - fieldWithPath("reservationProducts[].standard").type(JsonFieldType.NUMBER).description("객실 기준 인원") - .attributes(key("constraints").value( - reservationProductDescriptions.descriptionsForProperty("standard"))), - fieldWithPath("reservationProducts[].max").type(JsonFieldType.NUMBER).description("객실 최대 인원") - .attributes(key("constraints").value( - reservationProductDescriptions.descriptionsForProperty("max"))), fieldWithPath("reservationProducts[].startDate").type(JsonFieldType.STRING).description("숙박 시작일") .attributes(key("constraints").value( reservationProductDescriptions.descriptionsForProperty("startDate"))), fieldWithPath("reservationProducts[].endDate").type(JsonFieldType.STRING).description("숙박 마지막일") .attributes(key("constraints").value( reservationProductDescriptions.descriptionsForProperty("endDate"))), - fieldWithPath("reservationProducts[].checkIn").type(JsonFieldType.STRING).description("체크인 시간") - .attributes(key("constraints").value( - reservationProductDescriptions.descriptionsForProperty("checkIn"))), - fieldWithPath("reservationProducts[].checkOut").type(JsonFieldType.STRING).description("체크아웃 시간") - .attributes(key("constraints").value( - reservationProductDescriptions.descriptionsForProperty("checkOut"))), fieldWithPath("reservationProducts[].visitorName").type(JsonFieldType.STRING).description("방문자명") .attributes(key("constraints").value( reservationProductDescriptions.descriptionsForProperty("visitorName"))), @@ -165,11 +187,11 @@ void saveReservation() throws Exception { fieldWithPath("data").type(JsonFieldType.OBJECT).description("응답 데이터"), fieldWithPath("data.reservationId").type(JsonFieldType.NUMBER).description("예약 식별자"), fieldWithPath("data.reservationProducts").type(JsonFieldType.ARRAY).description("예약 숙소 리스트"), - fieldWithPath("data.reservationProducts[].roomId").type(JsonFieldType.NUMBER).description("객실 식별자"), fieldWithPath("data.reservationProducts[].productName").type(JsonFieldType.STRING).description("숙소명"), + fieldWithPath("data.reservationProducts[].roomId").type(JsonFieldType.NUMBER).description("객실 식별자"), fieldWithPath("data.reservationProducts[].roomName").type(JsonFieldType.STRING).description("객실명"), fieldWithPath("data.reservationProducts[].standard").type(JsonFieldType.NUMBER).description("기준 인원"), - fieldWithPath("data.reservationProducts[].max").type(JsonFieldType.NUMBER).description("최대 인원"), + fieldWithPath("data.reservationProducts[].capacity").type(JsonFieldType.NUMBER).description("최대 인원"), fieldWithPath("data.reservationProducts[].startDate").type(JsonFieldType.STRING).description("숙박 시작일"), fieldWithPath("data.reservationProducts[].endDate").type(JsonFieldType.STRING).description("숙박 마지막일"), fieldWithPath("data.reservationProducts[].checkIn").type(JsonFieldType.STRING).description("체크인 시간"), @@ -178,8 +200,9 @@ void saveReservation() throws Exception { fieldWithPath("data.reservationProducts[].visitorPhone").type(JsonFieldType.STRING).description("방문자 전화번호"), fieldWithPath("data.reservationProducts[].price").type(JsonFieldType.NUMBER).description("객실 이용 가격"), fieldWithPath("data.payMethod").type(JsonFieldType.STRING).description("결제 수단"), - fieldWithPath("data.totalPrice").type(JsonFieldType.NUMBER).description("총 결제 금액") - ) + fieldWithPath("data.totalPrice").type(JsonFieldType.NUMBER).description("총 결제 금액"), + fieldWithPath("data.createdAt").type(JsonFieldType.STRING).description("예약 주문 시간") + ) ) ); @@ -196,25 +219,27 @@ void getReservationInfoList() throws Exception { int page = 0; PageRequest pageRequest = PageRequest.of(page, size); - List content - = List.of( - new ReservationInfoResponseDto( - 2L, - 3L, - 5L, - "호텔1", - "호텔1 photoUrl", - "호텔1 주소 url", - 1L, - "객실1", - "2023-11-23", - "2023-11-26", - "14:00", - "12:00", - 220000, - "CREDIT_CARD" - ) - ); + List content = + List.of( + ReservationInfoResponseDto.builder() + .reservationId(2L) + .reservationProductId(3L) + .productId(5L) + .productName("호텔1") + .productImageUrl("호텔1 photo URL") + .productAddress("호텔1 주소") + .productDetailAddress("호텔 상세 주소") + .roomId(1L) + .roomName("객실1") + .startDate("2023-11-23") + .endDate("2023-11-26") + .checkIn("14:00") + .checkOut("12:00") + .price(220000) + .payMethod("CREDIT_CARD") + .createdAt("2023-11-20 10:00:00") + .build() + ); given(securityUtil.getCurrentMemberId()).willReturn(1L); given(reservationService.getReservationInfoList(anyLong(), any(Pageable.class))) @@ -242,6 +267,7 @@ void getReservationInfoList() throws Exception { fieldWithPath("data.content.[].productName").type(JsonFieldType.STRING).description("숙소명"), fieldWithPath("data.content.[].productImageUrl").type(JsonFieldType.STRING).description("숙소 대표 이미지 URL"), fieldWithPath("data.content.[].productAddress").type(JsonFieldType.STRING).description("숙소 주소"), + fieldWithPath("data.content.[].productDetailAddress").type(JsonFieldType.STRING).description("숙소 상세 주소"), fieldWithPath("data.content.[].roomId").type(JsonFieldType.NUMBER).description("예약한 객실 식별자"), fieldWithPath("data.content.[].roomName").type(JsonFieldType.STRING).description("객실명"), fieldWithPath("data.content.[].startDate").type(JsonFieldType.STRING).description("숙박 시작일"), @@ -250,6 +276,7 @@ void getReservationInfoList() throws Exception { fieldWithPath("data.content.[].checkOut").type(JsonFieldType.STRING).description("체크아웃 시간"), fieldWithPath("data.content.[].price").type(JsonFieldType.NUMBER).description("결제 금액"), fieldWithPath("data.content.[].payMethod").type(JsonFieldType.STRING).description("결제 수단"), + fieldWithPath("data.content.[].createdAt").type(JsonFieldType.STRING).description("예약 결제 완료 일시"), fieldWithPath("data.pageable.sort.sorted").type(JsonFieldType.BOOLEAN).description("정렬 여부"), fieldWithPath("data.pageable.sort.empty").type(JsonFieldType.BOOLEAN).description("데이터가 비었는지 여부"), @@ -285,16 +312,19 @@ void checkAvailableAndPreoccupy() throws Exception { // given String requestUrl = "/api/reservations/preoccupy"; - PreoccupyRoomsRequestDto requestDto - = new PreoccupyRoomsRequestDto( - List.of( - new PreoccupyRoomItemRequestDto(1L, "2023-12-23", "2023-12-25"), - new PreoccupyRoomItemRequestDto(2L, "2023-11-11", "2023-11-14") - ) - ); - - ValidationResultResponseDto responseDto - = new ValidationResultResponseDto(true, new ArrayList<>()); + PreoccupyRoomsRequestDto requestDto = + PreoccupyRoomsRequestDto.builder() + .rooms( + List.of( + PreoccupyRoomItemRequestDto.builder() + .roomId(1L).startDate("2023-12-23").endDate("2023-12-25") + .build(), + PreoccupyRoomItemRequestDto.builder() + .roomId(2L).startDate("2023-11-11").endDate("2023-11-14") + .build() + ) + ) + .build(); given(securityUtil.getCurrentMemberId()) .willReturn(1L); @@ -338,13 +368,22 @@ void releaseRooms() throws Exception { // given String requestUrl = "/api/reservations/release"; - ReleaseRoomsRequestDto requestDto = new ReleaseRoomsRequestDto( - List.of( - new ReleaseRoomItemRequestDto(1L, "2023-12-23", "2023-12-25"), - new ReleaseRoomItemRequestDto(2L, "2023-11-11", "2023-11-14"), - new ReleaseRoomItemRequestDto(3L, "2023-11-15", "2023-11-16") - ) - ); + ReleaseRoomsRequestDto requestDto = + ReleaseRoomsRequestDto.builder() + .rooms( + List.of( + ReleaseRoomItemRequestDto.builder() + .roomId(1L).startDate("2023-12-23").endDate("2023-12-25") + .build(), + ReleaseRoomItemRequestDto.builder() + .roomId(2L).startDate("2023-11-11").endDate("2023-11-14") + .build(), + ReleaseRoomItemRequestDto.builder() + .roomId(3L).startDate("2023-11-15").endDate("2023-11-16") + .build() + ) + ) + .build(); given(securityUtil.getCurrentMemberId()) .willReturn(1L); diff --git a/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/controller/ReservationRestControllerTest.java b/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/controller/ReservationRestControllerTest.java index cf317db2..efbdc1c1 100644 --- a/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/controller/ReservationRestControllerTest.java +++ b/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/controller/ReservationRestControllerTest.java @@ -5,12 +5,12 @@ import com.fc.shimpyo_be.domain.reservation.dto.request.*; import com.fc.shimpyo_be.domain.reservation.dto.response.ReservationInfoResponseDto; import com.fc.shimpyo_be.domain.reservation.dto.response.SaveReservationResponseDto; -import com.fc.shimpyo_be.domain.reservation.dto.response.ValidationResultResponseDto; import com.fc.shimpyo_be.domain.reservation.entity.PayMethod; import com.fc.shimpyo_be.domain.reservation.facade.PreoccupyRoomsLockFacade; import com.fc.shimpyo_be.domain.reservation.facade.ReservationLockFacade; import com.fc.shimpyo_be.domain.reservation.service.ReservationService; import com.fc.shimpyo_be.domain.reservationproduct.dto.request.ReservationProductRequestDto; +import com.fc.shimpyo_be.domain.reservationproduct.dto.response.ReservationProductResponseDto; import com.fc.shimpyo_be.global.util.SecurityUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -27,7 +27,6 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import java.util.ArrayList; import java.util.List; import static org.hamcrest.Matchers.is; @@ -78,18 +77,70 @@ void saveReservation_Api_test() throws Exception { String requestUrl = "/api/reservations"; SaveReservationRequestDto requestDto - = new SaveReservationRequestDto( - List.of( - getReservationProductRequestData( - 1L, "2023-11-20", "2023-11-23", - "visitor1", "010-1111-1111", 150000), - getReservationProductRequestData( - 2L, "2023-11-18", "2023-11-20", - "visitor2", "010-2222-2222", 200000) - ), PayMethod.CREDIT_CARD, 350000 - ); + = SaveReservationRequestDto.builder() + .reservationProducts( + List.of( + ReservationProductRequestDto.builder() + .roomId(1L) + .startDate("2023-11-20") + .endDate("2023-11-23") + .visitorName("visitor1") + .visitorPhone("010-1111-1111") + .price(300000) + .build(), + ReservationProductRequestDto.builder() + .roomId(3L) + .startDate("2023-12-10") + .endDate("2023-12-12") + .visitorName("visitor2") + .visitorPhone("010-2222-2222") + .price(150000) + .build() + ) + ) + .payMethod(PayMethod.CREDIT_CARD) + .totalPrice(450000) + .build(); - SaveReservationResponseDto responseDto = new SaveReservationResponseDto(1L, requestDto); + SaveReservationResponseDto responseDto = + SaveReservationResponseDto.builder() + .reservationId(1L) + .reservationProducts( + List.of( + ReservationProductResponseDto.builder() + .productName("숙소1") + .roomId(1L) + .roomName("객실1") + .standard(2) + .capacity(3) + .startDate("2023-11-20") + .endDate("2023-11-23") + .checkIn("13:00") + .checkOut("12:00") + .visitorName("visitor1") + .visitorPhone("010-1111-1111") + .price(300000) + .build(), + ReservationProductResponseDto.builder() + .productName("숙소2") + .roomId(3L) + .roomName("객실3") + .standard(2) + .capacity(3) + .startDate("2023-12-10") + .endDate("2023-12-12") + .checkIn("13:00") + .checkOut("12:00") + .visitorName("visitor2") + .visitorPhone("010-2222-2222") + .price(150000) + .build() + ) + ) + .payMethod(requestDto.payMethod()) + .totalPrice(requestDto.totalPrice()) + .createdAt("2023-12-06 10:30:35") + .build(); given(securityUtil.getCurrentMemberId()).willReturn(1L); given(reservationLockFacade.saveReservation(anyLong(), any(SaveReservationRequestDto.class))) @@ -118,22 +169,24 @@ void getReservationInfoList_Api_test() throws Exception { PageRequest pageRequest = PageRequest.of(page, size); List content = List.of( - new ReservationInfoResponseDto( - 2L, - 3L, - 5L, - "호텔2", - "호텔 photoUrl", - "호텔 주소 url", - 1L, - "객실1", - "2023-11-23", - "2023-11-26", - "14:00", - "12:00", - 220000, - "CREDIT_CARD" - ) + ReservationInfoResponseDto.builder() + .reservationId(2L) + .reservationProductId(3L) + .productId(5L) + .productName("호텔1") + .productImageUrl("호텔1 photo URL") + .productAddress("호텔1 주소") + .productDetailAddress("호텔 상세 주소") + .roomId(1L) + .roomName("객실1") + .startDate("2023-11-23") + .endDate("2023-11-26") + .checkIn("14:00") + .checkOut("12:00") + .price(220000) + .payMethod("CREDIT_CARD") + .createdAt("2023-11-20 10:00:00") + .build() ); given(securityUtil.getCurrentMemberId()).willReturn(1L); @@ -158,16 +211,23 @@ void checkAvailableAndPreoccupy_test() throws Exception { // given String requestUrl = "/api/reservations/preoccupy"; - PreoccupyRoomsRequestDto requestDto - = new PreoccupyRoomsRequestDto( - List.of( - new PreoccupyRoomItemRequestDto(1L, "2023-12-23", "2023-12-25"), - new PreoccupyRoomItemRequestDto(2L, "2023-11-11", "2023-11-14") + PreoccupyRoomsRequestDto requestDto = + PreoccupyRoomsRequestDto.builder() + .rooms( + List.of( + PreoccupyRoomItemRequestDto.builder() + .roomId(1L) + .startDate("2023-12-23") + .endDate("2023-12-25") + .build(), + PreoccupyRoomItemRequestDto.builder() + .roomId(2L) + .startDate("2023-11-11") + .endDate("2023-11-14") + .build() + ) ) - ); - - ValidationResultResponseDto responseDto - = new ValidationResultResponseDto(true, new ArrayList<>()); + .build(); given(securityUtil.getCurrentMemberId()) .willReturn(1L); @@ -177,10 +237,10 @@ void checkAvailableAndPreoccupy_test() throws Exception { // when & then mockMvc.perform( - post(requestUrl) - .content(objectMapper.writeValueAsString(requestDto)) - .contentType(MediaType.APPLICATION_JSON) - ) + post(requestUrl) + .content(objectMapper.writeValueAsString(requestDto)) + .contentType(MediaType.APPLICATION_JSON) + ) .andExpect(status().isOk()) .andExpect(jsonPath("$.data").isEmpty()); } @@ -192,18 +252,25 @@ void checkAvailableAndPreoccupy_size_validation_error_test() throws Exception { // given String requestUrl = "/api/reservations/preoccupy"; - PreoccupyRoomsRequestDto requestDto - = new PreoccupyRoomsRequestDto( - List.of( - new PreoccupyRoomItemRequestDto(1L, "2023-12-23", "2023-12-25"), - new PreoccupyRoomItemRequestDto(2L, "2023-11-11", "2023-11-14"), - new PreoccupyRoomItemRequestDto(3L, "2023-11-11", "2023-11-14"), - new PreoccupyRoomItemRequestDto(4L, "2023-11-11", "2023-11-14") - ) - ); - - ValidationResultResponseDto responseDto - = new ValidationResultResponseDto(true, new ArrayList<>()); + PreoccupyRoomsRequestDto requestDto = + PreoccupyRoomsRequestDto.builder() + .rooms( + List.of( + PreoccupyRoomItemRequestDto.builder() + .roomId(1L).startDate("2023-12-23").endDate("2023-12-25") + .build(), + PreoccupyRoomItemRequestDto.builder() + .roomId(2L).startDate("2023-11-11").endDate("2023-11-14") + .build(), + PreoccupyRoomItemRequestDto.builder() + .roomId(3L).startDate("2023-11-11").endDate("2023-11-14") + .build(), + PreoccupyRoomItemRequestDto.builder() + .roomId(4L).startDate("2023-11-16").endDate("2023-11-18") + .build() + ) + ) + .build(); given(securityUtil.getCurrentMemberId()) .willReturn(1L); @@ -228,17 +295,22 @@ void checkAvailableAndPreoccupy_localdate_validation_error_test() throws Excepti // given String requestUrl = "/api/reservations/preoccupy"; - PreoccupyRoomsRequestDto requestDto - = new PreoccupyRoomsRequestDto( - List.of( - new PreoccupyRoomItemRequestDto(1L, "202-12-23", "2023-12-25"), - new PreoccupyRoomItemRequestDto(2L, "2023-11-11", "2023-11-14"), - new PreoccupyRoomItemRequestDto(3L, "2023-11-11", "2023-11-14") - ) - ); - - ValidationResultResponseDto responseDto - = new ValidationResultResponseDto(true, new ArrayList<>()); + PreoccupyRoomsRequestDto requestDto = + PreoccupyRoomsRequestDto.builder() + .rooms( + List.of( + PreoccupyRoomItemRequestDto.builder() + .roomId(1L).startDate("202-12-23").endDate("2023-12-25") + .build(), + PreoccupyRoomItemRequestDto.builder() + .roomId(2L).startDate("2023-11-11").endDate("2023-11-14") + .build(), + PreoccupyRoomItemRequestDto.builder() + .roomId(3L).startDate("2023-11-11").endDate("2023-11-14") + .build() + ) + ) + .build(); given(securityUtil.getCurrentMemberId()) .willReturn(1L); @@ -263,13 +335,22 @@ void releaseRooms_test() throws Exception { // given String requestUrl = "/api/reservations/release"; - ReleaseRoomsRequestDto requestDto = new ReleaseRoomsRequestDto( - List.of( - new ReleaseRoomItemRequestDto(1L, "2023-12-23", "2023-12-25"), - new ReleaseRoomItemRequestDto(2L, "2023-11-11", "2023-11-14"), - new ReleaseRoomItemRequestDto(3L, "2023-11-15", "2023-11-16") - ) - ); + ReleaseRoomsRequestDto requestDto = + ReleaseRoomsRequestDto.builder() + .rooms( + List.of( + ReleaseRoomItemRequestDto.builder() + .roomId(1L).startDate("2023-12-23").endDate("2023-12-25") + .build(), + ReleaseRoomItemRequestDto.builder() + .roomId(2L).startDate("2023-11-11").endDate("2023-11-14") + .build(), + ReleaseRoomItemRequestDto.builder() + .roomId(3L).startDate("2023-11-15").endDate("2023-11-16") + .build() + ) + ) + .build(); given(securityUtil.getCurrentMemberId()) .willReturn(1L); @@ -287,29 +368,4 @@ void releaseRooms_test() throws Exception { .andExpect(jsonPath("$.code", is(200))) .andExpect(jsonPath("$.data").isEmpty()); } - - private ReservationProductRequestDto getReservationProductRequestData( - long roomId, - String startDate, - String endDate, - String visitorName, - String visitorPhone, - Integer price - ) { - String defaultValue = "DEFAULT_VALUE"; - return new ReservationProductRequestDto( - roomId, - defaultValue, - defaultValue, - 2, - 4, - startDate, - endDate, - "13:00", - "12:00", - visitorName, - visitorPhone, - price - ); - } } diff --git a/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/facade/ReservationLockFacadeTest.java b/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/facade/ReservationLockFacadeTest.java index 458b60ee..dd45f9a4 100644 --- a/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/facade/ReservationLockFacadeTest.java +++ b/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/facade/ReservationLockFacadeTest.java @@ -68,36 +68,47 @@ void saveReservation_test() throws InterruptedException { SaveReservationRequestDto request1 = new SaveReservationRequestDto( List.of( - getReservationProductRequestData(2L, "2023-11-20", "2023-11-23"), - getReservationProductRequestData(3L, "2023-11-24", "2023-11-26") + new ReservationProductRequestDto(2L, "2023-11-20", "2023-11-23", + "visitor1", "010-1111-1111", 100000), + new ReservationProductRequestDto(3L, "2023-11-24", "2023-11-26", + "visitor2", "010-2222-2222", 150000) ), PayMethod.KAKAO_PAY, 250000 ); SaveReservationRequestDto request2 = new SaveReservationRequestDto( - List.of(getReservationProductRequestData(4L, "2023-10-10", "2023-10-14")), + List.of(new ReservationProductRequestDto(4L, "2023-10-10", "2023-10-14", + "visitor3", "010-3333-3333", 125000)), PayMethod.CREDIT_CARD, 125000 ); SaveReservationRequestDto request3 = new SaveReservationRequestDto( List.of( - getReservationProductRequestData(2L, "2023-11-10", "2023-11-14"), - getReservationProductRequestData(5L, "2023-10-17", "2023-10-20"), - getReservationProductRequestData(3L, "2023-10-10", "2023-10-14") + new ReservationProductRequestDto(2L, "2023-11-10", "2023-11-14", + "visitor", "010-1111-1111", 90000), + new ReservationProductRequestDto(5L, "2023-10-17", "2023-10-20", + "visitor", "010-1111-1111", 110000), + new ReservationProductRequestDto(3L, "2023-10-10", "2023-10-14", + "visitor", "010-1111-1111", 100000) ), PayMethod.NAVER_PAY, 300000 ); SaveReservationRequestDto request4 = new SaveReservationRequestDto( List.of( - getReservationProductRequestData(4L, "2023-10-05", "2023-10-07"), - getReservationProductRequestData(5L, "2023-10-10", "2023-10-14") - ), PayMethod.KAKAO_PAY, 250000 + new ReservationProductRequestDto(4L, "2023-10-05", "2023-10-07", + "visitor", "010-1111-1111", 125000), + new ReservationProductRequestDto(5L, "2023-10-10", "2023-10-14", + "visitor", "010-1111-1111", 125000) + ), PayMethod.KAKAO_PAY, 250000 ); SaveReservationRequestDto request5 = new SaveReservationRequestDto( List.of( - getReservationProductRequestData(1L, "2023-10-10", "2023-10-14"), - getReservationProductRequestData(2L, "2023-12-11", "2023-12-15"), - getReservationProductRequestData(4L, "2023-11-11", "2023-11-14") + new ReservationProductRequestDto(1L, "2023-10-10", "2023-10-14", + "visitor4", "010-4444-4444", 150000), + new ReservationProductRequestDto(2L, "2023-12-11", "2023-12-15", + "visitor4", "010-4444-4444", 150000), + new ReservationProductRequestDto(4L, "2023-11-11", "2023-11-14", + "visitor4", "010-4444-4444", 100000) ), PayMethod.PAYPAL, 400000 ); @@ -189,22 +200,4 @@ private void saveRedisData(long memberId, long roomId, LocalDate start, LocalDat start = start.plusDays(1); } } - - private ReservationProductRequestDto getReservationProductRequestData(long roomId, String startDate, String endDate) { - String defaultValue = "DEFAULT_VALUE"; - return new ReservationProductRequestDto( - roomId, - defaultValue, - defaultValue, - 2, - 4, - startDate, - endDate, - defaultValue, - defaultValue, - defaultValue, - defaultValue, - 100000 - ); - } } diff --git a/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/service/GetReservationListServiceTest.java b/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/service/GetReservationListServiceTest.java index f6790dd9..c94bd3e7 100644 --- a/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/service/GetReservationListServiceTest.java +++ b/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/service/GetReservationListServiceTest.java @@ -2,6 +2,7 @@ import com.fc.shimpyo_be.config.AbstractContainersSupport; import com.fc.shimpyo_be.config.DatabaseCleanUp; +import com.fc.shimpyo_be.config.TestDBCleanerConfig; import com.fc.shimpyo_be.domain.member.entity.Authority; import com.fc.shimpyo_be.domain.member.entity.Member; import com.fc.shimpyo_be.domain.member.repository.MemberRepository; @@ -23,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -35,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; @Slf4j +@Import(TestDBCleanerConfig.class) @SpringBootTest public class GetReservationListServiceTest extends AbstractContainersSupport { diff --git a/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/service/ReservationServiceTest.java b/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/service/ReservationServiceTest.java index 429f5f80..0cd4d610 100644 --- a/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/service/ReservationServiceTest.java +++ b/src/test/java/com/fc/shimpyo_be/domain/reservation/unit/service/ReservationServiceTest.java @@ -1,215 +1,251 @@ package com.fc.shimpyo_be.domain.reservation.unit.service; +import com.fc.shimpyo_be.config.AbstractContainersSupport; +import com.fc.shimpyo_be.config.DatabaseCleanUp; +import com.fc.shimpyo_be.config.TestDBCleanerConfig; import com.fc.shimpyo_be.domain.member.entity.Authority; import com.fc.shimpyo_be.domain.member.entity.Member; import com.fc.shimpyo_be.domain.member.exception.MemberNotFoundException; import com.fc.shimpyo_be.domain.member.repository.MemberRepository; +import com.fc.shimpyo_be.domain.product.entity.*; import com.fc.shimpyo_be.domain.product.exception.RoomNotFoundException; +import com.fc.shimpyo_be.domain.product.repository.ProductRepository; import com.fc.shimpyo_be.domain.reservation.dto.request.SaveReservationRequestDto; import com.fc.shimpyo_be.domain.reservation.dto.response.SaveReservationResponseDto; import com.fc.shimpyo_be.domain.reservation.entity.PayMethod; -import com.fc.shimpyo_be.domain.reservation.entity.Reservation; -import com.fc.shimpyo_be.domain.reservation.repository.ReservationRepository; import com.fc.shimpyo_be.domain.reservation.service.ReservationService; import com.fc.shimpyo_be.domain.reservationproduct.dto.request.ReservationProductRequestDto; -import com.fc.shimpyo_be.domain.reservationproduct.repository.ReservationProductRepository; import com.fc.shimpyo_be.domain.room.entity.Room; +import com.fc.shimpyo_be.domain.room.entity.RoomOption; import com.fc.shimpyo_be.domain.room.entity.RoomPrice; import com.fc.shimpyo_be.domain.room.repository.RoomRepository; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import java.time.LocalTime; +import java.util.ArrayList; import java.util.List; -import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.willThrow; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; -@ExtendWith(MockitoExtension.class) -public class ReservationServiceTest { +@Slf4j +@Import(TestDBCleanerConfig.class) +@SpringBootTest +public class ReservationServiceTest extends AbstractContainersSupport { - @InjectMocks + @Autowired private ReservationService reservationService; - @Mock - private ReservationRepository reservationRepository; - - @Mock - private ReservationProductRepository reservationProductRepository; - - @Mock + @Autowired private MemberRepository memberRepository; - @Mock + @Autowired + private ProductRepository productRepository; + + @Autowired private RoomRepository roomRepository; - @Mock - private RedisTemplate redisTemplate; + @Autowired + private DatabaseCleanUp databaseCleanUp; + + private Member member; + + private final String[] tableNameArray = { + "member", "product", "room", "product_option", "address", "room_option", "amenity" + }; + + @BeforeEach + void setUp() { + databaseCleanUp.cleanUp(tableNameArray); - private final Member member - = Member.builder() - .id(1L) - .name("member") - .password("password") - .authority(Authority.ROLE_USER) - .photoUrl("photoUrl") - .email("email") - .build(); + member = memberRepository.save( + Member.builder() + .email("member@email.com") + .name("member") + .password("password") + .photoUrl("member photo url") + .authority(Authority.ROLE_USER) + .build() + ); + + List products = new ArrayList<>(); + for (int i = 1; i <= 3; i++) { + String productName = "호텔" + i; + float starAvg = ThreadLocalRandom.current().nextFloat(0, 5); + String infoCenter = String.format("02-1234-%d%d%d%d", i, i, i, i); + products.add( + productRepository.save( + Product.builder() + .name(productName) + .thumbnail(productName + " 썸네일 url") + .description(productName + " 설명") + .starAvg(starAvg) + .category(Category.TOURIST_HOTEL) + .address( + Address.builder() + .address(productName + " 주소") + .detailAddress(productName + " 상세 주소") + .mapX(1.0) + .mapY(1.5) + .build() + ) + .productOption( + ProductOption.builder() + .cooking(true) + .foodPlace("음료 가능") + .parking(true) + .pickup(false) + .infoCenter(infoCenter) + .build() + ) + .amenity( + Amenity.builder() + .barbecue(false) + .beauty(true) + .beverage(true) + .fitness(true) + .bicycle(false) + .campfire(false) + .karaoke(true) + .publicBath(true) + .publicPc(true) + .seminar(false) + .sports(false) + .build() + ) + .build() + ) + ); + } + + List rooms = new ArrayList<>(); + for (int i = 1; i <= 3; i++) { + String roomName = "객실" + i; + rooms.add( + roomRepository.save( + Room.builder() + .product(products.get(i - 1)) + .name(roomName) + .description(roomName + " 설명") + .standard(2) + .capacity(4) + .checkIn(LocalTime.of(14, 0)) + .checkOut(LocalTime.of(12, 0)) + .price( + RoomPrice.builder() + .offWeekDaysMinFee(75000) + .offWeekendMinFee(85000) + .peakWeekDaysMinFee(100000) + .peakWeekendMinFee(120000) + .build() + ) + .roomOption( + RoomOption.builder() + .cooking(true) + .airCondition(true) + .bath(true) + .bathFacility(true) + .pc(false) + .diningTable(true) + .hairDryer(true) + .homeTheater(false) + .internet(true) + .cable(false) + .refrigerator(true) + .sofa(true) + .toiletries(true) + .tv(true) + .build() + ) + .build() + ) + ); + } + } @DisplayName("정상적으로 예약을 저장할 수 있다.") @Test void saveReservation_test() { //given - long memberId = 1L; + long memberId = member.getId(); long roomId1 = 1L; long roomId2 = 2L; - Room room = Room.builder() - .id(1L) - .name("room1") - .description("description") - .price(RoomPrice.builder() - .offWeekDaysMinFee(50000) - .offWeekendMinFee(60000) - .peakWeekDaysMinFee(100000) - .peakWeekendMinFee(110000) - .build()) - .build(); - SaveReservationRequestDto requestDto = new SaveReservationRequestDto( List.of( - getReservationProductRequestData( + new ReservationProductRequestDto( roomId1, "2023-11-20", "2023-11-23", "visitor1", "010-1111-1111", 150000), - getReservationProductRequestData( - roomId2, "2023-11-18", "2023-11-20", - "visitor2", "010-2222-2222", 200000) + new ReservationProductRequestDto( + roomId2, "2023-11-26", "2023-11-30", + "visitor1", "010-1111-1111", 200000 + ) ), PayMethod.CREDIT_CARD, 350000 ); - Reservation reservation = Reservation.builder() - .id(1L) - .totalPrice(150000) - .payMethod(PayMethod.CREDIT_CARD) - .build(); - - given(memberRepository.findById(anyLong())) - .willReturn(Optional.of(member)); - given(roomRepository.findById(anyLong())) - .willReturn(Optional.of(room)); - given(reservationRepository.save(any(Reservation.class))) - .willReturn(reservation); - //when SaveReservationResponseDto result = reservationService.saveReservation(memberId, requestDto); //then assertThat(result.reservationId()).isNotNull(); - - verify(memberRepository, times(1)).findById(anyLong()); - verify(roomRepository, times(2)).findById(anyLong()); - verify(reservationRepository, times(1)).save(any(Reservation.class)); + assertThat(result.reservationProducts()).hasSize(2); } @DisplayName("회원이 존재하지 않으면 예약을 저장할 수 없다.") @Test void saveReservation_memberNotFound_test() { //given - long memberId = 1L; + long memberId = 1000L; long roomId1 = 1L; long roomId2 = 2L; SaveReservationRequestDto requestDto = new SaveReservationRequestDto( List.of( - getReservationProductRequestData( + new ReservationProductRequestDto( roomId1, "2023-11-20", "2023-11-23", "visitor1", "010-1111-1111", 150000), - getReservationProductRequestData( + new ReservationProductRequestDto( roomId2, "2023-11-18", "2023-11-20", "visitor2", "010-2222-2222", 200000) ), PayMethod.CREDIT_CARD, 350000 ); - willThrow(MemberNotFoundException.class) - .given(memberRepository).findById(anyLong()); - //when & then assertThatThrownBy(() -> reservationService.saveReservation(memberId, requestDto)) .isInstanceOf(MemberNotFoundException.class); - - verify(memberRepository, times(1)).findById(anyLong()); - verify(roomRepository, times(0)).findById(anyLong()); - verify(reservationRepository, times(0)).save(any(Reservation.class)); } @DisplayName("객실 정보가 존재하지 않으면 예약을 저장할 수 없다.") @Test void saveReservation_roomNotFound_test() { //given - long memberId = 1L; + long memberId = member.getId(); long roomId1 = 1L; - long roomId2 = 2L; + long roomId2 = 2000L; SaveReservationRequestDto requestDto = new SaveReservationRequestDto( List.of( - getReservationProductRequestData( + new ReservationProductRequestDto( roomId1, "2023-11-20", "2023-11-23", "visitor1", "010-1111-1111", 150000), - getReservationProductRequestData( + new ReservationProductRequestDto( roomId2, "2023-11-18", "2023-11-20", "visitor2", "010-2222-2222", 200000) ), PayMethod.CREDIT_CARD, 350000 ); - given(memberRepository.findById(anyLong())) - .willReturn(Optional.of(member)); - willThrow(RoomNotFoundException.class) - .given(roomRepository).findById(anyLong()); - //when & then assertThatThrownBy(() -> reservationService.saveReservation(memberId, requestDto)) .isInstanceOf(RoomNotFoundException.class); - - verify(memberRepository, times(1)).findById(anyLong()); - verify(roomRepository, times(1)).findById(anyLong()); - verify(reservationRepository, times(0)).save(any(Reservation.class)); - } - - private ReservationProductRequestDto getReservationProductRequestData( - long roomId, - String startDate, - String endDate, - String visitorName, - String visitorPhone, - Integer price - ) { - String defaultValue = "DEFAULT_VALUE"; - return new ReservationProductRequestDto( - roomId, - defaultValue, - defaultValue, - 2, - 4, - startDate, - endDate, - defaultValue, - defaultValue, - visitorName, - visitorPhone, - price - ); } }