Skip to content

Commit

Permalink
Merge branch 'main' into comment-preview
Browse files Browse the repository at this point in the history
  • Loading branch information
melonturtle authored Jan 15, 2024
2 parents a56f8df + 67c5861 commit ac78d28
Show file tree
Hide file tree
Showing 6 changed files with 1 addition and 191 deletions.
22 changes: 0 additions & 22 deletions src/docs/asciidoc/topic.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -101,28 +101,6 @@ E2. 투표 시간을 미래 시간으로 요청

operation::topic-controller-test/vote-for-topic_voted-at-future_throw-exception[snippets="http-request,http-response"]

### 1.7. 투표 취소
[source.html]
DELETE /topics/{topicId}/vote

OK

operation::topic-controller-test/cancel-vote-for-topic_existing-vote_success[snippets="http-request,http-response"]

E1. 토픽 작성자가 취소

<<_e1_토픽_작성자가_투표, 5. 투표 - E1>>과 동일

E2. 취소 시간을 미래 시간으로 요청

<<_e2_투표_시간을_미래_시간으로_요청, 5. 투표 - E2>>와 동일

E3. 투표하지 않은 멤버가 취소 요청

정상 로직에선 볼 일 없을 듯하므로 메시지는 임의로 작성함.

operation::topic-controller-test/cancel-vote-for-topic_non-existing-vote_throw-exception[snippets="http-request,http-response"]

### 1.8. 투표 수정

OK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,25 +191,6 @@ private static void checkTopicVotable(final Topic topic, final Member member, fi
}
}

@Transactional
public void cancelVoteForTopicByMember(final Long topicId, final Long memberId, final VoteCancelRequest request) {
Member member = findMember(memberId);
Topic topic = findTopic(topicId);
final LocalDateTime votedAt = convertUnixTime(request.canceledAt());

checkTopicVotable(topic, member, votedAt);

Vote vote = findVoteByMemberIdAndTopicId(memberId, topicId);
deleteVote(vote);
}

private void deleteVote(Vote vote) {
vote.removeAssociations();
voteRepository.delete(vote);

deleteVotersComments(vote.getVoter(), vote.getTopic());
}

@Transactional
public void modifyVoteForTopicByMember(final Long topicId, final Long memberId, final VoteModifyRequest request) {

Expand Down
11 changes: 0 additions & 11 deletions src/main/java/life/offonoff/ab/web/TopicController.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,6 @@ public ResponseEntity<VoteResponse> modifyVoteForTopic(
commentService.getLatestCommentOfTopic(topicId)));
}


@DeleteMapping("/{topicId}/vote")
public ResponseEntity<Void> cancelVoteForTopic(
@Authorized Long memberId,
@PathVariable("topicId") Long topicId,
@Valid @RequestBody final VoteCancelRequest request
) {
topicService.cancelVoteForTopicByMember(topicId, memberId, request);
return ok().build();
}

