Merge branch 'master' into master-web
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
package com.mangkyu.employment.interview.app.common.pagination;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@ToString
|
||||||
|
public class CursorPageable<T> {
|
||||||
|
|
||||||
|
private final T response;
|
||||||
|
private final ResponseMetaData responseMetaData;
|
||||||
|
|
||||||
|
private CursorPageable(final T response, final boolean hasNext, final int page, final int size) {
|
||||||
|
this.response = response;
|
||||||
|
this.responseMetaData = new ResponseMetaData(hasNext, page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> CursorPageable<T> of(final T response, final boolean hasNext, final int page, final int size) {
|
||||||
|
return new CursorPageable<>(response, hasNext, page, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.mangkyu.employment.interview.app.common.pagination;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@ToString
|
||||||
|
public class ResponseMetaData {
|
||||||
|
|
||||||
|
private final boolean hasNext;
|
||||||
|
private final int page;
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,4 +9,7 @@ public final class QuizConstants {
|
|||||||
public static final int MINIMUM_QUIZ_SIZE = 1;
|
public static final int MINIMUM_QUIZ_SIZE = 1;
|
||||||
public static final int MAXIMUM_QUIZ_SIZE = 5;
|
public static final int MAXIMUM_QUIZ_SIZE = 5;
|
||||||
|
|
||||||
|
public static final int MIN_PAGE_NUMBER = 0;
|
||||||
|
public static final int MIN_PAGE_SIZE = 1;
|
||||||
|
public static final int MAX_PAGE_SIZE = 30;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
package com.mangkyu.employment.interview.app.quiz.controller;
|
package com.mangkyu.employment.interview.app.quiz.controller;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.AddQuizRequest;
|
import com.mangkyu.employment.interview.app.common.pagination.CursorPageable;
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.AddQuizRequestHolder;
|
import com.mangkyu.employment.interview.app.quiz.dto.*;
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.QuizCategoryResponse;
|
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.QuizCategoryResponseHolder;
|
|
||||||
import com.mangkyu.employment.interview.app.quiz.service.QuizService;
|
import com.mangkyu.employment.interview.app.quiz.service.QuizService;
|
||||||
import com.mangkyu.employment.interview.enums.common.EnumMapperKey;
|
|
||||||
import com.mangkyu.employment.interview.enums.common.EnumMapperValue;
|
|
||||||
import com.mangkyu.employment.interview.enums.factory.EnumMapperFactory;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -18,8 +13,6 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -47,9 +40,14 @@ public class QuizController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/quiz/{id}")
|
@GetMapping("/quiz/{id}")
|
||||||
public ResponseEntity<Void> addQuiz(@PathVariable String id) {
|
public ResponseEntity<GetQuizResponse> getQuiz(@PathVariable final long id) {
|
||||||
return ResponseEntity.status(HttpStatus.CREATED)
|
return ResponseEntity.ok(quizService.getQuiz(id));
|
||||||
.build();
|
}
|
||||||
|
|
||||||
|
@GetMapping("/quizzes")
|
||||||
|
public ResponseEntity<CursorPageable<GetQuizResponseHolder>> getQuizList(@Valid final GetQuizRequest getQuizRequest) {
|
||||||
|
final CursorPageable<GetQuizResponseHolder> response = quizService.getQuizList(getQuizRequest);
|
||||||
|
return ResponseEntity.ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/quiz/categories")
|
@GetMapping("/quiz/categories")
|
||||||
@@ -60,4 +58,4 @@ public class QuizController {
|
|||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.mangkyu.employment.interview.app.quiz.converter;
|
||||||
|
|
||||||
|
import com.mangkyu.employment.interview.app.quiz.dto.GetQuizResponse;
|
||||||
|
import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
||||||
|
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
public final class QuizDtoConverter {
|
||||||
|
|
||||||
|
public static GetQuizResponse convert(final Quiz quiz) {
|
||||||
|
return GetQuizResponse.builder()
|
||||||
|
.id(quiz.getId())
|
||||||
|
.title(quiz.getTitle())
|
||||||
|
.quizCategory(quiz.getQuizCategory())
|
||||||
|
.quizLevelList(convert(quiz.getQuizLevel()))
|
||||||
|
.createdAt(Timestamp.valueOf(quiz.getCreatedAt()).getTime())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> convert(final List<QuizLevel> quizLevelList) {
|
||||||
|
return quizLevelList.stream()
|
||||||
|
.map(Enum::name)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.mangkyu.employment.interview.app.quiz.dto;
|
||||||
|
|
||||||
|
import com.mangkyu.employment.interview.app.quiz.constants.QuizConstants;
|
||||||
|
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.hibernate.validator.constraints.Range;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GetQuizRequest {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final QuizCategory category;
|
||||||
|
|
||||||
|
@Range(min = QuizConstants.MIN_PAGE_SIZE, max = QuizConstants.MAX_PAGE_SIZE)
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
@Range(min = QuizConstants.MIN_PAGE_NUMBER)
|
||||||
|
private final int page;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.mangkyu.employment.interview.app.quiz.dto;
|
||||||
|
|
||||||
|
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GetQuizResponse {
|
||||||
|
|
||||||
|
private final long id;
|
||||||
|
private final String title;
|
||||||
|
private final QuizCategory quizCategory;
|
||||||
|
private final List<String> quizLevelList;
|
||||||
|
private final long createdAt;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.mangkyu.employment.interview.app.quiz.dto;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GetQuizResponseHolder {
|
||||||
|
|
||||||
|
private final List<GetQuizResponse> quizList;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,14 +3,12 @@ package com.mangkyu.employment.interview.app.quiz.entity;
|
|||||||
import com.mangkyu.employment.interview.app.common.entity.BaseEntity;
|
import com.mangkyu.employment.interview.app.common.entity.BaseEntity;
|
||||||
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
||||||
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
||||||
import com.mangkyu.employment.interview.app.solvedquiz.entity.SolvedQuiz;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@@ -31,8 +29,4 @@ public class Quiz extends BaseEntity {
|
|||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private List<QuizLevel> quizLevel;
|
private List<QuizLevel> quizLevel;
|
||||||
|
|
||||||
@Builder.Default
|
}
|
||||||
@OneToMany(mappedBy = "quiz")
|
|
||||||
private List<SolvedQuiz> solvedQuizList = new ArrayList<>();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,8 @@ package com.mangkyu.employment.interview.app.quiz.repository;
|
|||||||
import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
||||||
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
||||||
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -10,6 +12,8 @@ import java.util.Set;
|
|||||||
|
|
||||||
public interface QuizRepository extends JpaRepository<Quiz, Long> {
|
public interface QuizRepository extends JpaRepository<Quiz, Long> {
|
||||||
|
|
||||||
|
Page<Quiz> findByQuizCategoryIs(final QuizCategory quizCategory, final Pageable pageable);
|
||||||
|
|
||||||
Long countByQuizCategory(final QuizCategory category);
|
Long countByQuizCategory(final QuizCategory category);
|
||||||
|
|
||||||
default List<Quiz> customFindByIdNotInAndQuizLevel(final Set<Long> quizIdSet, final QuizLevel quizLevel) {
|
default List<Quiz> customFindByIdNotInAndQuizLevel(final Set<Long> quizIdSet, final QuizLevel quizLevel) {
|
||||||
@@ -32,4 +36,4 @@ public interface QuizRepository extends JpaRepository<Quiz, Long> {
|
|||||||
|
|
||||||
List<Quiz> findByIdNotInAndQuizCategoryInAndQuizLevel(final Set<Long> quizIdSet, final Set<QuizCategory> quizCategorySet, final QuizLevel quizLevel);
|
List<Quiz> findByIdNotInAndQuizCategoryInAndQuizLevel(final Set<Long> quizIdSet, final Set<QuizCategory> quizCategorySet, final QuizLevel quizLevel);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package com.mangkyu.employment.interview.app.quiz.service;
|
package com.mangkyu.employment.interview.app.quiz.service;
|
||||||
|
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.AddQuizRequest;
|
import com.mangkyu.employment.interview.app.common.pagination.CursorPageable;
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.QuizCategoryResponse;
|
import com.mangkyu.employment.interview.app.quiz.converter.QuizDtoConverter;
|
||||||
|
import com.mangkyu.employment.interview.app.quiz.dto.*;
|
||||||
import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
||||||
import com.mangkyu.employment.interview.app.quiz.repository.QuizRepository;
|
import com.mangkyu.employment.interview.app.quiz.repository.QuizRepository;
|
||||||
import com.mangkyu.employment.interview.app.solvedquiz.repository.SolvedQuizRepository;
|
import com.mangkyu.employment.interview.app.solvedquiz.repository.SolvedQuizRepository;
|
||||||
@@ -12,6 +13,8 @@ import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
|||||||
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.modelmapper.ModelMapper;
|
import org.modelmapper.ModelMapper;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -37,6 +40,25 @@ public class QuizService {
|
|||||||
quizRepository.save(quiz);
|
quizRepository.save(quiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GetQuizResponse getQuiz(final long id) {
|
||||||
|
// TODO(MinKyu): Add Exception Handling
|
||||||
|
final Quiz quiz = quizRepository.findById(id).get();
|
||||||
|
return QuizDtoConverter.convert(quiz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CursorPageable<GetQuizResponseHolder> getQuizList(final GetQuizRequest getQuizRequest) {
|
||||||
|
final PageRequest pageRequest = PageRequest.of(getQuizRequest.getPage(), getQuizRequest.getSize());
|
||||||
|
final Page<Quiz> quizPage = quizRepository.findByQuizCategoryIs(getQuizRequest.getCategory(), pageRequest);
|
||||||
|
|
||||||
|
final List<GetQuizResponse> quizResponseList = quizPage.getContent().stream()
|
||||||
|
.map(QuizDtoConverter::convert)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
final GetQuizResponseHolder responseHolder = new GetQuizResponseHolder(quizResponseList);
|
||||||
|
|
||||||
|
return CursorPageable.of(responseHolder, quizPage.hasNext(), quizPage.nextOrLastPageable().getPageNumber(), quizPage.nextOrLastPageable().getPageSize());
|
||||||
|
}
|
||||||
|
|
||||||
public List<Quiz> getUnsolvedQuizList(final Long userId, final QuizLevel quizLevel, final Set<QuizCategory> quizCategorySet) {
|
public List<Quiz> getUnsolvedQuizList(final Long userId, final QuizLevel quizLevel, final Set<QuizCategory> quizCategorySet) {
|
||||||
final Set<Long> solvedQuizIdList = solvedQuizRepository.findAllByUser_Id(userId)
|
final Set<Long> solvedQuizIdList = solvedQuizRepository.findAllByUser_Id(userId)
|
||||||
.stream()
|
.stream()
|
||||||
@@ -81,4 +103,5 @@ public class QuizService {
|
|||||||
.desc(enumMapperValue.getDesc())
|
.desc(enumMapperValue.getDesc())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
package com.mangkyu.employment.interview.app.quiz.controller;
|
package com.mangkyu.employment.interview.app.quiz.controller;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.AddQuizRequest;
|
import com.mangkyu.employment.interview.app.common.pagination.CursorPageable;
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.QuizCategoryResponse;
|
import com.mangkyu.employment.interview.app.quiz.constants.QuizConstants;
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.QuizCategoryResponseHolder;
|
import com.mangkyu.employment.interview.app.quiz.dto.*;
|
||||||
import com.mangkyu.employment.interview.app.quiz.service.QuizService;
|
import com.mangkyu.employment.interview.app.quiz.service.QuizService;
|
||||||
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
||||||
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
@@ -19,9 +22,12 @@ import org.springframework.test.web.servlet.ResultActions;
|
|||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@@ -41,6 +47,97 @@ class QuizControllerTest {
|
|||||||
mockMvc = MockMvcBuilders.standaloneSetup(target).build();
|
mockMvc = MockMvcBuilders.standaloneSetup(target).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getQuiz() throws Exception {
|
||||||
|
// given
|
||||||
|
final long id = -1L;
|
||||||
|
final String url = "/quiz/" + id;
|
||||||
|
final GetQuizResponse quizResponse = GetQuizResponse.builder()
|
||||||
|
.title("quiz")
|
||||||
|
.quizLevelList(Arrays.asList(QuizLevel.JUNIOR.name(), QuizLevel.SENIOR.name()))
|
||||||
|
.quizCategory(QuizCategory.JAVA)
|
||||||
|
.build();
|
||||||
|
doReturn(quizResponse).when(quizService).getQuiz(id);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final ResultActions result = mockMvc.perform(
|
||||||
|
MockMvcRequestBuilders.get(url)
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
final ResultActions resultActions = result.andExpect(status().isOk());
|
||||||
|
final String stringResponse = resultActions.andReturn().getResponse().getContentAsString();
|
||||||
|
final GetQuizResponse getQuizResult = new Gson().fromJson(stringResponse, GetQuizResponse.class);
|
||||||
|
|
||||||
|
assertThat(getQuizResult.getId()).isEqualTo(quizResponse.getId());
|
||||||
|
assertThat(getQuizResult.getTitle()).isEqualTo(quizResponse.getTitle());
|
||||||
|
assertThat(getQuizResult.getQuizCategory()).isEqualTo(quizResponse.getQuizCategory());
|
||||||
|
assertThat(getQuizResult.getQuizCategory()).isEqualTo(quizResponse.getQuizCategory());
|
||||||
|
assertThat(getQuizResult.getCreatedAt()).isEqualTo(quizResponse.getCreatedAt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideParameters")
|
||||||
|
public void getQuizListFail_BadRequest(final QuizCategory quizCategory, final int size, final int page) throws Exception {
|
||||||
|
// given
|
||||||
|
final String url = "/quizzes";
|
||||||
|
final String category = quizCategory == null
|
||||||
|
? null
|
||||||
|
: quizCategory.name();
|
||||||
|
|
||||||
|
final GetQuizResponse quizResponse = GetQuizResponse.builder()
|
||||||
|
.title("quiz")
|
||||||
|
.quizLevelList(Arrays.asList(QuizLevel.JUNIOR.name(), QuizLevel.SENIOR.name()))
|
||||||
|
.quizCategory(QuizCategory.JAVA)
|
||||||
|
.build();
|
||||||
|
final GetQuizResponseHolder getQuizResponseHolder = GetQuizResponseHolder.builder()
|
||||||
|
.quizList(Collections.singletonList(quizResponse))
|
||||||
|
.build();
|
||||||
|
final CursorPageable<GetQuizResponseHolder> cursorPageable = CursorPageable.of(getQuizResponseHolder, false, page, size);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final ResultActions result = mockMvc.perform(
|
||||||
|
MockMvcRequestBuilders.get(url)
|
||||||
|
.param("category", category)
|
||||||
|
.param("size", String.valueOf(size))
|
||||||
|
.param("page", String.valueOf(page))
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
result.andExpect(status().isBadRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getQuizList() throws Exception {
|
||||||
|
// given
|
||||||
|
final int size = QuizConstants.MIN_PAGE_SIZE;
|
||||||
|
final int page = QuizConstants.MIN_PAGE_NUMBER;
|
||||||
|
final String url = "/quizzes";
|
||||||
|
|
||||||
|
final GetQuizResponse quizResponse = GetQuizResponse.builder()
|
||||||
|
.title("quiz")
|
||||||
|
.quizLevelList(Arrays.asList(QuizLevel.JUNIOR.name(), QuizLevel.SENIOR.name()))
|
||||||
|
.quizCategory(QuizCategory.JAVA)
|
||||||
|
.build();
|
||||||
|
final GetQuizResponseHolder getQuizResponseHolder = GetQuizResponseHolder.builder()
|
||||||
|
.quizList(Collections.singletonList(quizResponse))
|
||||||
|
.build();
|
||||||
|
final CursorPageable<GetQuizResponseHolder> cursorPageable = CursorPageable.of(getQuizResponseHolder, false, page, size);
|
||||||
|
|
||||||
|
doReturn(cursorPageable).when(quizService).getQuizList(any(GetQuizRequest.class));
|
||||||
|
|
||||||
|
// when
|
||||||
|
final ResultActions result = mockMvc.perform(
|
||||||
|
MockMvcRequestBuilders.get(url)
|
||||||
|
.param("category", QuizCategory.JAVA.name())
|
||||||
|
.param("size", String.valueOf(size))
|
||||||
|
.param("page", String.valueOf(page))
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
result.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addQuiz() throws Exception {
|
public void addQuiz() throws Exception {
|
||||||
// given
|
// given
|
||||||
@@ -91,4 +188,13 @@ class QuizControllerTest {
|
|||||||
assertThat(responseHolder.getCategoryList().get(0).getCount()).isEqualTo(count);
|
assertThat(responseHolder.getCategoryList().get(0).getCount()).isEqualTo(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> provideParameters() {
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(null, 10, 10),
|
||||||
|
Arguments.of(QuizCategory.JAVA, QuizConstants.MIN_PAGE_SIZE - 1, QuizConstants.MIN_PAGE_NUMBER),
|
||||||
|
Arguments.of(QuizCategory.JAVA, QuizConstants.MAX_PAGE_SIZE + 1, QuizConstants.MIN_PAGE_NUMBER),
|
||||||
|
Arguments.of(QuizCategory.JAVA, QuizConstants.MIN_PAGE_SIZE, QuizConstants.MIN_PAGE_NUMBER - 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.mangkyu.employment.interview.app.quiz.converter;
|
||||||
|
|
||||||
|
import com.mangkyu.employment.interview.app.quiz.dto.GetQuizResponse;
|
||||||
|
import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
||||||
|
import com.mangkyu.employment.interview.enums.value.QuizCategory;
|
||||||
|
import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class QuizDtoConverterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertQuizToGetQuizResponse() {
|
||||||
|
// given
|
||||||
|
final long id = -1L;
|
||||||
|
final Quiz quiz = quiz(id);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final GetQuizResponse result = QuizDtoConverter.convert(quiz);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result.getId()).isEqualTo(id);
|
||||||
|
assertThat(result.getTitle()).isEqualTo(quiz.getTitle());
|
||||||
|
assertThat(result.getQuizCategory()).isEqualTo(quiz.getQuizCategory());
|
||||||
|
assertThat(result.getQuizLevelList().size()).isEqualTo(quiz.getQuizLevel().size());
|
||||||
|
assertThat(result.getCreatedAt()).isEqualTo(Timestamp.valueOf(quiz.getCreatedAt()).getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Quiz quiz(final long id) {
|
||||||
|
final Quiz quiz = Quiz.builder()
|
||||||
|
.title("quiz")
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.quizCategory(QuizCategory.JAVA)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.NEW, QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ReflectionTestUtils.setField(quiz, "id", id);
|
||||||
|
ReflectionTestUtils.setField(quiz, "createdAt", LocalDateTime.now());
|
||||||
|
return quiz;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ import com.mangkyu.employment.interview.enums.value.QuizLevel;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -17,6 +19,78 @@ class QuizRepositoryTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private QuizRepository quizRepository;
|
private QuizRepository quizRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectQuizListByCategoryWithPaging() {
|
||||||
|
// given
|
||||||
|
final QuizCategory quizCategory = QuizCategory.JAVA;
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(quizCategory)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(quizCategory)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(quizCategory)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(quizCategory)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(quizCategory)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(quizCategory)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(quizCategory)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(quizCategory)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(QuizCategory.ALGORITHM)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
quizRepository.save(Quiz.builder()
|
||||||
|
.title("quiz4")
|
||||||
|
.quizCategory(QuizCategory.DATABASE)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
// when
|
||||||
|
boolean hasNext = true;
|
||||||
|
int page = 0;
|
||||||
|
int size = 3;
|
||||||
|
long result = 0;
|
||||||
|
while (hasNext) {
|
||||||
|
final PageRequest pageRequest = PageRequest.of(page++, size);
|
||||||
|
final Page<Quiz> pageQuiz = quizRepository.findByQuizCategoryIs(quizCategory, pageRequest);
|
||||||
|
|
||||||
|
result += pageQuiz.getContent().size();
|
||||||
|
hasNext = pageQuiz.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEqualTo(quizRepository.countByQuizCategory(quizCategory));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectQuizCountByCategory() {
|
public void selectQuizCountByCategory() {
|
||||||
// given
|
// given
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.mangkyu.employment.interview.app.quiz.service;
|
package com.mangkyu.employment.interview.app.quiz.service;
|
||||||
|
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.AddQuizRequest;
|
import com.mangkyu.employment.interview.app.common.pagination.CursorPageable;
|
||||||
import com.mangkyu.employment.interview.app.quiz.dto.QuizCategoryResponse;
|
import com.mangkyu.employment.interview.app.quiz.dto.*;
|
||||||
import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
||||||
import com.mangkyu.employment.interview.app.quiz.repository.QuizRepository;
|
import com.mangkyu.employment.interview.app.quiz.repository.QuizRepository;
|
||||||
import com.mangkyu.employment.interview.app.solvedquiz.entity.SolvedQuiz;
|
import com.mangkyu.employment.interview.app.solvedquiz.entity.SolvedQuiz;
|
||||||
@@ -20,8 +20,13 @@ import org.mockito.Spy;
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.modelmapper.ModelMapper;
|
import org.modelmapper.ModelMapper;
|
||||||
import org.modelmapper.config.Configuration;
|
import org.modelmapper.config.Configuration;
|
||||||
|
import org.springframework.data.domain.PageImpl;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -55,6 +60,51 @@ class QuizServiceTest {
|
|||||||
.setFieldMatchingEnabled(true);
|
.setFieldMatchingEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getQuiz_Success() {
|
||||||
|
// given
|
||||||
|
final long id = -1L;
|
||||||
|
final Quiz quiz = quiz(id);
|
||||||
|
|
||||||
|
doReturn(Optional.of(quiz)).when(quizRepository).findById(id);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final GetQuizResponse result = quizService.getQuiz(id);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result.getId()).isEqualTo(id);
|
||||||
|
assertThat(result.getTitle()).isEqualTo(quiz.getTitle());
|
||||||
|
assertThat(result.getQuizCategory()).isEqualTo(quiz.getQuizCategory());
|
||||||
|
assertThat(result.getQuizLevelList().size()).isEqualTo(quiz.getQuizLevel().size());
|
||||||
|
assertThat(result.getCreatedAt()).isEqualTo(Timestamp.valueOf(quiz.getCreatedAt()).getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCursorQuizList_Success() {
|
||||||
|
// given
|
||||||
|
final int page = 0;
|
||||||
|
final int size = 20;
|
||||||
|
|
||||||
|
final GetQuizRequest request = GetQuizRequest.builder()
|
||||||
|
.category(QuizCategory.JAVA)
|
||||||
|
.page(page)
|
||||||
|
.size(size)
|
||||||
|
.build();
|
||||||
|
final List<Quiz> quizList = quizList();
|
||||||
|
final Pageable pageable = PageRequest.of(page, size);
|
||||||
|
|
||||||
|
final PageImpl<Quiz> quizPage = new PageImpl<>(quizList(), pageable, quizList.size());
|
||||||
|
doReturn(quizPage).when(quizRepository).findByQuizCategoryIs(any(QuizCategory.class), any(PageRequest.class));
|
||||||
|
|
||||||
|
// when
|
||||||
|
final CursorPageable<GetQuizResponseHolder> result = quizService.getQuizList(request);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result.getResponseMetaData().isHasNext()).isFalse();
|
||||||
|
assertThat(result.getResponseMetaData().getPage()).isEqualTo(page);
|
||||||
|
assertThat(result.getResponseMetaData().getSize()).isEqualTo(size);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addQuiz_Success() {
|
public void addQuiz_Success() {
|
||||||
// given
|
// given
|
||||||
@@ -133,11 +183,7 @@ class QuizServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getRandomQuizListUnderLimitSuccess_OverLimit() {
|
public void getRandomQuizListUnderLimitSuccess_OverLimit() {
|
||||||
// given
|
// given
|
||||||
final List<Quiz> unsolvedQuizList = new ArrayList<>();
|
final List<Quiz> unsolvedQuizList = quizList();
|
||||||
unsolvedQuizList.add(quiz(1L));
|
|
||||||
unsolvedQuizList.add(quiz(2L));
|
|
||||||
unsolvedQuizList.add(quiz(3L));
|
|
||||||
unsolvedQuizList.add(quiz(4L));
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final List<Quiz> result = quizService.getRandomQuizListUnderLimit(unsolvedQuizList, quizSize);
|
final List<Quiz> result = quizService.getRandomQuizListUnderLimit(unsolvedQuizList, quizSize);
|
||||||
@@ -152,12 +198,6 @@ class QuizServiceTest {
|
|||||||
final long count = 15;
|
final long count = 15;
|
||||||
final QuizCategory quizCategory = QuizCategory.JAVA;
|
final QuizCategory quizCategory = QuizCategory.JAVA;
|
||||||
|
|
||||||
final List<Quiz> unsolvedQuizList = new ArrayList<>();
|
|
||||||
unsolvedQuizList.add(quiz(1L));
|
|
||||||
unsolvedQuizList.add(quiz(2L));
|
|
||||||
unsolvedQuizList.add(quiz(3L));
|
|
||||||
unsolvedQuizList.add(quiz(4L));
|
|
||||||
|
|
||||||
final EnumMapperValue enumMapperValue = EnumMapperValue.builder()
|
final EnumMapperValue enumMapperValue = EnumMapperValue.builder()
|
||||||
.code(quizCategory.name())
|
.code(quizCategory.name())
|
||||||
.title(quizCategory.getTitle())
|
.title(quizCategory.getTitle())
|
||||||
@@ -175,6 +215,17 @@ class QuizServiceTest {
|
|||||||
assertThat(result.get(0).getCount()).isEqualTo(count);
|
assertThat(result.get(0).getCount()).isEqualTo(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Quiz> quizList() {
|
||||||
|
final List<Quiz> unsolvedQuizList = new ArrayList<>();
|
||||||
|
|
||||||
|
unsolvedQuizList.add(quiz(1L));
|
||||||
|
unsolvedQuizList.add(quiz(2L));
|
||||||
|
unsolvedQuizList.add(quiz(3L));
|
||||||
|
unsolvedQuizList.add(quiz(4L));
|
||||||
|
|
||||||
|
return unsolvedQuizList;
|
||||||
|
}
|
||||||
|
|
||||||
private List<SolvedQuiz> solvedQuizList() {
|
private List<SolvedQuiz> solvedQuizList() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
solvedQuiz(1L),
|
solvedQuiz(1L),
|
||||||
@@ -192,8 +243,15 @@ class QuizServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Quiz quiz(final long id) {
|
private Quiz quiz(final long id) {
|
||||||
final Quiz quiz = Quiz.builder().build();
|
final Quiz quiz = Quiz.builder()
|
||||||
|
.title("quiz")
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.quizCategory(QuizCategory.JAVA)
|
||||||
|
.quizLevel(Arrays.asList(QuizLevel.NEW, QuizLevel.JUNIOR, QuizLevel.SENIOR))
|
||||||
|
.build();
|
||||||
|
|
||||||
ReflectionTestUtils.setField(quiz, "id", id);
|
ReflectionTestUtils.setField(quiz, "id", id);
|
||||||
|
ReflectionTestUtils.setField(quiz, "createdAt", LocalDateTime.now());
|
||||||
return quiz;
|
return quiz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user