Skip to content

Commit

Permalink
[feat]: 테스트를 위한 JwtProvider 에 메서드와 생성자 추가 + JwtProviderTest 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
ParkJuhan94 committed Jan 8, 2024
1 parent e3b54ae commit 149abd9
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 9 deletions.
40 changes: 31 additions & 9 deletions core/src/main/java/dev/hooon/auth/application/JwtProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.security.Key;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

Expand All @@ -22,6 +23,15 @@ public class JwtProvider {
private final Key key;
private static final String USER_ID = "userId";

/**
* 테스트를 위한 생성자
*/
public JwtProvider(Key key, int tokenValidSeconds) {
this.key = key;
this.tokenValidSeconds = tokenValidSeconds;
}

@Autowired
public JwtProvider(
@Value("${jwt.secret}") String secretKey,
@Value("${jwt.token-validity-in-seconds}") int tokenValidSeconds
Expand All @@ -32,6 +42,16 @@ public JwtProvider(
this.key = Keys.hmacShaKeyFor(keyBytes);
}

public Long getClaim(String token) {
Claims claimsBody = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();

return Long.valueOf((Integer)claimsBody.get(USER_ID));
}

public String createAccessToken(Long userId) {
Date now = new Date();

Expand Down Expand Up @@ -74,15 +94,17 @@ public void validateToken(String token) {
}
}

public Long getClaim(String token) {
Claims claimsBody = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
/**
* 테스트를 위한 메서드
*/
public String createTokenWithCustomExpiration(Long userId, long customExpirationMillis) {
Date now = new Date();

// return
return Long.valueOf((Integer)claimsBody.getOrDefault(USER_ID, 0L));
return Jwts.builder()
.claim(USER_ID, userId)
.setIssuedAt(now)
.setExpiration(new Date(now.getTime() + customExpirationMillis))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}

}
157 changes: 157 additions & 0 deletions core/src/test/java/dev/hooon/auth/application/JwtProviderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package dev.hooon.auth.application;

import static dev.hooon.auth.exception.AuthErrorCode.*;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;

import java.security.Key;
import java.util.Date;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;

import dev.hooon.auth.exception.AuthException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

@DisplayName("[JwtProvider 테스트]")
@ExtendWith(MockitoExtension.class)
class JwtProviderTest {

private JwtProvider jwtProvider;
private Key key;
private int tokenValidSeconds;

@BeforeEach
void setUp() {
String secretKey = "fdflsjhflkwejfblkjhvuixochvuhsofiuesafbidsfab223411";
key = Keys.hmacShaKeyFor(secretKey.getBytes());
tokenValidSeconds = 3600;
jwtProvider = new JwtProvider(key, tokenValidSeconds);
}

@Test
@DisplayName("Access Token을 성공적으로 만든다")
void createAccessTokenTest() {
// given
Long userId = 123L;

// when
String token = jwtProvider.createAccessToken(userId);

Jws<Claims> claimsJws = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token);
Claims claims = claimsJws.getBody();

// then
assertThat(token).isNotNull();
assertThat(userId).isEqualTo(claims.get("userId", Long.class));
assertThat(claims.getIssuedAt()).isNotNull();
assertThat(claims.getExpiration()).isNotNull();
assertThat(claims.getExpiration().getTime() - claims.getIssuedAt().getTime())
.isCloseTo(tokenValidSeconds, within(1000L)); // 토큰 생성 자체에 드는 시간 고려

}

@Test
@DisplayName("Refresh Token을 성공적으로 만든다")
void createRefreshTokenTest() {
// given
Long userId = 123L;

// when
String token = jwtProvider.createRefreshToken(userId);

Jws<Claims> claimsJws = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token);
Claims claims = claimsJws.getBody();

// then
assertThat(token).isNotNull();
assertThat(userId).isEqualTo(claims.get("userId", Long.class));
assertThat(claims.getIssuedAt()).isNotNull();
assertThat(claims.getExpiration()).isNotNull();
assertThat(claims.getExpiration().getTime() - claims.getIssuedAt().getTime())
.isCloseTo(tokenValidSeconds * 30L, within(1000L)); // 토큰 생성 자체에 드는 시간 고려

}

@Test
@DisplayName("Claim 에서 UserId를 뽑아온다")
void getClaimTest() {
// given
Long userId = 123L;
String token = jwtProvider.createAccessToken(userId);

// when
Long extractedUserId = jwtProvider.getClaim(token);

// then
assertThat(extractedUserId).isEqualTo(userId);
}

@Test
@DisplayName("유효성 검사에서 정상적인 토큰은 성공한다")
void validateValidTokenTest() {
// given
Long userId = 123L;
String validToken = jwtProvider.createAccessToken(userId);

// when, then
assertDoesNotThrow(() -> jwtProvider.validateToken(validToken));
}

@Test
@DisplayName("유효성 검사에서 구조가 안 맞는 토큰은 실패한다")
void validateInValidTokenTest() {
// given
String invalidToken = "invalidToken";

// when, then
assertThatThrownBy(
() -> jwtProvider.validateToken(invalidToken)
)
.isInstanceOf(AuthException.class)
.hasMessageContaining(MALFORMED_TOKEN.getMessage());
}

@Test
@DisplayName("유효성 검사에서 유효 기간이 지난 토큰은 실패한다")
void validateExpiredTokenTest() {
// given
Long userId = 123L;
String expiredToken = jwtProvider.createTokenWithCustomExpiration(userId, -1000000L);

// when, then
assertThatThrownBy(
() -> jwtProvider.validateToken(expiredToken)
)
.isInstanceOf(AuthException.class)
.hasMessageContaining(TOKEN_EXPIRED.getMessage());
}

@Test
@DisplayName("유효성 검사에서 잘못된 서명의 토큰은 실패한다")
void validateTokenWithAlteredSignatureTest() {
// given
Long userId = 123L;
String validToken = jwtProvider.createAccessToken(userId);
String alteredToken = validToken.substring(0, validToken.length() - 4) + "abcd";

// when, then
assertThatThrownBy(
() -> jwtProvider.validateToken(alteredToken)
)
.isInstanceOf(AuthException.class)
.hasMessageContaining(INVALID_TOKEN_ETC.getMessage());
}
}

0 comments on commit 149abd9

Please sign in to comment.