From 444489e873988c664fc2f72d80215adb69b280fd Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:23:43 +0900 Subject: [PATCH 01/13] =?UTF-8?q?[BE]=20test(#29):=20Kakao=20Adapter=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Google OAuth 인증 처리 --- .../oauth/adapter/kakao/KakaoAdapter.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java diff --git a/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java b/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java new file mode 100644 index 000000000..073e900d1 --- /dev/null +++ b/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java @@ -0,0 +1,60 @@ +package com.example.backend.auth.api.service.oauth.adapter.kakao; + +import com.example.backend.auth.api.service.oauth.adapter.OAuthAdapter; +import com.example.backend.auth.api.service.oauth.response.OAuthResponse; +import com.example.backend.common.exception.ExceptionMessage; +import com.example.backend.common.exception.oauth.OAuthException; +import com.example.backend.external.clients.oauth.kakao.KakaoProfileClients; +import com.example.backend.external.clients.oauth.kakao.KakaoTokenClients; +import com.example.backend.external.clients.oauth.kakao.response.KakaoProfileResponse; +import com.example.backend.external.clients.oauth.kakao.response.KakaoTokenResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.net.URI; + +import static com.example.backend.domain.define.user.constant.UserPlatformType.KAKAO; + +@Slf4j +@Component +@RequiredArgsConstructor +public class KakaoAdapter implements OAuthAdapter { + private final KakaoTokenClients kakaoTokenClients; + private final KakaoProfileClients kakaoProfileClients; + + @Override + public String getToken(String tokenURL) { + try { + KakaoTokenResponse token = kakaoTokenClients.getToken(URI.create(tokenURL)); + + // 받아온 token이 null일 경우 예외 발생 + if (token.getAccess_token() == null) { + throw new OAuthException(ExceptionMessage.OAUTH_INVALID_TOKEN_URL); + } + + return token.getAccess_token(); + } catch (RuntimeException e) { + log.error(">>>> [ Kakao Oauth 인증 에러 발생: {}", ExceptionMessage.OAUTH_INVALID_TOKEN_URL.getText()); + throw new OAuthException(ExceptionMessage.OAUTH_INVALID_TOKEN_URL); + } + } + + @Override + public OAuthResponse getProfile(String accessToken) { + try { + KakaoProfileResponse profile = kakaoProfileClients.getProfile("Bearer " + accessToken); + + return OAuthResponse.builder() + .platformId(profile.getId().toString()) + .platformType(KAKAO) + .email(profile.getEmail()) + .name(profile.getProperties().getNickname()) + .profileImageUrl(profile.getProperties().getProfile_image()) + .build(); + } catch (RuntimeException e) { + log.error(">>>> [ Kakao Oauth 인증 에러 발생: {}", ExceptionMessage.OAUTH_INVALID_ACCESS_TOKEN.getText()); + throw new OAuthException(ExceptionMessage.OAUTH_INVALID_ACCESS_TOKEN); + } + } +} From 881407675522f4450fa3a6235dd11ba4203ddc5a Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:28:52 +0900 Subject: [PATCH 02/13] =?UTF-8?q?[BE]=20feat(#29)=20KakaoURLBuilder=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Kakao OAuth 인증을 위한 URL 생성 * access token을 요청하는 URL 생성 * 사용자 프로필 정보 URL 생성 --- .../oauth/builder/kakao/KakaoURLBuilder.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 backend/src/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java diff --git a/backend/src/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java b/backend/src/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java new file mode 100644 index 000000000..04a4b35a1 --- /dev/null +++ b/backend/src/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java @@ -0,0 +1,66 @@ +package com.example.backend.auth.api.service.oauth.builder.kakao; + +import com.example.backend.auth.api.service.oauth.builder.OAuthURLBuilder; +import com.example.backend.auth.config.oauth.OAuthProperties; +import com.example.backend.common.exception.ExceptionMessage; +import com.example.backend.common.exception.oauth.OAuthException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class KakaoURLBuilder implements OAuthURLBuilder { + private static final String PLATFORM = "kakao"; + private final String authorizationUri; + private final String clientId; + private final String redirectUri; + private final String tokenUri; + private final String clientSecret; + private final String profileUri; + + + // 속성에서 읽어온 객체를 주입 + public KakaoURLBuilder(OAuthProperties oAuthProperties) { + try { + // 플랫폼(kakao)의 client, provider Map 획득 + OAuthProperties.Client kakaoClient = oAuthProperties.getClient().get(PLATFORM); + OAuthProperties.Provider kakaoProvider = oAuthProperties.getProvider().get(PLATFORM); + + this.authorizationUri = kakaoProvider.authorizationUri(); + this.clientId = kakaoClient.clientId(); + this.redirectUri = kakaoClient.redirectUri(); + this.tokenUri = kakaoProvider.tokenUri(); + this.clientSecret = kakaoClient.clientSecret(); + this.profileUri = kakaoProvider.profileUri(); + + } catch (NullPointerException e) { + log.error(">>>> OAuthProperties NullPointerException 발생: {}", ExceptionMessage.OAUTH_CONFIG_NULL); + throw new OAuthException(ExceptionMessage.OAUTH_CONFIG_NULL); + } + } + // "https://kauth.kakao.com/oauth/authorize?..." + @Override + public String authorize(String state) { + return authorizationUri + + "?response_type=code" // OAuth 인증 코드 그랜트 유형: code로 고정 + + "&client_id=" + clientId // 클라이언트 ID + + "&redirect_uri=" + redirectUri // 리다이렉트 URI + + "&state=" + state // CSRF 방지 + + "&scope=openid"; // 리소스 접근 범위: openid로 고정 + } + + // "https://kauth.kakao.com/oauth/token?..." + @Override + public String token(String code, String state) { + return tokenUri + + "?grant_type=authorization_code" // OAuth 인증 코드 그랜트 유형: code로 고정 + + "&client_id=" + clientId // 클라이언트 ID + + "&client_secret=" + clientSecret // 클라이언트 Secret + + "&redirect_uri=" + redirectUri // 리다이렉트 URI + + "&code=" + code; // authorize() 요청으로 얻은 인가 코드 + + } + // "https://kapi.kakao.com/v2/user/me" + @Override + public String profile() { return profileUri; } +} From b43cbdf95a9ab62e36266cb9292069a9b4fba6a3 Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:23:43 +0900 Subject: [PATCH 03/13] =?UTF-8?q?[BE]=20feat(#29):=20Kakao=20Adapter=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Kakao OAuth 인증 처리 --- .../oauth/adapter/kakao/KakaoAdapter.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java diff --git a/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java b/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java new file mode 100644 index 000000000..073e900d1 --- /dev/null +++ b/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java @@ -0,0 +1,60 @@ +package com.example.backend.auth.api.service.oauth.adapter.kakao; + +import com.example.backend.auth.api.service.oauth.adapter.OAuthAdapter; +import com.example.backend.auth.api.service.oauth.response.OAuthResponse; +import com.example.backend.common.exception.ExceptionMessage; +import com.example.backend.common.exception.oauth.OAuthException; +import com.example.backend.external.clients.oauth.kakao.KakaoProfileClients; +import com.example.backend.external.clients.oauth.kakao.KakaoTokenClients; +import com.example.backend.external.clients.oauth.kakao.response.KakaoProfileResponse; +import com.example.backend.external.clients.oauth.kakao.response.KakaoTokenResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.net.URI; + +import static com.example.backend.domain.define.user.constant.UserPlatformType.KAKAO; + +@Slf4j +@Component +@RequiredArgsConstructor +public class KakaoAdapter implements OAuthAdapter { + private final KakaoTokenClients kakaoTokenClients; + private final KakaoProfileClients kakaoProfileClients; + + @Override + public String getToken(String tokenURL) { + try { + KakaoTokenResponse token = kakaoTokenClients.getToken(URI.create(tokenURL)); + + // 받아온 token이 null일 경우 예외 발생 + if (token.getAccess_token() == null) { + throw new OAuthException(ExceptionMessage.OAUTH_INVALID_TOKEN_URL); + } + + return token.getAccess_token(); + } catch (RuntimeException e) { + log.error(">>>> [ Kakao Oauth 인증 에러 발생: {}", ExceptionMessage.OAUTH_INVALID_TOKEN_URL.getText()); + throw new OAuthException(ExceptionMessage.OAUTH_INVALID_TOKEN_URL); + } + } + + @Override + public OAuthResponse getProfile(String accessToken) { + try { + KakaoProfileResponse profile = kakaoProfileClients.getProfile("Bearer " + accessToken); + + return OAuthResponse.builder() + .platformId(profile.getId().toString()) + .platformType(KAKAO) + .email(profile.getEmail()) + .name(profile.getProperties().getNickname()) + .profileImageUrl(profile.getProperties().getProfile_image()) + .build(); + } catch (RuntimeException e) { + log.error(">>>> [ Kakao Oauth 인증 에러 발생: {}", ExceptionMessage.OAUTH_INVALID_ACCESS_TOKEN.getText()); + throw new OAuthException(ExceptionMessage.OAUTH_INVALID_ACCESS_TOKEN); + } + } +} From eb2ce335131641e09611afc2cb821f01fbd815f4 Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:28:52 +0900 Subject: [PATCH 04/13] =?UTF-8?q?[BE]=20feat(#29):=20KakaoURLBuilder=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Kakao OAuth 인증을 위한 URL 생성 * access token을 요청하는 URL 생성 * 사용자 프로필 정보 URL 생성 --- .../oauth/builder/kakao/KakaoURLBuilder.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 backend/src/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java diff --git a/backend/src/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java b/backend/src/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java new file mode 100644 index 000000000..04a4b35a1 --- /dev/null +++ b/backend/src/main/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilder.java @@ -0,0 +1,66 @@ +package com.example.backend.auth.api.service.oauth.builder.kakao; + +import com.example.backend.auth.api.service.oauth.builder.OAuthURLBuilder; +import com.example.backend.auth.config.oauth.OAuthProperties; +import com.example.backend.common.exception.ExceptionMessage; +import com.example.backend.common.exception.oauth.OAuthException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class KakaoURLBuilder implements OAuthURLBuilder { + private static final String PLATFORM = "kakao"; + private final String authorizationUri; + private final String clientId; + private final String redirectUri; + private final String tokenUri; + private final String clientSecret; + private final String profileUri; + + + // 속성에서 읽어온 객체를 주입 + public KakaoURLBuilder(OAuthProperties oAuthProperties) { + try { + // 플랫폼(kakao)의 client, provider Map 획득 + OAuthProperties.Client kakaoClient = oAuthProperties.getClient().get(PLATFORM); + OAuthProperties.Provider kakaoProvider = oAuthProperties.getProvider().get(PLATFORM); + + this.authorizationUri = kakaoProvider.authorizationUri(); + this.clientId = kakaoClient.clientId(); + this.redirectUri = kakaoClient.redirectUri(); + this.tokenUri = kakaoProvider.tokenUri(); + this.clientSecret = kakaoClient.clientSecret(); + this.profileUri = kakaoProvider.profileUri(); + + } catch (NullPointerException e) { + log.error(">>>> OAuthProperties NullPointerException 발생: {}", ExceptionMessage.OAUTH_CONFIG_NULL); + throw new OAuthException(ExceptionMessage.OAUTH_CONFIG_NULL); + } + } + // "https://kauth.kakao.com/oauth/authorize?..." + @Override + public String authorize(String state) { + return authorizationUri + + "?response_type=code" // OAuth 인증 코드 그랜트 유형: code로 고정 + + "&client_id=" + clientId // 클라이언트 ID + + "&redirect_uri=" + redirectUri // 리다이렉트 URI + + "&state=" + state // CSRF 방지 + + "&scope=openid"; // 리소스 접근 범위: openid로 고정 + } + + // "https://kauth.kakao.com/oauth/token?..." + @Override + public String token(String code, String state) { + return tokenUri + + "?grant_type=authorization_code" // OAuth 인증 코드 그랜트 유형: code로 고정 + + "&client_id=" + clientId // 클라이언트 ID + + "&client_secret=" + clientSecret // 클라이언트 Secret + + "&redirect_uri=" + redirectUri // 리다이렉트 URI + + "&code=" + code; // authorize() 요청으로 얻은 인가 코드 + + } + // "https://kapi.kakao.com/v2/user/me" + @Override + public String profile() { return profileUri; } +} From 215149e8efd3f33d699b5c42fe96118bc20f1f3f Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:36:05 +0900 Subject: [PATCH 05/13] [BE] feat(#29): OAuthService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 카카오 플랫폼 추가 --- .../backend/auth/api/service/oauth/OAuthService.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/example/backend/auth/api/service/oauth/OAuthService.java b/backend/src/main/java/com/example/backend/auth/api/service/oauth/OAuthService.java index f9094d817..78a347279 100644 --- a/backend/src/main/java/com/example/backend/auth/api/service/oauth/OAuthService.java +++ b/backend/src/main/java/com/example/backend/auth/api/service/oauth/OAuthService.java @@ -3,8 +3,10 @@ import com.example.backend.auth.api.controller.auth.response.AuthLoginPageResponse; import com.example.backend.auth.api.service.oauth.adapter.OAuthAdapter; import com.example.backend.auth.api.service.oauth.adapter.github.GithubAdapter; +import com.example.backend.auth.api.service.oauth.adapter.kakao.KakaoAdapter; import com.example.backend.auth.api.service.oauth.builder.OAuthURLBuilder; import com.example.backend.auth.api.service.oauth.builder.github.GithubURLBuilder; +import com.example.backend.auth.api.service.oauth.builder.kakao.KakaoURLBuilder; import com.example.backend.auth.api.service.oauth.response.OAuthResponse; import com.example.backend.domain.define.user.constant.UserPlatformType; import lombok.extern.slf4j.Slf4j; @@ -17,6 +19,7 @@ import java.util.stream.Collectors; import static com.example.backend.domain.define.user.constant.UserPlatformType.GITHUB; +import static com.example.backend.domain.define.user.constant.UserPlatformType.KAKAO; @Slf4j @Service @@ -25,13 +28,19 @@ public class OAuthService { private Map adapterMap; // 플랫폼별 Adapter, URLBuilder 등록 - public OAuthService(GithubAdapter githubAdapter, GithubURLBuilder githubURLBuilder) { + public OAuthService(GithubAdapter githubAdapter, GithubURLBuilder githubURLBuilder , KakaoAdapter kakaoAdapter, KakaoURLBuilder kakaoURLBuilder) { this.adapterMap = new HashMap<>() {{ // 깃허브 플랫폼 추가 put(GITHUB, OAuthFactory.builder() .oAuthAdapter(githubAdapter) .oAuthURLBuilder(githubURLBuilder) .build()); + // 카카오 플랫폼 추가 + put(KAKAO, OAuthFactory.builder() + .oAuthAdapter(kakaoAdapter) + .oAuthURLBuilder(kakaoURLBuilder) + .build()); + }}; } @@ -70,7 +79,6 @@ public OAuthResponse login(UserPlatformType platformType, String code, String st // Access Token 획득 String accessToken = adapter.getToken(tokenUrl); - // 사용자 프로필 조회 OAuthResponse userInfo = adapter.getProfile(accessToken); log.info(">>>> {} Login Success", platformType); From 73168819c19e3cb7cb9af357c6ff517926fe7f29 Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:42:33 +0900 Subject: [PATCH 06/13] =?UTF-8?q?[BE]=20feat(#29):=20Kakao=20Token=20Clien?= =?UTF-8?q?ts,=20Response=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Token uri로 요청 구현 * Token을 요청 후 반환받을 DTO 구현 --- .../oauth/kakao/KakaoTokenClients.java | 20 +++++++++++++++++++ .../kakao/response/KakaoTokenResponse.java | 19 ++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 backend/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoTokenClients.java create mode 100644 backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoTokenResponse.java diff --git a/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoTokenClients.java b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoTokenClients.java new file mode 100644 index 000000000..5ab731e37 --- /dev/null +++ b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoTokenClients.java @@ -0,0 +1,20 @@ +package com.example.backend.external.clients.oauth.kakao; + + +import com.example.backend.external.annotation.ExternalClients; +import com.example.backend.external.clients.oauth.kakao.response.KakaoTokenResponse; +import org.springframework.http.MediaType; +import org.springframework.web.service.annotation.PostExchange; + +import java.net.URI; + +/* + AccessToken을 얻기 위해 설정한 token URI로 POST 요청을 보낸다. + */ +@ExternalClients(baseUrl = "oauth2.provider.kakao.token-uri") +public interface KakaoTokenClients { + + // 요청의 content Type: FORM_URLENCODED 형식 ex) key1=value1&key2=value2 + @PostExchange(contentType = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + public KakaoTokenResponse getToken(URI uri); +} diff --git a/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoTokenResponse.java b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoTokenResponse.java new file mode 100644 index 000000000..be3e7b344 --- /dev/null +++ b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoTokenResponse.java @@ -0,0 +1,19 @@ +package com.example.backend.external.clients.oauth.kakao.response; + + +import lombok.Getter; +import lombok.NoArgsConstructor; + +/* + Kakao에 Access Token을 요청 후 반환받을 DTO + */ +@Getter +@NoArgsConstructor +public class KakaoTokenResponse { + private String access_token; + + public KakaoTokenResponse(String access_token) { + this.access_token = access_token; + } +} + From 7dcead9be62e1ab03cc4779056773da8394b49ae Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:46:03 +0900 Subject: [PATCH 07/13] =?UTF-8?q?[BE]=20feat(#29):=20Kakao=20Profile=20Cli?= =?UTF-8?q?ents,=20Response=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 프로필 uri로 요청 구현 * 프로필을 요청 후 반환받을 DTO 구현 * 카카오에선 email을 제공하지 않음 * response 받는 형식을 다르게 함 --- .../oauth/kakao/KakaoProfileClients.java | 17 +++++++++ .../kakao/response/KakaoProfileResponse.java | 35 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 backend/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoProfileClients.java create mode 100644 backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java diff --git a/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoProfileClients.java b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoProfileClients.java new file mode 100644 index 000000000..d0c756c44 --- /dev/null +++ b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/KakaoProfileClients.java @@ -0,0 +1,17 @@ +package com.example.backend.external.clients.oauth.kakao; + +import com.example.backend.external.annotation.ExternalClients; +import com.example.backend.external.clients.oauth.kakao.response.KakaoProfileResponse; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.service.annotation.GetExchange; + +/* + 사용자 정보를 얻기 위해 설정한 profile 요청 URI로 GET 요청을 보낸다. + */ +@ExternalClients(baseUrl = "https://kapi.kakao.com/v2/user/me") +public interface KakaoProfileClients { + + @GetExchange + public KakaoProfileResponse getProfile(@RequestHeader(value = "Authorization") String header); + +} diff --git a/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java new file mode 100644 index 000000000..e5abbd2e6 --- /dev/null +++ b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java @@ -0,0 +1,35 @@ +package com.example.backend.external.clients.oauth.kakao.response; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class KakaoProfileResponse { + private Long id; + private String name; + private String email; + + private Properties properties; + + public KakaoProfileResponse(Long id, String name, String email, Properties properties) { + this.id = id; + this.name = name; + this.email = email; + this.properties = properties; + } + + @Getter + @NoArgsConstructor + public static class Properties { + private String nickname; + private String profile_image; + private String thumbnail_image; + + public Properties(String nickname, String profile_image, String thumbnail_image) { + this.nickname = nickname; + this.profile_image = profile_image; + this.thumbnail_image = thumbnail_image; + } + } +} \ No newline at end of file From 5eecf8c9712521b6e6fab26abcc972f3227e1577 Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:52:24 +0900 Subject: [PATCH 08/13] [BE] test(#29) Kakao Adapter Test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 토큰 요청 테스트 * 프로필 요쳥 테스트 --- .../oauth/adapter/kakao/KakaoAdapterTest.java | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java diff --git a/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java b/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java new file mode 100644 index 000000000..c00cf1951 --- /dev/null +++ b/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java @@ -0,0 +1,125 @@ +package com.example.backend.auth.api.service.oauth.adapter.kakao; + + +import com.example.backend.auth.TestConfig; +import com.example.backend.auth.api.service.oauth.builder.kakao.KakaoURLBuilder; + +import com.example.backend.auth.api.service.oauth.response.OAuthResponse; +import com.example.backend.common.exception.ExceptionMessage; +import com.example.backend.common.exception.oauth.OAuthException; +import com.example.backend.external.clients.oauth.kakao.KakaoProfileClients; +import com.example.backend.external.clients.oauth.kakao.KakaoTokenClients; +import com.example.backend.external.clients.oauth.kakao.response.KakaoProfileResponse; +import com.example.backend.external.clients.oauth.kakao.response.KakaoTokenResponse; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.net.URI; + +import static com.example.backend.domain.define.user.constant.UserPlatformType.KAKAO; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class KakaoAdapterTest extends TestConfig { + @Autowired + private KakaoAdapter kakaoAdapter; + + @Autowired + private KakaoURLBuilder kakaoURLBuilder; + @Test + @DisplayName("kakao 토큰 요청 API에 정상적인 요청을 보내면, access_token이 발행된다.") + void kakaoAdapterGetTokenSuccess() { + // given + KakaoAdapterTest.MockKakaoTokenClients mockKakaoTokenClients = new KakaoAdapterTest.MockKakaoTokenClients(); + KakaoAdapterTest.MockKakaoProfileClients mockKakaoProfileClients = new KakaoAdapterTest.MockKakaoProfileClients(); + KakaoAdapter kakaoAdapter = new KakaoAdapter(mockKakaoTokenClients, mockKakaoProfileClients); + + // when + String accessToken = kakaoAdapter.getToken("tokenUrl"); + + // then + System.out.println("accessToken = " + accessToken); + assertThat(accessToken).isEqualTo("access-token"); + + } + + + @Test + @DisplayName("kakao 토큰 요청 중 예외가 발생하면, OAUTH_INVALID_TOKEN_URL 에외가 발생한다.") + void kakaoAdapterGetTokenFail() { + // given + String tokenURL = kakaoURLBuilder.token("error-token", "state"); + + // when + OAuthException exception = assertThrows(OAuthException.class, + () -> kakaoAdapter.getToken(tokenURL)); + + // then + assertThat(exception.getMessage()).isEqualTo(ExceptionMessage.OAUTH_INVALID_TOKEN_URL.getText()); + + } + + + + + @Test + @DisplayName("kakao 프로필 요청 API에 정상적인 요청을 보내면, 사용자 프로필이 반환된다.") + void kakaoAdapterGetProfileSuccess() { + // given + KakaoAdapterTest.MockKakaoTokenClients mockKakaoTokenClients = new KakaoAdapterTest.MockKakaoTokenClients(); + KakaoAdapterTest.MockKakaoProfileClients mockKakaoProfileClients = new KakaoAdapterTest.MockKakaoProfileClients(); + KakaoAdapter kakaoAdapter = new KakaoAdapter(mockKakaoTokenClients, mockKakaoProfileClients); + + // when + OAuthResponse profile = kakaoAdapter.getProfile("access-token"); + + // then + assertAll( + () -> assertThat(profile.getPlatformId()).isEqualTo("1"), + () -> assertThat(profile.getEmail()).isEqualTo("이메일 없음"), + () -> assertThat(profile.getProfileImageUrl()).isEqualTo("http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg"), + () -> assertThat(profile.getName()).isEqualTo("구영민"), + () -> assertThat(profile.getPlatformType()).isEqualTo(KAKAO) + ); + } + + + @Test // X + @DisplayName("kakao 프로필 요청 중 예외가 발생하면, OAUTH_INVALID_ACCESS_TOKEN 예외가 발생한다.") + void kakaoAdapterGetProfileFail() { + // when + OAuthException exception = assertThrows(OAuthException.class, + () -> kakaoAdapter.getProfile("error-token")); + + // then + assertThat(exception.getMessage()).isEqualTo(ExceptionMessage.OAUTH_INVALID_ACCESS_TOKEN.getText()); + + } + + + + + + static class MockKakaoTokenClients implements KakaoTokenClients { + + @Override + public KakaoTokenResponse getToken(URI uri) { + return new KakaoTokenResponse("access-token"); + } + } + static class MockKakaoProfileClients implements KakaoProfileClients { + + @Override + public KakaoProfileResponse getProfile(String header) { + return new KakaoProfileResponse(1L, + "구영민", + "이메일 없음", + new KakaoProfileResponse.Properties("구영민", + "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg", + "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_110x110.jpg")) + ; + } + } +} From 00c4f5d3862749508741ede19eb7f6c62178a78d Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:53:37 +0900 Subject: [PATCH 09/13] [BE] test(#29): OAuth Kakao URL Builder Test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 인가 코드 요청 URL 생성 테스트 * access token 요청 URL 생성 테스트 * 사용자 정보 요청 URL 생성 테스트 --- .../builder/kakao/KakaoURLBuilderTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 backend/src/test/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilderTest.java diff --git a/backend/src/test/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilderTest.java b/backend/src/test/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilderTest.java new file mode 100644 index 000000000..0b2009fd0 --- /dev/null +++ b/backend/src/test/java/com/example/backend/auth/api/service/oauth/builder/kakao/KakaoURLBuilderTest.java @@ -0,0 +1,76 @@ +package com.example.backend.auth.api.service.oauth.builder.kakao; + +import com.example.backend.auth.TestConfig; +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 static org.assertj.core.api.Assertions.assertThat; + +public class KakaoURLBuilderTest extends TestConfig { + @Autowired + private KakaoURLBuilder urlBuilder; + + @Value("${oauth2.client.kakao.client-id}") private String clientId; + @Value("${oauth2.client.kakao.client-secret}") private String clientSecret; + @Value("${oauth2.client.kakao.redirect-uri}") private String redirectUri; + + @Value("${oauth2.provider.kakao.authorization-uri}") String authorizationUri; + @Value("${oauth2.provider.kakao.token-uri}") private String tokenUri; + @Value("${oauth2.provider.kakao.profile-uri}") private String profileUri; + + @Test + @DisplayName("authorize(인가 코드 요청) URL을 성공적으로 생성한다.") + void authorizeURIBuildSuccess() { + // given + String state = "testState"; + + // when + String authorizeURL = urlBuilder.authorize(state); + + // then + System.out.println("authorize URL : " + authorizeURL); + assertThat(authorizeURL).isEqualTo(authorizationUri + + "?response_type=code" + + "&client_id=" + clientId + + "&redirect_uri=" + redirectUri + + "&state=" + state + + "&scope=openid"); + } + + + @Test + @DisplayName("token(Access Token 요청) URL을 성공적으로 생성한다.") + void tokenURIBuildSuccess() { + // given + String code = "testCode"; + String state = "testState"; + + // when + String tokenURL = urlBuilder.token(code, state); + + // then + System.out.println("tokenURL : " + tokenURL); + assertThat(tokenURL).isEqualTo(tokenUri + + "?grant_type=authorization_code" + + "&client_id=" + clientId + + "&client_secret=" + clientSecret + + "&redirect_uri=" + redirectUri + + "&code=" + code); + } + + @Test + @DisplayName("profile(사용자 정보 요청) URL을 성공적으로 생성한다.") + void profileURIBuildSuccess() { + // given + + // when + String profileURL = urlBuilder.profile(); + + // then + System.out.println("profileURL : " + profileURL); + assertThat(profileURL).isEqualTo(profileUri); + + } +} From ff90cd9a3f084b19349fe7857280066eae26c8b0 Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:56:04 +0900 Subject: [PATCH 10/13] [BE] test(#29): OAuth Service Test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 모든 플랫폼 로그인 페이지 반환 test에 카카오 추가 * 카카오 로그인 성공, 실패 테스트 추가 --- .../api/service/oauth/OAuthServiceTest.java | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/backend/src/test/java/com/example/backend/auth/api/service/oauth/OAuthServiceTest.java b/backend/src/test/java/com/example/backend/auth/api/service/oauth/OAuthServiceTest.java index 3229c070b..4d866b336 100644 --- a/backend/src/test/java/com/example/backend/auth/api/service/oauth/OAuthServiceTest.java +++ b/backend/src/test/java/com/example/backend/auth/api/service/oauth/OAuthServiceTest.java @@ -3,7 +3,9 @@ import com.example.backend.auth.TestConfig; import com.example.backend.auth.api.controller.auth.response.AuthLoginPageResponse; import com.example.backend.auth.api.service.oauth.adapter.github.GithubAdapter; +import com.example.backend.auth.api.service.oauth.adapter.kakao.KakaoAdapter; import com.example.backend.auth.api.service.oauth.builder.github.GithubURLBuilder; +import com.example.backend.auth.api.service.oauth.builder.kakao.KakaoURLBuilder; import com.example.backend.auth.api.service.oauth.response.OAuthResponse; import com.example.backend.common.exception.oauth.OAuthException; import org.junit.jupiter.api.DisplayName; @@ -14,6 +16,7 @@ import java.util.List; import static com.example.backend.domain.define.user.constant.UserPlatformType.GITHUB; +import static com.example.backend.domain.define.user.constant.UserPlatformType.KAKAO; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -29,6 +32,10 @@ class OAuthServiceTest extends TestConfig { @MockBean private GithubAdapter githubAdapter; + @Autowired + private KakaoURLBuilder kakaoUrlBuilder; + @MockBean + private KakaoAdapter kakaoAdapter; @Test @DisplayName("모든 플랫폼의 로그인 페이지를 성공적으로 반환한다.") void allUrlBuilderSuccess() { @@ -38,9 +45,20 @@ void allUrlBuilderSuccess() { // when List loginPages = oAuthService.loginPage(state); String authorizeURL = urlBuilder.authorize(state); - + String authorizeURLkakao = kakaoUrlBuilder.authorize(state); // then - assertThat(loginPages.get(0).getUrl()).isEqualTo(authorizeURL); + assertThat(loginPages).hasSize(2); // 리스트 크기 확인 + + // 각 플랫폼별 URL인지 확인 + boolean containsGithub = loginPages.stream() + .anyMatch(page -> page.getPlatformType().equals(GITHUB) && + page.getUrl().equals(authorizeURL)); + boolean containsKakao = loginPages.stream() + .anyMatch(page -> page.getPlatformType().equals(KAKAO) && + page.getUrl().equals(authorizeURLkakao)); + + assertThat(containsGithub).isTrue(); + assertThat(containsKakao).isTrue(); } @Test @@ -73,7 +91,35 @@ void githubLoginSuccess() { } @Test - @DisplayName("깃허브 로그인에 실하면 OAuthException 예외가 발생한다.") + @DisplayName("카카오 로그인에 성공하면 OAuthResponse 객체를 반환한다.") + void kakaoLoginSuccess() { + // given + String code = "valid-code"; + String state = "valid-state"; + + OAuthResponse response = OAuthResponse.builder() + .platformId("1") + .platformType(KAKAO) + .email("이메일 없음") + .name("구영민") + .profileImageUrl("http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg") + .build(); + + // when + // when 사용시 Mockito 패키지 사용 + when(kakaoAdapter.getToken(any(String.class))).thenReturn("access-token"); + when(kakaoAdapter.getProfile(any(String.class))).thenReturn(response); + OAuthResponse profile = oAuthService.login(KAKAO, code, state); + + // then + assertThat(profile) + .extracting("platformId", "platformType", "email", "name", "profileImageUrl") + .contains("1", KAKAO, "이메일 없음", "구영민", "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg"); + + + } + @Test + @DisplayName("깃허브 로그인에 실패하면 OAuthException 예외가 발생한다.") void githubLoginFail() { // given String code = "invalid-code"; @@ -85,4 +131,18 @@ void githubLoginFail() { () -> oAuthService.login(GITHUB, code, state)); } + + @Test + @DisplayName("카카오 로그인에 실패하면 OAuthException 예외가 발생한다.") + void kakaoLoginFail() { + // given + String code = "invalid-code"; + String state = "invalid-state"; + + // when + when(kakaoAdapter.getToken(any(String.class))).thenThrow(OAuthException.class); + assertThrows(OAuthException.class, + () -> oAuthService.login(KAKAO, code, state)); + + } } \ No newline at end of file From 19536eb524a5dc1eaadf5900494d36f8ac0cd3f6 Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Tue, 16 Jan 2024 17:57:45 +0900 Subject: [PATCH 11/13] =?UTF-8?q?[BE]=20test(#29):=20Kakao=20Client=20Test?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 추후에 구현 예정 --- .../clients/oauth/kakao/KakaoClientTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 backend/src/test/java/com/example/backend/external/clients/oauth/kakao/KakaoClientTest.java diff --git a/backend/src/test/java/com/example/backend/external/clients/oauth/kakao/KakaoClientTest.java b/backend/src/test/java/com/example/backend/external/clients/oauth/kakao/KakaoClientTest.java new file mode 100644 index 000000000..d0abdfc1a --- /dev/null +++ b/backend/src/test/java/com/example/backend/external/clients/oauth/kakao/KakaoClientTest.java @@ -0,0 +1,55 @@ +package com.example.backend.external.clients.oauth.kakao; + +import com.example.backend.auth.TestConfig; +import com.example.backend.external.clients.oauth.kakao.response.KakaoProfileResponse; +import com.example.backend.external.clients.oauth.kakao.response.KakaoTokenResponse; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.net.URI; + +import static org.junit.jupiter.api.Assertions.assertNull; + +public class KakaoClientTest extends TestConfig { + @Autowired + private KakaoTokenClients kakaoTokenClients; + + @Autowired + private KakaoProfileClients kakaoProfileClients; + + @Test + @DisplayName("인가 code를 URL에 담아 요청해 access_token을 성공적으로 받환받는다.") + void kakaoTokenRequestTest() { + // given + //String uri = "https://kauth.kakao.com/oauth/token?grant_type=authorization_code&client_id=1d8513aae332ebe7462f429d67f3cacc&client_secret=T2dW4O4bFTPYz7PKflnIlqqfYXNbr2U6&redirect_uri=http://localhost:8080/auth/KAKAO/login&code="; + + + // when + //KakaoTokenResponse token = kakaoTokenClients.getToken(URI.create(uri)); + //System.out.println("token = " + token.getAccess_token()); + + // then + // 현재는 동적인 테스트 불가하므로 null. OauthService 구현 후 동적으로 테스트할 예정 + //assertNull(token.getAccess_token()); + } + + @Test + @DisplayName("Access Token을 URL에 담아 요청해 사용자 정보를 성공적으로 받환받는다.") + void githubProfileRequestTest() { + // given + String accessToken = ""; + + /*KakaoProfileResponse profile = kakaoProfileClients.getProfile("Bearer " + accessToken); + + System.out.println("login = " + profile.getLogin()); + System.out.println("email = " + profile.getEmail()); + System.out.println("name = " + profile.getName()); + + assertAll( + () -> assertThat(profile.getLogin()).isEqualTo("jusung-c"), + () -> assertThat(profile.getEmail()).isEqualTo("anaooauc1236@naver.com"), + () -> assertThat(profile.getName()).isEqualTo("이주성") + );*/ + } +} From 0f942162ec6c9273937cc5329b8ff563e872b0bf Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Wed, 17 Jan 2024 21:21:16 +0900 Subject: [PATCH 12/13] =?UTF-8?q?[BE]=20refactor(#29):=20Email=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Email 관련 모두 삭제 --- .../auth/api/service/oauth/adapter/kakao/KakaoAdapter.java | 1 - .../clients/oauth/kakao/response/KakaoProfileResponse.java | 4 +--- .../api/service/oauth/adapter/kakao/KakaoAdapterTest.java | 2 -- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java b/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java index 073e900d1..702ead502 100644 --- a/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java +++ b/backend/src/main/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapter.java @@ -48,7 +48,6 @@ public OAuthResponse getProfile(String accessToken) { return OAuthResponse.builder() .platformId(profile.getId().toString()) .platformType(KAKAO) - .email(profile.getEmail()) .name(profile.getProperties().getNickname()) .profileImageUrl(profile.getProperties().getProfile_image()) .build(); diff --git a/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java index e5abbd2e6..8a20f5d08 100644 --- a/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java +++ b/backend/src/main/java/com/example/backend/external/clients/oauth/kakao/response/KakaoProfileResponse.java @@ -8,14 +8,12 @@ public class KakaoProfileResponse { private Long id; private String name; - private String email; private Properties properties; - public KakaoProfileResponse(Long id, String name, String email, Properties properties) { + public KakaoProfileResponse(Long id, String name, Properties properties) { this.id = id; this.name = name; - this.email = email; this.properties = properties; } diff --git a/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java b/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java index c00cf1951..2c52e8264 100644 --- a/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java +++ b/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java @@ -78,7 +78,6 @@ void kakaoAdapterGetProfileSuccess() { // then assertAll( () -> assertThat(profile.getPlatformId()).isEqualTo("1"), - () -> assertThat(profile.getEmail()).isEqualTo("이메일 없음"), () -> assertThat(profile.getProfileImageUrl()).isEqualTo("http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg"), () -> assertThat(profile.getName()).isEqualTo("구영민"), () -> assertThat(profile.getPlatformType()).isEqualTo(KAKAO) @@ -115,7 +114,6 @@ static class MockKakaoProfileClients implements KakaoProfileClients { public KakaoProfileResponse getProfile(String header) { return new KakaoProfileResponse(1L, "구영민", - "이메일 없음", new KakaoProfileResponse.Properties("구영민", "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg", "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_110x110.jpg")) From fe8b36e145a8b12f708e3534000f46bf7025df5c Mon Sep 17 00:00:00 2001 From: kooyeongmin Date: Thu, 18 Jan 2024 12:24:57 +0900 Subject: [PATCH 13/13] =?UTF-8?q?[BE]=20refactor(#29)=20:=20=ED=94=BC?= =?UTF-8?q?=EB=93=9C=EB=B0=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * kakaoAdapterTest.kakaoAdapterGetProfileSuccess() 테스트 given, then 변수화 --- .../oauth/adapter/kakao/KakaoAdapterTest.java | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java b/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java index 2c52e8264..432cf8444 100644 --- a/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java +++ b/backend/src/test/java/com/example/backend/auth/api/service/oauth/adapter/kakao/KakaoAdapterTest.java @@ -68,8 +68,16 @@ void kakaoAdapterGetTokenFail() { @DisplayName("kakao 프로필 요청 API에 정상적인 요청을 보내면, 사용자 프로필이 반환된다.") void kakaoAdapterGetProfileSuccess() { // given + Long expetedId = 1L; + String expectedName = "구영민"; + String expectedNickName = "구영민"; + String expectedProfileImageUrl = "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg"; + String expectedThumbnailImage = "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_110x110.jpg"; + KakaoAdapterTest.MockKakaoTokenClients mockKakaoTokenClients = new KakaoAdapterTest.MockKakaoTokenClients(); - KakaoAdapterTest.MockKakaoProfileClients mockKakaoProfileClients = new KakaoAdapterTest.MockKakaoProfileClients(); + KakaoAdapterTest.MockKakaoProfileClients mockKakaoProfileClients = new KakaoAdapterTest.MockKakaoProfileClients(expetedId, + expectedName, + new KakaoProfileResponse.Properties(expectedNickName, expectedProfileImageUrl, expectedThumbnailImage)); KakaoAdapter kakaoAdapter = new KakaoAdapter(mockKakaoTokenClients, mockKakaoProfileClients); // when @@ -77,9 +85,9 @@ void kakaoAdapterGetProfileSuccess() { // then assertAll( - () -> assertThat(profile.getPlatformId()).isEqualTo("1"), - () -> assertThat(profile.getProfileImageUrl()).isEqualTo("http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg"), - () -> assertThat(profile.getName()).isEqualTo("구영민"), + () -> assertThat(profile.getPlatformId()).isEqualTo(expetedId.toString()), + () -> assertThat(profile.getProfileImageUrl()).isEqualTo(expectedProfileImageUrl), + () -> assertThat(profile.getName()).isEqualTo(expectedName), () -> assertThat(profile.getPlatformType()).isEqualTo(KAKAO) ); } @@ -109,14 +117,33 @@ public KakaoTokenResponse getToken(URI uri) { } } static class MockKakaoProfileClients implements KakaoProfileClients { - + private Long id; + private String name; + private KakaoProfileResponse.Properties properties; + MockKakaoProfileClients(Long id, String name, KakaoProfileResponse.Properties properties){ + this.id = id; + this.name = name; + this.properties = properties; + } + MockKakaoProfileClients(){}; + public static class Properties { + private String nickname; + private String profile_image; + private String thumbnail_image; + + public Properties(String nickname, String profile_image, String thumbnail_image) { + this.nickname = nickname; + this.profile_image = profile_image; + this.thumbnail_image = thumbnail_image; + } + } @Override public KakaoProfileResponse getProfile(String header) { - return new KakaoProfileResponse(1L, - "구영민", - new KakaoProfileResponse.Properties("구영민", - "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_640x640.jpg", - "http://k.kakaocdn.net/dn/1G9kp/btsAot8liOn/8CWudi3uy07rvFNUkk3ER0/img_110x110.jpg")) + return new KakaoProfileResponse(id, + name, + new KakaoProfileResponse.Properties(properties.getNickname(), + properties.getProfile_image(), + properties.getThumbnail_image())) ; } }