Skip to content

Commit

Permalink
Merge pull request #88 from KUSITMS-MOAMOA/test/#82
Browse files Browse the repository at this point in the history
  • Loading branch information
oosedus authored Nov 15, 2024
2 parents d825fd2 + ad20f89 commit baf89bb
Show file tree
Hide file tree
Showing 9 changed files with 401 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/main/java/corecord/dev/common/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import corecord.dev.common.util.*;
import corecord.dev.domain.auth.handler.OAuthLoginFailureHandler;
import corecord.dev.domain.auth.handler.OAuthLoginSuccessHandler;
import corecord.dev.domain.auth.util.JwtFilter;
import corecord.dev.domain.auth.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package corecord.dev.domain.auth.handler;

import corecord.dev.common.util.CookieUtil;
import corecord.dev.common.util.JwtUtil;
import corecord.dev.domain.auth.util.JwtUtil;
import corecord.dev.domain.auth.dto.KakaoUserInfo;
import corecord.dev.domain.auth.dto.OAuth2UserInfo;
import corecord.dev.domain.auth.entity.RefreshToken;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import corecord.dev.common.exception.GeneralException;
import corecord.dev.common.status.ErrorStatus;
import corecord.dev.common.util.CookieUtil;
import corecord.dev.common.util.JwtUtil;
import corecord.dev.domain.auth.util.JwtUtil;
import corecord.dev.domain.auth.entity.RefreshToken;
import corecord.dev.domain.auth.entity.TmpToken;
import corecord.dev.domain.auth.exception.enums.TokenErrorStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package corecord.dev.common.util;
package corecord.dev.domain.auth.util;

import corecord.dev.common.util.CookieUtil;
import corecord.dev.domain.auth.exception.model.TokenException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package corecord.dev.common.util;
package corecord.dev.domain.auth.util;

