Add UserQuizCycle and apply
This commit is contained in:
@@ -3,6 +3,7 @@ package com.mangkyu.employment.interview.app.user.entity;
|
||||
import com.mangkyu.employment.interview.app.common.entity.BaseEntity;
|
||||
import com.mangkyu.employment.interview.app.quiz.enums.QuizLevel;
|
||||
import com.mangkyu.employment.interview.app.solvedquiz.entity.SolvedQuiz;
|
||||
import com.mangkyu.employment.interview.app.user.enums.UserQuizCycle;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@@ -27,6 +28,10 @@ public class User extends BaseEntity {
|
||||
@Enumerated(EnumType.STRING)
|
||||
private QuizLevel quizLevel;
|
||||
|
||||
@Builder.Default
|
||||
@Enumerated(EnumType.STRING)
|
||||
private UserQuizCycle userQuizCycle = UserQuizCycle.REGULAR_INTERVALS;
|
||||
|
||||
@Builder.Default
|
||||
private Integer quizSize = DEFAULT_QUIZ_SIZE;
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mangkyu.employment.interview.app.user.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum UserQuizCycle {
|
||||
|
||||
DAILY("Quiz Everyday"),
|
||||
REGULAR_INTERVALS("Quiz Regular Intervals"),
|
||||
;
|
||||
|
||||
private final String desc;
|
||||
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package com.mangkyu.employment.interview.app.user.repository;
|
||||
|
||||
import com.mangkyu.employment.interview.app.user.entity.User;
|
||||
import com.mangkyu.employment.interview.app.user.enums.UserQuizCycle;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserRepository extends JpaRepository <User, Long> {
|
||||
|
||||
List<User> findAllByIsEnableTrue();
|
||||
List<User> findAllByIsEnableTrueAndUserQuizCycleIs(final UserQuizCycle userQuizCycle);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.mangkyu.employment.interview.app.user.service;
|
||||
|
||||
import com.mangkyu.employment.interview.app.user.dto.AddUserRequest;
|
||||
import com.mangkyu.employment.interview.app.user.entity.User;
|
||||
import com.mangkyu.employment.interview.app.user.enums.UserQuizCycle;
|
||||
import com.mangkyu.employment.interview.app.user.repository.UserRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.modelmapper.ModelMapper;
|
||||
@@ -30,7 +31,7 @@ public class UserService {
|
||||
userRepository.save(user);
|
||||
}
|
||||
|
||||
public List<User> getEnabledUserList() {
|
||||
return userRepository.findAllByIsEnableTrue();
|
||||
public List<User> getEnabledUserList(final UserQuizCycle userQuizCycle) {
|
||||
return userRepository.findAllByIsEnableTrueAndUserQuizCycleIs(userQuizCycle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.mangkyu.employment.interview.app.quiz.entity.Quiz;
|
||||
import com.mangkyu.employment.interview.app.quiz.service.QuizService;
|
||||
import com.mangkyu.employment.interview.app.solvedquiz.service.SolvedQuizService;
|
||||
import com.mangkyu.employment.interview.app.user.entity.User;
|
||||
import com.mangkyu.employment.interview.app.user.enums.UserQuizCycle;
|
||||
import com.mangkyu.employment.interview.app.user.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -33,22 +34,35 @@ public class SendQuizCronJob {
|
||||
// @Scheduled(cron = "*/30 * * * * *") // every 30 seconds
|
||||
@Scheduled(cron = "0 0 01 * * 1,4") // every Monday, Thursday at 1am
|
||||
@Transactional
|
||||
public void sendQuizMailEveryWeek() {
|
||||
final List<User> userList = userService.getEnabledUserList();
|
||||
public void sendQuizMailEveryMondayAndThursday1AM() {
|
||||
final List<User> userList = userService.getEnabledUserList(UserQuizCycle.REGULAR_INTERVALS);
|
||||
for (final User user : userList) {
|
||||
final List<Quiz> unsolvedQuizList = quizService.getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
final boolean isLastMail = isLastMail(unsolvedQuizList, user.getQuizSize());
|
||||
|
||||
final List<Quiz> randomQuizList = quizService.getRandomQuizListUnderLimit(unsolvedQuizList, user.getQuizSize());
|
||||
if (isLastMail) {
|
||||
userService.disableUser(user);
|
||||
}
|
||||
|
||||
mailService.sendMail(user.getEmail(), randomQuizList, isLastMail);
|
||||
solvedQuizService.addSolvedQuizList(user, randomQuizList);
|
||||
sendUnsolvedQuizForUser(user);
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0 01 * * *") // everyday at 1am
|
||||
@Transactional
|
||||
public void sendQuizMailEveryDay1AM() {
|
||||
final List<User> userList = userService.getEnabledUserList(UserQuizCycle.DAILY);
|
||||
for (final User user : userList) {
|
||||
sendUnsolvedQuizForUser(user);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendUnsolvedQuizForUser(final User user) {
|
||||
final List<Quiz> unsolvedQuizList = quizService.getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
final boolean isLastMail = isLastMail(unsolvedQuizList, user.getQuizSize());
|
||||
|
||||
final List<Quiz> randomQuizList = quizService.getRandomQuizListUnderLimit(unsolvedQuizList, user.getQuizSize());
|
||||
if (isLastMail) {
|
||||
userService.disableUser(user);
|
||||
}
|
||||
|
||||
mailService.sendMail(user.getEmail(), randomQuizList, isLastMail);
|
||||
solvedQuizService.addSolvedQuizList(user, randomQuizList);
|
||||
}
|
||||
|
||||
private boolean isLastMail(final List<Quiz> quizList, final Integer quizSize) {
|
||||
return quizList.size() <= quizSize;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.mangkyu.employment.interview.app.user.repository;
|
||||
|
||||
import com.mangkyu.employment.interview.app.quiz.enums.QuizLevel;
|
||||
import com.mangkyu.employment.interview.app.user.entity.User;
|
||||
import com.mangkyu.employment.interview.app.user.enums.UserQuizCycle;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
@@ -16,6 +17,28 @@ class UserRepositoryTest {
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
|
||||
@Test
|
||||
public void selectUserListByCycle() {
|
||||
// given
|
||||
final User user = User.builder()
|
||||
.email("minkyu@test.com")
|
||||
.quizLevel(QuizLevel.JUNIOR)
|
||||
.userQuizCycle(UserQuizCycle.DAILY)
|
||||
.build();
|
||||
|
||||
final User savedUser = userRepository.save(user);
|
||||
userRepository.save(savedUser);
|
||||
|
||||
// when
|
||||
final List<User> dailyResult = userRepository.findAllByIsEnableTrueAndUserQuizCycleIs(UserQuizCycle.DAILY);
|
||||
final List<User> regularResult = userRepository.findAllByIsEnableTrueAndUserQuizCycleIs(UserQuizCycle.REGULAR_INTERVALS);
|
||||
|
||||
// then
|
||||
assertThat(dailyResult.size()).isOne();
|
||||
assertThat(regularResult.size()).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertUser() {
|
||||
// given
|
||||
@@ -40,6 +63,7 @@ class UserRepositoryTest {
|
||||
final User user = User.builder()
|
||||
.email("minkyu@test.com")
|
||||
.quizLevel(QuizLevel.JUNIOR)
|
||||
.userQuizCycle(UserQuizCycle.REGULAR_INTERVALS)
|
||||
.build();
|
||||
|
||||
final User savedUser = userRepository.save(user);
|
||||
@@ -47,7 +71,7 @@ class UserRepositoryTest {
|
||||
userRepository.save(savedUser);
|
||||
|
||||
// when
|
||||
final List<User> result = userRepository.findAllByIsEnableTrue();
|
||||
final List<User> result = userRepository.findAllByIsEnableTrueAndUserQuizCycleIs(UserQuizCycle.REGULAR_INTERVALS);
|
||||
|
||||
// then
|
||||
assertThat(result.size()).isZero();
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.mangkyu.employment.interview.app.user.service;
|
||||
import com.mangkyu.employment.interview.app.quiz.enums.QuizLevel;
|
||||
import com.mangkyu.employment.interview.app.user.dto.AddUserRequest;
|
||||
import com.mangkyu.employment.interview.app.user.entity.User;
|
||||
import com.mangkyu.employment.interview.app.user.enums.UserQuizCycle;
|
||||
import com.mangkyu.employment.interview.app.user.repository.UserRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -31,6 +32,8 @@ class UserServiceTest {
|
||||
@Spy
|
||||
private ModelMapper modelMapper;
|
||||
|
||||
private final UserQuizCycle userQuizCycle = UserQuizCycle.DAILY;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
modelMapper.getConfiguration()
|
||||
@@ -70,16 +73,16 @@ class UserServiceTest {
|
||||
public void getEnabledUserListSuccess() {
|
||||
// given
|
||||
final List<User> enabledUserList = Arrays.asList(user(true), user(true));
|
||||
doReturn(enabledUserList).when(userRepository).findAllByIsEnableTrue();
|
||||
doReturn(enabledUserList).when(userRepository).findAllByIsEnableTrueAndUserQuizCycleIs(userQuizCycle);
|
||||
|
||||
// when
|
||||
final List<User> result = target.getEnabledUserList();
|
||||
final List<User> result = target.getEnabledUserList(userQuizCycle);
|
||||
|
||||
// then
|
||||
assertThat(result.size()).isEqualTo(enabledUserList.size());
|
||||
|
||||
// verify
|
||||
verify(userRepository, times(1)).findAllByIsEnableTrue();
|
||||
verify(userRepository, times(1)).findAllByIsEnableTrueAndUserQuizCycleIs(userQuizCycle);
|
||||
}
|
||||
|
||||
private User user(final boolean isEnable) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.mangkyu.employment.interview.app.quiz.enums.QuizLevel;
|
||||
import com.mangkyu.employment.interview.app.quiz.service.QuizService;
|
||||
import com.mangkyu.employment.interview.app.solvedquiz.service.SolvedQuizService;
|
||||
import com.mangkyu.employment.interview.app.user.entity.User;
|
||||
import com.mangkyu.employment.interview.app.user.enums.UserQuizCycle;
|
||||
import com.mangkyu.employment.interview.app.user.service.UserService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -50,34 +51,34 @@ class SendQuizCronJobTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendQuizMailEveryWeekSuccess_UserNotExists() {
|
||||
public void sendQuizMailDaily_UserNotExists() {
|
||||
// given
|
||||
doReturn(Collections.emptyList())
|
||||
.when(userService)
|
||||
.getEnabledUserList();
|
||||
.getEnabledUserList(UserQuizCycle.DAILY);
|
||||
|
||||
// when
|
||||
target.sendQuizMailEveryWeek();
|
||||
target.sendQuizMailEveryDay1AM();
|
||||
|
||||
// then
|
||||
|
||||
// verify
|
||||
verify(quizService, times(0)).getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
verify(quizService, times(0)).getRandomQuizListUnderLimit(anyList(), user.getQuizSize());
|
||||
verify(quizService, times(0)).getRandomQuizListUnderLimit(anyList(), anyInt());
|
||||
verify(userService, times(0)).disableUser(user);
|
||||
verify(mailService, times(0)).sendMail(anyString(), anyList(), anyBoolean());
|
||||
verify(solvedQuizService, times(0)).addSolvedQuizList(any(User.class), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendQuizMailEveryWeekSuccess_NotLastMail() {
|
||||
public void sendQuizMailDaily_NotLastMail() {
|
||||
// given
|
||||
final List<Quiz> unsolvedQuizList = quizList(5);
|
||||
final List<Quiz> randomQuizList = unsolvedQuizList.subList(0, 3);
|
||||
|
||||
doReturn(userList)
|
||||
.when(userService)
|
||||
.getEnabledUserList();
|
||||
.getEnabledUserList(UserQuizCycle.DAILY);
|
||||
doReturn(unsolvedQuizList)
|
||||
.when(quizService)
|
||||
.getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
@@ -86,7 +87,7 @@ class SendQuizCronJobTest {
|
||||
.getRandomQuizListUnderLimit(unsolvedQuizList, user.getQuizSize());
|
||||
|
||||
// when
|
||||
target.sendQuizMailEveryWeek();
|
||||
target.sendQuizMailEveryDay1AM();
|
||||
|
||||
// then
|
||||
|
||||
@@ -99,14 +100,14 @@ class SendQuizCronJobTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendQuizMailEveryWeekSuccess_LastMail() {
|
||||
public void sendQuizMailDaily_LastMail() {
|
||||
// given
|
||||
final List<Quiz> unsolvedQuizList = quizList(3);
|
||||
final List<Quiz> randomQuizList = unsolvedQuizList.subList(0, 3);
|
||||
|
||||
doReturn(userList)
|
||||
.when(userService)
|
||||
.getEnabledUserList();
|
||||
.getEnabledUserList(UserQuizCycle.DAILY);
|
||||
doReturn(unsolvedQuizList)
|
||||
.when(quizService)
|
||||
.getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
@@ -115,7 +116,85 @@ class SendQuizCronJobTest {
|
||||
.getRandomQuizListUnderLimit(unsolvedQuizList, user.getQuizSize());
|
||||
|
||||
// when
|
||||
target.sendQuizMailEveryWeek();
|
||||
target.sendQuizMailEveryDay1AM();
|
||||
|
||||
// then
|
||||
|
||||
// verify
|
||||
verify(quizService, times(1)).getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
verify(quizService, times(1)).getRandomQuizListUnderLimit(unsolvedQuizList, user.getQuizSize());
|
||||
verify(userService, times(1)).disableUser(user);
|
||||
verify(mailService, times(1)).sendMail(user.getEmail(), randomQuizList, true);
|
||||
verify(solvedQuizService, times(1)).addSolvedQuizList(user, randomQuizList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendQuizMailRegulary_UserNotExists() {
|
||||
// given
|
||||
doReturn(Collections.emptyList())
|
||||
.when(userService)
|
||||
.getEnabledUserList(UserQuizCycle.REGULAR_INTERVALS);
|
||||
|
||||
// when
|
||||
target.sendQuizMailEveryMondayAndThursday1AM();
|
||||
|
||||
// then
|
||||
|
||||
// verify
|
||||
verify(quizService, times(0)).getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
verify(quizService, times(0)).getRandomQuizListUnderLimit(anyList(), anyInt());
|
||||
verify(userService, times(0)).disableUser(user);
|
||||
verify(mailService, times(0)).sendMail(anyString(), anyList(), anyBoolean());
|
||||
verify(solvedQuizService, times(0)).addSolvedQuizList(any(User.class), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendQuizMailRegulary_NotLastMail() {
|
||||
// given
|
||||
final List<Quiz> unsolvedQuizList = quizList(5);
|
||||
final List<Quiz> randomQuizList = unsolvedQuizList.subList(0, 3);
|
||||
|
||||
doReturn(userList)
|
||||
.when(userService)
|
||||
.getEnabledUserList(UserQuizCycle.REGULAR_INTERVALS);
|
||||
doReturn(unsolvedQuizList)
|
||||
.when(quizService)
|
||||
.getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
doReturn(randomQuizList)
|
||||
.when(quizService)
|
||||
.getRandomQuizListUnderLimit(unsolvedQuizList, user.getQuizSize());
|
||||
|
||||
// when
|
||||
target.sendQuizMailEveryMondayAndThursday1AM();
|
||||
|
||||
// then
|
||||
|
||||
// verify
|
||||
verify(quizService, times(1)).getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
verify(quizService, times(1)).getRandomQuizListUnderLimit(unsolvedQuizList, user.getQuizSize());
|
||||
verify(userService, times(0)).disableUser(user);
|
||||
verify(mailService, times(1)).sendMail(user.getEmail(), randomQuizList, false);
|
||||
verify(solvedQuizService, times(1)).addSolvedQuizList(user, randomQuizList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendQuizMailRegulary_LastMail() {
|
||||
// given
|
||||
final List<Quiz> unsolvedQuizList = quizList(3);
|
||||
final List<Quiz> randomQuizList = unsolvedQuizList.subList(0, 3);
|
||||
|
||||
doReturn(userList)
|
||||
.when(userService)
|
||||
.getEnabledUserList(UserQuizCycle.REGULAR_INTERVALS);
|
||||
doReturn(unsolvedQuizList)
|
||||
.when(quizService)
|
||||
.getUnsolvedQuizList(user.getId(), user.getQuizLevel());
|
||||
doReturn(randomQuizList)
|
||||
.when(quizService)
|
||||
.getRandomQuizListUnderLimit(unsolvedQuizList, user.getQuizSize());
|
||||
|
||||
// when
|
||||
target.sendQuizMailEveryMondayAndThursday1AM();
|
||||
|
||||
// then
|
||||
|
||||
|
||||
Reference in New Issue
Block a user