-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #96 from Shimpyo-House/feature/get-rooms
refactor: 주문/결제페이지 객실 정보 조회 기능 개발
- Loading branch information
Showing
14 changed files
with
737 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/main/java/com/fc/shimpyo_be/domain/room/controller/RoomRestController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.fc.shimpyo_be.domain.room.controller; | ||
|
||
import com.fc.shimpyo_be.domain.room.dto.request.GetRoomListWithProductInfoRequestDto; | ||
import com.fc.shimpyo_be.domain.room.dto.response.RoomListWithProductInfoResponseDto; | ||
import com.fc.shimpyo_be.domain.room.service.RoomService; | ||
import com.fc.shimpyo_be.global.common.ResponseDto; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
@RequestMapping("/api/rooms") | ||
@RestController | ||
public class RoomRestController { | ||
|
||
private final RoomService roomService; | ||
|
||
@GetMapping | ||
public ResponseEntity<ResponseDto<RoomListWithProductInfoResponseDto>> getRoomsWithProductInfo( | ||
@Valid @RequestBody GetRoomListWithProductInfoRequestDto request | ||
) { | ||
log.debug("GET /api/rooms, roomIds : {}", request.roomIds()); | ||
return ResponseEntity | ||
.status(HttpStatus.OK) | ||
.body( | ||
ResponseDto.res( | ||
HttpStatus.OK, | ||
new RoomListWithProductInfoResponseDto( | ||
roomService.getRoomsWithProductInfo(request.roomIds()) | ||
), | ||
"숙소 정보를 포함한 객실 정보 리스트가 정상적으로 조회되었습니다." | ||
) | ||
); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
.../java/com/fc/shimpyo_be/domain/room/dto/request/GetRoomListWithProductInfoRequestDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.fc.shimpyo_be.domain.room.dto.request; | ||
|
||
import jakarta.validation.constraints.Size; | ||
import lombok.Builder; | ||
|
||
import java.util.List; | ||
|
||
@Builder | ||
public record GetRoomListWithProductInfoRequestDto( | ||
@Size(min = 1, max = 3, message = "최소 1개, 최대 3개의 객실 식별자 정보가 필요합니다.") | ||
List<Long> roomIds | ||
) { | ||
} |
11 changes: 11 additions & 0 deletions
11
...n/java/com/fc/shimpyo_be/domain/room/dto/response/RoomListWithProductInfoResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.fc.shimpyo_be.domain.room.dto.response; | ||
|
||
import lombok.Builder; | ||
|
||
import java.util.List; | ||
|
||
@Builder | ||
public record RoomListWithProductInfoResponseDto( | ||
List<RoomWithProductResponseDto> rooms | ||
) { | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/com/fc/shimpyo_be/domain/room/dto/response/RoomWithProductResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.fc.shimpyo_be.domain.room.dto.response; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record RoomWithProductResponseDto( | ||
Long productId, | ||
String productName, | ||
String productThumbnail, | ||
String productAddress, | ||
String productDetailAddress, | ||
Long roomId, | ||
String roomName, | ||
Integer standard, | ||
Integer capacity, | ||
String checkIn, | ||
String checkOut, | ||
Long price | ||
) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/main/java/com/fc/shimpyo_be/domain/room/repository/RoomRepositoryCustom.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.fc.shimpyo_be.domain.room.repository; | ||
|
||
import com.fc.shimpyo_be.domain.room.entity.Room; | ||
|
||
import java.util.List; | ||
|
||
public interface RoomRepositoryCustom { | ||
|
||
List<Room> findAllInIdsWithProductAndPrice(List<Long> roomIds); | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/fc/shimpyo_be/domain/room/repository/RoomRepositoryImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.fc.shimpyo_be.domain.room.repository; | ||
|
||
import com.fc.shimpyo_be.domain.room.entity.Room; | ||
import com.querydsl.jpa.impl.JPAQueryFactory; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
import java.util.List; | ||
|
||
import static com.fc.shimpyo_be.domain.product.entity.QProduct.product; | ||
import static com.fc.shimpyo_be.domain.room.entity.QRoom.room; | ||
import static com.fc.shimpyo_be.domain.room.entity.QRoomPrice.roomPrice; | ||
|
||
@RequiredArgsConstructor | ||
public class RoomRepositoryImpl implements RoomRepositoryCustom { | ||
|
||
private final JPAQueryFactory jpaQueryFactory; | ||
|
||
@Override | ||
public List<Room> findAllInIdsWithProductAndPrice(List<Long> roomIds) { | ||
return jpaQueryFactory.selectFrom(room) | ||
.join(room.product, product).fetchJoin() | ||
.join(room.price, roomPrice).fetchJoin() | ||
.where(room.id.in(roomIds)) | ||
.fetch(); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/com/fc/shimpyo_be/domain/room/service/RoomService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.fc.shimpyo_be.domain.room.service; | ||
|
||
import com.fc.shimpyo_be.domain.room.dto.response.RoomWithProductResponseDto; | ||
import com.fc.shimpyo_be.domain.room.repository.RoomRepository; | ||
import com.fc.shimpyo_be.domain.room.util.RoomMapper; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.List; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
@Service | ||
public class RoomService { | ||
|
||
private final RoomRepository roomRepository; | ||
|
||
@Transactional(readOnly = true) | ||
public List<RoomWithProductResponseDto> getRoomsWithProductInfo(List<Long> roomIds) { | ||
log.debug("{} ::: {}", getClass().getSimpleName(), "getRoomsWithProductInfo"); | ||
|
||
return roomRepository.findAllInIdsWithProductAndPrice(roomIds) | ||
.stream() | ||
.map(RoomMapper::toRoomWithProductResponse) | ||
.toList(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
src/test/java/com/fc/shimpyo_be/domain/room/docs/RoomRestControllerDocsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package com.fc.shimpyo_be.domain.room.docs; | ||
|
||
import com.fc.shimpyo_be.config.RestDocsSupport; | ||
import com.fc.shimpyo_be.domain.room.dto.request.GetRoomListWithProductInfoRequestDto; | ||
import com.fc.shimpyo_be.domain.room.dto.response.RoomWithProductResponseDto; | ||
import com.fc.shimpyo_be.domain.room.service.RoomService; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.restdocs.constraints.ConstraintDescriptions; | ||
import org.springframework.restdocs.payload.JsonFieldType; | ||
import org.springframework.security.test.context.support.WithMockUser; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.List; | ||
|
||
import static org.mockito.BDDMockito.given; | ||
import static org.mockito.Mockito.times; | ||
import static org.mockito.Mockito.verify; | ||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; | ||
import static org.springframework.restdocs.payload.PayloadDocumentation.*; | ||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; | ||
import static org.springframework.restdocs.snippet.Attributes.key; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
|
||
public class RoomRestControllerDocsTest extends RestDocsSupport { | ||
|
||
@MockBean | ||
private RoomService roomService; | ||
|
||
private final ConstraintDescriptions getRoomListWithProductInfoDescriptions | ||
= new ConstraintDescriptions(GetRoomListWithProductInfoRequestDto.class); | ||
|
||
@WithMockUser(roles = "USER") | ||
@DisplayName("getRoomsWithProductInfo()는 숙소 정보를 포함한 객실 정보 리스트를 조회할 수 있다.") | ||
@Test | ||
void getRoomsWithProductInfo() throws Exception { | ||
//given | ||
String requestUrl = "/api/rooms"; | ||
List<Long> roomIds = List.of(1L, 3L, 4L); | ||
GetRoomListWithProductInfoRequestDto requestDto = new GetRoomListWithProductInfoRequestDto(roomIds); | ||
|
||
List<RoomWithProductResponseDto> rooms = List.of( | ||
RoomWithProductResponseDto.builder() | ||
.productId(1L) | ||
.productName("호텔1") | ||
.productThumbnail("호텔1 썸네일") | ||
.productAddress("호텔1 주소") | ||
.productDetailAddress("호텔1 상세 주소") | ||
.roomId(1L) | ||
.roomName("객실1") | ||
.standard(2) | ||
.capacity(4) | ||
.checkIn("14:00") | ||
.checkOut("12:00") | ||
.price(80000L) | ||
.build(), | ||
RoomWithProductResponseDto.builder() | ||
.productId(2L) | ||
.productName("호텔2") | ||
.productThumbnail("호텔2 썸네일") | ||
.productAddress("호텔2 주소") | ||
.productDetailAddress("호텔2 상세 주소") | ||
.roomId(3L) | ||
.roomName("객실3") | ||
.standard(2) | ||
.capacity(4) | ||
.checkIn("14:00") | ||
.checkOut("11:30") | ||
.price(95000L) | ||
.build(), | ||
RoomWithProductResponseDto.builder() | ||
.productId(3L) | ||
.productName("호텔3") | ||
.productThumbnail("호텔3 썸네일") | ||
.productAddress("호텔3 주소") | ||
.productDetailAddress("호텔3 상세 주소") | ||
.roomId(4L) | ||
.roomName("객실4") | ||
.standard(2) | ||
.capacity(4) | ||
.checkIn("13:00") | ||
.checkOut("11:00") | ||
.price(80000L) | ||
.build() | ||
); | ||
|
||
given(roomService.getRoomsWithProductInfo(roomIds)) | ||
.willReturn(rooms); | ||
|
||
//when & then | ||
mockMvc.perform( | ||
get(requestUrl) | ||
.content(objectMapper.writeValueAsString(requestDto)) | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.characterEncoding(StandardCharsets.UTF_8) | ||
) | ||
.andExpect(status().isOk()) | ||
.andDo(restDoc.document( | ||
requestFields( | ||
fieldWithPath("roomIds").type(JsonFieldType.ARRAY).description("조회할 객실 식별자 리스트") | ||
.attributes(key("constraints").value( | ||
getRoomListWithProductInfoDescriptions.descriptionsForProperty("roomIds"))) | ||
), | ||
responseFields(responseCommon()).and( | ||
fieldWithPath("data").type(JsonFieldType.OBJECT).description("응답 데이터"), | ||
fieldWithPath("data.rooms").type(JsonFieldType.ARRAY).description("조회한 객실 정보 리스트"), | ||
fieldWithPath("data.rooms[].productId").type(JsonFieldType.NUMBER).description("숙소 식별자"), | ||
fieldWithPath("data.rooms[].productName").type(JsonFieldType.STRING).description("숙소명"), | ||
fieldWithPath("data.rooms[].productThumbnail").type(JsonFieldType.STRING).description("숙소 썸네일 이미지 URL"), | ||
fieldWithPath("data.rooms[].productAddress").type(JsonFieldType.STRING).description("숙소 주소"), | ||
fieldWithPath("data.rooms[].productDetailAddress").type(JsonFieldType.STRING).description("숙소 상세 주소"), | ||
fieldWithPath("data.rooms[].roomId").type(JsonFieldType.NUMBER).description("객실 식별자"), | ||
fieldWithPath("data.rooms[].roomName").type(JsonFieldType.STRING).description("객실명"), | ||
fieldWithPath("data.rooms[].standard").type(JsonFieldType.NUMBER).description("기준 인원"), | ||
fieldWithPath("data.rooms[].capacity").type(JsonFieldType.NUMBER).description("최대 인원"), | ||
fieldWithPath("data.rooms[].checkIn").type(JsonFieldType.STRING).description("체크인 시간"), | ||
fieldWithPath("data.rooms[].checkOut").type(JsonFieldType.STRING).description("체크아웃 시간"), | ||
fieldWithPath("data.rooms[].price").type(JsonFieldType.NUMBER).description("객실 가격") | ||
) | ||
) | ||
); | ||
|
||
verify(roomService, times(1)).getRoomsWithProductInfo(roomIds); | ||
} | ||
} |
Oops, something went wrong.