@GetMapping("/{topicId}/comment")
public ResponseEntity<VoteResponse> getTopCommentOfTopic(
@Authorized Long memberId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package life.offonoff.ab.application.service;

import life.offonoff.ab.application.service.member.MemberService;
import life.offonoff.ab.application.service.request.VoteCancelRequest;
import life.offonoff.ab.application.service.request.VoteRequest;
import life.offonoff.ab.application.service.request.auth.SignUpRequest;
import life.offonoff.ab.domain.keyword.Keyword;
Expand All @@ -11,11 +10,10 @@
import life.offonoff.ab.domain.topic.choice.ChoiceOption;
import life.offonoff.ab.domain.vote.Vote;
import life.offonoff.ab.exception.FutureTimeRequestException;
import life.offonoff.ab.exception.MemberNotVoteException;
import life.offonoff.ab.exception.TopicReportDuplicateException;
import life.offonoff.ab.exception.VoteByAuthorException;
import life.offonoff.ab.repository.keyword.KeywordRepository;
import life.offonoff.ab.repository.VoteRepository;
import life.offonoff.ab.repository.keyword.KeywordRepository;
import life.offonoff.ab.repository.member.MemberRepository;
import life.offonoff.ab.repository.topic.TopicRepository;
import life.offonoff.ab.web.response.topic.TopicResponse;
Expand Down Expand Up @@ -187,39 +185,6 @@ void voteForTopicByMember_votedAtFuture_throwException() {
.isInstanceOf(FutureTimeRequestException.class);
}

@Test
void cancelVoteForTopicByMember_existingVote_success() {
Member author = createMember();
Member voter = createMember();
TopicResponse response = createMembersTopic(author.getId());
VoteRequest request = new VoteRequest(
ChoiceOption.CHOICE_A, LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond());
topicService.voteForTopicByMember(response.topicId(), voter.getId(), request);

topicService.cancelVoteForTopicByMember(
response.topicId(), voter.getId(),
new VoteCancelRequest(LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond()));
// Topic is still alive
Topic topic = topicRepository.findById(response.topicId()).get();
assertThat(topic.getVotes()).isEmpty();
// No votes left
assertThat(voteRepository.findAll()).isEmpty();
}

@Test
void cancelVoteForTopicByMember_nonExistingVote_throwException() {
Member author = createMember();
Member voter = createMember();
TopicResponse response = createMembersTopic(author.getId());

ThrowingCallable code = () -> topicService.cancelVoteForTopicByMember(
response.topicId(), voter.getId(),
new VoteCancelRequest(LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond()));

assertThatThrownBy(code)
.isInstanceOf(MemberNotVoteException.class);
}

private Member createMember() {
Member member = memberService.join(new SignUpRequest("email", "password", Provider.NONE));
member.registerPersonalInfo(new PersonalInfo("nickname", LocalDate.now(), Gender.MALE, "job"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,82 +316,6 @@ void create_vote() {
assertThat(voter.votedAlready(topic)).isTrue();
}

@Test
@DisplayName("투표 취소")
void cancel_vote() {
// given
Long topicId = 1L;
LocalDateTime deadline = LocalDateTime.now().plusHours(1);

Member author = TestMember.builder()
.id(1L)
.build().buildMember();
Member voter = TestMember.builder()
.id(2L)
.build().buildMember();

Topic topic = TestTopic.builder()
.id(topicId)
.deadline(deadline)
.author(author)
.build().buildTopic();

// Vote 생성
Vote vote = new Vote(ChoiceOption.CHOICE_A, LocalDateTime.now());
vote.associate(voter, topic);

when(memberRepository.findByIdAndActiveTrue(anyLong())).thenReturn(Optional.of(voter));
when(topicRepository.findByIdAndActiveTrue(anyLong())).thenReturn(Optional.of(topic));
when(voteRepository.findByVoterIdAndTopicId(any(), any())).thenReturn(Optional.of(vote));

// when
topicService.cancelVoteForTopicByMember(topicId, 2L, new VoteCancelRequest(getEpochSecond(deadline.minusHours(1))));

// then
assertThat(author.votedAlready(topic)).isFalse();
}

@Test
@DisplayName("투표 취소하면 투표자 댓글 모두 삭제")
void cancel_vote_then_delete_voters_comments() {
// given
Long topicId = 1L;
LocalDateTime deadline = LocalDateTime.now().plusHours(1);

Member author = TestMember.builder()
.id(1L)
.build().buildMember();

Member voter = TestMember.builder()
.id(2L)
.build().buildMember();

Topic topic = TestTopic.builder()
.id(topicId)
.deadline(deadline)
.author(author)
.build().buildTopic();

// Vote 생성
Vote vote = new Vote(ChoiceOption.CHOICE_A, LocalDateTime.now());
vote.associate(voter, topic);

// Comment 생성
Comment comment1 = Comment.createVotersComment(vote, "content1");
Comment comment2 = Comment.createVotersComment(vote, "content2");

when(memberRepository.findByIdAndActiveTrue(anyLong())).thenReturn(Optional.of(voter));
when(topicRepository.findByIdAndActiveTrue(anyLong())).thenReturn(Optional.of(topic));
when(voteRepository.findByVoterIdAndTopicId(any(), any())).thenReturn(Optional.of(vote));
when(commentRepository.deleteAllByWriterIdAndTopicId(anyLong(), anyLong())).thenReturn(2);

// when
topicService.cancelVoteForTopicByMember(topicId, 2L, new VoteCancelRequest(getEpochSecond(deadline.minusHours(1))));

// then
assertThat(topic.getCommentCount()).isZero();
}

@Test
@DisplayName("투표를 수정하면 기존 댓글 삭제")
void modify_vote() {
Expand Down
27 changes: 0 additions & 27 deletions src/test/java/life/offonoff/ab/web/TopicControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -242,33 +242,6 @@ void voteForTopic_votedAtFuture_throwException() throws Exception {
.andExpect(jsonPath("abCode").value("FUTURE_TIME_REQUEST"));
}

@Test
void cancelVoteForTopic_existingVote_success() throws Exception {
VoteCancelRequest request = new VoteCancelRequest(
LocalDateTime.now().plusMinutes(30).atZone(ZoneId.systemDefault()).toEpochSecond()
);
mvc.perform(delete(TopicUri.VOTE, 1).with(csrf().asHeader())
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().registerModule(new JavaTimeModule()) // For serializing localdatetime
.writeValueAsString(request)))
.andExpect(status().isOk());
}

@Test
void cancelVoteForTopic_nonExistingVote_throwException() throws Exception {
doThrow(new MemberNotVoteException(2L, 1L))
.when(topicService).cancelVoteForTopicByMember(any(), any(), any());
VoteCancelRequest request = new VoteCancelRequest(
LocalDateTime.now().plusMinutes(30).atZone(ZoneId.systemDefault()).toEpochSecond()
);
mvc.perform(delete(TopicUri.VOTE, 1).with(csrf().asHeader())
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().registerModule(new JavaTimeModule()) // For serializing localdatetime
.writeValueAsString(request)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("abCode").value("MEMBER_NOT_VOTE"));
}

@Test
void modifyVoteForTopic_not_duplicated_option() throws Exception {

Expand Down

0 comments on commit ac78d28

Please sign in to comment.