diff --git a/src/main/java/com/umc/networkingService/domain/board/controller/BoardCommentController.java b/src/main/java/com/umc/networkingService/domain/board/controller/BoardCommentController.java index 18efa349..9f9e48ae 100644 --- a/src/main/java/com/umc/networkingService/domain/board/controller/BoardCommentController.java +++ b/src/main/java/com/umc/networkingService/domain/board/controller/BoardCommentController.java @@ -2,8 +2,7 @@ import com.umc.networkingService.config.security.auth.CurrentMember; import com.umc.networkingService.domain.board.dto.request.BoardCommentRequest; -import com.umc.networkingService.domain.board.dto.response.BoardCommentResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardCommentResponse.*; import com.umc.networkingService.domain.board.entity.BoardType; import com.umc.networkingService.domain.board.entity.HostType; import com.umc.networkingService.domain.board.service.BoardCommentService; @@ -24,6 +23,9 @@ import java.util.UUID; +import static com.umc.networkingService.domain.board.dto.response.BoardCommentResponse.*; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.*; + @Tag(name = "게시판 댓글 API", description = "게시판 댓글 관련 API") @RestController @RequiredArgsConstructor @@ -32,15 +34,17 @@ public class BoardCommentController { private final BoardCommentService boardCommentService; - @Operation(summary = "댓글 작성 API", description = "댓글을 작성하는 API입니다.") + @Operation(summary = "댓글 작성 API", description = "댓글을 작성하는 API입니다. + 대댓글일 경우, 부모 댓글의 commentId를 param으로 주세요") @ApiResponses(value = { @ApiResponse(responseCode = "COMMON200", description = "성공"), - @ApiResponse(responseCode = "BOARD002", description = "게시글을 찾을 수 없을 경우 발생") + @ApiResponse(responseCode = "BOARD002", description = "게시글을 찾을 수 없을 경우 발생"), + @ApiResponse(responseCode = "COMMENT001", description = "댓글을 찾을 수 없을 경우 발생") }) @PostMapping - public BaseResponse addBoardComment(@CurrentMember Member member, - @Valid @RequestBody BoardCommentRequest.BoardCommentAddRequest request) { - return BaseResponse.onSuccess(boardCommentService.addBoardComment(member, request)); + public BaseResponse addBoardComment(@CurrentMember Member member, + @RequestParam(required = false) UUID commentId, + @Valid @RequestBody BoardCommentRequest.BoardCommentAddRequest request) { + return BaseResponse.onSuccess(boardCommentService.addBoardComment(member, commentId, request)); } @Operation(summary = "댓글 수정 API", description = "댓글을 수정하는 API입니다.") @@ -51,9 +55,9 @@ public BaseResponse addBoardComment(@Curren }) @PatchMapping("/{commentId}") - public BaseResponse updateBoardComment(@CurrentMember Member member, - @PathVariable(value = "commentId") UUID commentId, - @Valid @RequestBody BoardCommentRequest.BoardCommentUpdateRequest request) { + public BaseResponse updateBoardComment(@CurrentMember Member member, + @PathVariable(value = "commentId") UUID commentId, + @Valid @RequestBody BoardCommentRequest.BoardCommentUpdateRequest request) { return BaseResponse.onSuccess(boardCommentService.updateBoardComment(member, commentId, request)); } @@ -65,8 +69,8 @@ public BaseResponse updateBoardComment(@Cur @ApiResponse(responseCode = "COMMENT002", description = "댓글 삭제 권한이 없을 경우 발생") }) @DeleteMapping("/{commentId}") - public BaseResponse deleteBoardComment(@CurrentMember Member member, - @PathVariable(value = "commentId") UUID commentId) { + public BaseResponse deleteBoardComment(@CurrentMember Member member, + @PathVariable(value = "commentId") UUID commentId) { return BaseResponse.onSuccess(boardCommentService.deleteBoardComment(member, commentId)); } @@ -78,14 +82,28 @@ public BaseResponse deleteBoardComment(@Cur @Parameters(value = { @Parameter(name = "page", description = " page 시작은 0번부터, 오름차순으로 조회됩니다.") }) - @GetMapping(value = "/{boardId}") - public BaseResponse showBoardComments(@CurrentMember Member member, - @PathVariable(value = "boardId") UUID boardId, - @PageableDefault(sort = "created_at", direction = Sort.Direction.ASC) + @GetMapping( "/{boardId}") + public BaseResponse> showBoardComments(@CurrentMember Member member, + @PathVariable(value = "boardId") UUID boardId, + @PageableDefault(sort = "created_at", direction = Sort.Direction.ASC) @Parameter(hidden = true) Pageable pageable) { return BaseResponse.onSuccess(boardCommentService.showBoardComments(member, boardId, pageable)); } + @Operation(summary = " 특정 댓글의 대댓글 조회 API", description = "특정 댓글의 대댓글 목록을 createdAt 오름차순으로 조회하는 API입니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "COMMON200", description = "성공"), + @ApiResponse(responseCode = "COMMENT001", description = "댓글을 찾을 수 없을 경우 발생"), + @ApiResponse(responseCode = "COMMENT003", description = "댓글의 대댓글이 없을 경우 발생") + + }) + @GetMapping( "/children/{commentId}") + public BaseResponse showChildrenComments(@CurrentMember Member member, + @PathVariable(value = "commentId") UUID commentId) { + return BaseResponse.onSuccess(boardCommentService.showChildrenComments(member, commentId)); + } + + @Operation(summary = "[APP] 내가 댓글 쓴 글 조회/검색 API", description = "APP용 내가 댓글 쓴 글을 조회/검색하는 API입니다.") @ApiResponses(value = { @ApiResponse(responseCode = "COMMON200", description = "성공"), @@ -94,10 +112,10 @@ public BaseResponse showBoardComment @Parameter(name = "keyword", description = "keyword를 주지 않으면 모든 내가 댓글 쓴 글이 조회됩니다. keyword를 주면 검색이 가능합니다."), @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다.") }) - @GetMapping(value = "/member/comments/app") - public BaseResponse showBoardsByMemberCommentsForApp(@CurrentMember Member member, - @RequestParam(name = "keyword", required = false) String keyword, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) + @GetMapping( "/member/app") + public BaseResponse> showBoardsByMemberCommentsForApp(@CurrentMember Member member, + @RequestParam(name = "keyword", required = false) String keyword, + @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable) { return BaseResponse.onSuccess(boardCommentService.showBoardsByMemberCommentForApp(member, keyword, pageable)); } @@ -112,13 +130,15 @@ public BaseResponse showBoardsByMemberComments @Parameters(value = { @Parameter(name = "keyword", description = "keyword를 주지 않으면 모든 내가 댓글 쓴 글이 조회됩니다. keyword를 주면 검색이 가능합니다."), @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다.")}) - @GetMapping(value = "/member/comments/web") - public BaseResponse showBoardsByMemberCommentForWeb(@CurrentMember Member member, - @RequestParam(name = "host") HostType hostType, - @RequestParam(name = "board") BoardType boardType, - @RequestParam(name = "keyword", required = false) String keyword, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) + @GetMapping("/member/web") + public BaseResponse> showBoardsByMemberCommentForWeb(@CurrentMember Member member, + @RequestParam(name = "host") HostType hostType, + @RequestParam(name = "board") BoardType boardType, + @RequestParam(name = "keyword", required = false) String keyword, + @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable) { return BaseResponse.onSuccess(boardCommentService.showBoardsByMemberCommentForWeb(member, hostType, boardType,keyword, pageable)); } + + } diff --git a/src/main/java/com/umc/networkingService/domain/board/controller/BoardController.java b/src/main/java/com/umc/networkingService/domain/board/controller/BoardController.java index 0e510900..2acc1f00 100644 --- a/src/main/java/com/umc/networkingService/domain/board/controller/BoardController.java +++ b/src/main/java/com/umc/networkingService/domain/board/controller/BoardController.java @@ -3,7 +3,7 @@ import com.umc.networkingService.config.security.auth.CurrentMember; import com.umc.networkingService.domain.board.dto.request.BoardRequest; import com.umc.networkingService.domain.board.dto.response.BoardResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.*; import com.umc.networkingService.domain.board.entity.BoardType; import com.umc.networkingService.domain.board.entity.HostType; import com.umc.networkingService.domain.board.service.BoardService; @@ -27,6 +27,7 @@ import java.util.List; import java.util.UUID; + @Tag(name = "게시판 API", description = "게시판 관련 API") @RestController @RequiredArgsConstructor @@ -87,18 +88,24 @@ public BaseResponse deleteBoard(@CurrentMember Member mem return BaseResponse.onSuccess(boardService.deleteBoard(member, boardId)); } - @Operation(summary = "핀고정된 notice 조회 API", description = "핀 고정된 공지 게시글을 조회하는 API입니다.") - @ApiResponses(value = { + @Operation(summary = "핀고정된 notice 조회 API", description = "핀 고정된 공지 게시글을 조회하는 API입니다. 최대 10개까지 조회합니다. " + + "writerInfo에는 writer, profileImage가 포함됩니다. (semester, part는 반환되지 않음)" ) @ApiResponses(value = { @ApiResponse(responseCode = "COMMON200", description = "성공"), }) + @Parameters(value = { + @Parameter(name = "host", description = "CENTER, BRANCH, CAMPUS 중 하나의 값을 대문자로 주세요. " + + "host를 주지 않으면 모든 host의 핀고정 게시글이 조회됩니다.") + }) @GetMapping("/pinned") - public BaseResponse showPinnedNotices(@CurrentMember Member member) { - return BaseResponse.onSuccess(boardService.showPinnedNotices(member)); + public BaseResponse showPinnedNotices(@CurrentMember Member member, + @RequestParam(name = "host", required = false) HostType hostType) { + return BaseResponse.onSuccess(boardService.showPinnedNotices(member, hostType)); } @Operation(summary = "특정 게시판의 게시글 목록 조회 API", description = "특정 게시판의 게시글 목록을 조회하는 API입니다. " + "host: CENTER, BRANCH, CAMPUS 중 하나의 값을 대문자로 주세요. " + - "board: NOTICE, FREE, WORKBOOK, OB, QUESTION 중 하나의 값을 대문자로 주세요.") + "board: NOTICE, FREE, WORKBOOK, OB, QUESTION 중 하나의 값을 대문자로 주세요. " + + "writerInfo에는 writer, profileImage가 포함됩니다. (semester, part는 반환되지 않음)") @ApiResponses(value = { @ApiResponse(responseCode = "COMMON200", description = "성공"), @ApiResponse(responseCode = "COMMON405", description = "host, board type 자체 값이 적절하지 않은 값일 경우 발생"), @@ -108,10 +115,10 @@ public BaseResponse showPinnedNotices(@CurrentMembe @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다."), }) @GetMapping - public BaseResponse showBoards(@CurrentMember Member member, - @RequestParam(name = "host") HostType hostType, - @RequestParam(name = "board") BoardType boardType, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) + public BaseResponse> showBoards(@CurrentMember Member member, + @RequestParam(name = "host") HostType hostType, + @RequestParam(name = "board") BoardType boardType, + @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable) { return BaseResponse.onSuccess(boardService.showBoards(member, hostType, boardType, pageable)); @@ -130,7 +137,8 @@ public BaseResponse showBoardDetail(@CurrentMember Me } - @Operation(summary = "게시글 검색 API", description = "keyword로 게시글을 검색합니다.") + @Operation(summary = "게시글 검색 API", description = "keyword로 게시글을 검색합니다." + + "writerInfo에는 writer, profileImage가 포함됩니다. (semester, part는 반환되지 않음)") @ApiResponses(value = { @ApiResponse(responseCode = "COMMON200", description = "성공") }) @@ -139,32 +147,16 @@ public BaseResponse showBoardDetail(@CurrentMember Me @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다."), }) @GetMapping(value = "/search") - public BaseResponse searchBoard(@CurrentMember Member member, - @RequestParam(name = "keyword") String keyword, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) + public BaseResponse> searchBoard(@CurrentMember Member member, + @RequestParam(name = "keyword") String keyword, + @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable) { return BaseResponse.onSuccess(boardService.searchBoard(member, keyword, pageable)); } - @Operation(summary = "[APP] 내가 쓴 게시글 조회/검색 API", description = "APP용 내가 쓴 게시글을 조회하거나 검색하는 API입니다.") - @ApiResponses(value = { - @ApiResponse(responseCode = "COMMON200", description = "성공") - }) - @Parameters(value = { - @Parameter(name = "keyword", description = "keyword를 주지 않으면 모든 내가 쓴 게시글이 조회됩니다. keyword를 주면 검색이 가능합니다."), - @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다."), - }) - @GetMapping(value = "/member/app") - public BaseResponse showBoardsByMemberForApp(@CurrentMember Member member, - @RequestParam(name = "keyword", required = false) String keyword, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) - @Parameter(hidden = true) Pageable pageable) { - - return BaseResponse.onSuccess(boardService.showBoardsByMemberForApp(member, keyword, pageable)); - } - @Operation(summary = "[WEB] 내가 쓴 게시글 조회/검색 API", description = "WEB용 내가 쓴 게시글을 조회하거나 검색하는 API입니다. " + + @Operation(summary = "내가 쓴 게시글 조회/검색 API", description = "내가 쓴 게시글을 조회하거나 검색하는 API입니다. WEB일 경우 host와 board를 지정해주세요. APP일 경우 지정하지 않아도 됩니다. " + "host: CENTER, BRANCH, CAMPUS 중 하나의 값을 대문자로 주세요. " + "board: NOTICE, FREE, WORKBOOK, OB, QUESTION 중 하나의 값을 대문자로 주세요.") @ApiResponses(value = { @@ -175,35 +167,19 @@ public BaseResponse showBoardsByMemberForApp(@ @Parameter(name = "keyword", description = "keyword를 주지 않으면 모든 내가 쓴 게시글이 조회됩니다. keyword를 주면 검색이 가능합니다."), @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다."), }) - @GetMapping(value = "/member/web") - public BaseResponse showBoardsByMemberForWeb(@CurrentMember Member member, - @RequestParam(name = "host") HostType hostType, - @RequestParam(name = "board") BoardType boardType, - @RequestParam(name = "keyword", required = false) String keyword, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) + @GetMapping(value = "/member") + public BaseResponse> showBoardsByMemberForWeb(@CurrentMember Member member, + @RequestParam(name = "host", required = false) HostType hostType, + @RequestParam(name = "board", required = false) BoardType boardType, + @RequestParam(name = "keyword", required = false) String keyword, + @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable) { - return BaseResponse.onSuccess(boardService.showBoardsByMemberForWeb(member, hostType, boardType, keyword, pageable)); + return BaseResponse.onSuccess(boardService.showBoardsByMember(member, hostType, boardType, keyword, pageable)); } - @Operation(summary = "[APP] 내가 좋아요한 게시글 조회/검색 API", description = "APP용 내가 좋아요한 게시글을 조회하거나 검색하는 API입니다.") - @ApiResponses(value = { - @ApiResponse(responseCode = "COMMON200", description = "성공") - }) - @Parameters(value = { - @Parameter(name = "keyword", description = "keyword를 주지 않으면 내가 좋아요한 모든 글이 조회됩니다. keyword를 주면 검색이 가능합니다."), - @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다."), - }) - @GetMapping(value = "/member/hearts/app") - public BaseResponse showMemberBoardHeartForApp(@CurrentMember Member member, - @RequestParam(name = "keyword", required = false) String keyword, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) - @Parameter(hidden = true) Pageable pageable) { - return BaseResponse.onSuccess(boardService.showBoardsByMemberHeartForApp(member, keyword, pageable)); - } - - @Operation(summary = "[WEB] 내가 좋아요한 게시글 조회/검색 API", description = "WEB용 내가 좋아요한 게시글을 조회하거나 검색하는 API입니다. " + + @Operation(summary = "내가 좋아요한 게시글 조회/검색 API", description = "내가 좋아요한 게시글을 조회하거나 검색하는 API입니다. WEB일 경우 host와 board를 지정해주세요. APP일 경우 지정하지 않아도 됩니다. " + "host: CENTER, BRANCH, CAMPUS 중 하나의 값을 대문자로 주세요. " + "board: NOTICE, FREE, WORKBOOK, OB, QUESTION 중 하나의 값을 대문자로 주세요.") @ApiResponses(value = { @@ -214,14 +190,14 @@ public BaseResponse showMemberBoardHeartForApp @Parameter(name = "keyword", description = "keyword를 주지 않으면 내가 좋아요한 모든 글이 조회됩니다. keyword를 주면 검색이 가능합니다."), @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다."), }) - @GetMapping(value = "/member/hearts/web") - public BaseResponse showMemberBoardHeartForWeb(@CurrentMember Member member, - @RequestParam(name = "host") HostType hostType, - @RequestParam(name = "board") BoardType boardType, - @RequestParam(name = "keyword", required = false) String keyword, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) + @GetMapping(value = "/member/hearts") + public BaseResponse> showMemberBoardHeart(@CurrentMember Member member, + @RequestParam(name = "host",required = false) HostType hostType, + @RequestParam(name = "board",required = false) BoardType boardType, + @RequestParam(name = "keyword", required = false) String keyword, + @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable) { - return BaseResponse.onSuccess(boardService.showBoardsByMemberHeartForWeb(member, hostType, boardType, keyword, pageable)); + return BaseResponse.onSuccess(boardService.showBoardsByMemberHeart(member, hostType, boardType, keyword, pageable)); } diff --git a/src/main/java/com/umc/networkingService/domain/board/controller/StaffBoardController.java b/src/main/java/com/umc/networkingService/domain/board/controller/StaffBoardController.java index 238024a4..1f0da8b6 100644 --- a/src/main/java/com/umc/networkingService/domain/board/controller/StaffBoardController.java +++ b/src/main/java/com/umc/networkingService/domain/board/controller/StaffBoardController.java @@ -2,6 +2,8 @@ import com.umc.networkingService.config.security.auth.CurrentMember; import com.umc.networkingService.domain.board.dto.response.BoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageInfos; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.NoticePageElement; import com.umc.networkingService.domain.board.entity.HostType; import com.umc.networkingService.domain.board.service.StaffBoardService; import com.umc.networkingService.domain.member.entity.Member; @@ -34,16 +36,17 @@ public class StaffBoardController { @ApiResponse(responseCode = "BOARD003", description = "해당 host type의 공지사항을 볼 권한이 없을 경우 발생"), }) @Parameters(value = { - @Parameter(name = "host", description = "ALL, CENTER, BRANCH, CAMPUS 중 하나의 값을 대문자로 주세요."), - @Parameter(name = "keyword", description = "keyword를 주지 않으면 모든 교내 공지사항 글이 조회됩니다. keyword를 주면 검색이 가능합니다."), + @Parameter(name = "host", description = "CENTER, BRANCH, CAMPUS 중 하나의 값을 대문자로 주세요. " + + "host를 주지 않으면 해당 운영진의 직책에 따라 핀 설정 권한이 있는 host의 공지가 모두 조회됩니다."), + @Parameter(name = "keyword", description = "keyword를 주면 해당 hostType 내에서 검색이 가능합니다."), @Parameter(name = "page", description = "page 시작은 0번부터, 내림차순으로 조회됩니다."), }) @GetMapping("notices") - public BaseResponse showNotices(@CurrentMember Member member, - @RequestParam(name = "host") HostType hostType, - @RequestParam(name = "keyword", required = false) String keyword, - @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) + public BaseResponse> showNotices(@CurrentMember Member member, + @RequestParam(name = "host", required = false) HostType hostType, + @RequestParam(name = "keyword", required = false) String keyword, + @PageableDefault(sort = "created_at", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable) { return BaseResponse.onSuccess(staffBoardService.showNotices(member, hostType, keyword, pageable)); } @@ -56,12 +59,12 @@ public BaseResponse showNotices(@CurrentMember Me }) @Parameters(value = { @Parameter(name = "boardId", description = "핀을 설정하고자 하는 boardId입니다."), - @Parameter(name = "isPinned", description = "isPinned = true이면 핀으로 설정됩니다. false이면 핀 설정 해제됩니다.") + @Parameter(name = "isFixed", description = "isFixed = true이면 핀으로 설정됩니다. false이면 핀 설정 해제됩니다.") }) @PatchMapping("notices/{boardId}/pin") public BaseResponse toggleNoticePin(@CurrentMember Member member, @PathVariable(value = "boardId") UUID boardId, - @RequestParam boolean isPinned) { - return BaseResponse.onSuccess(staffBoardService.toggleNoticePin(member, boardId, isPinned)); + @RequestParam boolean isFixed) { + return BaseResponse.onSuccess(staffBoardService.toggleNoticePin(member, boardId, isFixed)); } } diff --git a/src/main/java/com/umc/networkingService/domain/board/dto/response/BoardCommentResponse.java b/src/main/java/com/umc/networkingService/domain/board/dto/response/BoardCommentResponse.java index e1152e56..328ad2b4 100644 --- a/src/main/java/com/umc/networkingService/domain/board/dto/response/BoardCommentResponse.java +++ b/src/main/java/com/umc/networkingService/domain/board/dto/response/BoardCommentResponse.java @@ -1,14 +1,10 @@ package com.umc.networkingService.domain.board.dto.response; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.umc.networkingService.global.common.enums.Part; -import com.umc.networkingService.global.common.enums.Semester; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -21,25 +17,42 @@ public static class BoardCommentId { } @Getter + @NoArgsConstructor + @AllArgsConstructor @Builder public static class BoardCommentPageElement { private UUID commentId; - private String writer; - private String profileImage; - private Semester semester; - private Part part; + private WriterInfo writerInfo; private String content; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime createdAt; + private Boolean isMine; + private String createdAt; + private int childrenNumber; + } + @Getter + @NoArgsConstructor + @AllArgsConstructor + @Builder + public static class BoardCommentChildrenElement { + private UUID commentId; + private WriterInfo writerInfo; + private String content; + private Boolean isMine; + private String createdAt; + } + + @Getter + @AllArgsConstructor + public static class BoardCommentChildrenInfos { + private List boardCommentChildrenElements = new ArrayList<>(); } @Getter @NoArgsConstructor @AllArgsConstructor @Builder - public static class BoardCommentPageInfos { - private List boardCommentPageElements = new ArrayList<>(); + public static class BoardCommentPageInfos { + private List boardCommentPageElements = new ArrayList<>(); private int page; private int totalPages; private int totalElements; diff --git a/src/main/java/com/umc/networkingService/domain/board/dto/response/BoardResponse.java b/src/main/java/com/umc/networkingService/domain/board/dto/response/BoardResponse.java index c50c50cf..c6e84abb 100644 --- a/src/main/java/com/umc/networkingService/domain/board/dto/response/BoardResponse.java +++ b/src/main/java/com/umc/networkingService/domain/board/dto/response/BoardResponse.java @@ -1,17 +1,13 @@ package com.umc.networkingService.domain.board.dto.response; -import com.fasterxml.jackson.annotation.JsonFormat; import com.umc.networkingService.domain.board.entity.BoardType; import com.umc.networkingService.domain.board.entity.HostType; -import com.umc.networkingService.global.common.enums.Part; -import com.umc.networkingService.global.common.enums.Semester; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -22,19 +18,16 @@ public class BoardResponse { public static class BoardDetail { private HostType hostType; private BoardType boardType; - private String writer; - private String profileImage; - private Part part; - private Semester semester; + private WriterInfo writerInfo; private String title; private String content; private List boardFiles; private int hitCount; private int heartCount; private int commentCount; - private boolean isLiked; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime createdAt; + private Boolean isLiked; + private Boolean isMine; + private String createdAt; } @Getter @@ -47,17 +40,14 @@ public static class BoardId { @SuperBuilder public static class BoardPageElement { private UUID boardId; - private String writer; - private String profileImage; + private WriterInfo writerInfo; private String title; private String content; private String thumbnail; private int hitCount; private int heartCount; private int commentCount; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime createdAt; - private boolean isFixed; + private String createdAt; } @Getter @@ -68,65 +58,44 @@ public static class BoardSearchPageElement extends BoardPageElement { } @Getter - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class BoardPageInfos { - private List boardPageElements = new ArrayList<>(); - private int page; - private int totalPages; - private int totalElements; - private Boolean isFirst; - private Boolean isLast; - } - - @Getter - @NoArgsConstructor - @AllArgsConstructor @Builder - public static class BoardSearchPageInfos { - private List boardSearchPageElements = new ArrayList<>(); - private int page; - private int totalPages; - private int totalElements; - private Boolean isFirst; - private Boolean isLast; - } - - @Getter - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class NoticePageInfos { - private List noticePageElements = new ArrayList<>(); - private int page; - private int totalPages; - private int totalElements; - private Boolean isFirst; - private Boolean isLast; + public static class NoticePageElement { + private UUID boardId; + private HostType hostType; + private String writer; + private String title; + private int hitCount; + private Boolean isFixed; + private String createdAt; } @Getter @Builder - public static class NoticePageElement { + public static class MyBoardPageElement { private UUID boardId; private HostType hostType; - private String writer; + private BoardType boardType; private String title; private int hitCount; - private boolean isFixed; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime createdAt; + private int heartCount; + private String createdAt; } @Getter @Builder - public static class PinnedNotice { + public static class MyBoardCommentPageElement { private UUID boardId; + private HostType hostType; + private BoardType boardType; private String title; - private String content; + private String comment; + private String commentCreatedAt; + } + + @Getter + @SuperBuilder + public static class PinnedNotice extends BoardPageElement { private HostType hostType; - private String nickname; } @Getter @@ -137,4 +106,16 @@ public static class PinnedNotices { List pinnedNotices = new ArrayList<>(); } + @Getter + @NoArgsConstructor + @AllArgsConstructor + @Builder + public static class BoardPageInfos { + private List boardPageElements = new ArrayList<>(); + private int page; + private int totalPages; + private int totalElements; + private Boolean isFirst; + private Boolean isLast; + } } diff --git a/src/main/java/com/umc/networkingService/domain/board/dto/response/MyBoardResponse.java b/src/main/java/com/umc/networkingService/domain/board/dto/response/MyBoardResponse.java deleted file mode 100644 index 5df68231..00000000 --- a/src/main/java/com/umc/networkingService/domain/board/dto/response/MyBoardResponse.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.umc.networkingService.domain.board.dto.response; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.umc.networkingService.domain.board.entity.BoardType; -import com.umc.networkingService.domain.board.entity.HostType; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -public class MyBoardResponse { - @Getter - @Builder - public static class MyBoardPageElement { - private UUID boardId; - private HostType hostType; - private BoardType boardType; - private String title; - private int hitCount; - private int heartCount; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime createdAt; - } - - @Getter - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class MyBoardPageInfos { - private List myBoardPageElements = new ArrayList<>(); - private int page; - private int totalPages; - private int totalElements; - private Boolean isFirst; - private Boolean isLast; - } - - @Getter - @Builder - public static class MyBoardCommentPageElement { - private UUID boardId; - private HostType hostType; - private BoardType boardType; - private String title; - private String comment; - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime commentCreatedAt; - } - - @Getter - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class MyBoardCommentPageInfos { - private List myBoardCommentPageElement = new ArrayList<>(); - private int page; - private int totalPages; - private int totalElements; - private Boolean isFirst; - private Boolean isLast; - } - -} diff --git a/src/main/java/com/umc/networkingService/domain/board/dto/response/WriterInfo.java b/src/main/java/com/umc/networkingService/domain/board/dto/response/WriterInfo.java new file mode 100644 index 00000000..3bf1651b --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/board/dto/response/WriterInfo.java @@ -0,0 +1,18 @@ +package com.umc.networkingService.domain.board.dto.response; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.umc.networkingService.global.common.enums.Part; +import com.umc.networkingService.global.common.enums.Semester; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class WriterInfo { + private String writer; + private String profileImage; + @JsonInclude(JsonInclude.Include.NON_NULL) + private Part part; + @JsonInclude(JsonInclude.Include.NON_NULL) + private Semester semester; +} \ No newline at end of file diff --git a/src/main/java/com/umc/networkingService/domain/board/entity/BoardCheck.java b/src/main/java/com/umc/networkingService/domain/board/entity/BoardCheck.java deleted file mode 100644 index 82411bb7..00000000 --- a/src/main/java/com/umc/networkingService/domain/board/entity/BoardCheck.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.umc.networkingService.domain.board.entity; - -import com.umc.networkingService.domain.member.entity.Member; -import com.umc.networkingService.global.common.base.BaseEntity; -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.hibernate.annotations.SQLRestriction; -import org.hibernate.annotations.UuidGenerator; - -import java.util.UUID; - -@Getter -@Entity -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@SQLRestriction("deleted_at is null") -public class BoardCheck extends BaseEntity { - - @Id - @UuidGenerator - @Column(name = "board_check_id") - private UUID id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(nullable = false, name = "member_id") - private Member member; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(nullable = false, name = "board_id") - private Board board; -} diff --git a/src/main/java/com/umc/networkingService/domain/board/entity/BoardComment.java b/src/main/java/com/umc/networkingService/domain/board/entity/BoardComment.java index 154dcfd8..92d0a257 100644 --- a/src/main/java/com/umc/networkingService/domain/board/entity/BoardComment.java +++ b/src/main/java/com/umc/networkingService/domain/board/entity/BoardComment.java @@ -6,9 +6,12 @@ import com.umc.networkingService.global.common.base.BaseEntity; import jakarta.persistence.*; import lombok.*; +import org.hibernate.annotations.BatchSize; import org.hibernate.annotations.SQLRestriction; import org.hibernate.annotations.UuidGenerator; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; @Getter @@ -37,6 +40,12 @@ public class BoardComment extends BaseEntity { @JoinColumn(name = "parent_comment_id") private BoardComment parentComment; + @BatchSize(size = 50) + @OneToMany(mappedBy = "parentComment", fetch = FetchType.LAZY) + @Builder.Default + private List children = new ArrayList<>(); + + @Column(nullable = false) private String content; @@ -44,4 +53,7 @@ public void update(BoardCommentRequest.BoardCommentUpdateRequest request) { this.content = request.getContent(); } + public void deleteComment() { + this.content = "삭제된 댓글입니다."; + } } diff --git a/src/main/java/com/umc/networkingService/domain/board/entity/HostType.java b/src/main/java/com/umc/networkingService/domain/board/entity/HostType.java index 48ae18d3..76d52d4b 100644 --- a/src/main/java/com/umc/networkingService/domain/board/entity/HostType.java +++ b/src/main/java/com/umc/networkingService/domain/board/entity/HostType.java @@ -9,20 +9,18 @@ public enum HostType { CENTER("연합", 3), BRANCH("지부", 4), - CAMPUS("학교", 5), - ALL("전체(staff 공지사항용)",100); //공지사항 판단을 위함 - + CAMPUS("학교", 5); private final String toKorean; private final int priority; //허용 가능한 최상위 hostType public static HostType getPermmissionHostType(Role role) { - if( role.ordinal() <= Role.CENTER_STAFF.ordinal()) + if (role.ordinal() <= Role.CENTER_STAFF.ordinal()) return CENTER; - else if(role.ordinal() == Role.BRANCH_STAFF.ordinal()) - return BRANCH; - else - return CAMPUS; + else if (role.ordinal() == Role.BRANCH_STAFF.ordinal()) + return BRANCH; + else + return CAMPUS; } } diff --git a/src/main/java/com/umc/networkingService/domain/board/mapper/BoardCommentMapper.java b/src/main/java/com/umc/networkingService/domain/board/mapper/BoardCommentMapper.java index 0ca0fc8f..88dd61e7 100644 --- a/src/main/java/com/umc/networkingService/domain/board/mapper/BoardCommentMapper.java +++ b/src/main/java/com/umc/networkingService/domain/board/mapper/BoardCommentMapper.java @@ -1,33 +1,33 @@ package com.umc.networkingService.domain.board.mapper; -import com.umc.networkingService.domain.board.dto.request.BoardCommentRequest; -import com.umc.networkingService.domain.board.dto.response.BoardCommentResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.MyBoardCommentPageElement; +import com.umc.networkingService.domain.board.dto.response.WriterInfo; import com.umc.networkingService.domain.board.entity.Board; import com.umc.networkingService.domain.board.entity.BoardComment; import com.umc.networkingService.domain.member.entity.Member; -import lombok.RequiredArgsConstructor; +import com.umc.networkingService.global.converter.DataConverter; import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; import java.util.List; +import static com.umc.networkingService.domain.board.dto.response.BoardCommentResponse.*; + @Component -@RequiredArgsConstructor public class BoardCommentMapper { - public BoardComment toEntity(Member member, Board board, BoardCommentRequest.BoardCommentAddRequest request) { + public BoardComment toEntity(Member member, Board board, BoardComment parentComment, String content) { return BoardComment.builder() .writer(member) - .content(request.getContent()) + .content(content) + .parentComment(parentComment) .board(board) .build(); } - public BoardCommentResponse.BoardCommentPageInfos toBoardCommentPageInfos(Page comments) { - List responses = comments.map(this::toBoardCommentPageElement) - .stream().toList(); - return BoardCommentResponse.BoardCommentPageInfos.builder() - .boardCommentPageElements(responses) + public BoardCommentPageInfos toBoardCommentPageInfos(Page comments, List commentPageElements) { + + return BoardCommentPageInfos.builder() + .boardCommentPageElements(commentPageElements) .page(comments.getNumber()) .totalPages(comments.getTotalPages()) .totalElements((int) comments.getTotalElements()) @@ -36,39 +36,37 @@ public BoardCommentResponse.BoardCommentPageInfos toBoardCommentPageInfos(Page comments) { - List responses = comments.map(this::toMyBoardCommentPageElement) - .stream().toList(); - return MyBoardResponse.MyBoardCommentPageInfos.builder() - .myBoardCommentPageElement(responses) - .page(comments.getNumber()) - .totalPages(comments.getTotalPages()) - .totalElements((int) comments.getTotalElements()) - .isFirst(comments.isFirst()) - .isLast(comments.isLast()) + public BoardCommentChildrenElement toBoardCommentChildrenElement(BoardComment comment, WriterInfo writerInfo, boolean isMine) { + return BoardCommentChildrenElement.builder() + .commentId(comment.getId()) + .writerInfo(writerInfo) + .content(comment.getContent()) + .isMine(isMine) + .createdAt(DataConverter.convertToRelativeTimeFormat(comment.getCreatedAt())) .build(); } - public MyBoardResponse.MyBoardCommentPageElement toMyBoardCommentPageElement(BoardComment comment) { - return MyBoardResponse.MyBoardCommentPageElement.builder() + + public MyBoardCommentPageElement toMyBoardCommentPageElement(BoardComment comment) { + return MyBoardCommentPageElement.builder() .boardId(comment.getBoard().getId()) .hostType(comment.getBoard().getHostType()) .boardType(comment.getBoard().getBoardType()) .title(comment.getBoard().getTitle()) .comment(comment.getContent()) - .commentCreatedAt(comment.getCreatedAt()) + .commentCreatedAt(DataConverter.convertToRelativeTimeFormat(comment.getCreatedAt())) .build(); } diff --git a/src/main/java/com/umc/networkingService/domain/board/mapper/BoardMapper.java b/src/main/java/com/umc/networkingService/domain/board/mapper/BoardMapper.java index 4df34f20..02a1f1c6 100644 --- a/src/main/java/com/umc/networkingService/domain/board/mapper/BoardMapper.java +++ b/src/main/java/com/umc/networkingService/domain/board/mapper/BoardMapper.java @@ -1,14 +1,14 @@ package com.umc.networkingService.domain.board.mapper; import com.umc.networkingService.domain.board.dto.request.BoardRequest; -import com.umc.networkingService.domain.board.dto.response.BoardResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.*; +import com.umc.networkingService.domain.board.dto.response.WriterInfo; import com.umc.networkingService.domain.board.entity.Board; import com.umc.networkingService.domain.board.entity.BoardType; import com.umc.networkingService.domain.board.entity.HostType; -import com.umc.networkingService.domain.board.service.BoardFileService; import com.umc.networkingService.domain.member.entity.Member; import com.umc.networkingService.global.common.enums.Semester; +import com.umc.networkingService.global.converter.DataConverter; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; @@ -18,7 +18,6 @@ @Component @RequiredArgsConstructor public class BoardMapper { - private final BoardFileService boardFileService; public Board toEntity(Member member, BoardRequest.BoardCreateRequest request, List semesterPermission) { @@ -32,140 +31,87 @@ public Board toEntity(Member member, BoardRequest.BoardCreateRequest request, .build(); } - public BoardResponse.PinnedNotice topinnedNotice(Board board) { - return BoardResponse.PinnedNotice.builder() + public PinnedNotice toPinnedNotice(Board board, WriterInfo writerInfo, String thumbnail) { + return PinnedNotice.builder() + .boardId(board.getId()) + .writerInfo(writerInfo) .hostType(board.getHostType()) .title(board.getTitle()) - .boardId(board.getId()) .content(board.getContent()) - .nickname(board.getWriter().getNickname()) + .thumbnail(thumbnail) + .heartCount(board.getHeartCount()) + .commentCount(board.getCommentCount()) + .hitCount(board.getHitCount()) + .createdAt(DataConverter.convertToRelativeTimeFormat(board.getCreatedAt())) .build(); } - public BoardResponse.PinnedNotices toPinnedNotices(List boards) { - List pinnedNotices = boards.stream().map(this::topinnedNotice).toList(); - return BoardResponse.PinnedNotices.builder() + + public PinnedNotices toPinnedNotices(List pinnedNotices) { + return PinnedNotices.builder() .pinnedNotices(pinnedNotices) .build(); } - public BoardResponse.BoardPageElement toBoardPageElement(Board board) { - return BoardResponse.BoardPageElement.builder() + + public BoardPageElement toBoardPageElement(Board board, WriterInfo writerInfo, String thumbnail) { + return BoardPageElement.builder() .boardId(board.getId()) - .writer(board.getWriter().getNickname() + "/" + board.getWriter().getName()) - .profileImage(board.getWriter().getProfileImage()) + .writerInfo(writerInfo) .title(board.getTitle()) .content(board.getContent()) - .thumbnail(boardFileService.findThumbnailImage(board)) + .thumbnail(thumbnail) .hitCount(board.getHitCount()) .heartCount(board.getHeartCount()) .commentCount(board.getCommentCount()) - .createdAt(board.getCreatedAt()) - .build(); - } - - public BoardResponse.BoardPageInfos toBoardPageInfos(Page boards) { - - List boardPageElements = boards.map(this::toBoardPageElement).stream().toList(); - return BoardResponse.BoardPageInfos.builder() - .boardPageElements(boardPageElements) - .page(boards.getNumber()) - .totalPages(boards.getTotalPages()) - .totalElements((int) boards.getTotalElements()) - .isFirst(boards.isFirst()) - .isLast(boards.isLast()) + .createdAt(DataConverter.convertToRelativeTimeFormat(board.getCreatedAt())) .build(); - } - public BoardResponse.BoardSearchPageInfos toBoardSearchPageInfos(Page boards) { - List boardSearchPageElements = boards.map(this::toBoardSearchPageElement).stream().toList(); - return BoardResponse.BoardSearchPageInfos.builder() - .boardSearchPageElements(boardSearchPageElements) - .page(boards.getNumber()) - .totalPages(boards.getTotalPages()) - .totalElements((int) boards.getTotalElements()) - .isFirst(boards.isFirst()) - .isLast(boards.isLast()) - .build(); - - } - - - public BoardResponse.BoardSearchPageElement toBoardSearchPageElement(Board board) { - return BoardResponse.BoardSearchPageElement.builder() + public BoardSearchPageElement toBoardSearchPageElement(Board board, WriterInfo writerInfo, String thumbnail) { + return BoardSearchPageElement.builder() .boardType(board.getBoardType()) .hostType(board.getHostType()) .boardId(board.getId()) - .writer(board.getWriter().getNickname() + "/" + board.getWriter().getName()) - .profileImage(board.getWriter().getProfileImage()) + .writerInfo(writerInfo) .title(board.getTitle()) .content(board.getContent()) - .thumbnail(boardFileService.findThumbnailImage(board)) + .thumbnail(thumbnail) .hitCount(board.getHitCount()) .heartCount(board.getHeartCount()) .commentCount(board.getCommentCount()) - .createdAt(board.getCreatedAt()) - .build(); - } - - public MyBoardResponse.MyBoardPageInfos toMyBoardPageInfos(Page boards) { - List myBoardPageElements = boards.map(this::toMyBoardPageElement).stream().toList(); - - return MyBoardResponse.MyBoardPageInfos.builder() - .myBoardPageElements(myBoardPageElements) - .page(boards.getNumber()) - .totalPages(boards.getTotalPages()) - .totalElements((int) boards.getTotalElements()) - .isFirst(boards.isFirst()) - .isLast(boards.isLast()) + .createdAt(DataConverter.convertToRelativeTimeFormat(board.getCreatedAt())) .build(); } - public MyBoardResponse.MyBoardPageElement toMyBoardPageElement(Board board) { - return MyBoardResponse.MyBoardPageElement.builder() + public MyBoardPageElement toMyBoardPageElement(Board board) { + return MyBoardPageElement.builder() .boardId(board.getId()) .hostType(board.getHostType()) .boardType(board.getBoardType()) .title(board.getTitle()) .hitCount(board.getHitCount()) .heartCount(board.getHeartCount()) - .createdAt(board.getCreatedAt()) + .createdAt(DataConverter.convertToRelativeTimeFormat(board.getCreatedAt())) .build(); } - public BoardResponse.NoticePageElement toNoticePageElement(Board board) { - return BoardResponse.NoticePageElement.builder() + public NoticePageElement toNoticePageElement(Board board) { + return NoticePageElement.builder() .boardId(board.getId()) .hostType(board.getHostType()) - .writer(board.getWriter().getNickname() + "/" + board.getWriter().getName()) + .writer(DataConverter.convertToWriter(board.getWriter())) .title(board.getTitle()) .hitCount(board.getHitCount()) .isFixed(board.isFixed()) - .createdAt(board.getCreatedAt()) - .build(); - } - - public BoardResponse.NoticePageInfos toBoardNoticePagingResponse(Page boards) { - List noticePageElements = boards.map(this::toNoticePageElement).stream().toList(); - - return BoardResponse.NoticePageInfos.builder() - .noticePageElements(noticePageElements) - .page(boards.getNumber()) - .totalPages(boards.getTotalPages()) - .totalElements((int) boards.getTotalElements()) - .isFirst(boards.isFirst()) - .isLast(boards.isLast()) + .createdAt(DataConverter.convertToRelativeTimeFormat(board.getCreatedAt())) .build(); } - public BoardResponse.BoardDetail toBoardDetail(Board board, List boardFiles, boolean isLiked) { - return BoardResponse.BoardDetail.builder() + public BoardDetail toBoardDetail(Board board, List boardFiles, WriterInfo writerInfo, boolean isLiked, boolean isMine) { + return BoardDetail.builder() .hostType(board.getHostType()) .boardType(board.getBoardType()) - .writer(board.getWriter().getNickname() + "/" + board.getWriter().getName()) - .profileImage(board.getWriter().getProfileImage()) - .part(board.getWriter().getRecentPart()) - .semester(board.getWriter().getRecentSemester()) + .writerInfo(writerInfo) .title(board.getTitle()) .content(board.getContent()) .hitCount(board.getHitCount()) @@ -173,8 +119,35 @@ public BoardResponse.BoardDetail toBoardDetail(Board board, List boardFi .commentCount(board.getCommentCount()) .boardFiles(boardFiles) .isLiked(isLiked) - .createdAt(board.getCreatedAt()) + .isMine(isMine) + .createdAt(DataConverter.convertToRelativeTimeFormat(board.getCreatedAt())) .build(); } + public BoardPageInfos toBoardPageInfos(Page boards, List boardPageElements) { + return BoardPageInfos.builder() + .boardPageElements(boardPageElements) + .page(boards.getNumber()) + .totalPages(boards.getTotalPages()) + .totalElements((int) boards.getTotalElements()) + .isFirst(boards.isFirst()) + .isLast(boards.isLast()) + .build(); + + } + + public WriterInfo toDetailWriterInfo(Member member) { + return WriterInfo.builder() + .writer(DataConverter.convertToWriter(member)) + .profileImage(member.getProfileImage()) + .part(member.getRecentPart()) + .semester(member.getRecentSemester()) + .build(); + } + + public WriterInfo toWriterInfo(Member member) { + return WriterInfo.builder() + .writer(DataConverter.convertToWriter(member)) + .profileImage(member.getProfileImage()).build(); + } } diff --git a/src/main/java/com/umc/networkingService/domain/board/repository/BoardCommentRepository.java b/src/main/java/com/umc/networkingService/domain/board/repository/BoardCommentRepository.java index 3e635640..2d73efa3 100644 --- a/src/main/java/com/umc/networkingService/domain/board/repository/BoardCommentRepository.java +++ b/src/main/java/com/umc/networkingService/domain/board/repository/BoardCommentRepository.java @@ -9,7 +9,7 @@ import java.util.UUID; public interface BoardCommentRepository extends JpaRepository, BoardRepositoryCustom { - @Query(value = "select b from BoardComment b where b.id = :commentId and b.deletedAt is null") - Optional findById(@Param("commentId") UUID commentId); + Optional findById(UUID commentId); + boolean existsByParentComment(BoardComment boardComment); } \ No newline at end of file diff --git a/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepository.java b/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepository.java index 30e16328..663545a3 100644 --- a/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepository.java +++ b/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepository.java @@ -11,8 +11,8 @@ import java.util.UUID; public interface BoardRepository extends JpaRepository, BoardRepositoryCustom { - @Query(value = "select b from Board b where b.id = :boardId and b.deletedAt is null") - Optional findById(@Param("boardId") UUID boardId); + + Optional findById(UUID boardId); boolean existsByBoardTypeAndHostType(BoardType boardType, HostType hostType); diff --git a/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepositoryCustom.java b/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepositoryCustom.java index 4c8f9600..878d5aac 100644 --- a/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepositoryCustom.java +++ b/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepositoryCustom.java @@ -12,20 +12,26 @@ import java.util.List; public interface BoardRepositoryCustom { - List findNoticesByMember(Member member); + List findPinnedNoticesByMember(Member member); + + List findPinnedNoticesByMemberAndHostType(Member member, HostType hostType); + Page findAllBoards(Member member, HostType hostType, BoardType boardType, Pageable pageable); + Page findKeywordBoards(Member member, String keyword, Pageable pageable); - Page findAllBoardComments(Member member, Board board, Pageable pageable); + Page findAllBoardComments(Board board, Pageable pageable); Page findBoardsByWriterForApp(Member member, String keyword, Pageable pageable); - Page findBoardsByWriterForWeb(Member member,HostType hostType, BoardType boardType, String keyword, Pageable pageable); + + Page findBoardsByWriterForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); Page findBoardsByMemberCommentForApp(Member member, String keyword, Pageable pageable); Page findBoardsByMemberCommentForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); Page findBoardsByMemberHeartForApp(Member member, String keyword, Pageable pageable); + Page findBoardsByMemberHeartForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); Page findNoticesByHostType(Member member, HostType hostType, String keyword, Pageable pageable); diff --git a/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepositoryCustomImpl.java b/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepositoryCustomImpl.java index 3bbd5eee..1539f37e 100644 --- a/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepositoryCustomImpl.java +++ b/src/main/java/com/umc/networkingService/domain/board/repository/BoardRepositoryCustomImpl.java @@ -26,10 +26,12 @@ public class BoardRepositoryCustomImpl implements BoardRepositoryCustom { /* - Home 화면에 보여지는 notices 목록 반환 + 핀 고정된 notices 목록 최대 10개 반환 */ @Override - public List findNoticesByMember(Member member) { + public List findPinnedNoticesByMember(Member member) { + + return query.selectFrom(board) .where(board.isFixed.eq(true) .and( @@ -38,6 +40,21 @@ public List findNoticesByMember(Member member) { .or(CampusPermission(member)) )) .orderBy(board.createdAt.desc()) + .limit(10) + .fetch(); + } + + /* + hostType에 따른 핀고정된 notice 최대 10개 반환 + */ + @Override + public List findPinnedNoticesByMemberAndHostType(Member member, HostType hostType) { + return query.selectFrom(board) + .where(board.isFixed.eq(true) + .and(addHostTypeAndBoardTypeCondition(member, hostType, BoardType.NOTICE)) + ) + .orderBy(board.createdAt.desc()) + .limit(10) .fetch(); } @@ -49,7 +66,8 @@ public Page findAllBoards(Member member, HostType hostType, BoardType boa List memberSemesters = member.getSemesters(); BooleanBuilder predicate = new BooleanBuilder() - .and(eqBoardType(boardType)); + .and(eqBoardType(boardType)) + .and(board.isFixed.isFalse()); switch (hostType) { case CAMPUS -> predicate.and(CampusPermission(member)) @@ -59,7 +77,7 @@ public Page findAllBoards(Member member, HostType hostType, BoardType boa } List boards = query.selectFrom(board).where(predicate) - .orderBy(board.isFixed.desc(), board.createdAt.desc()) + .orderBy(board.createdAt.desc()) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); @@ -94,17 +112,20 @@ public Page findKeywordBoards(Member member, String keyword, Pageable pag 게시글의 모든 댓글 목록 조회 */ @Override - public Page findAllBoardComments(Member member, Board board, Pageable pageable) { + public Page findAllBoardComments(Board board, Pageable pageable) { List boardComments = query.selectFrom(boardComment) - .where(boardComment.board.id.eq(board.getId())) + .where(boardComment.board.id.eq(board.getId()) + .and(boardComment.parentComment.isNull())) // parentComment가 null인 경우만 필터링 .orderBy(boardComment.createdAt.asc()) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); + return new PageImpl<>(boardComments, pageable, query.selectFrom(boardComment) - .where(boardComment.board.id.eq(board.getId())) + .where(boardComment.board.id.eq(board.getId()) + .and(boardComment.parentComment.isNull())) .fetch().size()); } @@ -292,7 +313,7 @@ public Page findNoticesByHostType(Member member, HostType hostType, Strin } /* - permissionHostType에 따라 최상위 권한이하의 공지글 목록을 조회 + permissionHostType에 따라 최상위 권한이하의 공지글 목록을 조회 (운영진용) */ @Override public Page findAllNotices(Member member, HostType permissionHostType, String keyword, Pageable pageable) { @@ -301,7 +322,7 @@ public Page findAllNotices(Member member, HostType permissionHostType, St switch (permissionHostType) { case CENTER: - predicate.and(CenterPermission()); + predicate.or(CenterPermission()); case BRANCH: predicate.or(BranchPermission(member)); case CAMPUS: @@ -321,7 +342,7 @@ public Page findAllNotices(Member member, HostType permissionHostType, St } - //hostTYpe과 boardType에 따라 조건 추가 + //hostType과 boardType에 따라 조건 추가 private BooleanBuilder addHostTypeAndBoardTypeCondition(Member member, HostType hostType, BoardType boardType) { BooleanBuilder predicate = new BooleanBuilder().and(eqBoardType(boardType)); @@ -341,7 +362,6 @@ private void addKeywordSearchCondition(BooleanBuilder predicate, String keyword) } } - private BooleanExpression eqUniversity(Member member) { if (member != null && member.getUniversity() != null) return board.writer.university.eq(member.getUniversity()); @@ -373,5 +393,6 @@ private BooleanExpression BranchPermission(Member member) { private BooleanExpression CampusPermission(Member member) { return eqHostType(CAMPUS).and(eqUniversity(member)); } + } diff --git a/src/main/java/com/umc/networkingService/domain/board/service/BoardCommentService.java b/src/main/java/com/umc/networkingService/domain/board/service/BoardCommentService.java index 051d5387..09aaaa5c 100644 --- a/src/main/java/com/umc/networkingService/domain/board/service/BoardCommentService.java +++ b/src/main/java/com/umc/networkingService/domain/board/service/BoardCommentService.java @@ -1,8 +1,6 @@ package com.umc.networkingService.domain.board.service; -import com.umc.networkingService.domain.board.dto.request.BoardCommentRequest; -import com.umc.networkingService.domain.board.dto.response.BoardCommentResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageInfos; import com.umc.networkingService.domain.board.entity.BoardComment; import com.umc.networkingService.domain.board.entity.BoardType; import com.umc.networkingService.domain.board.entity.HostType; @@ -12,18 +10,25 @@ import java.util.UUID; +import static com.umc.networkingService.domain.board.dto.request.BoardCommentRequest.BoardCommentAddRequest; +import static com.umc.networkingService.domain.board.dto.request.BoardCommentRequest.BoardCommentUpdateRequest; +import static com.umc.networkingService.domain.board.dto.response.BoardCommentResponse.*; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.MyBoardCommentPageElement; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.MyBoardPageElement; + public interface BoardCommentService extends EntityLoader { - BoardCommentResponse.BoardCommentId addBoardComment(Member member, BoardCommentRequest.BoardCommentAddRequest request); + BoardCommentId addBoardComment(Member member, UUID commentId, BoardCommentAddRequest request); - BoardCommentResponse.BoardCommentId updateBoardComment(Member member, UUID commentId, BoardCommentRequest.BoardCommentUpdateRequest request); + BoardCommentId updateBoardComment(Member member, UUID commentId, BoardCommentUpdateRequest request); - BoardCommentResponse.BoardCommentId deleteBoardComment(Member member, UUID commentId); + BoardCommentId deleteBoardComment(Member member, UUID commentId); - BoardCommentResponse.BoardCommentPageInfos showBoardComments(Member member, UUID boardId, Pageable pageable); + BoardCommentPageInfos showBoardComments(Member member, UUID boardId, Pageable pageable); - MyBoardResponse.MyBoardPageInfos showBoardsByMemberCommentForApp(Member member, String keyword, Pageable pageable); + BoardCommentChildrenInfos showChildrenComments(Member member, UUID commentId); - MyBoardResponse.MyBoardCommentPageInfos showBoardsByMemberCommentForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); + BoardPageInfos showBoardsByMemberCommentForApp(Member member, String keyword, Pageable pageable); + BoardCommentPageInfos showBoardsByMemberCommentForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); } diff --git a/src/main/java/com/umc/networkingService/domain/board/service/BoardCommentServiceImpl.java b/src/main/java/com/umc/networkingService/domain/board/service/BoardCommentServiceImpl.java index 3c0f9a1e..638926b3 100644 --- a/src/main/java/com/umc/networkingService/domain/board/service/BoardCommentServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/board/service/BoardCommentServiceImpl.java @@ -1,8 +1,10 @@ package com.umc.networkingService.domain.board.service; import com.umc.networkingService.domain.board.dto.request.BoardCommentRequest; +import com.umc.networkingService.domain.board.dto.request.BoardCommentRequest.BoardCommentAddRequest; import com.umc.networkingService.domain.board.dto.response.BoardCommentResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageInfos; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.MyBoardCommentPageElement; import com.umc.networkingService.domain.board.entity.Board; import com.umc.networkingService.domain.board.entity.BoardComment; import com.umc.networkingService.domain.board.entity.BoardType; @@ -11,14 +13,20 @@ import com.umc.networkingService.domain.board.mapper.BoardMapper; import com.umc.networkingService.domain.board.repository.BoardCommentRepository; import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.service.MemberService; import com.umc.networkingService.global.common.exception.RestApiException; import com.umc.networkingService.global.common.exception.code.BoardCommentErrorCode; +import com.umc.networkingService.global.common.exception.code.BoardErrorCode; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.UUID; +import java.util.*; + +import static com.umc.networkingService.domain.board.dto.response.BoardCommentResponse.*; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.MyBoardPageElement; @Service @RequiredArgsConstructor @@ -29,27 +37,34 @@ public class BoardCommentServiceImpl implements BoardCommentService { private final BoardService boardService; private final BoardCommentMapper boardCommentMapper; private final BoardMapper boardMapper; + private final MemberService memberService; @Override @Transactional - public BoardCommentResponse.BoardCommentId addBoardComment(Member member, BoardCommentRequest.BoardCommentAddRequest request) { + public BoardCommentId addBoardComment(Member member, UUID commentId, BoardCommentAddRequest request) { Board board = boardService.loadEntity(request.getBoardId()); + BoardComment parentComment = Optional.ofNullable(commentId) + .map(this::loadEntity).orElse(null); + BoardComment comment = boardCommentRepository.save( - boardCommentMapper.toEntity(member, board, request)); + boardCommentMapper.toEntity(member, board, parentComment, request.getContent())); + board.increaseCommentCount(); return new BoardCommentResponse.BoardCommentId(comment.getId()); } + @Override @Transactional - public BoardCommentResponse.BoardCommentId updateBoardComment(Member member, UUID commentId, - BoardCommentRequest.BoardCommentUpdateRequest request) { + public BoardCommentId updateBoardComment(Member loginMember, UUID commentId, BoardCommentRequest.BoardCommentUpdateRequest request) { + Member member = memberService.loadEntity(loginMember.getId()); BoardComment comment = loadEntity(commentId); //현재 로그인한 member와 writer가 같지 않으면 수정 권한 없음 - validateMember(comment, member); + if (!boardService.checkWriter(comment.getWriter(), member)) + throw new RestApiException(BoardCommentErrorCode.NO_AUTHORIZATION_BOARD_COMMENT); comment.update(request); @@ -58,43 +73,88 @@ public BoardCommentResponse.BoardCommentId updateBoardComment(Member member, UUI @Override @Transactional - public BoardCommentResponse.BoardCommentId deleteBoardComment(Member member, UUID commentId) { - + public BoardCommentId deleteBoardComment(Member loginMember, UUID commentId) { + Member member = memberService.loadEntity(loginMember.getId()); BoardComment comment = loadEntity(commentId); Board board = comment.getBoard(); + Member writer = comment.getWriter(); - //현재 로그인한 member와 writer가 같지 않으면 삭제 권한 없음 - validateMember(comment, member); + //현재 로그인한 member와 writer가 같지 않고, 로그인 한 멤버보다 상위 운영진이 아니라면 예외 반환 + if (!boardService.checkWriter(writer, member)) { + if (!boardService.checkHighStaff(writer, member)) { + throw new RestApiException(BoardErrorCode.NO_AUTHORIZATION_BOARD); + } + } board.decreaseCommentCount(); - comment.delete(); - + handleCommentDeletion(comment); return new BoardCommentResponse.BoardCommentId(comment.getId()); } @Override - public BoardCommentResponse.BoardCommentPageInfos showBoardComments(Member member, UUID boardId, Pageable pageable) { + public BoardCommentPageInfos showBoardComments(Member loginMember, UUID boardId, Pageable pageable) { + + Member member = memberService.loadEntity(loginMember.getId()); Board board = boardService.loadEntity(boardId); - return boardCommentMapper.toBoardCommentPageInfos( - boardCommentRepository.findAllBoardComments(member, board, pageable)); + + boardService.checkReadPermission(member, board); + + Page comments = boardCommentRepository.findAllBoardComments(board, pageable); + + //isMine 여부를 포함 + List commentPageElements = comments.map(comment -> + boardCommentMapper.toBoardCommentPageElement(comment, + boardMapper.toDetailWriterInfo(comment.getWriter()), + boardService.checkWriter(comment.getWriter(), member))).stream().toList(); + + return boardCommentMapper.toBoardCommentPageInfos(comments, commentPageElements); } + public BoardCommentChildrenInfos showChildrenComments(Member loginMember ,UUID commentId) { + Member member = memberService.loadEntity(loginMember.getId()); + BoardComment comment = loadEntity(commentId); + + boardService.checkReadPermission(member, comment.getBoard()); + if (comment.getChildren() == null) + throw new RestApiException(BoardCommentErrorCode.EMPTY_BOARD_COMMENT_CHILDREN); + + List sortedChildren = comment.getChildren().stream() + .sorted(Comparator.comparing(BoardComment::getCreatedAt)) // 시간 순서대로 정렬 + .toList(); + + List children = new ArrayList<>(); + for (BoardComment child : sortedChildren) { + children.add(boardCommentMapper.toBoardCommentChildrenElement(child, + boardMapper.toDetailWriterInfo(child.getWriter()), + boardService.checkWriter(child.getWriter(), member))); + } + + return new BoardCommentChildrenInfos(children); - @Override - public MyBoardResponse.MyBoardPageInfos showBoardsByMemberCommentForApp(Member member, String keyword, Pageable pageable) { - return boardMapper.toMyBoardPageInfos(boardCommentRepository.findBoardsByMemberCommentForApp(member, keyword, pageable)); } @Override - public MyBoardResponse.MyBoardCommentPageInfos showBoardsByMemberCommentForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable) { - return boardCommentMapper.toMyBoardCommentPageInfos(boardCommentRepository.findBoardsByMemberCommentForWeb(member, hostType, boardType, keyword, pageable)); + public BoardPageInfos showBoardsByMemberCommentForApp(Member member, String keyword, Pageable pageable) { + + Page boards = boardCommentRepository.findBoardsByMemberCommentForApp(member, keyword, pageable); + return boardMapper.toBoardPageInfos(boards, boards.map(boardMapper::toMyBoardPageElement).stream().toList()); } - private void validateMember(BoardComment comment, Member member) { - if(!comment.getWriter().getId().equals(member.getId())) - throw new RestApiException(BoardCommentErrorCode.NO_AUTHORIZATION_BOARD_COMMENT); + @Override + public BoardCommentPageInfos showBoardsByMemberCommentForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable) { + Page boardComments = boardCommentRepository.findBoardsByMemberCommentForWeb(member, hostType, boardType, keyword, pageable); + + return boardCommentMapper.toBoardCommentPageInfos(boardComments, + boardComments.map(boardCommentMapper::toMyBoardCommentPageElement).stream().toList()); + } + private void handleCommentDeletion(BoardComment comment) { + if (boardCommentRepository.existsByParentComment(comment)) { + comment.deleteComment(); + } else { + comment.delete(); + } } @Override diff --git a/src/main/java/com/umc/networkingService/domain/board/service/BoardService.java b/src/main/java/com/umc/networkingService/domain/board/service/BoardService.java index 87807ecd..8a0c8c3d 100644 --- a/src/main/java/com/umc/networkingService/domain/board/service/BoardService.java +++ b/src/main/java/com/umc/networkingService/domain/board/service/BoardService.java @@ -1,8 +1,6 @@ package com.umc.networkingService.domain.board.service; import com.umc.networkingService.domain.board.dto.request.BoardRequest; -import com.umc.networkingService.domain.board.dto.response.BoardResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; import com.umc.networkingService.domain.board.entity.Board; import com.umc.networkingService.domain.board.entity.BoardType; import com.umc.networkingService.domain.board.entity.HostType; @@ -14,31 +12,32 @@ import java.util.List; import java.util.UUID; -public interface BoardService extends EntityLoader { - BoardResponse.BoardId createBoard(Member member, BoardRequest.BoardCreateRequest request, List files); - - BoardResponse.BoardId updateBoard(Member member, UUID boardId, BoardRequest.BoardUpdateRequest request, List files); - - BoardResponse.BoardId deleteBoard(Member member, UUID boardId); +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.*; - BoardResponse.PinnedNotices showPinnedNotices(Member member); +public interface BoardService extends EntityLoader { + BoardId createBoard(Member member, BoardRequest.BoardCreateRequest request, List files); - BoardResponse.BoardPageInfos showBoards(Member member, HostType host, BoardType board, Pageable pageable); + BoardId updateBoard(Member member, UUID boardId, BoardRequest.BoardUpdateRequest request, List files); - BoardResponse.BoardDetail showBoardDetail(Member member, UUID boardId); + BoardId deleteBoard(Member member, UUID boardId); - BoardResponse.BoardSearchPageInfos searchBoard(Member member, String keyword, Pageable pageable); + PinnedNotices showPinnedNotices(Member member, HostType hostType); - BoardResponse.BoardId toggleBoardLike(Member member, UUID boardId); + BoardPageInfos showBoards(Member member, HostType host, BoardType board, Pageable pageable); - MyBoardResponse.MyBoardPageInfos showBoardsByMemberForApp(Member member, String keyword, Pageable pageable); + BoardDetail showBoardDetail(Member member, UUID boardId); - MyBoardResponse.MyBoardPageInfos showBoardsByMemberForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); + BoardPageInfos searchBoard(Member member, String keyword, Pageable pageable); - MyBoardResponse.MyBoardPageInfos showBoardsByMemberHeartForApp(Member member, String keyword, Pageable pageable); + BoardPageInfos showBoardsByMember(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); - MyBoardResponse.MyBoardPageInfos showBoardsByMemberHeartForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); + BoardPageInfos showBoardsByMemberHeart(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable); + BoardId toggleBoardLike(Member member, UUID boardId); Boolean existsByBoardTypeAndHostType(BoardType boardType, HostType hostType); + boolean checkWriter(Member writer, Member member); + boolean checkHighStaff(Member writer, Member member); + void checkReadPermission(Member member, Board board); + } diff --git a/src/main/java/com/umc/networkingService/domain/board/service/BoardServiceImpl.java b/src/main/java/com/umc/networkingService/domain/board/service/BoardServiceImpl.java index aca78b31..409d35d1 100644 --- a/src/main/java/com/umc/networkingService/domain/board/service/BoardServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/board/service/BoardServiceImpl.java @@ -3,7 +3,6 @@ import com.umc.networkingService.domain.board.dto.request.BoardRequest; import com.umc.networkingService.domain.board.dto.response.BoardResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; import com.umc.networkingService.domain.board.entity.*; import com.umc.networkingService.domain.board.mapper.BoardHeartMapper; import com.umc.networkingService.domain.board.mapper.BoardMapper; @@ -16,6 +15,7 @@ import com.umc.networkingService.global.common.exception.RestApiException; import com.umc.networkingService.global.common.exception.code.BoardErrorCode; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -23,9 +23,11 @@ import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.UUID; +import static com.umc.networkingService.domain.board.dto.request.BoardRequest.*; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.*; + @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -40,47 +42,65 @@ public class BoardServiceImpl implements BoardService { @Override - public BoardResponse.PinnedNotices showPinnedNotices(Member loginMember) { - + public PinnedNotices showPinnedNotices(Member loginMember, HostType hostType) { Member member = memberService.loadEntity(loginMember.getId()); - return boardMapper.toPinnedNotices(boardRepository.findNoticesByMember(member)); + List pinnedNotices = (hostType == null) ? + boardRepository.findPinnedNoticesByMember(member) : + boardRepository.findPinnedNoticesByMemberAndHostType(member, hostType); + return boardMapper.toPinnedNotices( + pinnedNotices.stream().map(notice -> boardMapper.toPinnedNotice(notice, + boardMapper.toWriterInfo(notice.getWriter()), + boardFileService.findThumbnailImage(notice))).toList() + ); } + @Override - public BoardResponse.BoardPageInfos showBoards(Member loginMember, HostType hostType, BoardType boardType, Pageable pageable) { + public BoardPageInfos showBoards(Member loginMember, HostType hostType, BoardType boardType, Pageable pageable) { + + checkBadRequest(hostType, boardType); Member member = memberService.loadEntity(loginMember.getId()); - checkBadRequest(hostType,boardType); - return boardMapper.toBoardPageInfos(boardRepository.findAllBoards(member, hostType, boardType, pageable)); - } + Page boards = boardRepository.findAllBoards(member, hostType, boardType, pageable); + return boardMapper.toBoardPageInfos(boards, boards.map(board -> + boardMapper.toBoardPageElement(board, + boardMapper.toWriterInfo(board.getWriter()), + boardFileService.findThumbnailImage(board))).stream().toList()); + } @Override - public BoardResponse.BoardSearchPageInfos searchBoard(Member loginMember, String keyword, Pageable pageable) { + public BoardPageInfos searchBoard(Member loginMember, String keyword, Pageable pageable) { Member member = memberService.loadEntity(loginMember.getId()); - return boardMapper.toBoardSearchPageInfos(boardRepository.findKeywordBoards(member, keyword, pageable)); + Page searchBoards = boardRepository.findKeywordBoards(member, keyword, pageable); + return boardMapper.toBoardPageInfos(searchBoards, searchBoards.map(board -> + boardMapper.toBoardSearchPageElement(board, + boardMapper.toWriterInfo(board.getWriter()), + boardFileService.findThumbnailImage(board))).stream().toList()); } @Override @Transactional - public BoardResponse.BoardDetail showBoardDetail(Member loginMember, UUID boardId) { + public BoardDetail showBoardDetail(Member loginMember, UUID boardId) { Member member = memberService.loadEntity(loginMember.getId()); Board board = loadEntity(boardId); - //게시글을 열람할 권한이 있는지 check - checkSemesterPermission(member, board); + //게시글 열람 권한 check + checkReadPermission(member, board); //좋아요 여부 확인 - boolean isLike = false; - Optional boardHeart = boardHeartRepository.findByMemberAndBoard(member, board); - if (boardHeart.isPresent()) - isLike = boardHeart.get().isChecked(); + boolean isLike = boardHeartRepository.findByMemberAndBoard(member, board) + .map(BoardHeart::isChecked) + .orElse(false); + + //본인글인지 확인 + boolean isMine = checkWriter(board.getWriter(), member); //조회수 증가 board.increaseHitCount(); @@ -89,22 +109,19 @@ public BoardResponse.BoardDetail showBoardDetail(Member loginMember, UUID boardI List boardFiles = boardFileService.findBoardFiles(board).stream() .map(BoardFile::getUrl).toList(); - return boardMapper.toBoardDetail(board, boardFiles, isLike); - + return boardMapper.toBoardDetail(board, boardFiles, boardMapper.toDetailWriterInfo(board.getWriter()), isLike, isMine); } - @Override @Transactional - public BoardResponse.BoardId toggleBoardLike(Member member, UUID boardId) { + public BoardId toggleBoardLike(Member member, UUID boardId) { Board board = loadEntity(boardId); //boardHeart에 없다면 새로 저장 BoardHeart boardHeart = boardHeartRepository.findByMemberAndBoard(member, board) .orElseGet(() -> { BoardHeart newHeart = boardHeartMapper.toBoardHeartEntity(board, member); - boardHeartRepository.save(newHeart); - return newHeart; + return boardHeartRepository.save(newHeart); }); boardHeart.toggleHeart(); @@ -115,42 +132,35 @@ public BoardResponse.BoardId toggleBoardLike(Member member, UUID boardId) { @Override - public MyBoardResponse.MyBoardPageInfos showBoardsByMemberForApp(Member member, String keyword, Pageable pageable) { - return boardMapper.toMyBoardPageInfos(boardRepository.findBoardsByWriterForApp(member, keyword, pageable)); - } + public BoardPageInfos showBoardsByMember(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable) { + Page boards = (hostType != null && boardType != null) ? + boardRepository.findBoardsByWriterForWeb(member, hostType, boardType, keyword, pageable) : + boardRepository.findBoardsByWriterForApp(member, keyword, pageable); - @Override - public MyBoardResponse.MyBoardPageInfos showBoardsByMemberForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable) { - return boardMapper.toMyBoardPageInfos(boardRepository.findBoardsByWriterForWeb(member, hostType, boardType, keyword, pageable)); + return boardMapper.toBoardPageInfos(boards, boards.map(boardMapper::toMyBoardPageElement).stream().toList()); } - @Override - public MyBoardResponse.MyBoardPageInfos showBoardsByMemberHeartForApp(Member member, String keyword, Pageable pageable) { - return boardMapper.toMyBoardPageInfos(boardRepository.findBoardsByMemberHeartForApp(member, keyword, pageable)); - } @Override - public MyBoardResponse.MyBoardPageInfos showBoardsByMemberHeartForWeb(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable) { - return boardMapper.toMyBoardPageInfos(boardRepository.findBoardsByMemberHeartForWeb(member, hostType, boardType, keyword, pageable)); - } + public BoardPageInfos showBoardsByMemberHeart(Member member, HostType hostType, BoardType boardType, String keyword, Pageable pageable) { + Page boards = (hostType != null && boardType != null) ? + boardRepository.findBoardsByMemberHeartForWeb(member, hostType, boardType, keyword, pageable) : + boardRepository.findBoardsByMemberHeartForApp(member, keyword, pageable); - @Override - public Boolean existsByBoardTypeAndHostType(BoardType boardType, HostType hostType) { - return boardRepository.existsByBoardTypeAndHostType(boardType, hostType); + return boardMapper.toBoardPageInfos(boards, boards.map(boardMapper::toMyBoardPageElement).stream().toList()); } @Override @Transactional - public BoardResponse.BoardId createBoard(Member member, BoardRequest.BoardCreateRequest request, List files) { + public BoardId createBoard(Member member, BoardCreateRequest request, List files) { //연합, 지부, 학교 타입 HostType hostType = HostType.valueOf(request.getHostType()); BoardType boardType = BoardType.valueOf(request.getBoardType()); //boardType과 HostType에 따라 금지된 요청, 권한 판단 - checkBadRequest(hostType,boardType); - List semesterPermission = checkPermission(member, hostType, boardType); - + checkBadRequest(hostType, boardType); + List semesterPermission = checkWritePermission(member, hostType, boardType); Board board = boardRepository.save(boardMapper.toEntity(member, request, semesterPermission)); if (files != null) @@ -159,9 +169,11 @@ public BoardResponse.BoardId createBoard(Member member, BoardRequest.BoardCreate return new BoardResponse.BoardId(board.getId()); } + @Override @Transactional - public BoardResponse.BoardId updateBoard(Member member, UUID boardId, BoardRequest.BoardUpdateRequest request, List files) { + public BoardId updateBoard(Member loginMember, UUID boardId, BoardUpdateRequest request, List files) { + Member member = memberService.loadEntity(loginMember.getId()); Board board = loadEntity(boardId); //연합, 지부, 학교 타입 @@ -169,11 +181,11 @@ public BoardResponse.BoardId updateBoard(Member member, UUID boardId, BoardReque BoardType boardType = BoardType.valueOf(request.getBoardType()); //boardType과 HostType에 따라 금지된 요청, 권한 판단 - checkBadRequest(hostType,boardType); - List semesterPermission = checkPermission(member, hostType, boardType); + checkBadRequest(hostType, boardType); + List semesterPermission = checkWritePermission(member, hostType, boardType); //현재 로그인한 member와 writer가 같지 않으면 수정 권한 없음 - if (!board.getWriter().getId().equals(member.getId())) + if (!checkWriter(board.getWriter(), member)) throw new RestApiException(BoardErrorCode.NO_AUTHORIZATION_BOARD); board.update(request, semesterPermission); @@ -182,17 +194,21 @@ public BoardResponse.BoardId updateBoard(Member member, UUID boardId, BoardReque return new BoardResponse.BoardId(board.getId()); } + @Override @Transactional - public BoardResponse.BoardId deleteBoard(Member member, UUID boardId) { + public BoardId deleteBoard(Member loginMember, UUID boardId) { + Member member = memberService.loadEntity(loginMember.getId()); Board board = loadEntity(boardId); + Member writer = board.getWriter(); - //현재 로그인한 member와 writer가 같지 않고, 로그인한 멤버가 운영진이 아니라면 삭제 불가 - if (!board.getWriter().getId().equals(member.getId())) { - if (member.getRole().getPriority() >= Role.MEMBER.getPriority()) { + //현재 로그인한 member와 writer가 같지 않고, 로그인 한 멤버보다 상위 운영진이 아니라면 예외 반환 + if (!checkWriter(writer, member)) { + if (!checkHighStaff(writer, member)) { throw new RestApiException(BoardErrorCode.NO_AUTHORIZATION_BOARD); } } + boardFileService.deleteBoardFiles(board); board.delete(); @@ -200,9 +216,43 @@ public BoardResponse.BoardId deleteBoard(Member member, UUID boardId) { } + @Override + public Boolean existsByBoardTypeAndHostType(BoardType boardType, HostType hostType) { + return boardRepository.existsByBoardTypeAndHostType(boardType, hostType); + } + + //게시글 열람 시 권한 check + @Override + public void checkReadPermission(Member member, Board board) { + //if hostType == CAMPUS -> board writer의 university와 로그인 member의 university 일치한지 확인 + //if hostType == BRANCH -> board writer의 branch와 로그인 member의 branch 일치한지 확인 + boolean hasPermission = true; + + switch (board.getHostType()) { + case CAMPUS -> + hasPermission = board.getWriter().getUniversity().getId().equals(member.getUniversity().getId()); + case BRANCH -> + hasPermission = board.getWriter().getBranch().getId().equals(member.getBranch().getId()); + } + + if (!hasPermission || !checkSemesterPermission(member,board)) { + throw new RestApiException(BoardErrorCode.NO_AUTHORIZATION_BOARD); + } + + } + + //게시글 열람 시 semester 권한 check + private static boolean checkSemesterPermission(Member member, Board board) { + List memberSemesters = member.getSemesters(); + List boardSemesterPermissions = board.getSemesterPermission(); + + //memberSemester의 어떤 기수도 허용기수에 포함되지 않으면 false + return memberSemesters.stream() + .anyMatch(boardSemesterPermissions::contains); + } - //게시글 작성, 수정 시 권한 Check - public List checkPermission(Member member, HostType hostType, BoardType boardType) { + //쓰기 권한 check + private List checkWritePermission(Member member, HostType hostType, BoardType boardType) { //현재 기수 Semester nowSemester = Semester.findActiveSemester(); @@ -211,10 +261,10 @@ public List checkPermission(Member member, HostType hostType, BoardTyp //boardType에 따라 권한 Check switch (boardType) { - case OB -> checkPermissionForOBBoard(member, nowSemester); - case NOTICE -> checkPermissionForNoticeBoard(member, hostType); + case OB -> checkInactiveMember(member, nowSemester); + case NOTICE -> checkNoticePermissionStaff(member, hostType); case WORKBOOK -> { - checkPermissionForWorkbookBoard(member); + checkStaff(member); //워크북의 경우 현재 기수만 볼 수 있도록 허용 permissionSemesters = List.of(nowSemester); } @@ -223,45 +273,33 @@ public List checkPermission(Member member, HostType hostType, BoardTyp } - //OB 게시판 권한 확인 함수 - public void checkPermissionForOBBoard(Member member, Semester nowSemester) { + //멤버가 현재 기수일 경우 예외 반환 + // OB -> Semester의 isActive가 활성화되지 않은 사용자만 가능 + private void checkInactiveMember(Member member, Semester nowSemester) { - // OB -> Semester의 isActive가 활성화되지 않은 사용자만 가능 if (member.getRecentSemester().equals(nowSemester)) throw new RestApiException(BoardErrorCode.NO_AUTHORIZATION_BOARD); } - //공지사항 게시판 권한 확인 함수 - public void checkPermissionForNoticeBoard(Member member, HostType hostType) { + + //NOTICE -> hostType 권한보다 멤버 권한이 높거나 같지 않을 경우 예외 반환 + private void checkNoticePermissionStaff(Member member, HostType hostType) { //HostType priority와 Member Role priority를 비교하여 권한 CHECK if (member.getRole().getPriority() >= hostType.getPriority()) throw new RestApiException(BoardErrorCode.NO_AUTHORIZATION_BOARD); } - //workbook 게시판 권한 확인 함수 - public void checkPermissionForWorkbookBoard(Member member) { - //CAMPUS && WORKBOOK -> 일반 MEMBER는 작성 불가 - if (member.getRole().getPriority() >= Role.MEMBER.getPriority()) - throw new RestApiException(BoardErrorCode.NO_AUTHORIZATION_BOARD); - } + //일반 멤버일 경우 예외 발생 + //CAMPUS && WORKBOOK -> 일반 MEMBER는 작성 불가 + private void checkStaff(Member member) { - //게시글 열람시 semester 권한 check - private static void checkSemesterPermission(Member member, Board board) { - List memberSemesters = member.getSemesters(); - List boardSemesterPermissions = board.getSemesterPermission(); - - if (!memberSemesters.stream() - .anyMatch(boardSemesterPermissions::contains)) + if (member.getRole().getPriority() >= Role.MEMBER.getPriority()) throw new RestApiException(BoardErrorCode.NO_AUTHORIZATION_BOARD); - } - public void checkBadRequest(HostType hostType, BoardType boardType) { - //운영진 공지사항 목록 조회 제외하고는 HostType ALL 불가능 - if (hostType.equals(HostType.ALL)) - throw new RestApiException(BoardErrorCode.BAD_REQUEST_BOARD); + private void checkBadRequest(HostType hostType, BoardType boardType) { //boardType: workbook, hostType: CAMPUS 가 아닐 경우 금지된 요청 if (boardType == BoardType.WORKBOOK && hostType != HostType.CAMPUS) throw new RestApiException(BoardErrorCode.BAD_REQUEST_BOARD); @@ -271,6 +309,18 @@ public void checkBadRequest(HostType hostType, BoardType boardType) { } + @Override + public boolean checkWriter(Member writer, Member member) { + return writer.getId() == member.getId(); + } + + + @Override + public boolean checkHighStaff(Member writer, Member member) { + return member.getRole().getPriority() < writer.getRole().getPriority(); + } + + @Override public Board loadEntity(UUID id) { return boardRepository.findById(id).orElseThrow(() -> new RestApiException(BoardErrorCode.EMPTY_BOARD)); diff --git a/src/main/java/com/umc/networkingService/domain/board/service/StaffBoardService.java b/src/main/java/com/umc/networkingService/domain/board/service/StaffBoardService.java index 1cb5436a..2ed0dba4 100644 --- a/src/main/java/com/umc/networkingService/domain/board/service/StaffBoardService.java +++ b/src/main/java/com/umc/networkingService/domain/board/service/StaffBoardService.java @@ -1,6 +1,8 @@ package com.umc.networkingService.domain.board.service; -import com.umc.networkingService.domain.board.dto.response.BoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardId; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageInfos; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.NoticePageElement; import com.umc.networkingService.domain.board.entity.HostType; import com.umc.networkingService.domain.member.entity.Member; import org.springframework.data.domain.Pageable; @@ -8,7 +10,7 @@ import java.util.UUID; public interface StaffBoardService { - BoardResponse.NoticePageInfos showNotices(Member member, HostType hostType, String keyword, Pageable pageable); + BoardPageInfos showNotices(Member member, HostType hostType, String keyword, Pageable pageable); - BoardResponse.BoardId toggleNoticePin(Member member, UUID boardId, boolean isPinned); + BoardId toggleNoticePin(Member member, UUID boardId, boolean isFixed); } diff --git a/src/main/java/com/umc/networkingService/domain/board/service/StaffBoardServiceImpl.java b/src/main/java/com/umc/networkingService/domain/board/service/StaffBoardServiceImpl.java index b6a675ad..67d3a789 100644 --- a/src/main/java/com/umc/networkingService/domain/board/service/StaffBoardServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/board/service/StaffBoardServiceImpl.java @@ -1,6 +1,7 @@ package com.umc.networkingService.domain.board.service; -import com.umc.networkingService.domain.board.dto.response.BoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageInfos; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.NoticePageElement; import com.umc.networkingService.domain.board.entity.Board; import com.umc.networkingService.domain.board.entity.HostType; import com.umc.networkingService.domain.board.mapper.BoardMapper; @@ -9,12 +10,15 @@ import com.umc.networkingService.global.common.exception.RestApiException; import com.umc.networkingService.global.common.exception.code.BoardErrorCode; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.UUID; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardId; + @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -24,34 +28,35 @@ public class StaffBoardServiceImpl implements StaffBoardService { private final BoardMapper boardMapper; @Override - public BoardResponse.NoticePageInfos showNotices(Member member, HostType hostType, String keyword, Pageable pageable) { - - checkPermissionForNoticeBoard(member,hostType); - - //해당 운영진이 조회 가능한 최상위 hostType을 구함 - HostType permissionHostType = HostType.getPermmissionHostType(member.getRole()); - - // findNoticesByHostType -> 해당 hostType만 조회 가능 (해당 멤버가 조회 가능한 hostType인지 확인 필요) - // findAllNotices -> 해당 운영진이 조회 가능한 모든 hostType의 공지를 조회 가능 - if(hostType.equals(HostType.ALL)) - return boardMapper.toBoardNoticePagingResponse(boardRepository.findAllNotices(member, permissionHostType, keyword,pageable)); - else - return boardMapper.toBoardNoticePagingResponse(boardRepository.findNoticesByHostType(member, hostType, keyword, pageable)); - + public BoardPageInfos showNotices(Member member, HostType hostType, String keyword, Pageable pageable) { + Page notices; + if(hostType == null) { + //해당 운영진이 조회 가능한 최상위 hostType을 구함 + HostType permissionHostType = HostType.getPermmissionHostType(member.getRole()); + // findAllNotices -> 해당 운영진이 조회 가능한 모든 hostType의 공지를 조회 가능 + notices = boardRepository.findAllNotices(member, permissionHostType, keyword, pageable); + } + else { + // findNoticesByHostType -> 해당 hostType만 조회 가능 (해당 멤버가 조회 가능한 hostType인지 확인 필요) + checkPermissionForNoticeBoard(member,hostType); + notices = boardRepository.findNoticesByHostType(member, hostType, keyword, pageable); + } + + return boardMapper.toBoardPageInfos(notices, notices.map(boardMapper::toNoticePageElement).stream().toList()); } @Override @Transactional - public BoardResponse.BoardId toggleNoticePin(Member member, UUID boardId, boolean isPinned) { + public BoardId toggleNoticePin(Member member, UUID boardId, boolean isFixed) { Board board = boardService.loadEntity(boardId); HostType hostType = board.getHostType(); checkPermissionForNoticeBoard(member, hostType); - board.setIsFixed(isPinned); + board.setIsFixed(isFixed); - return new BoardResponse.BoardId(board.getId()); + return new BoardId(board.getId()); } public void checkPermissionForNoticeBoard(Member member, HostType hostType) { diff --git a/src/main/java/com/umc/networkingService/global/common/exception/code/BoardCommentErrorCode.java b/src/main/java/com/umc/networkingService/global/common/exception/code/BoardCommentErrorCode.java index 91ce34d6..133f79e5 100644 --- a/src/main/java/com/umc/networkingService/global/common/exception/code/BoardCommentErrorCode.java +++ b/src/main/java/com/umc/networkingService/global/common/exception/code/BoardCommentErrorCode.java @@ -12,6 +12,7 @@ public enum BoardCommentErrorCode implements ErrorCodeInterface { EMPTY_BOARD_COMMENT(HttpStatus.NOT_FOUND,"COMMENT001","댓글을 찾을 수 없습니다."), NO_AUTHORIZATION_BOARD_COMMENT(HttpStatus.BAD_REQUEST,"COMMENT002", "댓글을 작성/수정/삭제 할 권한이 없습니다."), + EMPTY_BOARD_COMMENT_CHILDREN(HttpStatus.NOT_FOUND, "COMMENT003", "댓글의 대댓글이 없습니다."); ; private final HttpStatus httpStatus; diff --git a/src/test/java/com/umc/networkingService/domain/board/controller/BoardControllerTest.java b/src/test/java/com/umc/networkingService/domain/board/controller/BoardControllerTest.java index 4ac7da31..63f07876 100644 --- a/src/test/java/com/umc/networkingService/domain/board/controller/BoardControllerTest.java +++ b/src/test/java/com/umc/networkingService/domain/board/controller/BoardControllerTest.java @@ -4,10 +4,13 @@ import com.umc.networkingService.domain.board.dto.request.BoardRequest; import com.umc.networkingService.domain.board.dto.response.BoardCommentResponse; import com.umc.networkingService.domain.board.dto.response.BoardResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageInfos; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardSearchPageElement; +import com.umc.networkingService.domain.board.dto.response.WriterInfo; import com.umc.networkingService.domain.board.entity.BoardType; import com.umc.networkingService.domain.board.entity.HostType; import com.umc.networkingService.global.common.enums.Semester; +import com.umc.networkingService.global.converter.DataConverter; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -22,6 +25,7 @@ import java.util.Optional; import java.util.UUID; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; import static org.springframework.http.HttpMethod.PATCH; @@ -47,7 +51,7 @@ public void createBoardTest() throws Exception { .hostType(HostType.CAMPUS.toString()) .build(); - BoardResponse.BoardId response = new BoardResponse.BoardId(board.getId()); + BoardId response = new BoardId(board.getId()); MockMultipartFile file1 = new MockMultipartFile("file", "filename1.jpg", "image/jpeg", "file content".getBytes()); MockMultipartFile file2 = new MockMultipartFile("file", "filename2.jpg", "image/jpeg", "file content".getBytes()); @@ -82,7 +86,7 @@ public void updateBoardTest() throws Exception { .hostType(HostType.CAMPUS.toString()) .build(); - BoardResponse.BoardId response = new BoardResponse.BoardId(board.getId()); + BoardId response = new BoardId(board.getId()); MockMultipartFile file1 = new MockMultipartFile("file", "filename1.jpg", "image/jpeg", "file content".getBytes()); MockMultipartFile request = new MockMultipartFile("request", "request", "application/json", @@ -109,7 +113,7 @@ public void updateBoardTest() throws Exception { @DisplayName("게시글 삭제 API 테스트") public void deleteBoardTest() throws Exception { //given - BoardResponse.BoardId response = new BoardResponse.BoardId(board.getId()); + BoardId response = new BoardId(board.getId()); //when when(boardService.deleteBoard(eq(member), eq(board.getId()))).thenReturn(response); @@ -131,7 +135,7 @@ public void deleteBoardTest() throws Exception { @DisplayName("특정 게시판의 게시글 목록 조회 API 테스트") public void showBoardsTest() throws Exception { // given - BoardResponse.BoardPageInfos response = createMockBoardPageInfos(); + BoardPageInfos response = createMockBoardPageInfos(); // when when(boardService.showBoards(eq(member), any(HostType.class), any(BoardType.class), any(Pageable.class))).thenReturn(response); @@ -155,19 +159,20 @@ public void showBoardsTest() throws Exception { @DisplayName("게시글 상세 조회 API 테스트") public void showBoardDetailTest() throws Exception { // given - BoardResponse.BoardDetail response = BoardResponse.BoardDetail.builder() + BoardDetail response = BoardDetail.builder() .hostType(board.getHostType()) .boardType(board.getBoardType()) - .writer(board.getWriter().getNickname() + "/" + board.getWriter().getName()) - .profileImage(board.getWriter().getProfileImage()) - .semester(Semester.FIFTH) + .writerInfo(WriterInfo.builder() + .writer(board.getWriter().getNickname() + "/" + board.getWriter().getName()) + .profileImage(board.getWriter().getProfileImage()) + .semester(Semester.FIFTH) + .build()) .title(board.getTitle()) .content(board.getContent()) .hitCount(board.getHitCount()) .heartCount(board.getHeartCount()) .boardFiles(new ArrayList<>()) .commentCount(board.getCommentCount()) - .createdAt(board.getCreatedAt()) .build(); // when when(boardService.showBoardDetail(eq(member), eq(board.getId()))).thenReturn(response); @@ -188,7 +193,7 @@ public void showBoardDetailTest() throws Exception { @DisplayName("게시글 검색 API 테스트") public void searchBoardTest() throws Exception { // given - BoardResponse.BoardSearchPageInfos response = createMockBoardSearchPageInfos(); + BoardPageInfos response = createMockBoardSearchPageInfos(); // when when(boardService.searchBoard(eq(member), any(String.class), any(Pageable.class))).thenReturn(response); when(memberRepository.findById(any(UUID.class))).thenReturn(Optional.of(member)); @@ -210,7 +215,7 @@ public void searchBoardTest() throws Exception { @DisplayName("특정 게시글 좋아요/취소 테스트") public void toggleBoardHeart() throws Exception { //given - BoardResponse.BoardId response = new BoardResponse.BoardId(board.getId()); + BoardId response = new BoardId(board.getId()); //when when(boardService.toggleBoardLike(eq(member), eq(board.getId()))).thenReturn(response); @@ -233,15 +238,15 @@ public void addBoardCommentTest() throws Exception { //given BoardCommentRequest.BoardCommentAddRequest boardCommentAddRequest = BoardCommentRequest.BoardCommentAddRequest.builder() - .content("내용") - .boardId(board.getId()) - .build(); + .content("내용") + .boardId(board.getId()) + .build(); String request = objectMapper.writeValueAsString(boardCommentAddRequest); - BoardCommentResponse.BoardCommentId response = new BoardCommentResponse.BoardCommentId(board.getId()); + BoardCommentResponse.BoardCommentId response = new BoardCommentResponse.BoardCommentId(comment.getId()); //when - when(boardCommentService.addBoardComment(eq(member), any(BoardCommentRequest.BoardCommentAddRequest.class))).thenReturn(response); + when(boardCommentService.addBoardComment(eq(member), eq(null), any(BoardCommentRequest.BoardCommentAddRequest.class))).thenReturn(response); when(memberRepository.findById(any(UUID.class))).thenReturn(Optional.of(member)); //then @@ -257,15 +262,47 @@ public void addBoardCommentTest() throws Exception { .andExpect(jsonPath("$.result").exists()); } + @Test + @DisplayName("대댓글 작성 성공 테스트") + public void addReplyBoardCommentTest() throws Exception { + //given + BoardCommentRequest.BoardCommentAddRequest boardCommentAddRequest = + BoardCommentRequest.BoardCommentAddRequest.builder() + .content("대댓글") + .boardId(board.getId()) + .build(); + + String request = objectMapper.writeValueAsString(boardCommentAddRequest); + BoardCommentResponse.BoardCommentId response = new BoardCommentResponse.BoardCommentId(board.getId()); + + //when + when(boardCommentService.addBoardComment(eq(member), eq(comment.getId()), any(BoardCommentRequest.BoardCommentAddRequest.class))).thenReturn(response); + when(memberRepository.findById(any(UUID.class))).thenReturn(Optional.of(member)); + + //then + this.mockMvc.perform( + post("/boards/comments").param("commentId", String.valueOf(comment.getId())) + .header("Authorization", accessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(request)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("COMMON200")) + .andExpect(jsonPath("$.message").value("요청에 성공하였습니다.")) + .andExpect(jsonPath("$.result").exists()) + ; + + } + @Test @DisplayName("댓글 수정 성공 테스트") public void updateBoardCommentTest() throws Exception { //given BoardCommentRequest.BoardCommentUpdateRequest boardCommentUpdateRequest = - BoardCommentRequest.BoardCommentUpdateRequest .builder() - .content("수정") - .build(); + BoardCommentRequest.BoardCommentUpdateRequest.builder() + .content("수정") + .build(); String request = objectMapper.writeValueAsString(boardCommentUpdateRequest); BoardCommentResponse.BoardCommentId response = new BoardCommentResponse.BoardCommentId(comment.getId()); @@ -313,15 +350,15 @@ public void deleteBoardCommentTest() throws Exception { @DisplayName("App용 특정 멤버가 작성한 게시글 목록 조회/검색 API 테스트") public void showMemberBoardsTestForApp() throws Exception { // given - MyBoardResponse.MyBoardPageInfos response = createMockMyBoardResponse(); + BoardPageInfos response = createMockMyBoardResponse(); // when - when(boardService.showBoardsByMemberForApp(eq(member), any(String.class), any(Pageable.class))).thenReturn(response); + when(boardService.showBoardsByMember(eq(member), eq(null), eq(null), any(String.class), any(Pageable.class))).thenReturn(response); when(memberRepository.findById(any(UUID.class))).thenReturn(Optional.of(member)); // then mockMvc.perform(MockMvcRequestBuilders - .get("/boards/member/app") + .get("/boards/member") .param("keyword", "데모데이") .param("page", "0") .header("Authorization", accessToken)) @@ -337,15 +374,15 @@ public void showMemberBoardsTestForApp() throws Exception { @DisplayName("WEB용 특정 멤버가 작성한 게시글 목록 조회/검색 API 테스트") public void showMemberBoardsTestForWeb() throws Exception { // given - MyBoardResponse.MyBoardPageInfos response = createMockMyBoardResponse(); + BoardPageInfos response = createMockMyBoardResponse(); // when - when(boardService.showBoardsByMemberForWeb(eq(member), any(HostType.class), any(BoardType.class), any(String.class), any(Pageable.class))).thenReturn(response); + when(boardService.showBoardsByMember(eq(member), any(HostType.class), any(BoardType.class), any(String.class), any(Pageable.class))).thenReturn(response); when(memberRepository.findById(any(UUID.class))).thenReturn(Optional.of(member)); // then this.mockMvc.perform(MockMvcRequestBuilders - .get("/boards/member/web") + .get("/boards/member") .param("host", "CENTER") .param("board", "FREE") .param("keyword", "") @@ -359,12 +396,11 @@ public void showMemberBoardsTestForWeb() throws Exception { } - @Test @DisplayName("운영진용 교내 공지사항 조회 테스트") public void showStaffNoticesTest() throws Exception { //given - BoardResponse.NoticePageInfos response = createMockNoticePageInfos(); + BoardPageInfos response = createMockNoticePageInfos(); //when when(staffBoardService.showNotices(eq(member), any(HostType.class), any(String.class), any(Pageable.class))).thenReturn(response); when(memberRepository.findById(any(UUID.class))).thenReturn(Optional.of(member)); @@ -386,14 +422,14 @@ public void showStaffNoticesTest() throws Exception { @DisplayName("운영진용 핀설정 테스트") public void setStaffNoticePinTest() throws Exception { //given - BoardResponse.BoardId response = new BoardResponse.BoardId(board.getId()); + BoardId response = new BoardId(board.getId()); //when - when(staffBoardService.toggleNoticePin(eq(member),eq(board.getId()), any(boolean.class))).thenReturn(response); + when(staffBoardService.toggleNoticePin(eq(member), eq(board.getId()), any(boolean.class))).thenReturn(response); when(memberRepository.findById(any(UUID.class))).thenReturn(Optional.of(member)); // then - mockMvc.perform(patch("/staff/boards/notices/{boardId}/pin",board.getId()) - .param("isPinned", "true") + mockMvc.perform(patch("/staff/boards/notices/{boardId}/pin", board.getId()) + .param("isFixed", "true") .header("Authorization", accessToken)) .andDo(print()) .andExpect(status().isOk()) diff --git a/src/test/java/com/umc/networkingService/domain/board/controller/BoardControllerTestConfig.java b/src/test/java/com/umc/networkingService/domain/board/controller/BoardControllerTestConfig.java index 110d3756..a0a437b0 100644 --- a/src/test/java/com/umc/networkingService/domain/board/controller/BoardControllerTestConfig.java +++ b/src/test/java/com/umc/networkingService/domain/board/controller/BoardControllerTestConfig.java @@ -1,9 +1,12 @@ package com.umc.networkingService.domain.board.controller; import com.fasterxml.jackson.databind.ObjectMapper; +import com.umc.networkingService.config.initial.DataLoader; import com.umc.networkingService.config.security.jwt.JwtTokenProvider; import com.umc.networkingService.domain.board.dto.response.BoardResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageElement; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageInfos; +import com.umc.networkingService.domain.board.dto.response.WriterInfo; import com.umc.networkingService.domain.board.entity.Board; import com.umc.networkingService.domain.board.entity.BoardComment; import com.umc.networkingService.domain.board.entity.BoardType; @@ -19,6 +22,7 @@ import com.umc.networkingService.global.common.enums.Part; import com.umc.networkingService.global.common.enums.Role; import com.umc.networkingService.global.common.enums.Semester; +import com.umc.networkingService.global.converter.DataConverter; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -31,6 +35,8 @@ import java.util.List; import java.util.UUID; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.*; + @SpringBootTest @AutoConfigureMockMvc public abstract class BoardControllerTestConfig { @@ -50,7 +56,8 @@ public abstract class BoardControllerTestConfig { protected SemesterPartRepository semesterPartRepository; @MockBean protected StaffBoardService staffBoardService; - + @MockBean + protected DataLoader dataLoader; protected Member member; protected Board board; @@ -118,25 +125,24 @@ protected BoardComment createBoardComment() { //가상의 BoardPageInfos 생성 - protected BoardResponse.BoardPageInfos createMockBoardPageInfos() { - List boardPageResponses = new ArrayList<>(); + protected BoardPageInfos createMockBoardPageInfos() { + List boardPageResponses = new ArrayList<>(); for (int i = 0; i < 5; i++) { - BoardResponse.BoardPageElement boardPageResponse = BoardResponse.BoardPageElement.builder() + BoardPageElement boardPageResponse = BoardPageElement.builder() .title("제목") .content("내용") - .writer("루시/김수민") + .writerInfo(WriterInfo.builder().writer("루시/김수민").profileImage(".../img").build()) .hitCount(1) .commentCount(1) .heartCount(1) - .profileImage(".../img") - .createdAt(LocalDateTime.parse("2024-01-16T14:20:15")) + .createdAt("2024-01-16 14:20:15") .build(); boardPageResponses.add(boardPageResponse); } // 가상의 페이징 정보 설정 - return BoardResponse.BoardPageInfos.builder() + return BoardPageInfos.builder() .page(1) .totalPages(3) .totalElements(30) @@ -146,74 +152,74 @@ protected BoardResponse.BoardPageInfos createMockBoardPageInfos() { .build(); } - protected BoardResponse.BoardSearchPageInfos createMockBoardSearchPageInfos() { - List boardSearchPageElements = new ArrayList<>(); + protected BoardPageInfos createMockBoardSearchPageInfos() { + List boardSearchPageElements = new ArrayList<>(); for (int i = 0; i < 5; i++) { - BoardResponse.BoardSearchPageElement boardSearchPageResponse = BoardResponse.BoardSearchPageElement.builder() + BoardSearchPageElement boardSearchPageResponse = BoardSearchPageElement.builder() .boardType(BoardType.FREE) .hostType(HostType.CAMPUS) .boardId(UUID.randomUUID()) .title("제목") .content("내용") - .writer("루시/김수민") + .writerInfo(WriterInfo.builder().writer("루시/김수민").profileImage(".../img").build()) .hitCount(1) .commentCount(1) .heartCount(1) - .profileImage(".../img") - .createdAt(LocalDateTime.parse("2024-01-16T14:20:15")) + .createdAt("2024-01-16 14:20:15") .build(); + boardSearchPageElements.add(boardSearchPageResponse); } // 가상의 페이징 정보 설정 - return BoardResponse.BoardSearchPageInfos.builder() + return BoardPageInfos.builder() .page(1) .totalPages(3) .totalElements(30) - .boardSearchPageElements(boardSearchPageElements) + .boardPageElements(boardSearchPageElements) .isFirst(true) .isLast(false) .build(); } - protected MyBoardResponse.MyBoardPageInfos createMockMyBoardResponse() { - List myBoardPageElements = new ArrayList<>(); + protected BoardPageInfos createMockMyBoardResponse() { + List myBoardPageElements = new ArrayList<>(); for (int i = 0; i < 5; i++) { - MyBoardResponse.MyBoardPageElement myBoardPageElement = MyBoardResponse.MyBoardPageElement.builder() + MyBoardPageElement myBoardPageElement = MyBoardPageElement.builder() .boardType(BoardType.FREE) .hostType(HostType.CAMPUS) .boardId(UUID.randomUUID()) .title("제목") .hitCount(1) .heartCount(1) - .createdAt(LocalDateTime.parse("2024-01-16T14:20:15")) + .createdAt("2024-01-16 14:20:15") .build(); myBoardPageElements.add(myBoardPageElement); } // 가상의 페이징 정보 설정 - return MyBoardResponse.MyBoardPageInfos.builder() + return BoardPageInfos.builder() .page(1) .totalPages(3) .totalElements(30) - .myBoardPageElements(myBoardPageElements) + .boardPageElements(myBoardPageElements) .isFirst(true) .isLast(false) .build(); } - protected BoardResponse.NoticePageInfos createMockNoticePageInfos() { - List noticePageElements = new ArrayList<>(); + protected BoardPageInfos createMockNoticePageInfos() { + List noticePageElements = new ArrayList<>(); for (int i = 0; i < 5; i++) { - BoardResponse.NoticePageElement noticePageElement = BoardResponse.NoticePageElement.builder() + NoticePageElement noticePageElement = NoticePageElement.builder() .hostType(HostType.CAMPUS) .boardId(UUID.randomUUID()) .title("제목") .hitCount(1) - .createdAt(LocalDateTime.parse("2024-01-16T14:20:15")) + .createdAt("2024-01-16 14:20:15") .isFixed(false) .writer("루시/김수민") .build(); @@ -222,11 +228,11 @@ protected BoardResponse.NoticePageInfos createMockNoticePageInfos() { // 가상의 페이징 정보 설정 - return BoardResponse.NoticePageInfos.builder() + return BoardPageInfos.builder() .page(1) .totalPages(3) .totalElements(30) - .noticePageElements(noticePageElements) + .boardPageElements(noticePageElements) .isFirst(true) .isLast(false) .build(); diff --git a/src/test/java/com/umc/networkingService/domain/board/service/BoardCommentServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/board/service/BoardCommentServiceIntegrationTest.java new file mode 100644 index 00000000..08b91875 --- /dev/null +++ b/src/test/java/com/umc/networkingService/domain/board/service/BoardCommentServiceIntegrationTest.java @@ -0,0 +1,217 @@ +package com.umc.networkingService.domain.board.service; + +import com.umc.networkingService.domain.board.dto.request.BoardCommentRequest; +import com.umc.networkingService.domain.board.dto.response.BoardCommentResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse; +import com.umc.networkingService.domain.board.dto.response.BoardResponse.BoardPageInfos; +import com.umc.networkingService.domain.board.entity.BoardComment; +import com.umc.networkingService.domain.board.entity.BoardType; +import com.umc.networkingService.domain.board.entity.HostType; +import com.umc.networkingService.global.common.exception.RestApiException; +import com.umc.networkingService.global.common.exception.code.BoardErrorCode; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +import static com.umc.networkingService.domain.board.dto.response.BoardCommentResponse.*; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.*; +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("Board Comment 서비스의") +@SpringBootTest +public class BoardCommentServiceIntegrationTest extends BoardServiceTestConfig { + + + @Test + @DisplayName("댓글 작성 성공 테스트") + @Transactional + public void addBoardCommentTest() { + //given + BoardCommentRequest.BoardCommentAddRequest request = BoardCommentRequest.BoardCommentAddRequest.builder() + .content("내용") + .boardId(board.getId()) + .build(); + + //when + BoardCommentId response = boardCommentService.addBoardComment(inhaMember, null, request); + Optional optionalBoardComment = boardCommentRepository.findById(response.getCommentId()); + assertTrue(optionalBoardComment.isPresent()); + BoardComment comment = optionalBoardComment.get(); + + //then + assertEquals("내용", comment.getContent()); + assertEquals(board.getId(), comment.getBoard().getId()); + assertEquals(1, board.getCommentCount()); + } + + @Test + @DisplayName("대댓글 작성 성공 테스트") + @Transactional + public void addReplyOnComment() { + + BoardCommentRequest.BoardCommentAddRequest request = BoardCommentRequest.BoardCommentAddRequest.builder() + .boardId(board.getId()) + .content("대댓글") + .build(); + + BoardCommentId replyId = boardCommentService.addBoardComment(inhaMember, comment.getId(), request); + + BoardComment replyComment = boardCommentService.loadEntity(replyId.getCommentId()); + + assertEquals(comment.getId(), replyComment.getParentComment().getId()); + assertEquals("대댓글", replyComment.getContent()); + assertEquals(board.getId(), replyComment.getBoard().getId()); + + } + + @Test + @DisplayName("댓글 수정 성공 테스트") + @Transactional + public void updateBoardCommentTest() { + //given + BoardCommentRequest.BoardCommentUpdateRequest request = BoardCommentRequest.BoardCommentUpdateRequest.builder() + .content("수정") + .build(); + + //when + boardCommentService.updateBoardComment(inhaMember, comment.getId(), request); + + //then + assertEquals("수정", comment.getContent()); + } + + @Test + @DisplayName("댓글 삭제 성공 테스트") + @Transactional + public void deleteBoardCommentTest() { + //given + int commentCount = board.getCommentCount(); + //when + boardCommentService.deleteBoardComment(inhaMember, comment.getId()); + + //then + assertNotNull(comment.getDeletedAt()); + assertEquals(commentCount - 1, comment.getBoard().getCommentCount()); + } + + @Test + @DisplayName("댓글 삭제 테스트 - 대댓글이 있을 경우") + @Transactional + public void deleteBoardCommentTest2() { + //given + int commentCount = board.getCommentCount(); + BoardCommentRequest.BoardCommentAddRequest request = BoardCommentRequest.BoardCommentAddRequest.builder() + .boardId(board.getId()) + .content("대댓글") + .build(); + + BoardCommentId replyId = boardCommentService.addBoardComment(inhaMember, comment.getId(), request); + + //when + boardCommentService.deleteBoardComment(inhaMember, comment.getId()); + + //then + assertNull(comment.getDeletedAt()); + assertEquals("삭제된 댓글입니다.", comment.getContent()); + assertEquals(commentCount, comment.getBoard().getCommentCount()); + } + + @Test + @DisplayName("댓글 삭제 성공 테스트 - 운영진") + @Transactional + public void deleteBoardCommentFromStaffTest() { + //given + int commentCount = board.getCommentCount(); + //when + boardCommentService.deleteBoardComment(inhaStaff, comment.getId()); + + //then + assertNotNull(comment.getDeletedAt()); + assertEquals(commentCount - 1, comment.getBoard().getCommentCount()); + } + + @Test + @DisplayName("댓글 삭제 실패 테스트") + @Transactional + public void deleteBoardCommentFailTest() { + //given + int commentCount = board.getCommentCount(); + //when + RestApiException exception = assertThrows(RestApiException.class, () -> { + boardCommentService.deleteBoardComment(gachonMember, comment.getId()); + }); + //then + assertEquals(BoardErrorCode.NO_AUTHORIZATION_BOARD.getCode(), exception.getErrorCode().getCode()); + } + @Test + @DisplayName("댓글 목록 조회 테스트") + @Transactional + public void showBoardCommentsTest() { + //given + createBoardComments(); + Pageable pageable = PageRequest.of(1, 10, Sort.by(Sort.Order.asc("created_at"))); + + //when + BoardCommentPageInfos response = boardCommentService.showBoardComments(inhaMember, board.getId(), pageable); + + //then + assertEquals(1, response.getPage()); + assertEquals(3, response.getTotalPages()); + assertEquals(21, response.getTotalElements()); + assertEquals(10, response.getBoardCommentPageElements().size()); + assertEquals("벡스/김준석", response.getBoardCommentPageElements().get(0).getWriterInfo().getWriter()); + assertFalse(response.getBoardCommentPageElements().get(0).getIsMine()); + } + + + @Test + @DisplayName("내가 댓글 쓴 글 목록 조회 테스트 -APP용") + @Transactional + public void showBoardsByMemberCommentTestForApp() { + //given + createBoardComments(); + Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); + + //when + BoardPageInfos response = boardCommentService.showBoardsByMemberCommentForApp(inhaMember, null, pageable); + BoardPageInfos response2 = boardCommentService.showBoardsByMemberCommentForApp(gachonMember, null, pageable); + + //then + assertEquals(0, response.getPage()); + assertEquals(1, response.getTotalPages()); + assertEquals(1, response.getTotalElements()); + assertEquals(1, response.getBoardPageElements().size()); + assertEquals("제목",response.getBoardPageElements().get(0).getTitle()); + + assertEquals(0, response.getPage()); + assertEquals(0, response2.getTotalPages()); + assertEquals(0, response2.getTotalElements()); + assertEquals(0, response2.getBoardPageElements().size()); + } + + @Test + @DisplayName("내가 댓글 쓴 글 목록 조회 테스트 - WEB용") + @Transactional + public void showBoardsByMemberCommentTestForWeb() { + //given + createBoardComments(); + Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); + + //when + BoardCommentPageInfos response = boardCommentService.showBoardsByMemberCommentForWeb(inhaStaff, HostType.CAMPUS, BoardType.FREE,null, pageable); + + //then + assertEquals(0, response.getPage()); + assertEquals(2, response.getTotalPages()); + assertEquals(20, response.getTotalElements()); + assertEquals(10, response.getBoardCommentPageElements().size()); + assertEquals(HostType.CAMPUS, response.getBoardCommentPageElements().get(0).getHostType()); + assertEquals(BoardType.FREE, response.getBoardCommentPageElements().get(0).getBoardType()); + } +} diff --git a/src/test/java/com/umc/networkingService/domain/board/service/BoardServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/board/service/BoardServiceIntegrationTest.java index a5efe889..73dc0f4c 100644 --- a/src/test/java/com/umc/networkingService/domain/board/service/BoardServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/board/service/BoardServiceIntegrationTest.java @@ -1,13 +1,8 @@ package com.umc.networkingService.domain.board.service; -import com.umc.networkingService.domain.board.dto.request.BoardCommentRequest; import com.umc.networkingService.domain.board.dto.request.BoardRequest; -import com.umc.networkingService.domain.board.dto.response.BoardCommentResponse; -import com.umc.networkingService.domain.board.dto.response.BoardResponse; -import com.umc.networkingService.domain.board.dto.response.MyBoardResponse; import com.umc.networkingService.domain.board.entity.Board; -import com.umc.networkingService.domain.board.entity.BoardComment; import com.umc.networkingService.domain.board.entity.BoardType; import com.umc.networkingService.domain.board.entity.HostType; import com.umc.networkingService.global.common.enums.Part; @@ -29,6 +24,7 @@ import java.util.Optional; import java.util.UUID; +import static com.umc.networkingService.domain.board.dto.response.BoardResponse.*; import static org.junit.jupiter.api.Assertions.*; @DisplayName("Board 서비스의 ") @@ -55,7 +51,7 @@ public void createBoardTest() { //files.add(new MockMultipartFile("file", "filename2.jpg", "image/jpeg", "file content".getBytes())); //when - BoardResponse.BoardId response = boardService.createBoard(inhaMember, request, files); + BoardId response = boardService.createBoard(inhaMember, request, files); Optional optionalBoard = boardRepository.findById(response.getBoardId()); assertTrue(optionalBoard.isPresent()); Board board = optionalBoard.get(); @@ -217,15 +213,31 @@ public void showBoardDetailTest() { UUID boardId = board.getId(); //when - BoardResponse.BoardDetail boardDetail = boardService.showBoardDetail(inhaMember, boardId); + BoardDetail boardDetail = boardService.showBoardDetail(inhaMember, boardId); //then - assertEquals("루시/김수민", boardDetail.getWriter()); + assertEquals("루시/김수민", boardDetail.getWriterInfo().getWriter()); assertEquals(1, boardDetail.getHitCount()); - assertEquals(Semester.FIFTH, boardDetail.getSemester()); - assertEquals(Part.SPRING, boardDetail.getPart()); - assertEquals(false, boardDetail.isLiked()); + assertEquals(Semester.FIFTH, boardDetail.getWriterInfo().getSemester()); + assertEquals(Part.SPRING, boardDetail.getWriterInfo().getPart()); + assertEquals(false, boardDetail.getIsLiked()); assertEquals(0, boardDetail.getHeartCount()); + assertTrue(boardDetail.getIsMine()); + } + + @Test + @DisplayName("특정 게시글 상세 조회 실패 테스트") + @Transactional + public void showBoardDetailFailTest() { + //given + UUID boardId = board.getId(); + + //when + RestApiException exception = assertThrows(RestApiException.class, () -> { + boardService.showBoardDetail(gachonMember, boardId); + }); + //then + assertEquals(BoardErrorCode.NO_AUTHORIZATION_BOARD.getCode(), exception.getErrorCode().getCode()); } @@ -239,17 +251,16 @@ public void showBoardsTest() { Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); //when - BoardResponse.BoardPageInfos boardPageInfos = boardService.showBoards(inhaMember, hostType, boardType, pageable); + BoardPageInfos boardPageInfos = boardService.showBoards(inhaMember, hostType, boardType, pageable); //then assertNotNull(boardPageInfos.getBoardPageElements().get(0).getBoardId()); - assertFalse(boardPageInfos.getBoardPageElements().get(0).isFixed()); assertEquals(0, boardPageInfos.getPage()); assertEquals(1, boardPageInfos.getBoardPageElements().size()); assertEquals(1, boardPageInfos.getTotalElements()); //when - BoardResponse.BoardPageInfos boardPageInfos2 = boardService.showBoards(gachonMember, hostType, boardType, pageable); + BoardPageInfos boardPageInfos2 = boardService.showBoards(gachonMember, hostType, boardType, pageable); assertEquals(0, boardPageInfos2.getBoardPageElements().size()); assertEquals(0, boardPageInfos2.getTotalElements()); @@ -265,14 +276,14 @@ public void showBoardsSemesterPermissionsTest() { Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); //when - BoardResponse.BoardPageInfos boardPageInfos = boardService.showBoards(inhaMember, hostType, boardType, pageable); + BoardPageInfos boardPageInfos = boardService.showBoards(inhaMember, hostType, boardType, pageable); //then assertEquals(0, boardPageInfos.getBoardPageElements().size()); assertEquals(0, boardPageInfos.getTotalElements()); //when - BoardResponse.BoardPageInfos boardPageInfos2 = boardService.showBoards(inhaStaff, hostType, boardType, pageable); + BoardPageInfos boardPageInfos2 = boardService.showBoards(inhaStaff, hostType, boardType, pageable); //then assertEquals(1, boardPageInfos2.getBoardPageElements().size()); @@ -291,22 +302,22 @@ public void searchBoardTest() { createBoards(); //when - BoardResponse.BoardSearchPageInfos response = boardService.searchBoard(inhaMember, keyword, pageable); - BoardResponse.BoardSearchPageInfos response2 = boardService.searchBoard(inhaMember, keyword2, pageable); + BoardPageInfos response = boardService.searchBoard(inhaMember, keyword, pageable); + BoardPageInfos response2 = boardService.searchBoard(inhaMember, keyword2, pageable); //then assertEquals(0, response.getPage()); assertEquals(2, response.getTotalPages()); assertEquals(20, response.getTotalElements()); - assertEquals(10, response.getBoardSearchPageElements().size()); - assertEquals(BoardType.FREE, response.getBoardSearchPageElements().get(0).getBoardType()); - assertEquals(HostType.CENTER, response.getBoardSearchPageElements().get(0).getHostType()); + assertEquals(10, response.getBoardPageElements().size()); + assertEquals(BoardType.FREE, response.getBoardPageElements().get(0).getBoardType()); + assertEquals(HostType.CENTER, response.getBoardPageElements().get(0).getHostType()); assertEquals(0, response2.getPage()); assertEquals(1, response2.getTotalPages()); assertEquals(1, response2.getTotalElements()); - assertEquals(1, response2.getBoardSearchPageElements().size()); + assertEquals(1, response2.getBoardPageElements().size()); } @Test @@ -318,87 +329,17 @@ public void toggleBoardLikeTest() { UUID boardId = board.getId(); //when - BoardResponse.BoardId like = boardService.toggleBoardLike(inhaMember, boardId); + BoardId like = boardService.toggleBoardLike(inhaMember, boardId); //then assertEquals(1, board.getHeartCount()); //given - BoardResponse.BoardId cancel = boardService.toggleBoardLike(inhaMember, boardId); + BoardId cancel = boardService.toggleBoardLike(inhaMember, boardId); //then assertEquals(0, board.getHeartCount()); } - @Test - @DisplayName("댓글 작성 성공 테스트") - @Transactional - public void addBoardCommentTest() { - //given - BoardCommentRequest.BoardCommentAddRequest request = BoardCommentRequest.BoardCommentAddRequest.builder() - .content("내용") - .boardId(board.getId()) - .build(); - - //when - BoardCommentResponse.BoardCommentId response = boardCommentService.addBoardComment(inhaMember, request); - Optional optionalBoardComment = boardCommentRepository.findById(response.getCommentId()); - assertTrue(optionalBoardComment.isPresent()); - BoardComment comment = optionalBoardComment.get(); - - //then - assertEquals("내용", comment.getContent()); - assertEquals(board.getId(), comment.getBoard().getId()); - assertEquals(1, board.getCommentCount()); - } - - @Test - @DisplayName("댓글 수정 성공 테스트") - @Transactional - public void updateBoardCommentTest() { - //given - BoardCommentRequest.BoardCommentUpdateRequest request = BoardCommentRequest.BoardCommentUpdateRequest.builder() - .content("수정") - .build(); - - //when - boardCommentService.updateBoardComment(inhaMember, comment.getId(), request); - - //then - assertEquals("수정", comment.getContent()); - } - - @Test - @DisplayName("댓글 삭제 성공 테스트") - @Transactional - public void deleteBoardCommentTest() { - //given - int commentCount = board.getCommentCount(); - //when - boardCommentService.deleteBoardComment(inhaMember, comment.getId()); - - //then - assertNotNull(comment.getDeletedAt()); - assertEquals(commentCount - 1, comment.getBoard().getCommentCount()); - } - - @Test - @DisplayName("댓글 목록 조회 테스트") - @Transactional - public void showBoardCommentsTest() { - //given - createBoardComments(); - Pageable pageable = PageRequest.of(1, 10, Sort.by(Sort.Order.asc("created_at"))); - - //when - BoardCommentResponse.BoardCommentPageInfos response = boardCommentService.showBoardComments(inhaMember, board.getId(), pageable); - - //then - assertEquals(1, response.getPage()); - assertEquals(3, response.getTotalPages()); - assertEquals(21, response.getTotalElements()); - assertEquals(10, response.getBoardCommentPageElements().size()); - assertEquals("벡스/김준석", response.getBoardCommentPageElements().get(0).getWriter()); - } @Test @@ -410,15 +351,15 @@ public void showBoardsByWriterTestForApp() { Pageable pageable = PageRequest.of(1, 10, Sort.by(Sort.Order.desc("created_at"))); //when - MyBoardResponse.MyBoardPageInfos response = boardService.showBoardsByMemberForApp(inhaMember, "데모", pageable); + BoardPageInfos response = boardService.showBoardsByMember(inhaMember, null,null,"데모", pageable); //then assertEquals(1, response.getPage()); assertEquals(2, response.getTotalPages()); assertEquals(20, response.getTotalElements()); - assertEquals(10, response.getMyBoardPageElements().size()); - assertEquals(HostType.CENTER, response.getMyBoardPageElements().get(0).getHostType()); - assertEquals(BoardType.FREE, response.getMyBoardPageElements().get(0).getBoardType()); + assertEquals(10, response.getBoardPageElements().size()); + assertEquals(HostType.CENTER, response.getBoardPageElements().get(0).getHostType()); + assertEquals(BoardType.FREE, response.getBoardPageElements().get(0).getBoardType()); } @Test @@ -430,62 +371,18 @@ public void showBoardsByWriterTestForWeb() { Pageable pageable = PageRequest.of(1, 10, Sort.by(Sort.Order.desc("created_at"))); //when - MyBoardResponse.MyBoardPageInfos response = boardService.showBoardsByMemberForWeb(inhaMember, HostType.CENTER,BoardType.FREE,"데모", pageable); + BoardPageInfos response = boardService.showBoardsByMember(inhaMember, HostType.CENTER,BoardType.FREE,"데모", pageable); //then assertEquals(1, response.getPage()); assertEquals(2, response.getTotalPages()); assertEquals(20, response.getTotalElements()); - assertEquals(10, response.getMyBoardPageElements().size()); - assertEquals(HostType.CENTER, response.getMyBoardPageElements().get(0).getHostType()); - assertEquals(BoardType.FREE, response.getMyBoardPageElements().get(0).getBoardType()); - } - - - @Test - @DisplayName("내가 댓글 쓴 글 목록 조회 테스트 -APP용") - @Transactional - public void showBoardsByMemberCommentTestForApp() { - //given - createBoardComments(); - Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); - - //when - MyBoardResponse.MyBoardPageInfos response = boardCommentService.showBoardsByMemberCommentForApp(inhaMember, null, pageable); - MyBoardResponse.MyBoardPageInfos response2 = boardCommentService.showBoardsByMemberCommentForApp(gachonMember, null, pageable); - - //then - assertEquals(0, response.getPage()); - assertEquals(1, response.getTotalPages()); - assertEquals(1, response.getTotalElements()); - assertEquals(1, response.getMyBoardPageElements().size()); - assertEquals("제목",response.getMyBoardPageElements().get(0).getTitle()); - - assertEquals(0, response.getPage()); - assertEquals(0, response2.getTotalPages()); - assertEquals(0, response2.getTotalElements()); - assertEquals(0, response2.getMyBoardPageElements().size()); + assertEquals(10, response.getBoardPageElements().size()); + assertEquals(HostType.CENTER, response.getBoardPageElements().get(0).getHostType()); + assertEquals(BoardType.FREE, response.getBoardPageElements().get(0).getBoardType()); } - @Test - @DisplayName("내가 댓글 쓴 글 목록 조회 테스트 - WEB용") - @Transactional - public void showBoardsByMemberCommentTestForWeb() { - //given - createBoardComments(); - Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); - //when - MyBoardResponse.MyBoardCommentPageInfos response = boardCommentService.showBoardsByMemberCommentForWeb(inhaStaff, HostType.CAMPUS,BoardType.FREE,null, pageable); - - //then - assertEquals(0, response.getPage()); - assertEquals(2, response.getTotalPages()); - assertEquals(20, response.getTotalElements()); - assertEquals(10, response.getMyBoardCommentPageElement().size()); - assertEquals(HostType.CAMPUS, response.getMyBoardCommentPageElement().get(0).getHostType()); - assertEquals(BoardType.FREE, response.getMyBoardCommentPageElement().get(0).getBoardType()); - } @Test @DisplayName("내가 좋아요한 글 목록 조회 테스트 - APP용") @@ -496,14 +393,14 @@ public void showMemberBoardHeartTestForApp() { Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); //when - MyBoardResponse.MyBoardPageInfos response = boardService.showBoardsByMemberHeartForApp(inhaStaff, null, pageable); + BoardPageInfos response = boardService.showBoardsByMemberHeart(inhaStaff,null,null, null, pageable); //then assertEquals(0, response.getPage()); assertEquals(1, response.getTotalPages()); assertEquals(1, response.getTotalElements()); - assertEquals(1, response.getMyBoardPageElements().size()); - assertEquals(1, response.getMyBoardPageElements().get(0).getHeartCount()); + assertEquals(1, response.getBoardPageElements().size()); + assertEquals(1, response.getBoardPageElements().get(0).getHeartCount()); } @@ -516,13 +413,13 @@ public void showMemberBoardHeartTestForWeb() { Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); //when - MyBoardResponse.MyBoardPageInfos response = boardService.showBoardsByMemberHeartForWeb(inhaMember,HostType.CAMPUS,BoardType.WORKBOOK, null, pageable); + BoardPageInfos response = boardService.showBoardsByMemberHeart(inhaMember,HostType.CAMPUS,BoardType.WORKBOOK, null, pageable); //then assertEquals(0, response.getPage()); assertEquals(0, response.getTotalPages()); assertEquals(0, response.getTotalElements()); - assertEquals(0, response.getMyBoardPageElements().size()); + assertEquals(0, response.getBoardPageElements().size()); } @@ -538,12 +435,12 @@ public void showStaffNoticesTest() { Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.desc("created_at"))); //when - BoardResponse.NoticePageInfos noticePageInfos = staffBoardService.showNotices(inhaStaff,HostType.ALL,null , pageable); + BoardPageInfos noticePageInfos = staffBoardService.showNotices(centerStaff, null, null , pageable); //then - assertEquals(1, noticePageInfos.getNoticePageElements().size()); + assertEquals(1, noticePageInfos.getBoardPageElements().size()); assertEquals(1, noticePageInfos.getTotalElements()); - assertEquals("공지",noticePageInfos.getNoticePageElements().get(0).getTitle()); + assertEquals("연합공지", noticePageInfos.getBoardPageElements().get(0).getTitle()); } @@ -560,7 +457,7 @@ public void showStaffNoticePinTest() { staffBoardService.toggleNoticePin(inhaStaff, notice.getId(), true); //then - assertEquals(true, notice.isFixed()); + assertTrue(notice.isFixed()); } } diff --git a/src/test/java/com/umc/networkingService/domain/board/service/BoardServiceTestConfig.java b/src/test/java/com/umc/networkingService/domain/board/service/BoardServiceTestConfig.java index 35a42062..bde40022 100644 --- a/src/test/java/com/umc/networkingService/domain/board/service/BoardServiceTestConfig.java +++ b/src/test/java/com/umc/networkingService/domain/board/service/BoardServiceTestConfig.java @@ -105,6 +105,7 @@ protected Member createCenterStaff() { .role(Role.CENTER_STAFF) .name("김연합") .nickname("센터") + .semesterParts(createSemesterPartFIFTH(gachonMember)) .build()); } @@ -176,6 +177,7 @@ protected Board createBoard() { .hitCount(0) .heartCount(0) .commentCount(0) + .isFixed(false) .build()); } @@ -234,6 +236,7 @@ protected void createBoards() { .hitCount(0) .heartCount(0) .commentCount(0) + .isFixed(false) .build()); } } diff --git a/src/test/java/com/umc/networkingService/domain/branch/service/BranchUniversityServiceTest.java b/src/test/java/com/umc/networkingService/domain/branch/service/BranchUniversityServiceTest.java index e62b18e9..e29b9076 100644 --- a/src/test/java/com/umc/networkingService/domain/branch/service/BranchUniversityServiceTest.java +++ b/src/test/java/com/umc/networkingService/domain/branch/service/BranchUniversityServiceTest.java @@ -1,18 +1,13 @@ package com.umc.networkingService.domain.branch.service; -import com.umc.networkingService.domain.branch.entity.Branch; import com.umc.networkingService.domain.branch.entity.BranchUniversity; -import com.umc.networkingService.domain.branch.execption.BranchUniversityHandler; import com.umc.networkingService.domain.branch.repository.BranchRepository; import com.umc.networkingService.domain.branch.repository.BranchUniversityRepository; import com.umc.networkingService.domain.university.entity.University; import com.umc.networkingService.domain.university.repository.UniversityRepository; -import com.umc.networkingService.global.common.enums.Semester; import com.umc.networkingService.support.ServiceIntegrationTestConfig; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestExecutionListeners; @@ -24,9 +19,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; @DisplayName("BranchUniversity 서비스의 ") @SpringBootTest @@ -86,5 +78,6 @@ void connectBranchUniversity_AlreadyConnectedUniversity_Failure() { assertThrows(BranchUniversityHandler.class, () -> branchUniversityService.connectBranchUniversity(branch.getId(), universityIds)); } + } diff --git a/src/test/java/com/umc/networkingService/domain/member/service/AuthServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/member/service/AuthServiceIntegrationTest.java index c4e458a8..31d2e46d 100644 --- a/src/test/java/com/umc/networkingService/domain/member/service/AuthServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/member/service/AuthServiceIntegrationTest.java @@ -147,7 +147,6 @@ public void signUpTest() { assertEquals("BLUE(블루)", savedMember.getBranch().getName()); assertEquals("인하대학교", savedMember.getUniversity().getName()); assertEquals(2, savedMember.getSemesterParts().size()); - assertEquals(1, savedMember.getPositions().size()); } @Test