Skip to content

Commit 1a92697

Browse files
committed
Test: 테스트 작성 및 관련 코드 개선
1 parent 668bdf7 commit 1a92697

File tree

3 files changed

+141
-2
lines changed

3 files changed

+141
-2
lines changed

src/main/java/com/back/domain/user/service/UserService.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,13 @@ public void logout(HttpServletRequest request, HttpServletResponse response) {
144144
// 쿠키에서 Refresh Token 추출
145145
String refreshToken = resolveRefreshToken(request);
146146

147-
// 토큰 검증
148-
if (refreshToken == null || !jwtTokenProvider.validateToken(refreshToken)) {
147+
// Refresh Token 존재 여부 확인
148+
if (refreshToken == null) {
149+
throw new CustomException(ErrorCode.BAD_REQUEST);
150+
}
151+
152+
// Refresh Token 검증
153+
if (!jwtTokenProvider.validateToken(refreshToken)) {
149154
throw new CustomException(ErrorCode.INVALID_TOKEN);
150155
}
151156

src/test/java/com/back/domain/user/controller/AuthControllerTest.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.back.domain.user.entity.UserProfile;
55
import com.back.domain.user.entity.UserStatus;
66
import com.back.domain.user.repository.UserRepository;
7+
import jakarta.servlet.http.Cookie;
78
import org.junit.jupiter.api.DisplayName;
89
import org.junit.jupiter.api.Test;
910
import org.springframework.beans.factory.annotation.Autowired;
@@ -367,4 +368,77 @@ void login_deletedUser() throws Exception {
367368
.andExpect(status().isGone())
368369
.andExpect(jsonPath("$.code").value("USER_009"));
369370
}
371+
372+
@Test
373+
@DisplayName("정상 로그아웃 → 200 OK + RefreshToken 쿠키 만료")
374+
void logout_success() throws Exception {
375+
// given: 회원가입 + 로그인으로 refreshToken 쿠키 확보
376+
String rawPassword = "P@ssw0rd!";
377+
String registerBody = """
378+
{
379+
"username": "logoutuser",
380+
"email": "[email protected]",
381+
"password": "%s",
382+
"nickname": "홍길동"
383+
}
384+
""".formatted(rawPassword);
385+
386+
mvc.perform(post("/api/auth/register")
387+
.contentType(MediaType.APPLICATION_JSON)
388+
.content(registerBody))
389+
.andExpect(status().isCreated());
390+
391+
String loginBody = """
392+
{
393+
"username": "logoutuser",
394+
"password": "%s"
395+
}
396+
""".formatted(rawPassword);
397+
398+
ResultActions loginResult = mvc.perform(post("/api/auth/login")
399+
.contentType(MediaType.APPLICATION_JSON)
400+
.content(loginBody))
401+
.andExpect(status().isOk());
402+
403+
// 로그인 응답에서 refreshToken 쿠키 추출
404+
String refreshCookie = loginResult.andReturn()
405+
.getResponse()
406+
.getCookie("refreshToken")
407+
.getValue();
408+
409+
// when: 로그아웃 요청 (쿠키 포함)
410+
ResultActions logoutResult = mvc.perform(post("/api/auth/logout")
411+
.cookie(new Cookie("refreshToken", refreshCookie)))
412+
.andDo(print());
413+
414+
// then: 200 OK + 성공 메시지 + 쿠키 만료
415+
logoutResult
416+
.andExpect(status().isOk())
417+
.andExpect(jsonPath("$.success").value(true))
418+
.andExpect(jsonPath("$.message").value("로그아웃 되었습니다."))
419+
.andExpect(cookie().maxAge("refreshToken", 0));
420+
}
421+
422+
@Test
423+
@DisplayName("RefreshToken 누락 → 400 Bad Request")
424+
void logout_noToken() throws Exception {
425+
// when & then
426+
mvc.perform(post("/api/auth/logout"))
427+
.andDo(print())
428+
.andExpect(status().isBadRequest())
429+
.andExpect(jsonPath("$.code").value("COMMON_400"));
430+
}
431+
432+
@Test
433+
@DisplayName("유효하지 않은 RefreshToken → 401 Unauthorized")
434+
void logout_invalidToken() throws Exception {
435+
// given: 잘못된 refreshToken 쿠키
436+
Cookie invalid = new Cookie("refreshToken", "fake-token");
437+
438+
// when & then
439+
mvc.perform(post("/api/auth/logout").cookie(invalid))
440+
.andDo(print())
441+
.andExpect(status().isUnauthorized())
442+
.andExpect(jsonPath("$.code").value("AUTH_401"));
443+
}
370444
}

src/test/java/com/back/domain/user/service/UserServiceTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
import com.back.domain.user.entity.UserStatus;
88
import com.back.domain.user.repository.UserProfileRepository;
99
import com.back.domain.user.repository.UserRepository;
10+
import com.back.domain.user.repository.UserTokenRepository;
1011
import com.back.global.exception.CustomException;
1112
import com.back.global.exception.ErrorCode;
1213
import jakarta.servlet.http.Cookie;
1314
import org.junit.jupiter.api.DisplayName;
1415
import org.junit.jupiter.api.Test;
1516
import org.springframework.beans.factory.annotation.Autowired;
1617
import org.springframework.boot.test.context.SpringBootTest;
18+
import org.springframework.mock.web.MockHttpServletRequest;
1719
import org.springframework.mock.web.MockHttpServletResponse;
1820
import org.springframework.security.crypto.password.PasswordEncoder;
1921
import org.springframework.test.context.ActiveProfiles;
@@ -36,6 +38,9 @@ class UserServiceTest {
3638
@Autowired
3739
private UserProfileRepository userProfileRepository;
3840

41+
@Autowired
42+
private UserTokenRepository userTokenRepository;
43+
3944
@Autowired
4045
private PasswordEncoder passwordEncoder;
4146

@@ -263,4 +268,59 @@ void login_deletedUser() {
263268
.isInstanceOf(CustomException.class)
264269
.hasMessage(ErrorCode.USER_DELETED.getMessage());
265270
}
271+
@Test
272+
@DisplayName("정상 로그아웃 성공 → RefreshToken DB 삭제 + 쿠키 만료")
273+
void logout_success() {
274+
// given: 정상 로그인된 사용자
275+
String rawPassword = "P@ssw0rd!";
276+
User user = setupUser("logoutuser", "[email protected]", rawPassword, "닉네임", UserStatus.ACTIVE);
277+
MockHttpServletResponse loginResponse = new MockHttpServletResponse();
278+
279+
userService.login(new LoginRequest("logoutuser", rawPassword), loginResponse);
280+
Cookie refreshCookie = loginResponse.getCookie("refreshToken");
281+
assertThat(refreshCookie).isNotNull();
282+
283+
MockHttpServletResponse logoutResponse = new MockHttpServletResponse();
284+
MockHttpServletRequest request = new MockHttpServletRequest();
285+
request.setCookies(refreshCookie); // 쿠키를 요청에 실어줌
286+
287+
// when: 로그아웃 실행
288+
userService.logout(request, logoutResponse);
289+
290+
// then: DB에서 refreshToken 삭제됨
291+
assertThat(userTokenRepository.findByRefreshToken(refreshCookie.getValue())).isEmpty();
292+
293+
// 응답 쿠키는 만료 처리됨
294+
Cookie cleared = logoutResponse.getCookie("refreshToken");
295+
assertThat(cleared).isNotNull();
296+
assertThat(cleared.getMaxAge()).isZero();
297+
assertThat(cleared.getValue()).isNull();
298+
}
299+
300+
@Test
301+
@DisplayName("RefreshToken 없으면 INVALID_TOKEN 예외 발생")
302+
void logout_noToken() {
303+
// given: 쿠키 없이 로그아웃 요청
304+
MockHttpServletRequest request = new MockHttpServletRequest();
305+
MockHttpServletResponse response = new MockHttpServletResponse();
306+
307+
// when & then
308+
assertThatThrownBy(() -> userService.logout(request, response))
309+
.isInstanceOf(CustomException.class)
310+
.hasMessage(ErrorCode.BAD_REQUEST.getMessage());
311+
}
312+
313+
@Test
314+
@DisplayName("유효하지 않은 RefreshToken이면 INVALID_TOKEN 예외 발생")
315+
void logout_invalidToken() {
316+
// given: 잘못된 토큰 쿠키 세팅
317+
MockHttpServletRequest request = new MockHttpServletRequest();
318+
request.setCookies(new Cookie("refreshToken", "invalidToken"));
319+
MockHttpServletResponse response = new MockHttpServletResponse();
320+
321+
// when & then
322+
assertThatThrownBy(() -> userService.logout(request, response))
323+
.isInstanceOf(CustomException.class)
324+
.hasMessage(ErrorCode.INVALID_TOKEN.getMessage());
325+
}
266326
}

0 commit comments

Comments
 (0)