From c342f92e6f8d4ce326ffb53d5b2033123714a08d Mon Sep 17 00:00:00 2001 From: giraffeb Date: Thu, 11 Apr 2024 18:15:47 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A0=88=EA=B1=B0=EC=8B=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81=201=EB=8B=A8=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/qna/domain/Answers.java | 40 ++++++++++++++++++ .../nextstep/qna/domain/DeleteHistories.java | 41 +++++++++++++++++++ .../java/nextstep/qna/domain/Question.java | 5 ++- .../qna/service/DeleteHistoryService.java | 6 +++ .../java/nextstep/qna/service/QnAService.java | 19 ++++----- .../java/nextstep/qna/domain/AnswerTest.java | 15 +++++++ .../nextstep/qna/domain/QuestionTest.java | 33 +++++++++++++++ .../nextstep/qna/service/QnaServiceTest.java | 7 +++- 8 files changed, 151 insertions(+), 15 deletions(-) create mode 100644 src/main/java/nextstep/qna/domain/Answers.java create mode 100644 src/main/java/nextstep/qna/domain/DeleteHistories.java diff --git a/src/main/java/nextstep/qna/domain/Answers.java b/src/main/java/nextstep/qna/domain/Answers.java new file mode 100644 index 000000000..49002af71 --- /dev/null +++ b/src/main/java/nextstep/qna/domain/Answers.java @@ -0,0 +1,40 @@ +package nextstep.qna.domain; + +import nextstep.users.domain.NsUser; + +import java.util.ArrayList; +import java.util.List; + +public class Answers { + private List answerList = new ArrayList(); + + public void add(Answer answer){ + this.answerList.add(answer); + } + + public boolean isAllOwner(NsUser loginUser){ + return this.answerList + .stream() + .allMatch( answer -> answer.isOwner(loginUser)); + } + + private boolean isEmpty(){ + return this.answerList.isEmpty(); + } + + public boolean isDeletable(NsUser loginUser){ + boolean isEmpty = this.isEmpty(); + boolean isAllOwner = this.isAllOwner(loginUser); + + return isEmpty || isAllOwner; + } + + public void setAllDeleted(boolean deleted){ + this.answerList + .forEach( answer -> answer.setDeleted(deleted)); + } + + public List getAll(){ + return this.answerList; + } +} diff --git a/src/main/java/nextstep/qna/domain/DeleteHistories.java b/src/main/java/nextstep/qna/domain/DeleteHistories.java new file mode 100644 index 000000000..c10f0ba5c --- /dev/null +++ b/src/main/java/nextstep/qna/domain/DeleteHistories.java @@ -0,0 +1,41 @@ +package nextstep.qna.domain; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +public class DeleteHistories { + private List deleteHistories; + + public DeleteHistories(){ + this.deleteHistories = new ArrayList<>(); + } + + public DeleteHistories(List deleteHistories){ + this.deleteHistories = deleteHistories; + } + + private void addDeleteHistory(DeleteHistory deleteHistory){ + this.deleteHistories.add(deleteHistory); + } + + public void addQuestion(Question question){ + DeleteHistory deleteHistory = new DeleteHistory(ContentType.QUESTION, question.getId(), question.getWriter(), LocalDateTime.now()); + this.addDeleteHistory(deleteHistory); + } + + public void addAnswer(Answer answer){ + DeleteHistory deleteHistory = new DeleteHistory(ContentType.ANSWER, answer.getId(), answer.getWriter(), LocalDateTime.now()); + this.addDeleteHistory(deleteHistory); + } + + public void addAnswers(Answers answers){ + for(Answer answer : answers.getAll()){ + this.addAnswer(answer); + } + } + + public List getAll(){ + return this.deleteHistories; + } +} diff --git a/src/main/java/nextstep/qna/domain/Question.java b/src/main/java/nextstep/qna/domain/Question.java index b623c52c7..debb1c48b 100644 --- a/src/main/java/nextstep/qna/domain/Question.java +++ b/src/main/java/nextstep/qna/domain/Question.java @@ -15,7 +15,7 @@ public class Question { private NsUser writer; - private List answers = new ArrayList<>(); + private Answers answers = new Answers(); private boolean deleted = false; @@ -81,10 +81,11 @@ public boolean isDeleted() { return deleted; } - public List getAnswers() { + public Answers getAnswers() { return answers; } + @Override public String toString() { return "Question [id=" + getId() + ", title=" + title + ", contents=" + contents + ", writer=" + writer + "]"; diff --git a/src/main/java/nextstep/qna/service/DeleteHistoryService.java b/src/main/java/nextstep/qna/service/DeleteHistoryService.java index 7599dca96..0cf5d126d 100644 --- a/src/main/java/nextstep/qna/service/DeleteHistoryService.java +++ b/src/main/java/nextstep/qna/service/DeleteHistoryService.java @@ -1,5 +1,6 @@ package nextstep.qna.service; +import nextstep.qna.domain.DeleteHistories; import nextstep.qna.domain.DeleteHistory; import nextstep.qna.domain.DeleteHistoryRepository; import org.springframework.stereotype.Service; @@ -18,4 +19,9 @@ public class DeleteHistoryService { public void saveAll(List deleteHistories) { deleteHistoryRepository.saveAll(deleteHistories); } + + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void saveAll(DeleteHistories deleteHistories) { + deleteHistoryRepository.saveAll(deleteHistories.getAll()); + } } diff --git a/src/main/java/nextstep/qna/service/QnAService.java b/src/main/java/nextstep/qna/service/QnAService.java index 5741c84d6..ac0c19f4f 100644 --- a/src/main/java/nextstep/qna/service/QnAService.java +++ b/src/main/java/nextstep/qna/service/QnAService.java @@ -30,20 +30,17 @@ public void deleteQuestion(NsUser loginUser, long questionId) throws CannotDelet throw new CannotDeleteException("질문을 삭제할 권한이 없습니다."); } - List answers = question.getAnswers(); - for (Answer answer : answers) { - if (!answer.isOwner(loginUser)) { - throw new CannotDeleteException("다른 사람이 쓴 답변이 있어 삭제할 수 없습니다."); - } + Answers answers = question.getAnswers(); + if (!answers.isDeletable(loginUser)) { + throw new CannotDeleteException("다른 사람이 쓴 답변이 있어 삭제할 수 없습니다."); } - List deleteHistories = new ArrayList<>(); + DeleteHistories deleteHistories = new DeleteHistories(); question.setDeleted(true); - deleteHistories.add(new DeleteHistory(ContentType.QUESTION, questionId, question.getWriter(), LocalDateTime.now())); - for (Answer answer : answers) { - answer.setDeleted(true); - deleteHistories.add(new DeleteHistory(ContentType.ANSWER, answer.getId(), answer.getWriter(), LocalDateTime.now())); - } + deleteHistories.addQuestion(question); + answers.setAllDeleted(true); + deleteHistories.addAnswers(answers); + deleteHistoryService.saveAll(deleteHistories); } } diff --git a/src/test/java/nextstep/qna/domain/AnswerTest.java b/src/test/java/nextstep/qna/domain/AnswerTest.java index 8e80ffb42..73eca316e 100644 --- a/src/test/java/nextstep/qna/domain/AnswerTest.java +++ b/src/test/java/nextstep/qna/domain/AnswerTest.java @@ -1,8 +1,23 @@ package nextstep.qna.domain; +import nextstep.users.domain.NsUser; import nextstep.users.domain.NsUserTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; public class AnswerTest { public static final Answer A1 = new Answer(NsUserTest.JAVAJIGI, QuestionTest.Q1, "Answers Contents1"); public static final Answer A2 = new Answer(NsUserTest.SANJIGI, QuestionTest.Q1, "Answers Contents2"); + + + + @Test + @DisplayName("삭제 상태 질문 테스트") + public void testDeletedQuestionStatus(){ + A1.setDeleted(true); + assertThat(A1.isDeleted()).isTrue(); + } + } diff --git a/src/test/java/nextstep/qna/domain/QuestionTest.java b/src/test/java/nextstep/qna/domain/QuestionTest.java index 3b8782396..1b703b1a5 100644 --- a/src/test/java/nextstep/qna/domain/QuestionTest.java +++ b/src/test/java/nextstep/qna/domain/QuestionTest.java @@ -1,8 +1,41 @@ package nextstep.qna.domain; import nextstep.users.domain.NsUserTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; public class QuestionTest { public static final Question Q1 = new Question(NsUserTest.JAVAJIGI, "title1", "contents1"); public static final Question Q2 = new Question(NsUserTest.SANJIGI, "title2", "contents2"); + + @Test + @DisplayName("로그인한 사용자의 질문 테스트") + public void testIsLoginUserQuestion(){ + boolean isLoginUser = Q1.isOwner(NsUserTest.JAVAJIGI); + assertThat(isLoginUser).isTrue(); + } + + @Test + @DisplayName("로그인한 사용자가 아닌 질문 테스트") + public void testIsNotLoginUserQuestion(){ + boolean isLoginUser = Q1.isOwner(NsUserTest.SANJIGI); + assertThat(isLoginUser).isFalse(); + } + + @Test + @DisplayName("미삭제 상태 질문 테스트") + public void testIsNotDeleted(){ + boolean isDeleted = Q1.isDeleted(); + assertThat(isDeleted).isFalse(); + } + + @Test + @DisplayName("삭제 상태 질문 테스트") + public void testIsDeleted(){ + Q1.setDeleted(true); + boolean isDeleted = Q1.isDeleted(); + assertThat(isDeleted).isTrue(); + } } diff --git a/src/test/java/nextstep/qna/service/QnaServiceTest.java b/src/test/java/nextstep/qna/service/QnaServiceTest.java index e1e943c23..293ee821f 100644 --- a/src/test/java/nextstep/qna/service/QnaServiceTest.java +++ b/src/test/java/nextstep/qna/service/QnaServiceTest.java @@ -17,6 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.refEq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -82,9 +83,11 @@ public void setUp() throws Exception { } private void verifyDeleteHistories() { - List deleteHistories = Arrays.asList( + List deleteHistorieList = Arrays.asList( new DeleteHistory(ContentType.QUESTION, question.getId(), question.getWriter(), LocalDateTime.now()), new DeleteHistory(ContentType.ANSWER, answer.getId(), answer.getWriter(), LocalDateTime.now())); - verify(deleteHistoryService).saveAll(deleteHistories); + + DeleteHistories deleteHistories = new DeleteHistories(deleteHistorieList); + verify(deleteHistoryService).saveAll(refEq(deleteHistories)); } }