Skip to content

Commit

Permalink
Merge pull request #177 from maeil-mail/173
Browse files Browse the repository at this point in the history
์œ„ํ‚ค ๋ฐ ๋‹ต๋ณ€ ์‚ญ์ œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค.
  • Loading branch information
le2sky authored Jan 24, 2025
2 parents 7cb9dfc + 737fd85 commit cbe7ecc
Show file tree
Hide file tree
Showing 15 changed files with 347 additions and 57 deletions.
19 changes: 12 additions & 7 deletions maeil-wiki/src/main/java/maeilwiki/comment/Comment.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package maeilwiki.comment;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
Expand All @@ -15,7 +14,6 @@
import lombok.NoArgsConstructor;
import maeilsupport.BaseEntity;
import maeilwiki.member.Member;
import maeilwiki.wiki.Wiki;

@Entity
@Getter
Expand All @@ -38,21 +36,28 @@ public class Comment extends BaseEntity {
@JoinColumn(nullable = false)
private Member member;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(nullable = false)
private Wiki wiki;
@Column(nullable = false)
private Long wikiId;

public Comment(String answer, boolean isAnonymous, Member member, Wiki wiki) {
public Comment(String answer, boolean isAnonymous, Member member, Long wikiId) {
validateAnswer(answer);
this.answer = answer;
this.isAnonymous = isAnonymous;
this.member = member;
this.wiki = wiki;
this.wikiId = wikiId;
}

private void validateAnswer(String answer) {
if (answer == null || answer.isBlank()) {
throw new IllegalArgumentException("๋‹ต๋ณ€์€ ํ•„์ˆ˜ ์ž…๋ ฅ๊ฐ’์ž…๋‹ˆ๋‹ค.");
}
}

public void remove() {
if (deletedAt != null) {
throw new IllegalStateException("์ด๋ฏธ ์‚ญ์ œ๋œ ๋‹ต๋ณ€์ž…๋‹ˆ๋‹ค.");
}

deletedAt = LocalDateTime.now();
}
}
29 changes: 0 additions & 29 deletions maeil-wiki/src/main/java/maeilwiki/comment/CommentApi.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

import org.springframework.data.jpa.repository.JpaRepository;

interface CommentRepository extends JpaRepository<Comment, Long> {
public interface CommentRepository extends JpaRepository<Comment, Long> {

boolean existsByWikiIdAndDeletedAtIsNull(Long wikiId);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package maeilwiki.comment;

import maeilwiki.member.Member;
import maeilwiki.wiki.Wiki;

record CommentRequest(String answer, boolean isAnonymous) {
public record CommentRequest(String answer, boolean isAnonymous) {

public Comment toComment(Member member, Wiki wiki) {
return new Comment(answer, isAnonymous, member, wiki);
public Comment toComment(Member member, Long wikiId) {
return new Comment(answer, isAnonymous, member, wikiId);
}
}
20 changes: 12 additions & 8 deletions maeil-wiki/src/main/java/maeilwiki/comment/CommentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@
import lombok.RequiredArgsConstructor;
import maeilwiki.member.Member;
import maeilwiki.member.MemberRepository;
import maeilwiki.wiki.Wiki;
import maeilwiki.wiki.WikiRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationManager;

@Service
@RequiredArgsConstructor
class CommentService {
public class CommentService {

private final WikiRepository wikiRepository;
private final CommentRepository commentRepository;
private final MemberRepository memberRepository;
private final CommentRepository commentRepository;
private final CommentLikeRepository commentLikeRepository;

private final Map<String, Member> transactionTmpMemberMap = new ConcurrentHashMap<>();
Expand All @@ -29,13 +26,20 @@ public void comment(CommentRequest request, Long wikiId) {
String uuid = UUID.randomUUID().toString();
Member temporalMember = new Member(uuid, uuid, "GITHUB");
memberRepository.save(temporalMember);
Wiki wiki = wikiRepository.findById(wikiId)
.orElseThrow(NoSuchElementException::new);
Comment comment = request.toComment(temporalMember, wiki);
Comment comment = request.toComment(temporalMember, wikiId);

commentRepository.save(comment);
}

@Transactional
public void remove(Long commentId) {
// TODO: member ์†Œ์œ ์ธ์ง€ ํ™•์ธํ•ด์•ผํ•œ๋‹ค.
Comment comment = commentRepository.findById(commentId)
.orElseThrow(NoSuchElementException::new);

comment.remove();
}

@Transactional
public void toggleLike(Long id) {
Member member = memberSetting();
Expand Down
9 changes: 8 additions & 1 deletion maeil-wiki/src/main/java/maeilwiki/wiki/Wiki.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package maeilwiki.wiki;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
Expand Down Expand Up @@ -70,4 +69,12 @@ private void validateQuestion(String question) {
throw new IllegalArgumentException("์งˆ๋ฌธ์€ %d์ž ์ดํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.".formatted(MAX_QUESTION_LENGTH));
}
}

public void remove() {
if (deletedAt != null) {
throw new IllegalStateException("์ด๋ฏธ ์‚ญ์ œ๋œ ์œ„ํ‚ค์ž…๋‹ˆ๋‹ค.");
}

deletedAt = LocalDateTime.now();
}
}
38 changes: 38 additions & 0 deletions maeil-wiki/src/main/java/maeilwiki/wiki/WikiApi.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package maeilwiki.wiki;

import lombok.RequiredArgsConstructor;
import maeilwiki.comment.CommentRequest;
import maeilwiki.comment.CommentService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -11,11 +15,45 @@
class WikiApi {

private final WikiService wikiService;
private final CommentService commentService;

@PostMapping("/wiki")
public ResponseEntity<Void> createWiki(@RequestBody WikiRequest request) {
wikiService.create(request);

return ResponseEntity.noContent().build();
}

@DeleteMapping("/wiki/{id}")
public ResponseEntity<Void> deleteWiki(@PathVariable Long id) {
wikiService.remove(id);

return ResponseEntity.noContent().build();
}

@PostMapping("/wiki/{wikiId}/comment")
public ResponseEntity<Void> createComment(@RequestBody CommentRequest request, @PathVariable Long wikiId) {
wikiService.comment(request, wikiId);

return ResponseEntity.noContent().build();
}

/**
* wikiId๋Š” ํ˜„์žฌ ์‚ฌ์šฉ ๊ณ„ํš์ด ์—†์ง€๋งŒ, ์ž…๋ ฅ ๋ฐ›๋Š” ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
* - ๋‚˜์ค‘์— ํŠน์ • ์œ„ํ‚ค๊ฐ€ ์•„์นด์ด๋ธŒ ์ƒํƒœ๋กœ ์ „ํ™˜๋˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
* - comment๊ฐ€ wiki์— ์†ํ•˜๋Š” ๊ฐœ๋…์ด๋ผ๋Š” ๊ฒƒ์„ uri๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
*/
@DeleteMapping("/wiki/{wikiId}/comment/{id}")
public ResponseEntity<Void> deleteComment(@PathVariable Long wikiId, @PathVariable Long id) {
commentService.remove(id);

return ResponseEntity.noContent().build();
}

@PostMapping("/wiki/{wikiId}/comment/{id}/like")
public ResponseEntity<Void> toggleLike(@PathVariable Long wikiId, @PathVariable Long id) {
commentService.toggleLike(id);

return ResponseEntity.noContent().build();
}
}
3 changes: 3 additions & 0 deletions maeil-wiki/src/main/java/maeilwiki/wiki/WikiRepository.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package maeilwiki.wiki;

import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface WikiRepository extends JpaRepository<Wiki, Long> {

Optional<Wiki> findByIdAndDeletedAtIsNull(Long id);
}
31 changes: 31 additions & 0 deletions maeil-wiki/src/main/java/maeilwiki/wiki/WikiService.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package maeilwiki.wiki;

import java.util.NoSuchElementException;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import maeilwiki.comment.CommentRepository;
import maeilwiki.comment.CommentRequest;
import maeilwiki.comment.CommentService;
import maeilwiki.member.Member;
import maeilwiki.member.MemberRepository;
import org.springframework.stereotype.Service;
Expand All @@ -13,6 +17,8 @@ class WikiService {

private final WikiRepository wikiRepository;
private final MemberRepository memberRepository;
private final CommentRepository commentRepository;
private final CommentService commentService;

@Transactional
public void create(WikiRequest request) {
Expand All @@ -23,4 +29,29 @@ public void create(WikiRequest request) {

wikiRepository.save(wiki);
}

@Transactional
public void remove(Long wikiId) {
// TODO : member ์†Œ์œ ์ธ์ง€ ํ™•์ธํ•ด์•ผํ•œ๋‹ค.
validateHasComment(wikiId);
Wiki wiki = wikiRepository.findById(wikiId)
.orElseThrow(NoSuchElementException::new);

wiki.remove();
}

private void validateHasComment(Long wikiId) {
boolean hasComment = commentRepository.existsByWikiIdAndDeletedAtIsNull(wikiId);
if (hasComment) {
throw new IllegalStateException("๋‹ต๋ณ€์ด ์กด์žฌํ•˜๋Š” ์œ„ํ‚ค๋Š” ์‚ญ์ œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
}
}

@Transactional
public void comment(CommentRequest request, Long wikiId) {
Wiki wiki = wikiRepository.findByIdAndDeletedAtIsNull(wikiId)
.orElseThrow(NoSuchElementException::new);

commentService.comment(request, wiki.getId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package maeilwiki.comment;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

import java.util.UUID;
import maeilwiki.member.Member;
import maeilwiki.member.MemberRepository;
import maeilwiki.support.IntegrationTestSupport;
import maeilwiki.wiki.Wiki;
import maeilwiki.wiki.WikiRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

class CommentRepositoryTest extends IntegrationTestSupport {

@Autowired
private WikiRepository wikiRepository;

@Autowired
private MemberRepository memberRepository;

@Autowired
private CommentRepository commentRepository;

@Test
@DisplayName("์ฃผ์–ด์ง„ ์œ„ํ‚ค์— ์†ํ•˜๋Š” ๋‹ต๋ณ€์ด ์กด์žฌํ•˜๋Š”์ง€ ์กฐํšŒํ•œ๋‹ค.")
void existsComment() {
Member member = createMember();
Wiki wiki = createWiki(member);
Wiki noCommentWiki = createWiki(member);
createComment(member, wiki);
Comment comment = createComment(member, noCommentWiki);
comment.remove();

assertAll(
() -> assertThat(commentRepository.existsByWikiIdAndDeletedAtIsNull(wiki.getId())).isTrue(),
() -> assertThat(commentRepository.existsByWikiIdAndDeletedAtIsNull(noCommentWiki.getId())).isFalse()
);
}

private Member createMember() {
Member member = new Member(UUID.randomUUID().toString(), UUID.randomUUID().toString(), "GITHUB");

return memberRepository.save(member);
}

private Wiki createWiki(Member member) {
Wiki wiki = new Wiki("question", "backend", false, member);

return wikiRepository.save(wiki);
}

private Comment createComment(Member member, Wiki wiki) {
Comment comment = new Comment("answer", false, member, wiki.getId());

return commentRepository.save(comment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,17 @@ class CommentServiceTest extends IntegrationTestSupport {
private WikiRepository wikiRepository;

@Test
@DisplayName("์กด์žฌํ•˜์ง€ ์•Š๋Š” ์œ„ํ‚ค์— ๋‹ต๋ณ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์—†๋‹ค.")
void notfound() {
CommentRequest request = new CommentRequest("๋‹ต๋ณ€์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.", false);
Long unknownWikiId = -1L;
@DisplayName("์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋‹ต๋ณ€์„ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋‹ค.")
void notFoundComment() {
Long unknownCommentId = -1L;

assertThatThrownBy(() -> commentService.comment(request, unknownWikiId))
assertThatThrownBy(() -> commentService.remove(unknownCommentId))
.isInstanceOf(NoSuchElementException.class);
}

@Test
@DisplayName("์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋‹ต๋ณ€์— ์ข‹์•„์š”๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†๋‹ค.")
void notFoundComment() {
void notFoundCommentForLike() {
Long unknownCommentId = -1L;

assertThatThrownBy(() -> commentService.toggleLike(unknownCommentId))
Expand Down Expand Up @@ -80,7 +79,7 @@ private Comment createComment() {
Wiki wiki = new Wiki("question", "backend", false, member);
wikiRepository.save(wiki);

Comment comment = new Comment("answer", false, member, wiki);
Comment comment = new Comment("answer", false, member, wiki.getId());
return commentRepository.save(comment);
}
}
Loading

0 comments on commit cbe7ecc

Please sign in to comment.