Skip to content
Open
4 changes: 3 additions & 1 deletion src/main/java/codesquad/domain/Answer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;

@Entity
public class Answer extends AbstractEntity implements UrlGeneratable {
Expand Down Expand Up @@ -75,11 +76,12 @@ public void updateContents(User loginUser, String updatedContents) {
this.contents = updatedContents;
}

public void delete(User loginUser) {
public DeleteHistory delete(User loginUser) {
if (!isOwner(loginUser)) {
throw new UnAuthorizedException();
}
this.deleted = true;
return new DeleteHistory(ContentType.ANSWER, this.getId(), loginUser, LocalDateTime.now());
}

@Override
Expand Down
26 changes: 25 additions & 1 deletion src/main/java/codesquad/domain/Question.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package codesquad.domain;

import codesquad.CannotDeleteException;
import org.hibernate.annotations.Where;
import support.domain.AbstractEntity;
import support.domain.UrlGeneratable;
Expand All @@ -9,6 +10,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Entity
public class Question extends AbstractEntity implements UrlGeneratable {
Expand Down Expand Up @@ -86,8 +88,25 @@ public void update(Question updatedQuestion) {
this.writer = updatedQuestion.writer;
}

public void delete() {
public List<DeleteHistory> delete(User loginUser) throws CannotDeleteException {

if (!this.isOwner(loginUser)) {
throw new CannotDeleteException("삭제 권한이 없습니다.");
}

if(!hasSameWriterWithAnswers()) {
throw new CannotDeleteException("삭제 권한이 없습니다.");
}

List<DeleteHistory> deleteHistories = new ArrayList<>();

answers.stream()
.filter(answer -> answer.isOwner(writer))
.forEach(answer -> deleteHistories.add(answer.delete(loginUser)));

this.deleted = true;

return deleteHistories;
}

@Override
Expand All @@ -108,4 +127,9 @@ public boolean equalsTitleAndContents(Question target) {
return this.title.equals(target.getTitle()) &&
this.contents.equals(target.getContents());
}

public boolean hasSameWriterWithAnswers() {
return answers.stream()
.allMatch(answer -> answer.isOwner(writer));
}
}
5 changes: 5 additions & 0 deletions src/main/java/codesquad/service/DeleteHistoryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ public void saveAll(List<DeleteHistory> deleteHistories) {
deleteHistoryRepository.save(deleteHistory);
}
}

@Transactional
public void save(DeleteHistory deleteHistory) {
deleteHistoryRepository.save(deleteHistory);
}
}
9 changes: 2 additions & 7 deletions src/main/java/codesquad/service/QnaService.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,9 @@ public Question update(User loginUser, long id, Question updatedQuestion) throws

@Transactional
public Question deleteQuestion(User loginUser, long questionId) throws CannotDeleteException {
// TODO 삭제 기능 구현
Question savedQuestion = findById(questionId);

if (!savedQuestion.isOwner(loginUser)) {
throw new CannotDeleteException("삭제 권한이 없습니다.");
}

savedQuestion.delete();
deleteHistoryService.saveAll(savedQuestion.delete(loginUser));
return questionRepository.save(savedQuestion);
}

Expand Down Expand Up @@ -92,7 +87,7 @@ public Answer updateAnswer(User loginUser, long id, String updatedContents) {
@Transactional
public Answer deleteAnswer(User loginUser, long id) {
Answer answer = findAnswerById(id);
answer.delete(loginUser);
deleteHistoryService.save(answer.delete(loginUser));
return answerRepository.save(answer);
}
}
39 changes: 37 additions & 2 deletions src/test/java/codesquad/domain/QuestionTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package codesquad.domain;

import codesquad.CannotDeleteException;
import codesquad.CannotDeleteException;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -39,12 +41,45 @@ public void update() {
}

@Test
public void delete() {
public void delete() throws CannotDeleteException {
User loginUser = UserTest.JAVAJIGI;
Question question = newQuestion(1L, loginUser);

question.delete();
question.delete(loginUser);

assertThat(question.isDeleted()).isTrue();
}

@Test(expected = CannotDeleteException.class)
public void delete_fail_when_loginUser_mismatch_writer() throws CannotDeleteException {
User loginUser = UserTest.JAVAJIGI;
User otherUser = UserTest.SANJIGI;
Question question = newQuestion(1L, loginUser);

question.delete(otherUser);
}

@Test
public void delete_success_when_loginUser_is_writer_correspond_to_answers() throws CannotDeleteException {
User loginUser = UserTest.JAVAJIGI;
Question question = newQuestion(1L, loginUser);
question.addAnswer(new Answer(loginUser, "하이"));

assertThat(question.hasSameWriterWithAnswers()).isTrue();

question.delete(loginUser);
assertThat(question.isDeleted()).isTrue();
}

@Test(expected = CannotDeleteException.class)
public void delete_fail_when_loginUser_is_not_writer_correspond_to_answers() throws CannotDeleteException {
User loginUser = UserTest.JAVAJIGI;
User otherUser = UserTest.SANJIGI;
Question question = newQuestion(1L, loginUser);
question.addAnswer(new Answer(otherUser, "하이"));

assertThat(question.hasSameWriterWithAnswers()).isFalse();

question.delete(loginUser);
}
}
17 changes: 11 additions & 6 deletions src/test/java/codesquad/web/ApiQuestionAcceptanceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ public class ApiQuestionAcceptanceTest extends AcceptanceTest {

private Question newQuestion;

@Before
public void setUp() throws Exception {
newQuestion = defaultQuestion();
}

@Test
public void create() {
Question newQuestion = defaultQuestion();
Expand Down Expand Up @@ -68,7 +63,7 @@ public void update() {
}

@Test
public void delete() {
public void delete_success() {
String location = createResource(DEFAULT_QUESTION_URL, newQuestion);

basicAuthTemplate().delete(location);
Expand All @@ -77,6 +72,16 @@ public void delete() {
assertThat(dbQuestion.isDeleted()).isTrue();
}

@Test
public void delete_fail() {
String location = createResource(DEFAULT_QUESTION_URL, newQuestion);

template().delete(location);

Question dbQuestion = getResource(location, Question.class);
assertThat(dbQuestion.isDeleted()).isFalse();
}

@Test
public void delete_다른_사람() {
String location = createResource(DEFAULT_QUESTION_URL, newQuestion);
Expand Down
1 change: 0 additions & 1 deletion src/test/java/codesquad/web/QuestionAcceptanceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public void update_with_login() {
ResponseEntity<String> response = basicAuthTemplate().postForEntity(String.format("/questions/%d", defaultQuestion().getId()), request, String.class);

assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FOUND);
assertThat(response.getHeaders().getLocation().getPath()).startsWith("/questions");
}

@Test
Expand Down