Skip to content

Commit

Permalink
Merge pull request #39 from jisung-in/feature/38-talkroom-comment-edi…
Browse files Browse the repository at this point in the history
…t-delete-api

[Feature] TalkRoom Comment 수정, 삭제 API 구현
  • Loading branch information
AHNYUNKI authored Mar 25, 2024
2 parents a7227bc + 2cf58a6 commit 3675e63
Show file tree
Hide file tree
Showing 10 changed files with 334 additions and 7 deletions.
22 changes: 22 additions & 0 deletions src/main/java/com/jisungin/api/comment/CommentController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import com.jisungin.api.ApiResponse;
import com.jisungin.api.comment.request.CommentCreateRequest;
import com.jisungin.api.comment.request.CommentEditRequest;
import com.jisungin.api.oauth.Auth;
import com.jisungin.api.oauth.AuthContext;
import com.jisungin.application.comment.CommentService;
import com.jisungin.application.comment.response.CommentResponse;
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.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
Expand All @@ -28,4 +32,22 @@ public ApiResponse<CommentResponse> writeComment(@PathVariable Long talkRoomId,
return ApiResponse.ok(commentService.writeComment(request.toService(), talkRoomId, authContext.getUserId()));
}

@PatchMapping("/talk-rooms/comments/{commentId}")
public ApiResponse<CommentResponse> editComment(@PathVariable Long commentId,
@Valid @RequestBody CommentEditRequest request,
@Auth AuthContext authContext) {
return ApiResponse.ok(commentService.editComment(commentId, request.toService(), authContext.getUserId()));
}

@DeleteMapping("/talk-rooms/comments/{commentId}")
public ApiResponse<Void> deleteComment(@PathVariable Long commentId,
@Auth AuthContext authContext) {
commentService.deleteComment(commentId, authContext.getUserId());

return ApiResponse.<Void>builder()
.message("OK")
.status(HttpStatus.OK)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.jisungin.api.comment.request;

import com.jisungin.application.comment.request.CommentEditServiceRequest;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class CommentEditRequest {

private String content;

@Builder
private CommentEditRequest(String content) {
this.content = content;
}

public CommentEditServiceRequest toService() {
return CommentEditServiceRequest.builder()
.content(content)
.build();
}

}
34 changes: 34 additions & 0 deletions src/main/java/com/jisungin/application/comment/CommentService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.jisungin.application.comment;

import com.jisungin.application.comment.request.CommentCreateServiceRequest;
import com.jisungin.application.comment.request.CommentEditServiceRequest;
import com.jisungin.application.comment.response.CommentResponse;
import com.jisungin.domain.comment.Comment;
import com.jisungin.domain.comment.repository.CommentRepository;
Expand All @@ -12,7 +13,9 @@
import com.jisungin.exception.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Transactional(readOnly = true)
@RequiredArgsConstructor
@Service
public class CommentService {
Expand All @@ -21,6 +24,7 @@ public class CommentService {
private final TalkRoomRepository talkRoomRepository;
private final UserRepository userRepository;

@Transactional
public CommentResponse writeComment(CommentCreateServiceRequest request, Long talkRoomId, Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));
Expand All @@ -35,4 +39,34 @@ public CommentResponse writeComment(CommentCreateServiceRequest request, Long ta
return CommentResponse.of(comment.getContent(), user.getName());
}

@Transactional
public CommentResponse editComment(Long commentId, CommentEditServiceRequest request, Long userId) {
Comment comment = commentRepository.findById(commentId)
.orElseThrow(() -> new BusinessException(ErrorCode.COMMENT_NOT_FOUND));

User user = userRepository.findById(userId).orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));

if (!comment.isCommentOwner(user.getId())) {
throw new BusinessException(ErrorCode.UNAUTHORIZED_REQUEST);
}

comment.edit(request.getContent());

return CommentResponse.of(comment.getContent(), user.getName());
}

@Transactional
public void deleteComment(Long commentId, Long userId) {
Comment comment = commentRepository.findById(commentId)
.orElseThrow(() -> new BusinessException(ErrorCode.COMMENT_NOT_FOUND));

User user = userRepository.findById(userId).orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));

if (!comment.isCommentOwner(user.getId())) {
throw new BusinessException(ErrorCode.UNAUTHORIZED_REQUEST);
}

