Skip to content

Commit

Permalink
test: exam, submission query service test
Browse files Browse the repository at this point in the history
  • Loading branch information
alstn113 committed Dec 26, 2024
1 parent 5f32c33 commit fae362e
Show file tree
Hide file tree
Showing 15 changed files with 493 additions and 33 deletions.
6 changes: 3 additions & 3 deletions server/src/main/java/com/fluffy/exam/api/ExamController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.fluffy.exam.application.ExamQueryService;
import com.fluffy.exam.application.ExamService;
import com.fluffy.exam.application.response.CreateExamResponse;
import com.fluffy.exam.application.response.ExamResponse;
import com.fluffy.exam.application.response.ExamDetailResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse;
import com.fluffy.exam.domain.ExamStatus;
import com.fluffy.exam.domain.dto.ExamSummaryDto;
Expand Down Expand Up @@ -63,8 +63,8 @@ public ResponseEntity<PageResponse<ExamSummaryDto>> getMyExamSummaries(


@GetMapping("/api/v1/exams/{examId}")
public ResponseEntity<ExamResponse> getExam(@PathVariable Long examId) {
ExamResponse response = examQueryService.getExam(examId);
public ResponseEntity<ExamDetailResponse> getExamDetail(@PathVariable Long examId) {
ExamDetailResponse response = examQueryService.getExamDetail(examId);

return ResponseEntity.ok(response);
}
Expand Down
12 changes: 6 additions & 6 deletions server/src/main/java/com/fluffy/exam/application/ExamMapper.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.fluffy.exam.application;

import com.fluffy.exam.application.response.ExamResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse;
import com.fluffy.exam.application.response.CreateExamResponse;
import com.fluffy.exam.application.response.ExamDetailResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse;
import com.fluffy.exam.domain.Exam;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -18,14 +18,14 @@ public CreateExamResponse toCreateResponse(Exam exam) {
return new CreateExamResponse(exam.getId(), exam.getTitle());
}

public List<ExamResponse> toResponses(List<Exam> exams) {
public List<ExamDetailResponse> toResponses(List<Exam> exams) {
return exams.stream()
.map(this::toResponse)
.map(this::toDetailResponse)
.toList();
}

public ExamResponse toResponse(Exam exam) {
return new ExamResponse(
public ExamDetailResponse toDetailResponse(Exam exam) {
return new ExamDetailResponse(
exam.getId(),
exam.getTitle(),
exam.getDescription(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.fluffy.exam.application;

import com.fluffy.exam.application.response.ExamResponse;
import com.fluffy.exam.application.response.ExamDetailResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse;
import com.fluffy.exam.domain.Exam;
import com.fluffy.exam.domain.ExamRepository;
Expand Down Expand Up @@ -37,10 +37,10 @@ public PageResponse<ExamSummaryDto> getMyExamSummaries(Pageable pageable, ExamSt
}

@Transactional(readOnly = true)
public ExamResponse getExam(Long examId) {
public ExamDetailResponse getExamDetail(Long examId) {
Exam exam = examRepository.findByIdOrThrow(examId);

return examMapper.toResponse(exam);
return examMapper.toDetailResponse(exam);
}

@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package com.fluffy.exam.application;

import com.fluffy.exam.application.response.ExamResponse.AnswerQuestionResponse;
import com.fluffy.exam.application.response.ExamResponse.ChoiceQuestionResponse;
import com.fluffy.exam.application.response.ExamResponse.QuestionResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse.AnswerQuestionWithAnswersResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse.ChoiceQuestionWithAnswersResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse.QuestionWithAnswersResponse;
import com.fluffy.exam.application.request.question.LongAnswerQuestionAppRequest;
import com.fluffy.exam.application.request.question.MultipleChoiceAppRequest;
import com.fluffy.exam.application.request.question.QuestionAppRequest;
import com.fluffy.exam.application.request.question.QuestionOptionRequest;
import com.fluffy.exam.application.request.question.ShortAnswerQuestionAppRequest;
import com.fluffy.exam.application.request.question.SingleChoiceQuestionAppRequest;
import com.fluffy.exam.application.request.question.TrueOrFalseQuestionAppRequest;
import com.fluffy.exam.application.response.ExamDetailResponse.AnswerQuestionResponse;
import com.fluffy.exam.application.response.ExamDetailResponse.ChoiceQuestionResponse;
import com.fluffy.exam.application.response.ExamDetailResponse.QuestionResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse.AnswerQuestionWithAnswersResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse.ChoiceQuestionWithAnswersResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse.QuestionWithAnswersResponse;
import com.fluffy.exam.domain.Question;
import com.fluffy.exam.domain.QuestionOption;
import com.fluffy.exam.domain.QuestionType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.fluffy.exam.application;

import com.fluffy.exam.application.response.ExamResponse.ChoiceQuestionResponse.QuestionOptionResponse;
import com.fluffy.exam.application.response.ExamDetailResponse.ChoiceQuestionResponse.QuestionOptionResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse.ChoiceQuestionWithAnswersResponse.QuestionOptionWithAnswersResponse;
import com.fluffy.exam.domain.QuestionOption;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.time.LocalDateTime;
import java.util.List;

public record ExamResponse(
public record ExamDetailResponse(
Long id,
String title,
String description,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import com.fluffy.global.web.Accessor;
import com.fluffy.global.web.Auth;
import com.fluffy.submission.api.request.SubmissionWebRequest;
import com.fluffy.submission.application.SubmissionQueryService;
import com.fluffy.submission.application.SubmissionService;
import com.fluffy.submission.application.response.SubmissionDetailResponse;
import com.fluffy.submission.domain.dto.SubmissionSummaryDto;
import com.fluffy.submission.api.request.SubmissionWebRequest;
import jakarta.validation.Valid;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@ public List<SubmissionSummaryDto> getSummariesByExamId(Long examId, Accessor acc
throw new ForbiddenException("해당 시험 제출 목록을 조회할 권한이 없습니다.");
}

return submissionRepository.findSummariesByExamId(examId);
return submissionRepository.findSubmissionSummariesByExamId(examId);
}

@Transactional(readOnly = true)
public SubmissionDetailResponse getDetail(Long examId, Long submissionId, Accessor accessor) {
Exam exam = examRepository.findByIdOrThrow(examId);
Member member = memberRepository.findByIdOrThrow(accessor.id());

if (exam.isNotWrittenBy(member.getId())) {
if (exam.isNotWrittenBy(accessor.id())) {
throw new ForbiddenException("해당 시험 제출을 조회할 권한이 없습니다.");
}

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

public interface SubmissionRepositoryCustom {

List<SubmissionSummaryDto> findSummariesByExamId(Long examId);
List<SubmissionSummaryDto> findSubmissionSummariesByExamId(Long examId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class SubmissionRepositoryImpl implements SubmissionRepositoryCustom {
private final JPAQueryFactory queryFactory;

@Override
public List<SubmissionSummaryDto> findSummariesByExamId(Long examId) {
public List<SubmissionSummaryDto> findSubmissionSummariesByExamId(Long examId) {
return queryFactory
.select(new QSubmissionSummaryDto(
submission.id,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package com.fluffy.exam.application;

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

import com.fluffy.auth.domain.Member;
import com.fluffy.auth.domain.MemberRepository;
import com.fluffy.exam.application.response.ExamDetailResponse;
import com.fluffy.exam.application.response.ExamDetailResponse.AnswerQuestionResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse;
import com.fluffy.exam.application.response.ExamWithAnswersResponse.AnswerQuestionWithAnswersResponse;
import com.fluffy.exam.domain.Exam;
import com.fluffy.exam.domain.ExamRepository;
import com.fluffy.exam.domain.ExamStatus;
import com.fluffy.exam.domain.Question;
import com.fluffy.exam.domain.dto.ExamSummaryDto;
import com.fluffy.global.exception.ForbiddenException;
import com.fluffy.global.response.PageInfo;
import com.fluffy.global.response.PageResponse;
import com.fluffy.global.web.Accessor;
import com.fluffy.support.AbstractIntegrationTest;
import com.fluffy.support.data.MemberTestData;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

class ExamQueryServiceTest extends AbstractIntegrationTest {

@Autowired
private MemberRepository memberRepository;

@Autowired
private ExamRepository examRepository;

@Autowired
private ExamQueryService examQueryService;

@Test
@DisplayName("출제된 시험 요약 목록을 조회할 수 있다.")
void getPublishedExamSummaries() {
// given
Member author = MemberTestData.defaultMember().build();
memberRepository.save(author);

Exam exam1 = Exam.create("시험 제목1", author.getId());
exam1.updateQuestions(List.of(Question.shortAnswer("질문1", "답1")));
exam1.publish(null, null);
examRepository.save(exam1);

Exam exam2 = Exam.create("시험 제목2", author.getId());
exam2.updateQuestions(List.of(Question.shortAnswer("질문2", "답2")));
exam2.publish(null, null);
examRepository.save(exam2);

Exam exam3 = Exam.create("시험 제목3", author.getId());
exam3.updateQuestions(List.of(Question.shortAnswer("질문3", "답3")));
exam3.publish(null, null);
examRepository.save(exam3);

// when
Pageable pageable = PageRequest.of(0, 2);
PageResponse<ExamSummaryDto> summaries = examQueryService.getPublishedExamSummaries(pageable);

// then
assertAll(
() -> assertThat(summaries.content()).hasSize(2),
() -> assertThat(summaries.pageInfo()).isEqualTo(new PageInfo(0, 2, 3, true, false)),
() -> assertThat(summaries.content().stream().map(ExamSummaryDto::getId))
.containsExactlyElementsOf(List.of(exam3.getId(), exam2.getId()))
);
}

@Test
@DisplayName("나의 시험 요약 목록을 조회할 수 있다.")
void getMyExamSummaries() {
// given
Member author = MemberTestData.defaultMember().build();
memberRepository.save(author);

Member another = MemberTestData.defaultMember().build();
memberRepository.save(another);

Exam exam1 = Exam.create("시험 제목1", author.getId());
exam1.updateQuestions(List.of(Question.shortAnswer("질문1", "답1")));
exam1.publish(null, null);
examRepository.save(exam1);

Exam exam2 = Exam.create("시험 제목2", author.getId());
exam2.updateQuestions(List.of(Question.shortAnswer("질문2", "답2")));
exam2.publish(null, null);
examRepository.save(exam2);

Exam otherExam1 = Exam.create("시험 제목3", author.getId());
otherExam1.updateQuestions(List.of(Question.shortAnswer("질문3", "답3")));
examRepository.save(otherExam1);

Exam exam4 = Exam.create("시험 제목4", another.getId());
exam4.updateQuestions(List.of(Question.shortAnswer("질문4", "답4")));
exam4.publish(null, null);
examRepository.save(exam4);

Exam exam5 = Exam.create("시험 제목5", author.getId());
exam5.updateQuestions(List.of(Question.shortAnswer("질문5", "답5")));
exam5.publish(null, null);
examRepository.save(exam5);

// when
Pageable pageable = PageRequest.of(0, 2);
PageResponse<ExamSummaryDto> summaries = examQueryService
.getMyExamSummaries(pageable, ExamStatus.PUBLISHED, new Accessor(author.getId()));

// then
assertAll(
() -> assertThat(summaries.content()).hasSize(2),
() -> assertThat(summaries.pageInfo()).isEqualTo(new PageInfo(0, 2, 3, true, false)),
() -> assertThat(summaries.content().stream().map(ExamSummaryDto::getId))
.containsExactlyElementsOf(List.of(exam5.getId(), exam2.getId()))
);
}

@Test
@DisplayName("시험 상세 정보를 조회할 수 있다.")
void getExamDetail() {
// given
Member member = MemberTestData.defaultMember().build();
memberRepository.save(member);

Exam exam = Exam.create("시험 제목", member.getId());
exam.updateQuestions(List.of(Question.shortAnswer("질문", "답")));
exam.publish(null, null);
examRepository.save(exam);

// when
ExamDetailResponse response = examQueryService.getExamDetail(exam.getId());
AnswerQuestionResponse answerQuestion = (AnswerQuestionResponse) response.questions().getFirst();

// then
assertAll(
() -> assertThat(response.id()).isEqualTo(exam.getId()),
() -> assertThat(response.title()).isEqualTo(exam.getTitle()),
() -> assertThat(response.status()).isEqualTo(exam.getStatus().name()),
() -> assertThat(response.questions()).hasSize(1),
() -> assertThat(answerQuestion.text()).isEqualTo("질문")
);
}

@Test
@DisplayName("시험 상세 정보를 답안과 함께 조회할 수 있다.")
void getExamWithAnswers() {
// given
Member member = MemberTestData.defaultMember().build();
memberRepository.save(member);

Exam exam = Exam.create("시험 제목", member.getId());
exam.updateQuestions(List.of(Question.shortAnswer("질문", "답")));
exam.publish(null, null);
examRepository.save(exam);

// when
ExamWithAnswersResponse response = examQueryService
.getExamWithAnswers(exam.getId(), new Accessor(member.getId()));

AnswerQuestionWithAnswersResponse answerQuestion =
(AnswerQuestionWithAnswersResponse) response.questions().getFirst();

// then
assertAll(
() -> assertThat(response.id()).isEqualTo(exam.getId()),
() -> assertThat(response.title()).isEqualTo(exam.getTitle()),
() -> assertThat(response.status()).isEqualTo(exam.getStatus().name()),
() -> assertThat(response.questions()).hasSize(1),
() -> assertThat(answerQuestion.text()).isEqualTo("질문"),
() -> assertThat(answerQuestion.correctAnswer()).isEqualTo("답")
);
}

@Test
@DisplayName("시험 상세 정보를 답안과 함께 조회 시 작성자가 아닌 경우 예외를 발생시킨다.")
void getExamWithAnswersFailWhenNotWrittenBy() {
// given
Member member = MemberTestData.defaultMember().build();
memberRepository.save(member);

Exam exam = Exam.create("시험 제목", member.getId());
exam.updateQuestions(List.of(Question.shortAnswer("질문", "답")));
exam.publish(null, null);
examRepository.save(exam);

// when
Accessor notAuthor = new Accessor(-1L);

// then
assertThatThrownBy(() -> examQueryService.getExamWithAnswers(exam.getId(), notAuthor))
.isInstanceOf(ForbiddenException.class)
.hasMessage("해당 시험에 접근할 수 없습니다.");
}
}
Loading

0 comments on commit fae362e

Please sign in to comment.