generated from pricelees/issue-pr-template
test: JwtHandlerTest 코틀린 전환
This commit is contained in:
parent
227e2999b4
commit
44005fbdd7
@ -1,118 +0,0 @@
|
|||||||
package roomescape.global.auth.jwt;
|
|
||||||
|
|
||||||
import static roomescape.system.exception.ErrorType.*;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.assertj.core.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.DisplayName;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
|
||||||
import org.springframework.test.context.jdbc.Sql;
|
|
||||||
|
|
||||||
import io.jsonwebtoken.Jwts;
|
|
||||||
import io.jsonwebtoken.SignatureAlgorithm;
|
|
||||||
import io.restassured.RestAssured;
|
|
||||||
import roomescape.system.auth.infrastructure.jwt.JwtHandler;
|
|
||||||
import roomescape.system.exception.ErrorType;
|
|
||||||
import roomescape.system.exception.RoomEscapeException;
|
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
||||||
@Sql(scripts = "/truncate.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
|
|
||||||
class JwtHandlerTest {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private JwtHandler jwtHandler;
|
|
||||||
|
|
||||||
@Value("${security.jwt.token.secret-key}")
|
|
||||||
private String secretKey;
|
|
||||||
|
|
||||||
@LocalServerPort
|
|
||||||
private int port;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() {
|
|
||||||
RestAssured.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("토큰이 만료되면 401 Unauthorized 를 발생시킨다.")
|
|
||||||
void jwtExpired() {
|
|
||||||
//given
|
|
||||||
Date date = new Date();
|
|
||||||
Date expiredAt = new Date(date.getTime() - 1);
|
|
||||||
|
|
||||||
String accessToken = Jwts.builder()
|
|
||||||
.claim("memberId", 1L)
|
|
||||||
.setIssuedAt(date)
|
|
||||||
.setExpiration(expiredAt)
|
|
||||||
.signWith(SignatureAlgorithm.HS256, secretKey.getBytes())
|
|
||||||
.compact();
|
|
||||||
|
|
||||||
// when & then
|
|
||||||
Assertions.assertThatThrownBy(() -> jwtHandler.getMemberIdFromToken(accessToken))
|
|
||||||
.isInstanceOf(RoomEscapeException.class)
|
|
||||||
.hasMessage(EXPIRED_TOKEN.getDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("지원하지 않는 토큰이면 401 Unauthorized 를 발생시킨다.")
|
|
||||||
void jwtMalformed() {
|
|
||||||
// given
|
|
||||||
Date date = new Date();
|
|
||||||
Date expiredAt = new Date(date.getTime() + 100000);
|
|
||||||
|
|
||||||
String accessToken = Jwts.builder()
|
|
||||||
.claim("memberId", 1L)
|
|
||||||
.setIssuedAt(date)
|
|
||||||
.setExpiration(expiredAt)
|
|
||||||
.signWith(SignatureAlgorithm.HS256, secretKey.getBytes())
|
|
||||||
.compact();
|
|
||||||
|
|
||||||
String[] splitAccessToken = accessToken.split("\\.");
|
|
||||||
String unsupportedAccessToken = splitAccessToken[0] + "." + splitAccessToken[1];
|
|
||||||
|
|
||||||
// when & then
|
|
||||||
Assertions.assertThatThrownBy(() -> jwtHandler.getMemberIdFromToken(unsupportedAccessToken))
|
|
||||||
.isInstanceOf(RoomEscapeException.class)
|
|
||||||
.hasMessage(ErrorType.MALFORMED_TOKEN.getDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("토큰의 Signature 가 잘못되었다면 401 Unauthorized 를 발생시킨다.")
|
|
||||||
void jwtInvalidSignature() {
|
|
||||||
// given
|
|
||||||
Date date = new Date();
|
|
||||||
Date expiredAt = new Date(date.getTime() + 100000);
|
|
||||||
|
|
||||||
String invalidSecretKey = secretKey.substring(1);
|
|
||||||
|
|
||||||
String accessToken = Jwts.builder()
|
|
||||||
.claim("memberId", 1L)
|
|
||||||
.setIssuedAt(date)
|
|
||||||
.setExpiration(expiredAt)
|
|
||||||
.signWith(SignatureAlgorithm.HS256, invalidSecretKey.getBytes()) // 기존은 HS256 알고리즘
|
|
||||||
.compact();
|
|
||||||
|
|
||||||
// when & then
|
|
||||||
Assertions.assertThatThrownBy(() -> jwtHandler.getMemberIdFromToken(accessToken))
|
|
||||||
.isInstanceOf(RoomEscapeException.class)
|
|
||||||
.hasMessage(ErrorType.INVALID_SIGNATURE_TOKEN.getDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("토큰이 공백값이라면 401 Unauthorized 를 발생시킨다.")
|
|
||||||
void jwtIllegal() {
|
|
||||||
// given
|
|
||||||
String accessToken = "";
|
|
||||||
|
|
||||||
// when & then
|
|
||||||
Assertions.assertThatThrownBy(() -> jwtHandler.getMemberIdFromToken(accessToken))
|
|
||||||
.isInstanceOf(RoomEscapeException.class)
|
|
||||||
.hasMessage(ErrorType.ILLEGAL_TOKEN.getDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package roomescape.system.auth.infrastructure.jwt
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Jwts
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm
|
||||||
|
import io.kotest.assertions.throwables.shouldThrow
|
||||||
|
import io.kotest.core.spec.style.FunSpec
|
||||||
|
import io.kotest.matchers.shouldBe
|
||||||
|
import roomescape.common.JwtFixture
|
||||||
|
import roomescape.system.exception.ErrorType
|
||||||
|
import roomescape.system.exception.RoomEscapeException
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
class JwtHandlerTest : FunSpec({
|
||||||
|
|
||||||
|
context("JWT 토큰 조회") {
|
||||||
|
val memberId = Random.nextLong()
|
||||||
|
val jwtHandler: JwtHandler = JwtFixture.create()
|
||||||
|
|
||||||
|
test("토큰에서 멤버 ID를 올바르게 추출한다.") {
|
||||||
|
val token = jwtHandler.createToken(memberId)
|
||||||
|
val extractedMemberId = jwtHandler.getMemberIdFromToken(token)
|
||||||
|
|
||||||
|
extractedMemberId shouldBe memberId
|
||||||
|
}
|
||||||
|
|
||||||
|
test("만료된 토큰이면 예외를 던진다.") {
|
||||||
|
// given
|
||||||
|
val expirationTime = 0L
|
||||||
|
val shortExpirationTimeJwtHandler: JwtHandler = JwtFixture.create(expirationTime = expirationTime)
|
||||||
|
val token = shortExpirationTimeJwtHandler.createToken(memberId)
|
||||||
|
|
||||||
|
Thread.sleep(expirationTime) // 만료 시간 이후로 대기
|
||||||
|
|
||||||
|
// when & then
|
||||||
|
shouldThrow<RoomEscapeException> {
|
||||||
|
shortExpirationTimeJwtHandler.getMemberIdFromToken(token)
|
||||||
|
}.errorType shouldBe ErrorType.EXPIRED_TOKEN
|
||||||
|
}
|
||||||
|
|
||||||
|
test("토큰이 빈 값이면 예외를 던진다.") {
|
||||||
|
shouldThrow<RoomEscapeException> {
|
||||||
|
jwtHandler.getMemberIdFromToken("")
|
||||||
|
}.errorType shouldBe ErrorType.INVALID_TOKEN
|
||||||
|
}
|
||||||
|
|
||||||
|
test("시크릿 키가 잘못된 경우 예외를 던진다.") {
|
||||||
|
val now: Date = Date()
|
||||||
|
val invalidSignatureToken: String = Jwts.builder()
|
||||||
|
.claim("memberId", memberId)
|
||||||
|
.setIssuedAt(now)
|
||||||
|
.setExpiration(Date(now.time + JwtFixture.EXPIRATION_TIME))
|
||||||
|
.signWith(SignatureAlgorithm.HS256, JwtFixture.SECRET_KEY.substring(1).toByteArray())
|
||||||
|
.compact()
|
||||||
|
|
||||||
|
shouldThrow<RoomEscapeException> {
|
||||||
|
jwtHandler.getMemberIdFromToken(invalidSignatureToken)
|
||||||
|
}.errorType shouldBe ErrorType.INVALID_SIGNATURE_TOKEN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user