Skip to content

Commit

Permalink
feat: 퀴즈 응답 DTO에 학습 여부 정보 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
amaran-th committed Aug 11, 2023
1 parent df92752 commit 9745eef
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ public class QuizStepDefinitions extends AcceptanceSteps {

//:todo keyword 와 합친 이후에 작성 예정
@When("퀴즈를 생성하면")
public void 퀴즈를생성하면(Long sessionId, Long keywordId) {
public void 퀴즈를_생성하면(Long sessionId, Long keywordId) {
final QuizRequest 수달이_만든_테스트_퀴즈 = new QuizRequest("수달이 만든 테스트 퀴즈");
context.invokeHttpPost("", 수달이_만든_테스트_퀴즈);
}

@Then("퀴즈가 추가된다")
public void 강의를추가된다() {
public void 퀴즈가_추가된다() {
assertThat(context.response.statusCode()).isEqualTo(HttpStatus.CREATED.value());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class QuizDocumentation extends NewDocumentation {

@Test
void Keyword별_Quiz_목록_조회() {
given(quizService.findQuizzesByKeywordId(any())).willReturn(QUIZZES_RESPONSE);
given(quizService.findQuizzesByKeywordId(any(), any())).willReturn(QUIZZES_RESPONSE);

given
.contentType(MediaType.APPLICATION_JSON_VALUE)
Expand Down Expand Up @@ -82,6 +82,7 @@ public class QuizDocumentation extends NewDocumentation {
);

private static final QuizzesResponse QUIZZES_RESPONSE = new QuizzesResponse(1L,
Arrays.asList(new QuizResponse(1L, "브라운을 위해 낸 퀴즈"), new QuizResponse(1L, "포코를 위해 낸 퀴즈")));
Arrays.asList(new QuizResponse(1L, "브라운을 위해 낸 퀴즈", true),
new QuizResponse(1L, "포코를 위해 낸 퀴즈", false)));

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_QUIZ_NOT_FOUND_EXCEPTION;

import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -13,6 +14,7 @@
import wooteco.prolog.roadmap.application.dto.QuizzesResponse;
import wooteco.prolog.roadmap.domain.Keyword;
import wooteco.prolog.roadmap.domain.Quiz;
import wooteco.prolog.roadmap.domain.repository.EssayAnswerRepository;
import wooteco.prolog.roadmap.domain.repository.KeywordRepository;
import wooteco.prolog.roadmap.domain.repository.QuizRepository;

Expand All @@ -23,6 +25,7 @@ public class QuizService {

private final KeywordRepository keywordRepository;
private final QuizRepository quizRepository;
private final EssayAnswerRepository essayAnswerRepository;

@Transactional
public Long createQuiz(Long keywordId, QuizRequest quizRequest) {
Expand All @@ -32,9 +35,20 @@ public Long createQuiz(Long keywordId, QuizRequest quizRequest) {
return quiz.getId();
}

public QuizzesResponse findQuizzesByKeywordId(Long keywordId) {
public QuizzesResponse findQuizzesByKeywordId(Long keywordId, Long memberId) {
final List<Quiz> quizzes = quizRepository.findFetchQuizByKeywordId(keywordId);
return QuizzesResponse.of(keywordId, quizzes);
final List<QuizResponse> quizResponses = quizzes.stream()
.map(quiz -> QuizResponse.of(quiz, isLearning(memberId, quiz.getId())))
.collect(Collectors.toList());
return QuizzesResponse.of(keywordId, quizResponses);
}

private boolean isLearning(Long memberId, Long quizId) {
if (memberId == null) {
return false;
}
return essayAnswerRepository.existsByQuizIdAndMemberId(quizId,
memberId);
}

@Transactional
Expand All @@ -52,9 +66,9 @@ public void deleteQuiz(Long quizId) {
quizRepository.deleteById(quizId);
}

public QuizResponse findById(Long quizId) {
public QuizResponse findById(Long quizId, Long memberId) {
final Quiz quiz = quizRepository.findById(quizId)
.orElseThrow(() -> new BadRequestException(ROADMAP_QUIZ_NOT_FOUND_EXCEPTION));
return QuizResponse.of(quiz);
return QuizResponse.of(quiz, isLearning(memberId, quizId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package wooteco.prolog.roadmap.application.dto;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import wooteco.prolog.roadmap.domain.Quiz;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class EssayAnswerQuizResponse {

private Long quizId;
private String question;

public EssayAnswerQuizResponse(Long quizId, String question) {
this.quizId = quizId;
this.question = question;
}

public static EssayAnswerQuizResponse of(Quiz quiz) {
return new EssayAnswerQuizResponse(quiz.getId(), quiz.getQuestion());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class EssayAnswerResponse {

private Long id;
private QuizResponse quiz;
private EssayAnswerQuizResponse quiz;
private String answer;
private MemberResponse author;
private LocalDateTime createdAt;
Expand All @@ -22,7 +22,7 @@ public static EssayAnswerResponse of(EssayAnswer essayAnswer) {
EssayAnswerResponse response = new EssayAnswerResponse();

response.id = essayAnswer.getId();
response.quiz = QuizResponse.of(essayAnswer.getQuiz());
response.quiz = EssayAnswerQuizResponse.of(essayAnswer.getQuiz());
response.answer = essayAnswer.getAnswer();
response.author = MemberResponse.of(essayAnswer.getMember());
response.createdAt = essayAnswer.getCreatedAt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ public class QuizResponse {

private Long quizId;
private String question;
private Boolean isLearning;

public QuizResponse(Long quizId, String question) {
public QuizResponse(Long quizId, String question, boolean isLearning) {
this.quizId = quizId;
this.question = question;
this.isLearning = isLearning;
}

public static QuizResponse of(Quiz quiz) {
return new QuizResponse(quiz.getId(), quiz.getQuestion());
public static QuizResponse of(Quiz quiz, boolean isLearning) {
return new QuizResponse(quiz.getId(), quiz.getQuestion(), isLearning);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package wooteco.prolog.roadmap.application.dto;

import java.util.List;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import wooteco.prolog.roadmap.domain.Quiz;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
Expand All @@ -21,9 +19,7 @@ public QuizzesResponse(Long keywordId,
this.data = data;
}

public static QuizzesResponse of(Long keywordId, List<Quiz> quizzes) {
final List<QuizResponse> responses = quizzes.stream().map(QuizResponse::of)
.collect(Collectors.toList());
return new QuizzesResponse(keywordId, responses);
public static QuizzesResponse of(Long keywordId, List<QuizResponse> quizzes) {
return new QuizzesResponse(keywordId, quizzes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import wooteco.prolog.roadmap.domain.EssayAnswer;

public interface EssayAnswerRepository extends JpaRepository<EssayAnswer, Long> {

@Query("select ea from EssayAnswer ea where ea.quiz.id = :quizId and ea.member.id = :memberId ")
boolean existsByQuizIdAndMemberId(Long quizId, Long memberId);

Optional<EssayAnswer> findByIdAndMemberId(Long id, Long memberId);

List<EssayAnswer> findByQuizIdOrderByIdDesc(Long quizId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
package wooteco.prolog.roadmap.ui;

import static java.util.stream.Collectors.toList;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
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;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import wooteco.prolog.login.domain.AuthMemberPrincipal;
import wooteco.prolog.login.ui.LoginMember;
import wooteco.prolog.roadmap.application.EssayAnswerService;
Expand All @@ -13,10 +23,6 @@
import wooteco.prolog.roadmap.application.dto.QuizResponse;
import wooteco.prolog.roadmap.domain.EssayAnswer;

import java.util.List;

import static java.util.stream.Collectors.toList;

@RestController
@RequestMapping
public class EssayAnswerController {
Expand Down Expand Up @@ -61,8 +67,9 @@ public ResponseEntity<Void> deleteEssayAnswerById(@PathVariable Long essayAnswer
}

@GetMapping("/quizzes/{quizId}")
public ResponseEntity<QuizResponse> findQuizById(@PathVariable Long quizId) {
return ResponseEntity.ok(quizService.findById(quizId));
public ResponseEntity<QuizResponse> findQuizById(@PathVariable Long quizId,
@AuthMemberPrincipal LoginMember member) {
return ResponseEntity.ok(quizService.findById(quizId, member.getId()));
}

@GetMapping("/quizzes/{quizId}/essay-answers")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import wooteco.prolog.login.domain.AuthMemberPrincipal;
import wooteco.prolog.login.ui.LoginMember;
import wooteco.prolog.roadmap.application.QuizService;
import wooteco.prolog.roadmap.application.dto.QuizRequest;
import wooteco.prolog.roadmap.application.dto.QuizResponse;
Expand All @@ -35,14 +37,16 @@ public ResponseEntity<Void> create(@PathVariable Long sessionId, @PathVariable L
}

@GetMapping("/{quizId}")
public ResponseEntity<QuizResponse> findQuizById(@PathVariable Long quizId) {
return ResponseEntity.ok(quizService.findById(quizId));
public ResponseEntity<QuizResponse> findQuizById(@PathVariable Long quizId,
@AuthMemberPrincipal LoginMember member) {
return ResponseEntity.ok(quizService.findById(quizId, member.getId()));
}

@GetMapping
public ResponseEntity<QuizzesResponse> findQuizzesByKeyword(@PathVariable Long sessionId,
@PathVariable Long keywordId) {
return ResponseEntity.ok(quizService.findQuizzesByKeywordId(keywordId));
@PathVariable Long keywordId,
@AuthMemberPrincipal LoginMember member) {
return ResponseEntity.ok(quizService.findQuizzesByKeywordId(keywordId, member.getId()));
}

@PutMapping("/{quizId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Arrays;
import java.util.Optional;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
Expand All @@ -25,6 +26,7 @@
import wooteco.prolog.roadmap.application.dto.QuizzesResponse;
import wooteco.prolog.roadmap.domain.Keyword;
import wooteco.prolog.roadmap.domain.Quiz;
import wooteco.prolog.roadmap.domain.repository.EssayAnswerRepository;
import wooteco.prolog.roadmap.domain.repository.KeywordRepository;
import wooteco.prolog.roadmap.domain.repository.QuizRepository;

Expand All @@ -37,6 +39,9 @@ class QuizServiceTest {
@Mock
private QuizRepository quizRepository;

@Mock
private EssayAnswerRepository essayAnswerRepository;

@InjectMocks
QuizService quizService;

Expand Down Expand Up @@ -96,7 +101,7 @@ void findQuizzesByKeywordId() {

//when
final QuizzesResponse quizzesByKeywordId = quizService.findQuizzesByKeywordId(
requestKeywordId);
requestKeywordId, null);

//then
assertAll(
Expand Down Expand Up @@ -172,7 +177,7 @@ void findById_fail() {
.thenReturn(Optional.empty());

//when,then
assertThatThrownBy(() -> quizService.findById(1L))
assertThatThrownBy(() -> quizService.findById(1L, null))
.isInstanceOf(BadRequestException.class)
.hasMessage(ROADMAP_QUIZ_NOT_FOUND_EXCEPTION.getMessage());
}
Expand All @@ -187,7 +192,7 @@ void findById() {
.thenReturn(Optional.of(new Quiz(findQuizId, null, findQuizQuestion)));

//when
final QuizResponse quizResponseById = quizService.findById(1L);
final QuizResponse quizResponseById = quizService.findById(1L, null);

//then
assertAll(
Expand All @@ -196,4 +201,62 @@ void findById() {
);
}

@DisplayName("quizId로 Quiz를 조회할 때 quiz의 답변 여부가 QuizResponse에 포함된다.")
@Nested
class findQuizzesByKeywordId {

@DisplayName("조회한 Quiz에 대해 답변을 게시한 적이 있으면 isLearning 값이 true이다.")
@Test
void findById_isLearning_true() {
//given
final long findQuizId = 1L;
final String findQuizQuestion = "question";
when(essayAnswerRepository.existsByQuizIdAndMemberId(anyLong(), anyLong()))
.thenReturn(true);
when(quizRepository.findById(anyLong()))
.thenReturn(Optional.of(new Quiz(findQuizId, null, findQuizQuestion)));

//when
final QuizResponse quizResponseById = quizService.findById(1L, 1L);

//then
assertThat(quizResponseById.getIsLearning()).isTrue();
}

@DisplayName("조회한 Quiz에 대해 답변을 게시한 적이 없으면 isLearning 값이 false이다.")
@Test
void findById_isLearning_false() {
//given
final long findQuizId = 1L;
final String findQuizQuestion = "question";
when(essayAnswerRepository.existsByQuizIdAndMemberId(anyLong(), anyLong()))
.thenReturn(false);
when(quizRepository.findById(anyLong()))
.thenReturn(Optional.of(new Quiz(findQuizId, null, findQuizQuestion)));

//when
final QuizResponse quizResponseById = quizService.findById(1L, 1L);

//then
assertThat(quizResponseById.getIsLearning()).isFalse();
}

@DisplayName("로그인되지 않은 사용자이면 isLearning 값이 false이다.")
@Test
void findById_isLearning_false_anonymous() {
//given
final long findQuizId = 1L;
final String findQuizQuestion = "question";
when(quizRepository.findById(anyLong()))
.thenReturn(Optional.of(new Quiz(findQuizId, null, findQuizQuestion)));

//when
final QuizResponse quizResponseById = quizService.findById(1L, null);

//then
assertThat(quizResponseById.getIsLearning()).isFalse();
}

}

}

0 comments on commit 9745eef

Please sign in to comment.