diff --git a/src/main/java/soongsil/kidbean/server/auth/presentation/filter/JwtFilter.java b/src/main/java/soongsil/kidbean/server/auth/presentation/filter/JwtFilter.java index 85a4ce15..1371a84e 100644 --- a/src/main/java/soongsil/kidbean/server/auth/presentation/filter/JwtFilter.java +++ b/src/main/java/soongsil/kidbean/server/auth/presentation/filter/JwtFilter.java @@ -32,7 +32,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse Member member = jwtTokenProvider.getMember(token); AuthenticationUtil.makeAuthentication(member); - log.info("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}", member.getSocialId(), requestURI); + log.info("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}", member.getMemberId(), requestURI); } filterChain.doFilter(request, response); diff --git a/src/main/java/soongsil/kidbean/server/auth/util/AuthenticationUtil.java b/src/main/java/soongsil/kidbean/server/auth/util/AuthenticationUtil.java index 1d54ab42..50be4be7 100644 --- a/src/main/java/soongsil/kidbean/server/auth/util/AuthenticationUtil.java +++ b/src/main/java/soongsil/kidbean/server/auth/util/AuthenticationUtil.java @@ -3,7 +3,6 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; @@ -13,19 +12,9 @@ import soongsil.kidbean.server.auth.dto.AuthUser; import soongsil.kidbean.server.member.domain.Member; -@RequiredArgsConstructor @Component public class AuthenticationUtil { - public static Authentication getAuthentication(AuthUser authUser) { - - List grantedAuthorities = authUser.roles().stream() - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()); - - return new UsernamePasswordAuthenticationToken(authUser, "", grantedAuthorities); - } - public static void makeAuthentication(Member member) { // Authentication 정보 만들기 AuthUser authUser = AuthUser.builder() @@ -39,4 +28,12 @@ public static void makeAuthentication(Member member) { Authentication auth = AuthenticationUtil.getAuthentication(authUser); SecurityContextHolder.getContext().setAuthentication(auth); } + + private static Authentication getAuthentication(AuthUser authUser) { + List grantedAuthorities = authUser.roles().stream() + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + return new UsernamePasswordAuthenticationToken(authUser, "", grantedAuthorities); + } } \ No newline at end of file diff --git a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizscorer/ImageQuizScorer.java b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizscorer/ImageQuizScorer.java index 43a08b6b..f3d8981c 100644 --- a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizscorer/ImageQuizScorer.java +++ b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizscorer/ImageQuizScorer.java @@ -14,14 +14,14 @@ public class ImageQuizScorer implements QuizScorer { private final QuizScoreRepository quizScoreRepository; + @Override public Long addPerQuizScore(SolvedQuizInfo solvedQuizInfo, Member member) { QuizScore quizScore = quizScoreRepository.findByMemberAndQuizCategory(member, solvedQuizInfo.category()) .orElseGet(() -> quizScoreRepository.save( QuizScore.makeInitQuizScore(member, solvedQuizInfo.category()))); - QuizScore updateQuizScore = quizScore.addScore(solvedQuizInfo.score()) - .addCount(solvedQuizInfo.isExist()); + QuizScore updateQuizScore = quizScore.addScore(solvedQuizInfo.score()).addCount(); quizScoreRepository.save(updateQuizScore); return solvedQuizInfo.score(); diff --git a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizscorer/WordQuizScorer.java b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizscorer/WordQuizScorer.java index 1b219340..44c0364b 100644 --- a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizscorer/WordQuizScorer.java +++ b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizscorer/WordQuizScorer.java @@ -11,17 +11,17 @@ @Service @Transactional @RequiredArgsConstructor -public class WordQuizScorer implements QuizScorer{ +public class WordQuizScorer implements QuizScorer { private final QuizScoreRepository quizScoreRepository; + @Override public Long addPerQuizScore(SolvedQuizInfo solvedQuizInfo, Member member) { QuizScore quizScore = quizScoreRepository.findByMemberAndQuizCategory(member, solvedQuizInfo.category()) .orElseGet(() -> quizScoreRepository.save( QuizScore.makeInitQuizScore(member, solvedQuizInfo.category()))); - QuizScore updateQuizScore = quizScore.addScore(solvedQuizInfo.score()) - .addCount(solvedQuizInfo.isExist()); + QuizScore updateQuizScore = quizScore.addScore(solvedQuizInfo.score()).addCount(); quizScoreRepository.save(updateQuizScore); return solvedQuizInfo.score(); diff --git a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/ImageQuizSolver.java b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/ImageQuizSolver.java index 9f42e1cf..af36f344 100644 --- a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/ImageQuizSolver.java +++ b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/ImageQuizSolver.java @@ -38,43 +38,15 @@ public SolvedQuizInfo solveQuiz(QuizSolvedRequest solvedRequest, Member member) .orElseThrow(() -> new ImageQuizNotFoundException(IMAGE_QUIZ_NOT_FOUND)); QuizSolved imageQuizSolved = solvedRequest.toQuizSolved(imageQuiz, member); - if (imageQuizSolvedExists(imageQuiz, member)) { - return solveExistingImageQuizSolved(imageQuizSolved, imageQuiz); - } else { - return solveNewImageQuiz(imageQuizSolved, imageQuiz); - } - } - - private Boolean imageQuizSolvedExists(ImageQuiz imageQuiz, Member member) { - return quizSolvedRepository.existsByImageQuizAndMember(imageQuiz, member); + return solveNewImageQuiz(imageQuizSolved, imageQuiz); } private SolvedQuizInfo solveNewImageQuiz(QuizSolved newQuizSolved, ImageQuiz imageQuiz) { - newQuizSolved.setAnswerIsCorrect(newQuizSolved.getReply().contains(imageQuiz.getAnswer())); - quizSolvedRepository.save(newQuizSolved); - - return newQuizSolved.getIsCorrect() ? new SolvedQuizInfo(imageQuiz.getQuizCategory(), - getPoint(imageQuiz.getLevel()), false) : new SolvedQuizInfo(imageQuiz.getQuizCategory(), 0L, false); - } - - private SolvedQuizInfo solveExistingImageQuizSolved(QuizSolved newQuizSolved, ImageQuiz imageQuiz) { - - Member member = newQuizSolved.getMember(); - boolean exCorrect = quizSolvedRepository.existsByImageQuizAndMemberAndIsCorrect(imageQuiz, member, true); - //이번에 정답을 맞췄는지 확인 - boolean isCorrect = newQuizSolved.getReply().contains(imageQuiz.getAnswer()); - - //푼 QuizSolved 등록 - newQuizSolved.setAnswerIsCorrect(isCorrect); quizSolvedRepository.save(newQuizSolved); - //이전에 오답이었고 현재 정답인 경우 - if (!exCorrect && isCorrect) { - return new SolvedQuizInfo(imageQuiz.getQuizCategory(), getPoint(imageQuiz.getLevel()), true); - } else { //이전에 정답인 경우 or 둘 다 오답인 경우 - return new SolvedQuizInfo(imageQuiz.getQuizCategory(), 0L, true); - } + return !newQuizSolved.getIsCorrect() ? new SolvedQuizInfo(imageQuiz.getQuizCategory(), 0L) + : new SolvedQuizInfo(imageQuiz.getQuizCategory(), getPoint(imageQuiz.getLevel())); } private static Long getPoint(Level level) { diff --git a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/WordQuizSolver.java b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/WordQuizSolver.java index af9977a8..b192e03f 100644 --- a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/WordQuizSolver.java +++ b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/WordQuizSolver.java @@ -38,44 +38,15 @@ public SolvedQuizInfo solveQuiz(QuizSolvedRequest solvedRequest, Member member) .orElseThrow(() -> new WordQuizNotFoundException(WORD_QUIZ_NOT_FOUND)); QuizSolved wordQuizSolved = solvedRequest.toQuizSolved(wordQuiz, member); - if (wordQuizSolvedExists(wordQuiz, member)) { - return solveExistingWordQuizSolved(wordQuizSolved, wordQuiz); - } else { - return solveNewWordQuiz(wordQuizSolved, wordQuiz); - } - } - - private Boolean wordQuizSolvedExists(WordQuiz wordQuiz, Member member) { - return quizSolvedRepository.existsByWordQuizAndMember(wordQuiz, member); + return solveNewWordQuiz(wordQuizSolved, wordQuiz); } private SolvedQuizInfo solveNewWordQuiz(QuizSolved newQuizSolved, WordQuiz wordQuiz) { - newQuizSolved.setAnswerIsCorrect(newQuizSolved.getReply().contains(wordQuiz.getAnswer())); - quizSolvedRepository.save(newQuizSolved); - - return newQuizSolved.getIsCorrect() ? new SolvedQuizInfo(wordQuiz.getQuizCategory(), - getPoint(wordQuiz.getLevel()), false) : new SolvedQuizInfo(wordQuiz.getQuizCategory(), 0L, false); - } - - private SolvedQuizInfo solveExistingWordQuizSolved(QuizSolved newQuizSolved, WordQuiz wordQuiz) { - - Member member = newQuizSolved.getMember(); - //이전에 맞았는지 - boolean exCorrect = quizSolvedRepository.existsByWordQuizAndMemberAndIsCorrect(wordQuiz, member, true); - //정답을 포함하고 있는지 - boolean isCorrect = newQuizSolved.getReply().contains(wordQuiz.getAnswer()); - - //푼 QuizSolved 등록 - newQuizSolved.setAnswerIsCorrect(isCorrect); quizSolvedRepository.save(newQuizSolved); - //이전에 오답이었고 현재 정답인 경우 - if (!exCorrect && isCorrect) { - return new SolvedQuizInfo(wordQuiz.getQuizCategory(), getPoint(wordQuiz.getLevel()), true); - } else { //이전에 정답인 경우 or 둘 다 오답인 경우 - return new SolvedQuizInfo(wordQuiz.getQuizCategory(), 0L, true); - } + return !newQuizSolved.getIsCorrect() ? new SolvedQuizInfo(wordQuiz.getQuizCategory(), 0L) + : new SolvedQuizInfo(wordQuiz.getQuizCategory(), getPoint(wordQuiz.getLevel())); } private static Long getPoint(Level level) { diff --git a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/dto/SolvedQuizInfo.java b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/dto/SolvedQuizInfo.java index a588a7e1..2e363eae 100644 --- a/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/dto/SolvedQuizInfo.java +++ b/src/main/java/soongsil/kidbean/server/quizsolve/application/quizsolver/dto/SolvedQuizInfo.java @@ -4,7 +4,6 @@ public record SolvedQuizInfo( QuizCategory category, - Long score, - boolean isExist + Long score ) { } diff --git a/src/main/java/soongsil/kidbean/server/quizsolve/dto/request/QuizSolvedRequest.java b/src/main/java/soongsil/kidbean/server/quizsolve/dto/request/QuizSolvedRequest.java index 8e180b7c..3f2b0976 100644 --- a/src/main/java/soongsil/kidbean/server/quizsolve/dto/request/QuizSolvedRequest.java +++ b/src/main/java/soongsil/kidbean/server/quizsolve/dto/request/QuizSolvedRequest.java @@ -19,6 +19,7 @@ public QuizSolved toQuizSolved(ImageQuiz imageQuiz, Member member) { .imageQuiz(imageQuiz) .reply(answer) .member(member) + .isCorrect(answer.equals(imageQuiz.getAnswer())) .build(); } @@ -27,6 +28,7 @@ public QuizSolved toQuizSolved(WordQuiz wordQuiz, Member member) { .wordQuiz(wordQuiz) .reply(answer) .member(member) + .isCorrect(answer.equals(wordQuiz.getAnswer())) .build(); } } diff --git a/src/main/java/soongsil/kidbean/server/summary/domain/QuizScore.java b/src/main/java/soongsil/kidbean/server/summary/domain/QuizScore.java index f7acbe46..b1f83ca0 100644 --- a/src/main/java/soongsil/kidbean/server/summary/domain/QuizScore.java +++ b/src/main/java/soongsil/kidbean/server/summary/domain/QuizScore.java @@ -51,12 +51,7 @@ public QuizScore(Member member, QuizCategory quizCategory, Long totalScore, Long } public static QuizScore makeInitQuizScore(Member member, QuizCategory quizCategory) { - return new QuizScore( - member, - quizCategory, - 0L, - 0L - ); + return new QuizScore(member, quizCategory, 0L, 0L); } public void updateScore(Level beforeLevel, Level afterLevel) { @@ -68,10 +63,8 @@ public QuizScore addScore(Long score) { return this; } - public QuizScore addCount(boolean isExist) { - if (!isExist) { - quizCount++; - } + public QuizScore addCount() { + quizCount++; return this; } } diff --git a/src/test/java/soongsil/kidbean/server/quizsolve/application/QuizSolvedServiceTest.java b/src/test/java/soongsil/kidbean/server/quizsolve/application/QuizSolvedServiceTest.java index 60b2fdb5..b6b97264 100644 --- a/src/test/java/soongsil/kidbean/server/quizsolve/application/QuizSolvedServiceTest.java +++ b/src/test/java/soongsil/kidbean/server/quizsolve/application/QuizSolvedServiceTest.java @@ -55,7 +55,7 @@ void solveQuizzes() { QuizSolvedRequest request = new QuizSolvedRequest(WORD_QUIZ.getQuizId(), WORD_QUIZ.getAnswer()); SolvedQuizInfo solvedQuizInfo = - new SolvedQuizInfo(WORD_QUIZ.getQuizCategory(), Level.getPoint(WORD_QUIZ.getLevel()), false); + new SolvedQuizInfo(WORD_QUIZ.getQuizCategory(), Level.getPoint(WORD_QUIZ.getLevel())); given(quizSolverFactory.getSolver(QuizType.WORD_QUIZ)).willReturn(wordQuizSolver); given(wordQuizSolver.solveQuiz(request, MEMBER1)).willReturn(solvedQuizInfo); @@ -76,8 +76,7 @@ void solveQuizzes2() { QuizSolvedRequest request = new QuizSolvedRequest(IMAGE_QUIZ_ANIMAL1.getQuizId(), IMAGE_QUIZ_ANIMAL1.getAnswer()); SolvedQuizInfo solvedQuizInfo = - new SolvedQuizInfo(IMAGE_QUIZ_ANIMAL1.getQuizCategory(), Level.getPoint(IMAGE_QUIZ_ANIMAL1.getLevel()), - false); + new SolvedQuizInfo(IMAGE_QUIZ_ANIMAL1.getQuizCategory(), Level.getPoint(IMAGE_QUIZ_ANIMAL1.getLevel())); given(quizSolverFactory.getSolver(QuizType.IMAGE_QUIZ)).willReturn(imageQuizSolver); given(imageQuizSolver.solveQuiz(request, MEMBER1)).willReturn(solvedQuizInfo); diff --git a/src/test/java/soongsil/kidbean/server/quizsolve/application/quizsolver/ImageQuizSolverTest.java b/src/test/java/soongsil/kidbean/server/quizsolve/application/quizsolver/ImageQuizSolverTest.java index 2ab96b37..e03b74ad 100644 --- a/src/test/java/soongsil/kidbean/server/quizsolve/application/quizsolver/ImageQuizSolverTest.java +++ b/src/test/java/soongsil/kidbean/server/quizsolve/application/quizsolver/ImageQuizSolverTest.java @@ -30,57 +30,14 @@ class ImageQuizSolverTest { @Mock private ImageQuizRepository imageQuizRepository; - @Test - @DisplayName("이미 푼 맞은 ImageQuiz 풀었을 때") - public void solveImageQuiz1() { - //given - QuizSolvedRequest request = - new QuizSolvedRequest(IMAGE_QUIZ_ANIMAL1.getQuizId(), IMAGE_QUIZ_ANIMAL1.getAnswer()); - - given(imageQuizRepository.findById(IMAGE_QUIZ_ANIMAL1.getQuizId())) - .willReturn(Optional.of(IMAGE_QUIZ_ANIMAL1)); - //이전에 풀었던 문제 - given(quizSolvedRepository.existsByImageQuizAndMember(IMAGE_QUIZ_ANIMAL1, MEMBER1)).willReturn(true); - given(quizSolvedRepository.existsByImageQuizAndMemberAndIsCorrect(IMAGE_QUIZ_ANIMAL1, MEMBER1, true)) - .willReturn(true); - - //when - SolvedQuizInfo solvedQuizInfo = imageQuizSolver.solveQuiz(request, MEMBER1); - - //then - assertThat(solvedQuizInfo.score()).isEqualTo(0L); - assertThat(solvedQuizInfo.category()).isEqualTo(IMAGE_QUIZ_ANIMAL1.getQuizCategory()); - } - - @Test - @DisplayName("이미 푼 틀린 ImageQuiz 풀었을 때") - public void solveImageQuiz2() { - //given - QuizSolvedRequest request = - new QuizSolvedRequest(IMAGE_QUIZ_ANIMAL1.getQuizId(), IMAGE_QUIZ_ANIMAL1.getAnswer()); - - given(imageQuizRepository.findById(IMAGE_QUIZ_ANIMAL1.getQuizId())).willReturn(Optional.of(IMAGE_QUIZ_ANIMAL1)); - given(quizSolvedRepository.existsByImageQuizAndMember(IMAGE_QUIZ_ANIMAL1, MEMBER1)).willReturn(true); - given(quizSolvedRepository.existsByImageQuizAndMemberAndIsCorrect(IMAGE_QUIZ_ANIMAL1, MEMBER1, true)) - .willReturn(false); - - //when - SolvedQuizInfo solvedQuizInfo = imageQuizSolver.solveQuiz(request, MEMBER1); - - //then - assertThat(solvedQuizInfo.score()).isEqualTo(Level.getPoint(IMAGE_QUIZ_ANIMAL1.getLevel())); - assertThat(solvedQuizInfo.category()).isEqualTo(IMAGE_QUIZ_ANIMAL1.getQuizCategory()); - } - @Test @DisplayName("풀지 않은 ImageQuiz 풀었을 때") - public void solveImageQuiz3() { + public void solveImageQuiz() { //given QuizSolvedRequest request = new QuizSolvedRequest(IMAGE_QUIZ_ANIMAL1.getQuizId(), IMAGE_QUIZ_ANIMAL1.getAnswer()); given(imageQuizRepository.findById(IMAGE_QUIZ_ANIMAL1.getQuizId())).willReturn(Optional.of(IMAGE_QUIZ_ANIMAL1)); - given(quizSolvedRepository.existsByImageQuizAndMember(IMAGE_QUIZ_ANIMAL1, MEMBER1)).willReturn(false); //when SolvedQuizInfo solvedQuizInfo = imageQuizSolver.solveQuiz(request, MEMBER1); diff --git a/src/test/java/soongsil/kidbean/server/quizsolve/application/quizsolver/WordQuizSolverTest.java b/src/test/java/soongsil/kidbean/server/quizsolve/application/quizsolver/WordQuizSolverTest.java index d3e233ad..14a1e477 100644 --- a/src/test/java/soongsil/kidbean/server/quizsolve/application/quizsolver/WordQuizSolverTest.java +++ b/src/test/java/soongsil/kidbean/server/quizsolve/application/quizsolver/WordQuizSolverTest.java @@ -31,47 +31,6 @@ class WordQuizSolverTest { @Mock private WordQuizRepository wordQuizRepository; - @Test - @DisplayName("이미 푼 맞은 WordQuiz 풀었을 때") - public void solveWordQuiz1() { - //given - QuizSolvedRequest request = - new QuizSolvedRequest(WORD_QUIZ.getQuizId(), WORD_QUIZ.getAnswer()); - - given(wordQuizRepository.findById(WORD_QUIZ.getQuizId())).willReturn(Optional.of(WORD_QUIZ)); - //이전에 풀었던 문제 - given(quizSolvedRepository.existsByWordQuizAndMember(WORD_QUIZ, MEMBER1)).willReturn(true); - given(quizSolvedRepository.existsByWordQuizAndMemberAndIsCorrect(WORD_QUIZ, MEMBER1, true)) - .willReturn(true); - - //when - SolvedQuizInfo solvedQuizInfo = wordQuizSolver.solveQuiz(request, MEMBER1); - - //then - assertThat(solvedQuizInfo.score()).isEqualTo(0L); - assertThat(solvedQuizInfo.category()).isEqualTo(WORD_QUIZ.getQuizCategory()); - } - - @Test - @DisplayName("이미 푼 틀린 WordQuiz 풀었을 때") - public void solveWordQuiz2() { - //given - QuizSolvedRequest request = - new QuizSolvedRequest(WORD_QUIZ.getQuizId(), WORD_QUIZ.getAnswer()); - - given(wordQuizRepository.findById(WORD_QUIZ.getQuizId())).willReturn(Optional.of(WORD_QUIZ)); - given(quizSolvedRepository.existsByWordQuizAndMember(WORD_QUIZ, MEMBER1)).willReturn(true); - given(quizSolvedRepository.existsByWordQuizAndMemberAndIsCorrect(WORD_QUIZ, MEMBER1, true)) - .willReturn(false); - - //when - SolvedQuizInfo solvedQuizInfo = wordQuizSolver.solveQuiz(request, MEMBER1); - - //then - assertThat(solvedQuizInfo.score()).isEqualTo(Level.getPoint(WORD_QUIZ.getLevel())); - assertThat(solvedQuizInfo.category()).isEqualTo(WORD_QUIZ.getQuizCategory()); - } - @Test @DisplayName("풀지 않은 WordQuiz 풀었을 때") public void solveWordQuiz() { @@ -80,7 +39,6 @@ public void solveWordQuiz() { new QuizSolvedRequest(WORD_QUIZ.getQuizId(), WORD_QUIZ.getAnswer()); given(wordQuizRepository.findById(WORD_QUIZ.getQuizId())).willReturn(Optional.of(WORD_QUIZ)); - given(quizSolvedRepository.existsByWordQuizAndMember(WORD_QUIZ, MEMBER1)).willReturn(false); //when SolvedQuizInfo solvedQuizInfo = wordQuizSolver.solveQuiz(request, MEMBER1); diff --git a/src/test/java/soongsil/kidbean/server/tuning/ImageQuizTuningTest.java b/src/test/java/soongsil/kidbean/server/tuning/ImageQuizTuningTest.java index 6fb2bf62..e519d5f6 100644 --- a/src/test/java/soongsil/kidbean/server/tuning/ImageQuizTuningTest.java +++ b/src/test/java/soongsil/kidbean/server/tuning/ImageQuizTuningTest.java @@ -27,9 +27,7 @@ import org.junit.jupiter.api.TestInstance; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; import org.springframework.util.StopWatch; -import soongsil.kidbean.server.global.application.config.AwsS3MockConfig; import soongsil.kidbean.server.global.domain.S3Info; import soongsil.kidbean.server.imagequiz.application.ImageQuizService; import soongsil.kidbean.server.imagequiz.domain.ImageQuiz; @@ -42,9 +40,8 @@ import soongsil.kidbean.server.member.repository.MemberRepository; @Slf4j -@Import(AwsS3MockConfig.class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) -@SpringBootTest +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class ImageQuizTuningTest { @Autowired diff --git a/src/test/java/soongsil/kidbean/server/tuning/WordQuizTuningTest.java b/src/test/java/soongsil/kidbean/server/tuning/WordQuizTuningTest.java new file mode 100644 index 00000000..a99b8919 --- /dev/null +++ b/src/test/java/soongsil/kidbean/server/tuning/WordQuizTuningTest.java @@ -0,0 +1,157 @@ +package soongsil.kidbean.server.tuning; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.util.StopWatch; +import org.springframework.web.context.WebApplicationContext; +import soongsil.kidbean.server.auth.application.jwt.JwtTokenProvider; +import soongsil.kidbean.server.auth.presentation.filter.JwtFilter; +import soongsil.kidbean.server.member.domain.Member; +import soongsil.kidbean.server.member.domain.type.Gender; +import soongsil.kidbean.server.member.domain.type.Role; +import soongsil.kidbean.server.member.repository.MemberRepository; +import soongsil.kidbean.server.quizsolve.domain.type.Level; +import soongsil.kidbean.server.quizsolve.domain.type.QuizCategory; +import soongsil.kidbean.server.quizsolve.dto.request.QuizSolvedListRequest; +import soongsil.kidbean.server.quizsolve.dto.request.QuizSolvedRequest; +import soongsil.kidbean.server.quizsolve.repository.QuizSolvedRepository; +import soongsil.kidbean.server.wordquiz.domain.Word; +import soongsil.kidbean.server.wordquiz.domain.WordQuiz; +import soongsil.kidbean.server.wordquiz.repository.WordQuizRepository; + +@Slf4j +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SpringBootTest +public class WordQuizTuningTest { + + @Autowired + private MemberRepository memberRepository; + + @Autowired + private QuizSolvedRepository quizSolvedRepository; + + @Autowired + private WordQuizRepository wordQuizRepository; + + @Autowired + private JwtTokenProvider jwtTokenProvider; + + @Autowired + private WebApplicationContext webApplicationContext; + + @Autowired + private JwtFilter jwtFilter; + + private MockMvc mockMvc; + private ObjectMapper objectMapper; + + @BeforeAll + void setUp() { + for (int i = 0; i < 10; i++) { + Member member = memberRepository.save( + Member.builder() + .email("email1") + .name("name1") + .socialId("socialId1") + .gender(Gender.MAN) + .role(Role.MEMBER) + .score(25L) + .build()); + + WordQuiz wordQuiz = WordQuiz.builder() + .title("title") + .answer("answer") + .words(List.of(new Word("word1", null), + new Word("word1", null), + new Word("word1", null))) + .quizCategory(QuizCategory.ANIMAL) + .level(Level.BRONZE) + .member(member) + .build(); + + wordQuizRepository.save(wordQuiz); + } + + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .apply(SecurityMockMvcConfigurers.springSecurity()) + .addFilter(jwtFilter) + .build(); + + objectMapper = new ObjectMapper(); + } + + @Test + @DisplayName("AnswerQuiz 풀기 테스트 - 동시성(데드락)") + void solveAnswerQuizConcurrent() throws Exception { + //given + int loopCnt = 1; + + ExecutorService executorService = Executors.newFixedThreadPool(loopCnt); + CountDownLatch latch = new CountDownLatch(loopCnt); + + StopWatch stopWatch = new StopWatch(); + + //when + stopWatch.start(); + + for (long i = 1; i <= loopCnt; i++) { + long finalI = i; + + executorService.execute(() -> { + try { + String accessToken = + jwtTokenProvider.createAccessToken(memberRepository.findById(1L).orElseThrow()); + + QuizSolvedListRequest quizSolvedListRequest = + new QuizSolvedListRequest(List.of(QuizSolvedRequest.builder() + .quizId(finalI) + .answer("answer") + .build())); + + mockMvc.perform(post("/quiz/word/solve") + .header("Authorization", "Bearer " + accessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(quizSolvedListRequest))) + .andExpect(MockMvcResultMatchers.status().isOk()); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + latch.countDown(); + } + }); + } + + latch.await(); // 모든 스레드가 작업을 완료할 때까지 기다림 + stopWatch.stop(); + + executorService.shutdown(); + + //then + log.info("===================결과 출력부==================="); + long dataCount = quizSolvedRepository.count(); + + Assertions.assertThat(dataCount).isEqualTo(loopCnt); + + log.info("데이터 수: {} 개", dataCount); + log.info("반복 횟수: {} 회", loopCnt); + log.info("총 소요 시간: {} ms", stopWatch.getTotalTimeMillis()); + } +} diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 97061488..fd37a34f 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -14,7 +14,7 @@ spring: properties: hibernate: format_sql: true - show_sql: true + show_sql: false cloud: aws: