From 5e9989fcf47f5487f2ea5b7e27718054a81f408d Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Sat, 13 Jan 2024 08:19:18 +0900 Subject: [PATCH] =?UTF-8?q?test:=20Jwt=20=EC=9E=AC=EB=B0=9C=EA=B8=89=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=8B=A8=EC=9C=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A7=84=ED=96=89=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/teumteum/meeting/domain/Meeting.java | 32 +++-- .../java/net/teumteum/user/domain/User.java | 27 ++++- .../unit/auth/service/AuthServiceTest.java | 111 ++++++++++++++++++ 3 files changed, 155 insertions(+), 15 deletions(-) create mode 100644 src/test/java/net/teumteum/unit/auth/service/AuthServiceTest.java diff --git a/src/main/java/net/teumteum/meeting/domain/Meeting.java b/src/main/java/net/teumteum/meeting/domain/Meeting.java index 7c1a2c02..bb08d50d 100644 --- a/src/main/java/net/teumteum/meeting/domain/Meeting.java +++ b/src/main/java/net/teumteum/meeting/domain/Meeting.java @@ -1,16 +1,25 @@ package net.teumteum.meeting.domain; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.PrePersist; +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.Set; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import net.teumteum.core.entity.TimeBaseEntity; import org.springframework.util.Assert; -import java.time.LocalDateTime; -import java.util.HashSet; -import java.util.Set; - @Entity @Getter @NoArgsConstructor @@ -75,18 +84,23 @@ private void assertField() { } private void assertIntroduction() { - Assert.isTrue(introduction.length() >= 10 && introduction.length() <= 200, "모임 소개는 10자 ~ 200자 사이가 되어야 합니다. [현재 입력된 모임 소개] : " + introduction); + Assert.isTrue(introduction.length() >= 10 && introduction.length() <= 200, + "모임 소개는 10자 ~ 200자 사이가 되어야 합니다. [현재 입력된 모임 소개] : " + introduction); } private void assertNumberOfRecruits() { - Assert.isTrue(numberOfRecruits >= 2 && numberOfRecruits <= 6, "참여자 수는 2명 ~ 6명 사이가 되어야 합니다. [현재 입력된 참여자 수] : " + numberOfRecruits); + Assert.isTrue(numberOfRecruits >= 2 && numberOfRecruits <= 6, + "참여자 수는 2명 ~ 6명 사이가 되어야 합니다. [현재 입력된 참여자 수] : " + numberOfRecruits); } private void assertTitle() { - Assert.isTrue(title.length() >= 2 && title.length() <= 32, "모임 제목은 2자 ~ 32자 사이가 되어야 합니다. [현재 입력된 모임 제목] : " + title); + Assert.isTrue(title.length() >= 2 && title.length() <= 32, + "모임 제목은 2자 ~ 32자 사이가 되어야 합니다. [현재 입력된 모임 제목] : " + title); } private void assertParticipantUserIds() { - Assert.isTrue(participantUserIds.size() + 1 <= numberOfRecruits, "최대 참여자 수에 도달한 모임에 참여할 수 없습니다." + "[최대 참여자 수] : " + numberOfRecruits + "[현재 참여자 수] : " + participantUserIds.size()); + Assert.isTrue(participantUserIds.size() + 1 <= numberOfRecruits, + "최대 참여자 수에 도달한 모임에 참여할 수 없습니다." + "[최대 참여자 수] : " + numberOfRecruits + "[현재 참여자 수] : " + + participantUserIds.size()); } } diff --git a/src/main/java/net/teumteum/user/domain/User.java b/src/main/java/net/teumteum/user/domain/User.java index ed220211..a022e769 100644 --- a/src/main/java/net/teumteum/user/domain/User.java +++ b/src/main/java/net/teumteum/user/domain/User.java @@ -1,18 +1,28 @@ package net.teumteum.user.domain; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.PrePersist; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import net.teumteum.core.entity.TimeBaseEntity; +import net.teumteum.core.security.Authenticated; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.util.Assert; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - @Getter @Entity(name = "users") @NoArgsConstructor @@ -69,6 +79,11 @@ public class User extends TimeBaseEntity { @ElementCollection(fetch = FetchType.LAZY) private Set friends = new HashSet<>(); + public User(Long id, String oauthId, Authenticated authenticated) { + this.id = id; + this.oauth = new OAuth(oauthId, authenticated); + } + @PrePersist private void assertField() { assertName(); diff --git a/src/test/java/net/teumteum/unit/auth/service/AuthServiceTest.java b/src/test/java/net/teumteum/unit/auth/service/AuthServiceTest.java new file mode 100644 index 00000000..4312b9f3 --- /dev/null +++ b/src/test/java/net/teumteum/unit/auth/service/AuthServiceTest.java @@ -0,0 +1,111 @@ +package net.teumteum.unit.auth.service; + +import static net.teumteum.core.security.Authenticated.네이버; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Optional; +import net.teumteum.auth.domain.response.TokenResponse; +import net.teumteum.auth.service.AuthService; +import net.teumteum.core.security.service.JwtService; +import net.teumteum.core.security.service.RedisService; +import net.teumteum.user.domain.User; +import net.teumteum.user.domain.UserConnector; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +@DisplayName("인증 서비스 단위 테스트의") +public class AuthServiceTest { + + @InjectMocks + AuthService authService; + + @Mock + JwtService jwtService; + + @Mock + RedisService redisService; + + @Mock + UserConnector userConnector; + + @Nested + @DisplayName("토큰 재발급 API는") + class Reissue_jwt_api_unit { + + @Test + @DisplayName("유효하지 않은 access token 과 유효한 refresh token 이 주어지면, 새로운 토큰을 발급한다.") + void Return_new_jwt_if_access_and_refresh_is_exist() { + // given + Optional user = Optional.of(new User(1L, "oauthId", 네이버)); + + HttpServletRequest httpServletRequest = mock(HttpServletRequest.class); + + given(jwtService.extractAccessToken(any(HttpServletRequest.class))).willReturn("access token"); + + given(jwtService.extractRefreshToken(any(HttpServletRequest.class))).willReturn("refresh token"); + + given(jwtService.getUserIdFromToken(anyString())).willReturn("1"); + + given(jwtService.createAccessToken(anyString())).willReturn("new access token"); + + given(jwtService.createRefreshToken()).willReturn("new refresh token"); + + given(redisService.getData(anyString())).willReturn("refresh token"); + + given(userConnector.findUserById(anyLong())).willReturn(user); + + given(jwtService.validateToken(anyString())).willReturn(true); + + // when + TokenResponse response = authService.reissue(httpServletRequest); + + // then + assertThat(response).isNotNull(); + assertThat(response.getAccessToken()).isEqualTo("new access token"); + assertThat(response.getRefreshToken()).isEqualTo("new refresh token"); + verify(userConnector, times(1)).findUserById(anyLong()); + verify(jwtService, times(1)).validateToken(any()); + } + + @Test + @DisplayName("유효하지 않은 access token 과 유효하지 않은 refresh token 이 주어지면, 500 server 에러로 응답한다. ") + void Return_500_bad_request_if_refresh_token_is_not_valid() { + Optional user = Optional.of(new User(1L, "oauthId", 네이버)); + + HttpServletRequest httpServletRequest = mock(HttpServletRequest.class); + + given(jwtService.extractAccessToken(any(HttpServletRequest.class))).willReturn("access token"); + + given(jwtService.extractRefreshToken(any(HttpServletRequest.class))).willReturn("refresh token"); + + given(jwtService.validateToken(anyString())).willReturn(true); + + given(jwtService.getUserIdFromToken(anyString())).willReturn("1"); + + given(userConnector.findUserById(anyLong())).willReturn(user); + + given(redisService.getData(anyString())).willThrow( + new IllegalArgumentException("refresh token 이 일치하지 않습니다.")); + + // when + assertThatThrownBy(() -> authService.reissue(httpServletRequest)).isInstanceOf( + IllegalArgumentException.class).hasMessage("refresh token 이 일치하지 않습니다."); + + } + } +}