Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/#58 auth 도메인 테스트 코드 작성 #59

Merged
merged 16 commits into from
Oct 27, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
@RequestMapping("/api/v1/auth")
public class AuthController {

private final AuthService authService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package coffeemeet.server.oauth.client;

import coffeemeet.server.oauth.dto.OAuthInfoDto;
import coffeemeet.server.oauth.dto.OAuthUserInfoDto;
import coffeemeet.server.user.domain.OAuthProvider;

public interface OAuthMemberClient {

OAuthProvider oAuthProvider();

OAuthInfoDto.Response fetch(String authCode);
OAuthUserInfoDto.Response fetch(String authCode);

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package coffeemeet.server.oauth.client;

import coffeemeet.server.oauth.dto.OAuthInfoDto;
import coffeemeet.server.oauth.dto.OAuthUserInfoDto;
import coffeemeet.server.user.domain.OAuthProvider;
import java.util.Map;
import java.util.Optional;
Expand All @@ -21,7 +21,7 @@ public OAuthMemberClientComposite(Set<OAuthMemberClient> clients) {
);
}

public OAuthInfoDto.Response fetch(OAuthProvider oAuthProvider, String authCode) {
public OAuthUserInfoDto.Response fetch(OAuthProvider oAuthProvider, String authCode) {
return getClient(oAuthProvider).fetch(authCode);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import coffeemeet.server.user.domain.OAuthProvider;

public sealed interface OAuthInfoDto permits OAuthInfoDto.Response {
public sealed interface OAuthUserInfoDto permits OAuthUserInfoDto.Response {

record Response(
String name,
Expand All @@ -12,9 +12,9 @@ record Response(
String email,
OAuthProvider oAuthProvider,
String oAuthProviderId
) implements OAuthInfoDto {
) implements OAuthUserInfoDto {

public static OAuthInfoDto.Response of(
public static OAuthUserInfoDto.Response of(
String name,
String profileImage,
String birthYear,
Expand All @@ -23,7 +23,7 @@ public static OAuthInfoDto.Response of(
OAuthProvider oAuthProvider,
String oAuthProviderId
) {
return new OAuthInfoDto.Response(
return new OAuthUserInfoDto.Response(
name,
profileImage,
birthYear,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package coffeemeet.server.oauth.infrastructure.kakao.client;

import coffeemeet.server.oauth.client.OAuthMemberClient;
import coffeemeet.server.oauth.dto.OAuthInfoDto;
import coffeemeet.server.oauth.dto.OAuthUserInfoDto;
import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse;
import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens;
import coffeemeet.server.user.domain.OAuthProvider;
Expand All @@ -20,7 +20,7 @@ public OAuthProvider oAuthProvider() {
}

@Override
public OAuthInfoDto.Response fetch(String authCode) {
public OAuthUserInfoDto.Response fetch(String authCode) {
KakaoTokens tokenInfo = kakaoApiClient.fetchToken(authCode);
KakaoMemberResponse response = kakaoApiClient.fetchMember(tokenInfo.accessToken());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package coffeemeet.server.oauth.infrastructure.kakao.dto;

import coffeemeet.server.oauth.dto.OAuthInfoDto;
import coffeemeet.server.oauth.dto.OAuthUserInfoDto;
import coffeemeet.server.user.domain.OAuthProvider;
import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
Expand All @@ -11,8 +11,8 @@ public record KakaoMemberResponse(
KakaoAccount kakaoAccount
) {

public OAuthInfoDto.Response toOAuthInfoResponse() {
return OAuthInfoDto.Response.of(
public OAuthUserInfoDto.Response toOAuthInfoResponse() {
return OAuthUserInfoDto.Response.of(
kakaoAccount.name,
kakaoAccount.profile.profileImageUrl,
kakaoAccount.birthyear,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite;
import coffeemeet.server.oauth.client.OAuthMemberClientComposite;
import coffeemeet.server.oauth.dto.OAuthInfoDto;
import coffeemeet.server.oauth.dto.OAuthUserInfoDto;
import coffeemeet.server.user.domain.OAuthProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -18,7 +18,7 @@ public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) {
return authCodeRequestUrlProviderComposite.provide(oAuthProvider);
}

public OAuthInfoDto.Response getOAuthInfo(OAuthProvider oAuthProvider, String authCode) {
public OAuthUserInfoDto.Response getOAuthInfo(OAuthProvider oAuthProvider, String authCode) {
return oauthMemberClientComposite.fetch(oAuthProvider,
authCode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import coffeemeet.server.interest.domain.Keyword;
import coffeemeet.server.interest.repository.InterestRepository;
import coffeemeet.server.interest.service.InterestService;
import coffeemeet.server.oauth.dto.OAuthInfoDto;
import coffeemeet.server.oauth.dto.OAuthUserInfoDto;
import coffeemeet.server.oauth.service.OAuthService;
import coffeemeet.server.user.domain.Birth;
import coffeemeet.server.user.domain.Email;
Expand Down Expand Up @@ -94,7 +94,7 @@ public void updateProfileInfo(Long userId, String nickname, String name,

@Transactional
public AuthTokens signup(SignupRequest request) {
OAuthInfoDto.Response response = oAuthService.getOAuthInfo(request.oAuthProvider(),
OAuthUserInfoDto.Response response = oAuthService.getOAuthInfo(request.oAuthProvider(),
request.authCode());

checkDuplicatedUser(response);
Expand All @@ -113,7 +113,7 @@ public AuthTokens signup(SignupRequest request) {
}

public AuthTokens login(OAuthProvider oAuthProvider, String authCode) {
OAuthInfoDto.Response response = oAuthService.getOAuthInfo(oAuthProvider, authCode);
OAuthUserInfoDto.Response response = oAuthService.getOAuthInfo(oAuthProvider, authCode);
User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId(
response.oAuthProvider(), response.oAuthProviderId()).orElseThrow(
() -> new IllegalArgumentException(
Expand All @@ -134,7 +134,7 @@ public void checkDuplicatedNickname(String nickname) {
}
}

public void checkDuplicatedUser(OAuthInfoDto.Response response) {
public void checkDuplicatedUser(OAuthUserInfoDto.Response response) {
if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId(
response.oAuthProvider(), response.oAuthProviderId())) {
throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package coffeemeet.server.auth.controller;

import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document;
import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willDoNothing;
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import coffeemeet.server.auth.domain.AuthTokens;
import coffeemeet.server.auth.domain.RefreshToken;
import coffeemeet.server.auth.service.AuthService;
import coffeemeet.server.common.config.ControllerTestConfig;
import coffeemeet.server.common.fixture.dto.AuthTokensFixture;
import coffeemeet.server.common.fixture.dto.RefreshTokenFixture;
import com.epages.restdocs.apispec.Schema;
import java.util.Optional;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.restdocs.payload.JsonFieldType;

@WebMvcTest(AuthController.class)
class AuthControllerTest extends ControllerTestConfig {

@MockBean
private AuthService authService;

@DisplayName("refresh token 을 통해 access token 을 갱신할 수 있다.")
@Test
void renewTest() throws Exception {
// given
AuthTokens authTokens = AuthTokensFixture.authTokens();
RefreshToken refreshToken = RefreshTokenFixture.refreshToken();

given(authService.renew(anyLong(), any())).willReturn(authTokens);
given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken));

// when, then
mockMvc.perform(post("/api/v1/auth/renew-token")
.header("Authorization", TOKEN)
.contentType(MediaType.APPLICATION_JSON)
)
.andDo(document("auth-renew",
resourceDetails().tag("인증").description("토큰 갱신")
.responseSchema(Schema.schema("AuthTokens")),
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("Authorization").description("토큰")
),
responseFields(
fieldWithPath("accessToken").type(JsonFieldType.STRING).description("액세스 토큰"),
fieldWithPath("refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰")
)
)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.accessToken").value(authTokens.accessToken()))
.andExpect(jsonPath("$.refreshToken").value(authTokens.refreshToken()));
}

@DisplayName("사용자는 로그아웃 할 수 있다.")
@Test
void logoutTest() throws Exception {
// given
RefreshToken refreshToken = RefreshTokenFixture.refreshToken();
willDoNothing().given(authService).logout(anyLong());
given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken));

// when, then
mockMvc.perform(post("/api/v1/auth/logout")
.header("Authorization", TOKEN)
.contentType(MediaType.APPLICATION_JSON)
)
.andDo(document("auth-logout",
resourceDetails().tag("인증").description("로그아웃"),
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("Authorization").description("토큰")
)
)
)
.andExpect(status().isOk());
}

@DisplayName("사용자는 회원탈퇴 할 수 있다.")
@Test
void deleteTest() throws Exception {
// given
RefreshToken refreshToken = RefreshTokenFixture.refreshToken();
willDoNothing().given(authService).delete(anyLong());
given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken));

// when, then
mockMvc.perform(post("/api/v1/auth/delete")
.header("Authorization", TOKEN)
.contentType(MediaType.APPLICATION_JSON)
)
.andDo(document("auth-delete",
resourceDetails().tag("인증").description("회원탈퇴"),
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestHeaders(
headerWithName("Authorization").description("토큰")
)
)
)
.andExpect(status().isOk());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package coffeemeet.server.auth.domain;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;

import coffeemeet.server.auth.repository.RefreshTokenRepository;
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.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class AuthTokensGeneratorTest {

private static final Long accessTokenExpireTime = 1800L;
private static final Long refreshTokenExpireTime = 3600L;
private static final String BEARER_TYPE = "Bearer ";
private static final String ACCESS_TOKEN = "accessToken";
private static final String REFRESH_TOKEN = "refreshToken";

@InjectMocks
private AuthTokensGenerator authTokensGenerator;

@Mock
private JwtTokenProvider jwtTokenProvider;

@Mock
private RefreshTokenRepository refreshTokenRepository;

@BeforeEach
public void init() {
authTokensGenerator = new AuthTokensGenerator(jwtTokenProvider, accessTokenExpireTime,
refreshTokenExpireTime, refreshTokenRepository);
}

@DisplayName("access token & refresh token 발급할 수 있다.")
@Test
void generateTest() {
// given
given(jwtTokenProvider.generate(anyString(), any(Date.class))).willReturn(ACCESS_TOKEN,
REFRESH_TOKEN);

// when
AuthTokens authTokens = authTokensGenerator.generate((long) Math.random());

// then
assertAll(
() -> assertThat(authTokens.accessToken()).isEqualTo(BEARER_TYPE + ACCESS_TOKEN),
() -> assertThat(authTokens.refreshToken()).isEqualTo(BEARER_TYPE + REFRESH_TOKEN)
);
}

@DisplayName("access token 을 갱신 할 수 있다.")
@Test
void reissueAccessTokenTest() {
// given
given(jwtTokenProvider.generate(anyString(), any(Date.class))).willReturn(ACCESS_TOKEN,
REFRESH_TOKEN);

// when
AuthTokens authTokens = authTokensGenerator.reissueAccessToken((long) Math.random(),
REFRESH_TOKEN);

// then
assertAll(
() -> assertThat(authTokens.accessToken()).isEqualTo(BEARER_TYPE + ACCESS_TOKEN),
() -> assertThat(authTokens.refreshToken()).isEqualTo(BEARER_TYPE + REFRESH_TOKEN)
);
}

}
Loading