diff --git a/src/main/java/com/jisungin/api/ApiResponse.java b/src/main/java/com/jisungin/api/ApiResponse.java index 548e9ae..9ac65ed 100644 --- a/src/main/java/com/jisungin/api/ApiResponse.java +++ b/src/main/java/com/jisungin/api/ApiResponse.java @@ -1,5 +1,6 @@ package com.jisungin.api; +import lombok.Builder; import lombok.Getter; import org.springframework.http.HttpStatus; @@ -11,6 +12,7 @@ public class ApiResponse { private String message; private T data; + @Builder public ApiResponse(HttpStatus status, String message, T data) { this.code = status.value(); this.status = status; diff --git a/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java b/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java index 80e1e3e..02a3aea 100644 --- a/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java +++ b/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java @@ -13,6 +13,8 @@ import com.jisungin.application.talkroom.response.TalkRoomResponse; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PatchMapping; @@ -53,4 +55,14 @@ public ApiResponse editTalkRoom(@Valid @RequestBody TalkRoomEd return ApiResponse.ok(talkRoomService.editTalkRoom(request.toServiceRequest(), authContext.getUserId())); } + @DeleteMapping("/talk-rooms/{talkRoomId}") + public ApiResponse deleteTalkRoom(@PathVariable Long talkRoomId, @Auth AuthContext authContext) { + talkRoomService.deleteTalkRoom(talkRoomId, authContext.getUserId()); + + return ApiResponse.builder() + .message("OK") + .status(HttpStatus.OK) + .build(); + } + } diff --git a/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java b/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java index 5726016..19261ac 100644 --- a/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java +++ b/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java @@ -10,6 +10,7 @@ import com.jisungin.domain.ReadingStatus; import com.jisungin.domain.book.Book; import com.jisungin.domain.book.repository.BookRepository; +import com.jisungin.domain.comment.repository.CommentRepository; import com.jisungin.domain.talkroom.TalkRoom; import com.jisungin.domain.talkroom.TalkRoomRole; import com.jisungin.domain.talkroom.repository.TalkRoomRepository; @@ -32,6 +33,7 @@ public class TalkRoomService { private final TalkRoomRoleRepository talkRoomRoleRepository; private final BookRepository bookRepository; private final UserRepository userRepository; + private final CommentRepository commentRepository; @Transactional public TalkRoomResponse createTalkRoom(TalkRoomCreateServiceRequest request, Long userId) { @@ -88,4 +90,21 @@ public TalkRoomResponse editTalkRoom(TalkRoomEditServiceRequest request, Long us talkRoom.getBook().getImageUrl(), talkRoom.getBook().getTitle()); } + @Transactional + public void deleteTalkRoom(Long talkRoomId, Long userId) { + TalkRoom talkRoom = talkRoomRepository.findById(talkRoomId) + .orElseThrow(() -> new BusinessException(ErrorCode.TALK_ROOM_NOT_FOUND)); + + User user = userRepository.findById(userId).orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)); + + if (!talkRoom.isTalkRoomOwner(user.getId())) { + throw new BusinessException(ErrorCode.UNAUTHORIZED_REQUEST); + } + + commentRepository.findByTalkRoom(talkRoom).ifPresent(commentRepository::delete); + + talkRoomRoleRepository.deleteAllByTalkRoom(talkRoom); + talkRoomRepository.delete(talkRoom); + } + } diff --git a/src/main/java/com/jisungin/domain/comment/repository/CommentRepository.java b/src/main/java/com/jisungin/domain/comment/repository/CommentRepository.java index eec459d..deafba2 100644 --- a/src/main/java/com/jisungin/domain/comment/repository/CommentRepository.java +++ b/src/main/java/com/jisungin/domain/comment/repository/CommentRepository.java @@ -1,10 +1,13 @@ package com.jisungin.domain.comment.repository; import com.jisungin.domain.comment.Comment; +import com.jisungin.domain.talkroom.TalkRoom; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface CommentRepository extends JpaRepository { + Optional findByTalkRoom(TalkRoom talkRoom); } diff --git a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java index b11458f..0175155 100644 --- a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java +++ b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java @@ -60,7 +60,6 @@ public TalkRoomFindOneResponse findOneTalkRoom(Long talkRoomId) { findOneTalkRoom.addTalkRoomComments(talkRoomComments); return findOneTalkRoom; - } private List findCommentsByTalkRoomId(Long talkRoomId) { diff --git a/src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java b/src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java index 351d274..e4da65f 100644 --- a/src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java +++ b/src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java @@ -1,6 +1,7 @@ package com.jisungin.api.talkroom; import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -188,4 +189,18 @@ void findOneTalkRoom() throws Exception { .andExpect(jsonPath("$.message").value("OK")); } + @Test + @DisplayName("토크방을 삭제한다.") + void deleteTalkRoom() throws Exception { + // when // then + mockMvc.perform(delete("/v1/talk-rooms/1") + .contentType(APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("200")) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("OK")); + } + } \ No newline at end of file diff --git a/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java b/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java index 03909fd..383e5f7 100644 --- a/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java +++ b/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java @@ -453,11 +453,7 @@ void findOneTalkRoom() { createTalkRoomRole(talkRoom); - Comment comment = Comment.builder() - .talkRoom(talkRoom) - .user(user) - .content("의견 남기기") - .build(); + Comment comment = createComment(talkRoom, user); commentRepository.save(comment); // when @@ -470,17 +466,6 @@ void findOneTalkRoom() { assertThat("user@gmail.com").isEqualTo(findOneTalkRoomResponse.getComments().get(0).getUserName()); } - private void createTalkRoomRole(TalkRoom talkRoom) { - List request = new ArrayList<>(); - request.add("읽는 중"); - request.add("읽음"); - - List readingStatus = ReadingStatus.createReadingStatus(request); - - readingStatus.stream().map(status -> TalkRoomRole.roleCreate(talkRoom, status)) - .forEach(talkRoomRoleRepository::save); - } - @Test @DisplayName("토크방을 단건 조회 했을 때 의견이 담기지 않았아도 조회는 정상적으로 되어야 한다.") void findOneTalkRoomWithCommentNull() { @@ -539,6 +524,111 @@ void findOneTalkRoomWithFindAllComment() { assertThat("의견 19").isEqualTo(findOneTalkRoomResponse.getComments().get(19).getContent()); } + @Test + @DisplayName("토크방을 생성한 유저가 토크방을 삭제한다.") + void deleteTalkRoom() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + TalkRoom talkRoom = createTalkRoom(book, user); + talkRoomRepository.save(talkRoom); + + createTalkRoomRole(talkRoom); + + Comment comment = createComment(talkRoom, user); + + commentRepository.save(comment); + + // when + talkRoomService.deleteTalkRoom(talkRoom.getId(), user.getId()); + + // then + assertThat(0).isEqualTo(talkRoomRepository.findAll().size()); + assertThat(0).isEqualTo(commentRepository.findAll().size()); + } + + @Test + @DisplayName("토크방을 생성하지 않은 유저(UserB)가 다른 유저(UserA)가 생성한 토크방을 삭제할 수 없다.") + void deleteTalkRoomWithUserB() { + // given + User userA = createUser(); + userRepository.save(userA); + + User userB = User.builder() + .name("userB@gmail.com") + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId2") + .oauthType(OauthType.KAKAO) + .build() + ) + .build(); + userRepository.save(userB); + + Book book = createBook(); + bookRepository.save(book); + + TalkRoom talkRoom = createTalkRoom(book, userA); + talkRoomRepository.save(talkRoom); + + createTalkRoomRole(talkRoom); + + Comment comment = createComment(talkRoom, userA); + + commentRepository.save(comment); + + // when // then + assertThatThrownBy(() -> talkRoomService.deleteTalkRoom(talkRoom.getId(), userB.getId())) + .isInstanceOf(BusinessException.class) + .hasMessage("권한이 없는 사용자입니다."); + } + + @Test + @DisplayName("토크방을 삭제할 때 의견이 없어도 정상적으로 삭제가 된다.") + void deleteTalkRoomWithComment() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + TalkRoom talkRoom = createTalkRoom(book, user); + talkRoomRepository.save(talkRoom); + + createTalkRoomRole(talkRoom); + + // when + talkRoomService.deleteTalkRoom(talkRoom.getId(), user.getId()); + + // then + assertThat(0).isEqualTo(talkRoomRepository.findAll().size()); + } + + private static Comment createComment(TalkRoom talkRoom, User user) { + return Comment.builder() + .talkRoom(talkRoom) + .user(user) + .content("의견 남기기") + .build(); + } + + private void createTalkRoomRole(TalkRoom talkRoom) { + List request = new ArrayList<>(); + request.add("읽는 중"); + request.add("읽음"); + + List readingStatus = ReadingStatus.createReadingStatus(request); + + readingStatus.stream().map(status -> TalkRoomRole.roleCreate(talkRoom, status)) + .forEach(talkRoomRoleRepository::save); + } + private static TalkRoom createTalkRoom(Book book, User user) { return TalkRoom.builder() .book(book)