commentRepository.delete(comment);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.jisungin.application.comment.request;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class CommentEditServiceRequest {

private String content;

@Builder
private CommentEditServiceRequest(String content) {
this.content = content;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public TalkRoomResponse editTalkRoom(TalkRoomEditServiceRequest request, Long us
throw new BusinessException(ErrorCode.UNAUTHORIZED_REQUEST);
}

talkRoom.edit(request);
talkRoom.edit(request.getTitle(), request.getContent());

talkRoomRoleRepository.deleteAllByTalkRoom(talkRoom);

Expand Down
18 changes: 17 additions & 1 deletion src/main/java/com/jisungin/domain/comment/Comment.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
import com.jisungin.domain.BaseEntity;
import com.jisungin.domain.talkroom.TalkRoom;
import com.jisungin.domain.user.User;
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand Down Expand Up @@ -47,4 +55,12 @@ public static Comment create(CommentCreateServiceRequest request, User user, Tal
.build();
}

public boolean isCommentOwner(Long userId) {
return user.isMe(userId);
}

public void edit(String requestContent) {
this.content = requestContent != null ? requestContent : content;
}

}
7 changes: 3 additions & 4 deletions src/main/java/com/jisungin/domain/talkroom/TalkRoom.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.jisungin.domain.talkroom;

import com.jisungin.application.talkroom.request.TalkRoomEditServiceRequest;
import com.jisungin.domain.BaseEntity;
import com.jisungin.domain.book.Book;
import com.jisungin.domain.user.User;
Expand Down Expand Up @@ -60,9 +59,9 @@ public static TalkRoom create(String title, String content, Book book, User user
.build();
}

public void edit(TalkRoomEditServiceRequest request) {
this.title = request.getTitle() != null ? request.getTitle() : title;
this.content = request.getContent() != null ? request.getContent() : content;
public void edit(String requestTitle, String requestContent) {
this.title = requestTitle != null ? requestTitle : title;
this.content = requestContent != null ? requestContent : content;
}

public boolean isTalkRoomOwner(Long userId) {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/jisungin/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public enum ErrorCode {
PARTICIPATION_CONDITION_ERROR(400, "참가 조건은 1개 이상이어야 합니다."),
OAUTH_TYPE_NOT_FOUND(404, "지원하지 않는 소셜 로그인입니다."),
TALK_ROOM_NOT_FOUND(400, "토크방을 찾을 수 없습니다."),
UNAUTHORIZED_REQUEST(400, "권한이 없는 사용자입니다.");
UNAUTHORIZED_REQUEST(400, "권한이 없는 사용자입니다."),
COMMENT_NOT_FOUND(404, "의견을 찾을 수 없습니다.");


private final int code;
Expand Down
37 changes: 37 additions & 0 deletions src/test/java/com/jisungin/api/comment/CommentControllerTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.jisungin.api.comment;

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.patch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.jisungin.ControllerTestSupport;
import com.jisungin.api.comment.request.CommentCreateRequest;
import com.jisungin.api.comment.request.CommentEditRequest;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -51,4 +54,38 @@ void writeCommentWithEmptyContent() throws Exception {
.andExpect(jsonPath("$.message").value("내용은 필수 입니다."));
}

@Test
@DisplayName("의견을 작성한 유저가 자신의 의견을 수정한다.")
void editComment() throws Exception {
// given
CommentEditRequest request = CommentEditRequest.builder()
.content("의견 수정")
.build();

// when // then
mockMvc.perform(patch("/v1/talk-rooms/comments/1")
.content(objectMapper.writeValueAsString(request))
.contentType(APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value("200"))
.andExpect(jsonPath("$.status").value("OK"))
.andExpect(jsonPath("$.message").value("OK"));
}

@Test
@DisplayName("의견을 작성한 유저가 자신의 의견을 삭제한다.")
void deleteComment() throws Exception {
// when // then
mockMvc.perform(delete("/v1/talk-rooms/comments/1")
.contentType(APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value("200"))
.andExpect(jsonPath("$.status").value("OK"))
.andExpect(jsonPath("$.message").value("OK"));
}

}
Loading

0 comments on commit 3675e63

Please sign in to comment.