import corecord.dev.domain.auth.exception.enums.TokenErrorStatus;
import corecord.dev.domain.auth.exception.model.TokenException;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -94,7 +95,7 @@ private boolean isTokenValid(String token, String claimKey, TokenErrorStatus err
} catch (ExpiredJwtException e) {
log.warn("토큰이 만료되었습니다: {}", e.getMessage());
throw new TokenException(errorStatus);
} catch (JwtException | IllegalArgumentException e) {
} catch (JwtException | MalformedJwtException e) {
log.warn("유효하지 않은 토큰입니다: {}", e.getMessage());
throw new TokenException(errorStatus);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import corecord.dev.common.exception.GeneralException;
import corecord.dev.common.status.ErrorStatus;
import corecord.dev.common.util.CookieUtil;
import corecord.dev.common.util.JwtUtil;
import corecord.dev.domain.auth.util.JwtUtil;
import corecord.dev.domain.ability.repository.AbilityRepository;
import corecord.dev.domain.analysis.repository.AnalysisRepository;
import corecord.dev.domain.folder.repository.FolderRepository;
Expand Down
148 changes: 148 additions & 0 deletions src/test/java/corecord/dev/auth/util/JwtUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package corecord.dev.auth.util;

import corecord.dev.domain.auth.util.JwtUtil;
import corecord.dev.domain.auth.exception.enums.TokenErrorStatus;
import corecord.dev.domain.auth.exception.model.TokenException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;

import javax.crypto.SecretKey;

import java.util.Date;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class JwtUtilTest {

private JwtUtil jwtUtil;
private final String SECRET_KEY = "testsecretkeytestsecretkeytestsecretkeytestsecretkeytestsecretkeytestsecretkeytestsecretkeytestsecretkey";
private final long REGISTER_TOKEN_EXPIRE_TIME = 1000 * 60 * 60; // 1 hour
private final long ACCESS_TOKEN_EXPIRE_TIME = 1000 * 60 * 60 * 24; // 24 hours
private final long REFRESH_TOKEN_EXPIRE_TIME = 1000 * 60 * 60 * 24 * 7; // 7 days
private SecretKey key;
private Long userId;
private String providerId;

@BeforeEach
void setUp() {
userId = 1L;
providerId = "testProvider";
jwtUtil = new JwtUtil();
ReflectionTestUtils.setField(jwtUtil, "SECRET_KEY", SECRET_KEY);
ReflectionTestUtils.setField(jwtUtil, "REGISTER_TOKEN_EXPIRATION_TIME", REGISTER_TOKEN_EXPIRE_TIME);
ReflectionTestUtils.setField(jwtUtil, "ACCESS_TOKEN_EXPIRATION_TIME", ACCESS_TOKEN_EXPIRE_TIME);
ReflectionTestUtils.setField(jwtUtil, "REFRESH_TOKEN_EXPIRATION_TIME", REFRESH_TOKEN_EXPIRE_TIME);
key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(SECRET_KEY));
}

@Test
@DisplayName("액세스 토큰 생성 및 유효성 검사")
void generateAndValidateAccessToken() {
// when
String accessToken = jwtUtil.generateAccessToken(userId);

// then
assertThat(accessToken).isNotNull().isNotEmpty();
assertThat(accessToken.split("\\.")).hasSize(3);

Claims payload = Jwts.parser()
.setSigningKey(key)
.build()
.parseClaimsJws(accessToken)
.getBody();

assertThat(payload.get("userId", String.class)).isEqualTo(userId.toString());
}

@Test
@DisplayName("리프레쉬 토큰 생성 및 유효성 검사")
void generateAndValidateRefreshToken() {
// when
String refreshToken = jwtUtil.generateRefreshToken(userId);

// then
assertThat(refreshToken).isNotNull().isNotEmpty();
assertThat(refreshToken.split("\\.")).hasSize(3);

Claims payload = Jwts.parser()
.setSigningKey(key)
.build()
.parseClaimsJws(refreshToken)
.getBody();

assertThat(payload.get("userId", String.class)).isEqualTo(userId.toString());
}

@Test
@DisplayName("레지스터 토큰 생성 및 유효성 검사")
void generateAndValidateRegisterToken() {
// when
String registerToken = jwtUtil.generateRegisterToken(providerId);

// then
assertThat(registerToken).isNotNull().isNotEmpty();
assertThat(registerToken.split("\\.")).hasSize(3);

Claims payload = Jwts.parser()
.setSigningKey(key)
.build()
.parseClaimsJws(registerToken)
.getBody();

assertThat(payload.get("providerId", String.class)).isEqualTo(providerId);
}

@Test
@DisplayName("임시 토큰 생성 및 유효성 검사")
void generateAndValidateTmpToken() {
// when
String tmpToken = jwtUtil.generateTmpToken(userId);

// then
assertThat(tmpToken).isNotNull().isNotEmpty();
assertThat(tmpToken.split("\\.")).hasSize(3);

Claims payload = Jwts.parser()
.setSigningKey(key)
.build()
.parseClaimsJws(tmpToken)
.getBody();

assertThat(payload.get("userId", String.class)).isEqualTo(userId.toString());
}

@Test
@DisplayName("만료된 액세스 토큰 예외 발생")
void expiredAccessTokenThrowsException() {
// given
String expiredAccessToken = Jwts.builder()
.setSubject(userId.toString())
.setExpiration(new Date(System.currentTimeMillis() - 1000)) // 이미 만료된 시간 설정
.signWith(SignatureAlgorithm.HS256, key)
.compact();

// then
TokenException exception = assertThrows(TokenException.class, () -> jwtUtil.isAccessTokenValid(expiredAccessToken));
assertThat(exception.getTokenErrorStatus()).isEqualTo(TokenErrorStatus.INVALID_ACCESS_TOKEN);
}


@Test
@DisplayName("유효하지 않은 토큰 예외 발생")
void invalidTokenThrowsException() {
// given
String invalidToken = "invalid.token";

// then
TokenException exception = assertThrows(TokenException.class, () -> jwtUtil.isAccessTokenValid(invalidToken));
assertThat(exception.getTokenErrorStatus()).isEqualTo(TokenErrorStatus.INVALID_ACCESS_TOKEN);
}
}
59 changes: 59 additions & 0 deletions src/test/java/corecord/dev/user/repository/UserRepositoryTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package corecord.dev.user.repository;

import corecord.dev.domain.user.entity.Status;
import corecord.dev.domain.user.entity.User;
import corecord.dev.domain.user.repository.UserRepository;
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Optional;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@DataJpaTest
@Transactional
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class UserRepositoryTest {
@Autowired
UserRepository userRepository;

@Autowired
EntityManager entityManager;

@Test
@DisplayName("UserId로 회원 삭제")
void deleteUserByUserId() {
// Given
User user = createTestUser();
userRepository.save(user);

// When
userRepository.deleteUserByUserId(user.getUserId());
entityManager.flush();
entityManager.clear();

// Then
Optional<User> deletedUser = userRepository.findById(user.getUserId());
assertThat(deletedUser).isEmpty();
}


private User createTestUser() {
return User.builder()
.userId(1L)
.providerId("providerId")
.nickName("testUser")
.status(Status.UNIVERSITY_STUDENT)
.abilities(new ArrayList<>())
.chatRooms(new ArrayList<>())
.folders(new ArrayList<>())
.records(new ArrayList<>())
.build();
}
}
Loading

0 comments on commit baf89bb

Please sign in to comment.