템플릿 시험지 / 문제
시험지
문제 풀기
Paper.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name = "sp_paper")
public class Paper {
// 학생들에게 배부될 시험지
@Id
@GeneratedValue
private Long PaperId;
private Long paperTemplateId; // 이를 기반으로 만들어 짐
private String name;
private Long studyUserId; // 학생 아이디
@Transient
private User user;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "paper")
private List<PaperAnswer> paperAnswerList;
private LocalDateTime created;
private LocalDateTime startTime;
private LocalDateTime endTime;
private PaperState state;
public static enum PaperState {
READY,
START,
END,
CANCELED
}
private int total;
private int answered;
private int correct;
@Transient
public double getScore(){
if(total < 1) return 0;
return correct* 100.0 / total;
}
public void addAnswered() {
answered++;
}
public void addCorrect() {
correct++;
}
public Map<Integer, PaperAnswer> answerMap(){
if(paperAnswerList == null) return new HashMap<>();
return paperAnswerList.stream().collect(Collectors.toMap(PaperAnswer::num,
Function.identity()));
}
}
PaperAnswer
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table
public class PaperAnswer {
@JsonIgnore
@ManyToOne
@JoinColumn(foreignKey = @ForeignKey(name = "paperId"))
Paper paper;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Embeddable
public static class PaperAnswerId implements Serializable {
private Long paperId;
private Integer num; // 1-base(1,2,3,4~~~) // 이 두 필드가 Unique한 Id 역할을 하게 끔
}
@EmbeddedId
private PaperAnswerId id;
private Long problemId;
private String answer;
private boolean correct;
private LocalDateTime answered;
public Integer num(){
return id.getNum();
}
}
PaperTemplate.java
Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name="sp_paper_template")
public class PaperTemplate {
// 선생님이 작성하는 시험지
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long paperTemplateId;
private String name;
private Long userId;
@Transient
private User creator; // 작성자 아이디
private int total; // problemList 갯수를 사용하기 위해 매번 접근하는 것은 부담
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(foreignKey = @ForeignKey(name="paperTemplateId"))
private List<Problem> problemList;
private long publishedCount;
private long completeCount;
@Column(updatable = false)
private LocalDateTime created;
private LocalDateTime updated;
}
Problem.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name = "sp_problem")
public class Problem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long problemId;
private Long paperTemplateId;
private int indexNum; // 1번 부터 2,3,4~~~
private String content;
private String answer; // paper answer와 correct 한지 확인 하기 위해
@Column(updatable = false)
private LocalDateTime created;
private LocalDateTime updated;
}
PaperAnswerRepository
public interface PaperAnswerRepository extends JpaRepository<PaperAnswer, PaperAnswer.PaperAnswerId> {
}
PaperRepository
public interface PaperRepository extends JpaRepository<Paper, Long> {
List<Paper> findAllByPaperTemplateIdAndStudyUserIdIn(Long paperTemplateId, List<Long> studyIdlist);
List<Paper> findAllByPaperTemplateId(Long paperTemplateId);
long countByPaperTemplateId(Long paperTemplateId);
List<Paper> findAllByStudyUserIdOrderByCreatedDesc(Long studyUserId);
long countByStudyUserId(Long studyUserId);
Page<Paper> findAllByStudyUserIdAndStateOrderByCreatedDesc(Long studyUserId, Paper.PaperState state, Pageable pageable);
List<Paper> findAllByStudyUserIdAndStateOrderByCreatedDesc(Long studyUserId, Paper.PaperState state);
long countByStudyUserIdAndState(Long studyUserId, Paper.PaperState state);
List<Paper> findAllByStudyUserIdAndStateInOrderByCreatedDesc(Long studyUserId, List<Paper.PaperState> states);
long countByStudyUserIdAndStateIn(Long studyUserId, List<Paper.PaperState> states);
}
PaperTemplateRepository
public interface PaperTemplateRepository extends JpaRepository<PaperTemplate, Long> {
List<PaperTemplate> findAllByUserIdOrderByCreatedDesc(Long userId);
Page<PaperTemplate> findAllByUserIdOrderByCreatedDesc(Long userId, Pageable pageable);
long countByUserId(Long userId);
}
ProblemRepository
public interface ProblemRepository extends JpaRepository<Problem, Long> {
List<Problem> findAllByPaperTemplateIdOrderByIndexNumAsc(Long paperTemplateId);
@Modifying
@Query("update Problem set content=?2, answer=?3, updated=?4 where problemId=?1")
void updateProblem(long problemId, String content, String answer, LocalDateTime now);
}
PaperService.java
@Service
@RequiredArgsConstructor
@Transactional
public class PaperService {
private final UserRepository userRepository;
private final PaperTemplateService paperTemplateService;
private final PaperRepository paperRepository;
private final PaperAnswerRepository paperAnswerRepository;
protected Paper save(Paper paper){
if(paper.getPaperId() == null){
paper.setCreated(LocalDateTime.now());
}
return paperRepository.save(paper);
}
@Transactional
// 시험지를 나눠줄때 해당 메서드 실행(study -> student라 생각하자)
public List<Paper> publishPaper(long paperTemplateId, List<Long> studyIdList){
List<Paper> papers = paperTemplateService.findById(paperTemplateId).map(paperTemplate ->
StreamSupport.stream(userRepository.findAllById(studyIdList).spliterator(), false)
.map(study -> {
Paper paper = Paper.builder()
.paperTemplateId(paperTemplate.getPaperTemplateId())
.name(paperTemplate.getName())
.state(Paper.PaperState.READY)
.studyUserId(study.getUserId())
.total(paperTemplate.getTotal())
.build();
return save(paper);
}).collect(Collectors.toList())
).orElseThrow(()->new IllegalArgumentException(paperTemplateId+" 시험지 템플릿이 존재하지 않습니다."));
paperTemplateService.updatePublishedCount(paperTemplateId, papers.size());
return papers;
}
public void removePaper(long paperTemplateId, List<Long> studyIdList){
paperRepository.findAllByPaperTemplateIdAndStudyUserIdIn(paperTemplateId, studyIdList)
.forEach(paper -> {
paperRepository.delete(paper);
});
}
@Transactional
// 문제를 풀때마다 , paperId로 페이퍼를 찾고 해당 페이퍼에 Answer이 있다면 마킹한 내용 업데이트
public void answer(Long paperId, Long problemId, int num, String answer){
paperRepository.findById(paperId).ifPresentOrElse(paper->{
Optional<PaperAnswer> pa = paper.getPaperAnswerList() == null ? Optional.empty() :
paper.getPaperAnswerList().stream().filter(a -> a.getId().getNum() == num).findFirst();
if(pa.isPresent()){
PaperAnswer pAnswer = pa.get();
pAnswer.setAnswer(answer);
pAnswer.setAnswered(LocalDateTime.now());
pAnswer.setProblemId(problemId);
paperAnswerRepository.save(pAnswer);
}else{
PaperAnswer pAnswer = PaperAnswer.builder()
.id(new PaperAnswer.PaperAnswerId(paperId, num))
.problemId(problemId)
.answer(answer)
.answered(LocalDateTime.now())
.build();
// paperAnswerRepository.save(pAnswer);
pAnswer.setPaper(paper);
if(paper.getPaperAnswerList() == null) paper.setPaperAnswerList(new ArrayList<>());
paper.getPaperAnswerList().add(pAnswer);
paper.addAnswered();
if(paper.getState() != Paper.PaperState.START){
paper.setState(Paper.PaperState.START);
paper.setStartTime(LocalDateTime.now());
}
paperRepository.save(paper);
}
}, ()->new IllegalArgumentException(paperId+" 시험지를 찾을 수 없습니다."));
}
@Transactional
public void paperDone(Long paperId){
// 시험을 끝냈으면 해당 시험지의 답안을 비교해서 채점 한다.
final Paper paper = paperRepository.findById(paperId).orElseThrow(()->new IllegalArgumentException(paperId+" 시험지를 찾을 수 없습니다."));
final Map<Integer, String> answerSheet = paperTemplateService.getPaperAnswerSheet(paper.getPaperTemplateId());
paper.setCorrect(0);
if(paper.getPaperAnswerList() != null) {
paper.getPaperAnswerList().forEach(answer -> {
if (answer.getAnswer() != null && answer.getAnswer().equals(answerSheet.get(answer.getId().getNum()))) {
answer.setCorrect(true); // 정답인지 아닌지 마킹
paper.addCorrect(); // score는 자동으로 계산됨
paperAnswerRepository.save(answer);
}
});
}
paper.setState(Paper.PaperState.END);
paper.setEndTime(LocalDateTime.now());
Paper saved = paperRepository.save(paper);
// paperTemplateService.findById(saved.getPaperTemplateId()).map(paperTemplate -> paperTemplate.setCompleteCount(saved.))
paperTemplateService.updateCompleteCount(saved.getPaperTemplateId());
}
@Transactional(readOnly = true)
public List<Paper> getPapers(Long paperTemplateId) {
return paperRepository.findAllByPaperTemplateId(paperTemplateId);
}
@Transactional(readOnly = true)
public List<Paper> getPapersByUser(Long studyUserId) {
return paperRepository.findAllByStudyUserIdOrderByCreatedDesc(studyUserId);
}
@Transactional(readOnly = true)
public List<Paper> getPapersByUserState(Long studyUserId, Paper.PaperState state) {
return paperRepository.findAllByStudyUserIdAndStateOrderByCreatedDesc(studyUserId, state);
}
@Transactional(readOnly = true)
public List<Paper> getPapersByUserIng(Long studyUserId) {
return paperRepository.findAllByStudyUserIdAndStateInOrderByCreatedDesc(studyUserId, List.of(Paper.PaperState.READY, Paper.PaperState.START));
}
@Transactional(readOnly = true)
public long countPapersByUserIng(Long studyUserId) {
return paperRepository.countByStudyUserIdAndStateIn(studyUserId, List.of(Paper.PaperState.READY, Paper.PaperState.START));
}
@Transactional(readOnly = true)
public Page<Paper> getPapersByUserResult(Long studyUserId, int pageNum, int size) {
return paperRepository.findAllByStudyUserIdAndStateOrderByCreatedDesc(studyUserId, Paper.PaperState.END, PageRequest.of(pageNum-1, size));
}
@Transactional(readOnly = true)
public long countPapersByUserResult(Long studyUserId) {
return paperRepository.countByStudyUserIdAndState(studyUserId, Paper.PaperState.END);
}
@Transactional(readOnly = true)
public List<Paper> getPapersByUserState(Long studyUserId, List<Paper.PaperState> states) {
return paperRepository.findAllByStudyUserIdAndStateInOrderByCreatedDesc(studyUserId, states);
}
@Transactional(readOnly = true)
public Optional<Paper> findPaper(Long paperId) {
return paperRepository.findById(paperId);
}
}
PaperTemplateService
@Transactional
@Service
@RequiredArgsConstructor
public class PaperTemplateService {
private final PaperTemplateRepository paperTemplateRepository;
private final ProblemService problemService;
public PaperTemplate save(PaperTemplate paperTemplate) {
if(paperTemplate.getPaperTemplateId() == null){
paperTemplate.setCreated(LocalDateTime.now());
}
paperTemplate.setUpdated(LocalDateTime.now());
return paperTemplateRepository.save(paperTemplate);
}
// 문제 한개씩 추가
public Problem addProblem(long paperTemplateId, Problem problem){
problem.setPaperTemplateId(paperTemplateId);
return findById(paperTemplateId).map(paperTemplate -> {
if(paperTemplate.getProblemList() == null){
paperTemplate.setProblemList(new ArrayList<>());
}
problem.setCreated(LocalDateTime.now());
paperTemplate.getProblemList().add(problem);
IntStream.rangeClosed(1, paperTemplate.getProblemList().size()).forEach(i->{
paperTemplate.getProblemList().get(i-1).setIndexNum(i);
});
paperTemplate.setTotal(paperTemplate.getProblemList().size());
Problem saved = problemService.save(problem);
save(paperTemplate);
return saved;
}).orElseThrow(()-> new IllegalArgumentException(paperTemplateId+" 아이디 시험지가 없습니다."));
}
public Optional<PaperTemplate> findById(long paperTemplateId) {
return paperTemplateRepository.findById(paperTemplateId);
}
public PaperTemplate removeProblem(long paperTemplateId, long problemId){
return findById(paperTemplateId).map(paperTemplate -> {
if(paperTemplate.getProblemList() == null){
return paperTemplate;
}
Optional<Problem> problem = paperTemplate.getProblemList().stream().filter(p -> p.getProblemId().equals(problemId)).findFirst();
if(problem.isPresent()){
paperTemplate.setProblemList(
paperTemplate.getProblemList().stream().filter(p -> !p.getProblemId().equals(problemId))
.collect(Collectors.toList())
);
problemService.delete(problem.get());
IntStream.rangeClosed(1, paperTemplate.getProblemList().size()).forEach(i->{
paperTemplate.getProblemList().get(i-1).setIndexNum(i);
});
}
paperTemplate.setTotal(paperTemplate.getProblemList().size());
return save(paperTemplate);
}).orElseThrow(()-> new IllegalArgumentException(paperTemplateId+" 아이디 시험지가 없습니다."));
}
public void update(long problemId, String content, String answer){
problemService.updateProblem(problemId, content, answer);
}
@Transactional(readOnly = true)
public Optional<PaperTemplate> findProblemTemplate(Long paperTemplateId) {
return paperTemplateRepository.findById(paperTemplateId).map(pt->{
if(pt.getProblemList().size() != pt.getTotal()){ // lazy 해결위해 체크..., 혹시나 total과 list 사이즈가 다를까봐
pt.setTotal(pt.getProblemList().size());
}
return pt;
});
}
@Transactional(readOnly = true)
public Map<Integer, String> getPaperAnswerSheet(Long paperTemplateId) {
Optional<PaperTemplate> template = findById(paperTemplateId);
if(!template.isPresent()) return new HashMap<>();
// Map으로 가져오면 정답을 가져올때 유용
return template.get().getProblemList().stream().collect(Collectors.toMap(Problem::getIndexNum, Problem::getAnswer));
}
@Transactional(readOnly = true)
public List<PaperTemplate> findByTeacherId(Long userId) {
return paperTemplateRepository.findAllByUserIdOrderByCreatedDesc(userId);
}
@Transactional(readOnly = true)
public Page<PaperTemplate> findByTeacherId(Long userId, int pageNum, int size) {
return paperTemplateRepository.findAllByUserIdOrderByCreatedDesc(userId, PageRequest.of(pageNum-1, size));
}
@Transactional(readOnly = true)
public Object countByUserId(Long userId) {
return paperTemplateRepository.countByUserId(userId);
}
// Controller가 학생에게 시험지를 배부할때
public void updatePublishedCount(long paperTemplateId, long publishedCount) {
paperTemplateRepository.findById(paperTemplateId).ifPresent(paperTemplate -> {
paperTemplate.setPublishedCount(publishedCount);
paperTemplateRepository.save(paperTemplate);
});
}
public void updateCompleteCount(Long paperTemplateId) {
paperTemplateRepository.findById(paperTemplateId).ifPresent(paperTemplate -> {
paperTemplate.setCompleteCount(paperTemplate.getCompleteCount()+1);
paperTemplateRepository.save(paperTemplate);
});
}
}
ProblemService
@Service
@Transactional
@RequiredArgsConstructor
public class ProblemService {
private final ProblemRepository problemRepository;
public Problem save(Problem problem) {
if(problem.getProblemId() == null){
problem.setCreated(LocalDateTime.now());
}
problem.setUpdated(LocalDateTime.now());
return problemRepository.save(problem);
}
public Optional<Problem> findProblem(Long problemId){
return problemRepository.findById(problemId);
}
public List<Problem> listProblems(long paperTemplateId){
return problemRepository.findAllByPaperTemplateIdOrderByIndexNumAsc(paperTemplateId);
}
public void delete(Problem problem) {
problemRepository.delete(problem);
}
public void updateProblem(long problemId, String content, String answer) {
problemRepository.updateProblem(problemId, content, answer, LocalDateTime.now());
}
}
테스트코드
@RequiredArgsConstructor
public class PaperTemplateTestHelper {
private final PaperTemplateService paperTemplateService;
public PaperTemplate createPaperTemplate(User teacher, String paperName){
PaperTemplate paperTemplate = PaperTemplate.builder()
.name(paperName)
.creator(teacher)
.build();
return paperTemplateService.save(paperTemplate);
}
public Problem addProblem(long paperTemplateId, Problem problem){
return paperTemplateService.addProblem(paperTemplateId, problem);
}
public static void assertPaperTemplate(PaperTemplate pt, User user, String paperName) {
assertNotNull(pt.getPaperTemplateId());
assertNotNull(pt.getCreated());
assertNotNull(pt.getUpdated());
assertEquals(paperName, pt.getName());
assertEquals(user.getUserId(), pt.getCreator().getUserId());
}
}
public class WithPaperTemplateTest extends WithUserTest {
@Autowired
protected PaperTemplateRepository paperTemplateRepository;
@Autowired
protected ProblemRepository problemRepository;
protected PaperTemplateService paperTemplateService;
protected PaperTemplateTestHelper paperTemplateTestHelper;
protected ProblemService problemService;
protected User teacher;
protected void preparePaperTemplate(){
this.problemRepository.deleteAll();
this.paperTemplateRepository.deleteAll();
prepareUserServices();
this.problemService = new ProblemService(problemRepository);
this.paperTemplateService = new PaperTemplateService(paperTemplateRepository, problemService);
this.paperTemplateTestHelper = new PaperTemplateTestHelper(this.paperTemplateService);
this.teacher = this.userTestHelper.createTeacher(school, "선생님1");
}
protected Problem problem(long ptId, String content, String answer){
return Problem.builder().paperTemplateId(ptId)
.content(content).answer(answer).build();
}
}
@DisplayName("학습자가 시험지를 푸는 것에 대해서 테스트 한다. ")
@DataJpaTest
public class PaperSolveTest extends WithPaperTemplateTest {
@Autowired
private PaperRepository paperRepository;
@Autowired
private PaperAnswerRepository paperAnswerRepository;
private PaperService paperService;
private PaperTemplate paperTemplate;
private Problem problem1;
private Problem problem2;
private User study1;
private Paper paper;
@BeforeEach
void before(){
paperRepository.deleteAll();
preparePaperTemplate();
this.paperService = new PaperService(userRepository, paperTemplateService, paperRepository, paperAnswerRepository);
this.study1 = this.userTestHelper.createStudent(school, teacher, "study1", "중1");
this.paperTemplate = this.paperTemplateTestHelper.createPaperTemplate(teacher, "시험지1");
this.problem1 = this.paperTemplateTestHelper.addProblem(paperTemplate.getPaperTemplateId(),
problem(paperTemplate.getPaperTemplateId(), "문제1", "답1"));
this.problem2 = this.paperTemplateTestHelper.addProblem(paperTemplate.getPaperTemplateId(),
problem(paperTemplate.getPaperTemplateId(), "문제2", "답2"));
this.paper = paperService.publishPaper(paperTemplate.getPaperTemplateId(), List.of(study1.getUserId())).get(0);
}
@DisplayName("1. 시험지를 모두 풀어서 100점을 맞는다.")
@Test
void 시험지를_모두_풀어서_100점을_맞는다() {
paperService.answer(paper.getPaperId(), problem1.getProblemId(), 1, "답1");
Paper ingPaper = paperService.findPaper(this.paper.getPaperId()).get();
assertEquals(2, ingPaper.getTotal());
assertEquals(1, ingPaper.getAnswered());
assertEquals(0, ingPaper.getCorrect());
assertEquals(Paper.PaperState.START, ingPaper.getState());
assertNotNull(ingPaper.getStartTime());
assertNull(ingPaper.getEndTime());
paperService.answer(paper.getPaperId(), problem2.getProblemId(), 2, "답2");
ingPaper = paperService.findPaper(this.paper.getPaperId()).get();
assertEquals(2, ingPaper.getTotal());
assertEquals(2, ingPaper.getAnswered());
assertEquals(0, ingPaper.getCorrect());
assertEquals(Paper.PaperState.START, ingPaper.getState());
assertNotNull(ingPaper.getStartTime());
assertNull(ingPaper.getEndTime());
paperService.paperDone(paper.getPaperId());
Paper resultPaper = paperService.findPaper(this.paper.getPaperId()).get();
assertEquals(2, resultPaper.getTotal());
assertEquals(2, resultPaper.getAnswered());
assertEquals(2, resultPaper.getCorrect());
assertEquals(Paper.PaperState.END, resultPaper.getState());
assertNotNull(resultPaper.getStartTime());
assertNotNull(resultPaper.getEndTime());
PaperTemplate result = paperTemplateService.findById(paperTemplate.getPaperTemplateId()).get();
assertEquals(1, result.getPublishedCount());
assertEquals(1, result.getCompleteCount());
}
@DisplayName("2. 문제를 한개 틀려서 50점을 맞는다.")
@Test
void 문제를_한개_틀려서_50점을_맞는다() {
paperService.answer(paper.getPaperId(), problem1.getProblemId(), 1, "답1");
paperService.answer(paper.getPaperId(), problem2.getProblemId(), 2, "오답");
paperService.paperDone(paper.getPaperId());
Paper resultPaper = paperService.findPaper(this.paper.getPaperId()).get();
assertEquals(2, resultPaper.getTotal());
assertEquals(2, resultPaper.getAnswered());
assertEquals(1, resultPaper.getCorrect());
}
@DisplayName("3. 문제를 모두 틀려서 0점을 맞는다.")
@Test
void 문제를_모두_틀려서_0점을_맞는다() {
paperService.answer(paper.getPaperId(), problem1.getProblemId(), 1, "오답");
paperService.answer(paper.getPaperId(), problem2.getProblemId(), 2, "오답");
paperService.paperDone(paper.getPaperId());
Paper resultPaper = paperService.findPaper(this.paper.getPaperId()).get();
assertEquals(2, resultPaper.getTotal());
assertEquals(2, resultPaper.getAnswered());
assertEquals(0, resultPaper.getCorrect());
}
@DisplayName("4. 1번 문제 풀고 중간에 제출해 버린다.")
@Test
void 첫번째_문제_풀고_중간에_제출해_버린다() {
paperService.answer(paper.getPaperId(), problem1.getProblemId(), 1, "답1");
paperService.paperDone(paper.getPaperId());
Paper resultPaper = paperService.findPaper(this.paper.getPaperId()).get();
assertEquals(2, resultPaper.getTotal());
assertEquals(1, resultPaper.getAnswered());
assertEquals(1, resultPaper.getCorrect());
}
@DisplayName("5. 2문제 풀고 중간에 제출해 버린다.")
@Test
void 두번째_문제_풀고_중간에_제출해_버린다() {
paperService.answer(paper.getPaperId(), problem2.getProblemId(), 2, "답2");
paperService.paperDone(paper.getPaperId());
Paper resultPaper = paperService.findPaper(this.paper.getPaperId()).get();
assertEquals(2, resultPaper.getTotal());
assertEquals(1, resultPaper.getAnswered());
assertEquals(1, resultPaper.getCorrect());
}
@DisplayName("6. 문제를 풀지 않고 그냥 제출해 버린다.")
@Test
void 문제를_풀지_않고_그냥_제출해_버린다() {
paperService.paperDone(paper.getPaperId());
Paper resultPaper = paperService.findPaper(this.paper.getPaperId()).get();
assertEquals(2, resultPaper.getTotal());
assertEquals(0, resultPaper.getAnswered());
assertEquals(0, resultPaper.getCorrect());
}
@DisplayName("7. 상태에 따라 시험지가 조회된다.")
@Test
void 상태에_따라_시험지가_조회된다() {
assertEquals(1, paperService.getPapersByUserState(study1.getUserId(), List.of(Paper.PaperState.READY, Paper.PaperState.START)).size());
assertEquals(0, paperService.getPapersByUserState(study1.getUserId(), Paper.PaperState.END).size());
paperService.answer(paper.getPaperId(), problem2.getProblemId(), 2, "답2");
assertEquals(1, paperService.getPapersByUserState(study1.getUserId(), List.of(Paper.PaperState.READY, Paper.PaperState.START)).size());
assertEquals(0, paperService.getPapersByUserState(study1.getUserId(), Paper.PaperState.END).size());
paperService.paperDone(paper.getPaperId());
assertEquals(0, paperService.getPapersByUserState(study1.getUserId(), List.of(Paper.PaperState.READY, Paper.PaperState.START)).size());
assertEquals(1, paperService.getPapersByUserState(study1.getUserId(), Paper.PaperState.END).size());
}
}
PaperTemplateTest
@DataJpaTest
public class PaperTemplateTest extends WithPaperTemplateTest {
private PaperTemplate template;
@BeforeEach
void before(){
preparePaperTemplate();
template = paperTemplateTestHelper.createPaperTemplate(teacher, "paper1");
}
private Problem problem(String content, String answer){
return Problem.builder().paperTemplateId(template.getPaperTemplateId())
.content(content)
.answer(answer)
.build();
}
@DisplayName("1. 시험지를 한개 만든다.")
@Test
void test_1(){
assertEquals(1, paperTemplateRepository.count());
PaperTemplateTestHelper.assertPaperTemplate(
paperTemplateRepository.findAll().get(0), teacher, "paper1");
}
@DisplayName("2. 문제를 추가한다.")
@Test
void test_2() {
paperTemplateTestHelper.addProblem(template.getPaperTemplateId(), problem("문제1", "정답1"));
paperTemplateTestHelper.addProblem(template.getPaperTemplateId(), problem("문제2", "정답2"));
paperTemplateTestHelper.addProblem(template.getPaperTemplateId(), problem("문제3", "정답3"));
assertEquals(3, paperTemplateRepository.findAll().get(0).getProblemList().size());
}
@DisplayName("3. 문제를 삭제한다.")
@Test
void test_3() {
paperTemplateTestHelper.addProblem(template.getPaperTemplateId(), problem("문제1", "정답1"));
paperTemplateTestHelper.addProblem(template.getPaperTemplateId(), problem("문제2", "정답2"));
paperTemplateTestHelper.addProblem(template.getPaperTemplateId(), problem("문제3", "정답3"));
PaperTemplate paperTemplate = paperTemplateRepository.findAll().get(0);
paperTemplateService.removeProblem(template.getPaperTemplateId(), paperTemplate.getProblemList().get(1).getProblemId());
assertEquals(2, paperTemplateRepository.findAll().get(0).getProblemList().size());
paperTemplate = paperTemplateRepository.findAll().get(0);
assertEquals(1, paperTemplate.getProblemList().get(0).getIndexNum());
assertEquals(2, paperTemplate.getProblemList().get(1).getIndexNum());
assertEquals("문제3", paperTemplate.getProblemList().get(1).getContent());
}
}
@DisplayName("템플릿을 가지고 학습자들에게 시험지를 낸다.")
@DataJpaTest
public class PaperTest extends WithPaperTemplateTest {
@Autowired
private PaperRepository paperRepository;
@Autowired
private PaperAnswerRepository paperAnswerRepository;
private PaperService paperService;
private PaperTemplate paperTemplate;
private User study1;
private User study2;
@BeforeEach
void before(){
paperRepository.deleteAll();
preparePaperTemplate();
this.paperService = new PaperService(userRepository, paperTemplateService, paperRepository, paperAnswerRepository);
this.study1 = this.userTestHelper.createStudent(school, teacher, "study1", "중1");
this.study2 = this.userTestHelper.createStudent(school, teacher, "study2", "중1");
this.paperTemplate = this.paperTemplateTestHelper.createPaperTemplate(teacher, "시험지1");
this.paperTemplateTestHelper.addProblem(paperTemplate.getPaperTemplateId(),
problem(paperTemplate.getPaperTemplateId(), "문제1", "답1"));
this.paperTemplateTestHelper.addProblem(paperTemplate.getPaperTemplateId(),
problem(paperTemplate.getPaperTemplateId(), "문제2", "답2"));
}
@DisplayName("1. 시험지 템플릿을 학습자1에게 시험지를 낸다.")
@Test
void 시험지_템플릿을_학습자1에게_시험지를_낸다() {
paperService.publishPaper(paperTemplate.getPaperTemplateId(), List.of(study1.getUserId()));
List<Paper> papers = paperService.getPapers(paperTemplate.getPaperTemplateId());
assertEquals(1, papers.size());
Paper paper = papers.get(0);
assertNotNull(paper.getPaperId());
assertNotNull(paper.getCreated());
assertEquals(study1.getUserId(), paper.getStudyUserId());
assertEquals(paperTemplate.getPaperTemplateId(), paper.getPaperTemplateId());
assertEquals(paperTemplate.getName(), paper.getName());
assertNull(paper.getStartTime());
assertNull(paper.getEndTime());
assertEquals(Paper.PaperState.READY, paper.getState());
assertEquals(2, paper.getTotal());
assertEquals(0, paper.getAnswered());
assertEquals(0, paper.getCorrect());
PaperTemplate result = paperTemplateService.findById(paperTemplate.getPaperTemplateId()).get();
assertEquals(1, result.getPublishedCount());
assertEquals(0, result.getCompleteCount());
}
@DisplayName("2. 시험지를 2명 이상의 user 를 검색해 낸다. (학습자1, 학습자2) ")
@Test
void 시험지를_2명_이상의_user를_검색해_낸다() {
paperService.publishPaper(paperTemplate.getPaperTemplateId(), List.of(study1.getUserId(), study2.getUserId()));
List<Paper> papers = paperService.getPapers(paperTemplate.getPaperTemplateId());
assertEquals(2, papers.size());
}
@DisplayName("3. 시험지 삭제 기능")
@Test
void 시험지_삭제_기능() {
paperService.publishPaper(paperTemplate.getPaperTemplateId(), List.of(study1.getUserId(), study2.getUserId()));
paperService.removePaper(paperTemplate.getPaperTemplateId(), List.of(study1.getUserId()));
List<Paper> papers = paperService.getPapers(paperTemplate.getPaperTemplateId());
assertEquals(1, papers.size());
paperService.removePaper(paperTemplate.getPaperTemplateId(), List.of(study2.getUserId()));
papers = paperService.getPapers(paperTemplate.getPaperTemplateId());
assertEquals(0, papers.size());
paperService.removePaper(paperTemplate.getPaperTemplateId(), List.of(study2.getUserId()));
papers = paperService.getPapers(paperTemplate.getPaperTemplateId());
assertEquals(0, papers.size());
}
}
PaperTestApplication
@SpringBootApplication(scanBasePackages = {
"com.sp.fc.config"
})
public class PaperTestApp {
public static void main(String[] args) {
SpringApplication.run(PaperTestApp.class, args);
}
@Configuration
@EntityScan(basePackages = {
"com.sp.fc.user.domain",
"com.sp.fc.paper.domain"
})
@EnableJpaRepositories(basePackages = {
"com.sp.fc.user.repository",
"com.sp.fc.paper.repository"
})
class JpaConfig {
}
}
build.gradle
dependencies {
implementation("$boot:spring-boot-starter-data-jpa")
testRuntime("com.h2database:h2")
compile project(":comp-paper-user")
testCompile project(":comp-paper-user").sourceSets.test.output
}