From 4bdddafe08897dd4b763a76cf08c7ab78b4d0b6b Mon Sep 17 00:00:00 2001 From: yeonise Date: Thu, 4 Apr 2024 08:26:57 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20[RoomController]=20=EB=B0=A9=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20endpoint=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 관련된 DTO 클래스도 함께 생성합니다. - RoomDetail - RoomList --- .../site/youtogether/room/dto/RoomDetail.java | 26 ++++++++++++++++ .../site/youtogether/room/dto/RoomList.java | 31 +++++++++++++++++++ .../room/presentation/RoomController.java | 13 ++++++++ .../youtogether/util/api/ResponseResult.java | 3 +- 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/main/java/site/youtogether/room/dto/RoomDetail.java create mode 100644 src/main/java/site/youtogether/room/dto/RoomList.java diff --git a/src/main/java/site/youtogether/room/dto/RoomDetail.java b/src/main/java/site/youtogether/room/dto/RoomDetail.java new file mode 100644 index 0000000..568485a --- /dev/null +++ b/src/main/java/site/youtogether/room/dto/RoomDetail.java @@ -0,0 +1,26 @@ +package site.youtogether.room.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +public class RoomDetail { + + private String roomCode; + private String roomTitle; + private String videoTitle; + private String videoThumbnail; + private int capacity; + private int currentParticipant; + + @Builder + public RoomDetail(String roomCode, String roomTitle, String videoTitle, String videoThumbnail, int capacity, int currentParticipant) { + this.roomCode = roomCode; + this.roomTitle = roomTitle; + this.videoTitle = videoTitle; + this.videoThumbnail = videoThumbnail; + this.capacity = capacity; + this.currentParticipant = currentParticipant; + } + +} diff --git a/src/main/java/site/youtogether/room/dto/RoomList.java b/src/main/java/site/youtogether/room/dto/RoomList.java new file mode 100644 index 0000000..42b090d --- /dev/null +++ b/src/main/java/site/youtogether/room/dto/RoomList.java @@ -0,0 +1,31 @@ +package site.youtogether.room.dto; + +import java.util.List; + +import lombok.Builder; +import lombok.Getter; + +@Getter +public class RoomList { + + private int pageNumber; + private int pageSize; + private int totalData; + private int totalPage; + private boolean hasPrevious; + private boolean hasNext; + + private List rooms; + + @Builder + public RoomList(int pageNumber, int pageSize, int totalData, int totalPage, boolean hasPrevious, boolean hasNext, List rooms) { + this.pageNumber = pageNumber; + this.pageSize = pageSize; + this.totalData = totalData; + this.totalPage = totalPage; + this.hasPrevious = hasPrevious; + this.hasNext = hasNext; + this.rooms = rooms; + } + +} diff --git a/src/main/java/site/youtogether/room/presentation/RoomController.java b/src/main/java/site/youtogether/room/presentation/RoomController.java index 8e2ba32..f564a63 100644 --- a/src/main/java/site/youtogether/room/presentation/RoomController.java +++ b/src/main/java/site/youtogether/room/presentation/RoomController.java @@ -2,13 +2,17 @@ import static site.youtogether.util.AppConstants.*; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseCookie; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import jakarta.servlet.http.Cookie; @@ -20,6 +24,7 @@ import site.youtogether.resolver.Address; import site.youtogether.room.application.RoomService; import site.youtogether.room.dto.RoomCode; +import site.youtogether.room.dto.RoomList; import site.youtogether.room.dto.RoomSettings; import site.youtogether.util.RandomUtil; import site.youtogether.util.api.ApiResponse; @@ -61,4 +66,12 @@ public ResponseEntity> createRoom(@CookieValue(value = SES .body(ApiResponse.created(ResponseResult.ROOM_CREATION_SUCCESS, roomCode)); } + @GetMapping("/rooms") + public ResponseEntity> fetchRoomList(@PageableDefault Pageable pageable, @RequestParam(required = false) String search) { + RoomList roomList = roomService.fetchAll(pageable, search); + + return ResponseEntity.ok() + .body(ApiResponse.ok(ResponseResult.ROOM_LIST_FETCH_SUCCESS, roomList)); + } + } diff --git a/src/main/java/site/youtogether/util/api/ResponseResult.java b/src/main/java/site/youtogether/util/api/ResponseResult.java index c615ec1..3323025 100644 --- a/src/main/java/site/youtogether/util/api/ResponseResult.java +++ b/src/main/java/site/youtogether/util/api/ResponseResult.java @@ -9,7 +9,8 @@ public enum ResponseResult { EXCEPTION_OCCURRED("예외가 발생했습니다"), // Room - ROOM_CREATION_SUCCESS("방 생성에 성공했습니다"); + ROOM_CREATION_SUCCESS("방 생성에 성공했습니다"), + ROOM_LIST_FETCH_SUCCESS("방 목록 조회에 성공했습니다"); private final String description; From 36fea7dbe05eec6a0c9eb8c3ff2408558c87b321 Mon Sep 17 00:00:00 2001 From: yeonise Date: Thu, 4 Apr 2024 08:27:29 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20[RoomService]=20=EC=9E=84=EC=9D=98?= =?UTF-8?q?=EC=9D=98=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/site/youtogether/room/application/RoomService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/site/youtogether/room/application/RoomService.java b/src/main/java/site/youtogether/room/application/RoomService.java index fa0333d..a9b252f 100644 --- a/src/main/java/site/youtogether/room/application/RoomService.java +++ b/src/main/java/site/youtogether/room/application/RoomService.java @@ -1,10 +1,12 @@ package site.youtogether.room.application; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; import site.youtogether.room.Room; import site.youtogether.room.dto.RoomCode; +import site.youtogether.room.dto.RoomList; import site.youtogether.room.dto.RoomSettings; import site.youtogether.room.infrastructure.RoomStorage; import site.youtogether.user.Role; @@ -40,4 +42,8 @@ public RoomCode create(String sessionCode, String address, RoomSettings roomSett return new RoomCode(room); } + public RoomList fetchAll(Pageable pageable, String search) { + return null; + } + } From a766c1719aaaf88a5961a879f82b38e09abf624f Mon Sep 17 00:00:00 2001 From: yeonise Date: Thu, 4 Apr 2024 08:28:03 +0900 Subject: [PATCH 3/4] =?UTF-8?q?test:=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?-=20=EB=B0=A9=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../room/presentation/RoomControllerTest.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/test/java/site/youtogether/room/presentation/RoomControllerTest.java b/src/test/java/site/youtogether/room/presentation/RoomControllerTest.java index e1bf9f2..b8c5301 100644 --- a/src/test/java/site/youtogether/room/presentation/RoomControllerTest.java +++ b/src/test/java/site/youtogether/room/presentation/RoomControllerTest.java @@ -9,8 +9,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static site.youtogether.exception.ErrorType.*; +import java.util.List; +import java.util.stream.IntStream; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.restdocs.payload.JsonFieldType; @@ -19,6 +23,8 @@ import site.youtogether.RestDocsSupport; import site.youtogether.exception.room.SingleRoomParticipationViolationException; import site.youtogether.room.dto.RoomCode; +import site.youtogether.room.dto.RoomDetail; +import site.youtogether.room.dto.RoomList; import site.youtogether.room.dto.RoomSettings; import site.youtogether.util.api.ResponseResult; @@ -164,4 +170,83 @@ void createRoomFail_SingleRoomParticipantViolation() throws Exception { )); } + @Test + @DisplayName("방 목록 조회 성공") + void fetchRoomListSuccess() throws Exception { + // given + // Setting up response data for the fetched room list + RoomList roomList = RoomList.builder() + .pageNumber(0) + .pageSize(10) + .totalData(3) + .totalPage(1) + .hasPrevious(false) + .hasNext(false) + .rooms(generateRoomDetails(3)) + .build(); + given(roomService.fetchAll(any(Pageable.class), anyString())) + .willReturn(roomList); + + // when / then + mockMvc.perform(get("/rooms") + .param("page", "0") + .param("size", "10") + .param("search", "침착")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.status").value(HttpStatus.OK.getReasonPhrase())) + .andExpect(jsonPath("$.result").value(ResponseResult.ROOM_LIST_FETCH_SUCCESS.getDescription())) + .andExpect(jsonPath("$.result").value(ResponseResult.ROOM_LIST_FETCH_SUCCESS.getDescription())) + .andExpect(jsonPath("$.data.pageNumber").value(roomList.getPageNumber())) + .andExpect(jsonPath("$.data.pageSize").value(roomList.getPageSize())) + .andExpect(jsonPath("$.data.totalData").value(roomList.getTotalData())) + .andExpect(jsonPath("$.data.totalPage").value(roomList.getTotalPage())) + .andExpect(jsonPath("$.data.hasPrevious").value(roomList.isHasPrevious())) + .andExpect(jsonPath("$.data.hasNext").value(roomList.isHasNext())) + .andExpect(jsonPath("$.data.rooms[0].roomCode").value(roomList.getRooms().get(0).getRoomCode())) + .andExpect(jsonPath("$.data.rooms[0].roomTitle").value(roomList.getRooms().get(0).getRoomTitle())) + .andExpect(jsonPath("$.data.rooms[0].videoTitle").value(roomList.getRooms().get(0).getVideoTitle())) + .andExpect(jsonPath("$.data.rooms[0].videoThumbnail").value(roomList.getRooms().get(0).getVideoThumbnail())) + .andExpect(jsonPath("$.data.rooms[0].capacity").value(roomList.getRooms().get(0).getCapacity())) + .andExpect(jsonPath("$.data.rooms[0].currentParticipant").value(roomList.getRooms().get(0).getCurrentParticipant())) + .andDo(document("fetch-room-list-success", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + responseFields( + fieldWithPath("code").type(JsonFieldType.NUMBER).description("코드"), + fieldWithPath("status").type(JsonFieldType.STRING).description("상태"), + fieldWithPath("result").type(JsonFieldType.STRING).description("결과"), + fieldWithPath("data").type(JsonFieldType.OBJECT).description("응답 데이터"), + fieldWithPath("data.pageNumber").type(JsonFieldType.NUMBER).description("현재 페이지"), + fieldWithPath("data.pageSize").type(JsonFieldType.NUMBER).description("페이지 크기"), + fieldWithPath("data.totalData").type(JsonFieldType.NUMBER).description("총 데이터 수"), + fieldWithPath("data.totalPage").type(JsonFieldType.NUMBER).description("총 페이지 수"), + fieldWithPath("data.hasPrevious").type(JsonFieldType.BOOLEAN).description("이전 페이지 존재 여부"), + fieldWithPath("data.hasNext").type(JsonFieldType.BOOLEAN).description("다음 페이지 존재 여부"), + fieldWithPath("data.rooms").type(JsonFieldType.ARRAY).description("방 목록 조회 결과"), + fieldWithPath("data.rooms[].roomCode").type(JsonFieldType.STRING).description("방 식별 코드"), + fieldWithPath("data.rooms[].roomTitle").type(JsonFieldType.STRING).description("방 제목"), + fieldWithPath("data.rooms[].videoTitle").type(JsonFieldType.STRING).description("영상 제목"), + fieldWithPath("data.rooms[].videoThumbnail").type(JsonFieldType.STRING).description("영상 썸네일 URL"), + fieldWithPath("data.rooms[].capacity").type(JsonFieldType.NUMBER).description("정원"), + fieldWithPath("data.rooms[].currentParticipant").type(JsonFieldType.NUMBER).description("현재 참여자 수") + ) + )); + } + + private List generateRoomDetails(int count) { + return IntStream.rangeClosed(1, count) + .mapToObj(number -> RoomDetail.builder() + .roomCode("1e7050f7d" + number) + .roomTitle("2023년 침착맨 정주행 " + number) + .videoTitle("궤도 '연애의 과학' 특강 " + number) + .videoThumbnail( + "https://i.ytimg.com/vi/sl7ih5rLfYM/hq720.jpg?sqp=-oaymwEcCNAFEJQDSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDbjCXvhBJSBKs9bX_XMy_EfUtvSw") + .capacity(10) + .currentParticipant(6) + .build()) + .toList(); + } + } From 5b42db39d6825dfdee3f15958a858bfe503df98d Mon Sep 17 00:00:00 2001 From: yeonise Date: Thu, 4 Apr 2024 08:30:09 +0900 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20API=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20-=20=EB=B0=A9=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=84=B1=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/api/room.adoc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/docs/asciidoc/api/room.adoc b/src/docs/asciidoc/api/room.adoc index 9248ebd..a951d25 100644 --- a/src/docs/asciidoc/api/room.adoc +++ b/src/docs/asciidoc/api/room.adoc @@ -43,3 +43,17 @@ include::{snippets}/create-room-fail-single-room-participant-violation/request-f include::{snippets}/create-room-fail-single-room-participant-violation/http-response.adoc[] include::{snippets}/create-room-fail-single-room-participant-violation/response-fields.adoc[] + +{nbsp} + +[[fetch-room-list-success]] +=== 방 목록 조회 성공 + +==== HTTP Request + +include::{snippets}/fetch-room-list-success/http-request.adoc[] + +==== HTTP Response + +include::{snippets}/fetch-room-list-success/http-response.adoc[] +include::{snippets}/fetch-room-list-success/response-fields.adoc[]