From 4e4e3223a0e927b9bcbbfd0d8e514a2b657d03a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9E=AC=EC=9B=90?= Date: Mon, 28 Oct 2024 20:02:46 +0900 Subject: [PATCH] =?UTF-8?q?Refactor:=20OauthService=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=20=EA=B0=80=EC=9E=85,=20=EB=A1=9C=EA=B7=B8=EC=9D=B8,=20?= =?UTF-8?q?=ED=83=88=ED=87=B4=20=EC=8B=9C=20Oauth=20id=20token,=20access?= =?UTF-8?q?=20token=20=EC=9A=94=EC=B2=AD/=EC=9D=91=EB=8B=B5=EA=B3=BC=20db?= =?UTF-8?q?=20=ED=8A=B8=EB=9E=9C=EC=9E=AD=EC=85=98=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=20(#276)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor: OauthService에서 socialProfile 생성 로직을 SocialProfileService로 분리 * Refactor: SignupEvent와 WithdrawEvent 추가 * Refactor: MemberWithdrawService에서 탈퇴 시 러닝 데이터가 없어도 탈퇴 id를 로깅하도룩 수정 * Fix: social profile 조회 시 member도 fetch join하도록 수정 * Test: OauthServiceTest에 리팩토링 사항 반영 --- .../member/MemberEventHandler.java | 25 +++++++ .../application/member/MemberService.java | 6 ++ .../member/MemberWithdrawService.java | 15 ++-- .../application/member/event/SignupEvent.java | 5 ++ .../member/event/WithdrawEvent.java | 3 + .../runus/application/oauth/OauthService.java | 73 ++++--------------- .../oauth/SocialProfileService.java | 65 +++++++++++++++++ .../member/JpaSocialProfileRepository.java | 2 + .../application/oauth/OauthServiceTest.java | 71 ++++++------------ 9 files changed, 151 insertions(+), 114 deletions(-) create mode 100644 src/main/java/com/dnd/runus/application/member/MemberEventHandler.java create mode 100644 src/main/java/com/dnd/runus/application/member/event/SignupEvent.java create mode 100644 src/main/java/com/dnd/runus/application/member/event/WithdrawEvent.java create mode 100644 src/main/java/com/dnd/runus/application/oauth/SocialProfileService.java diff --git a/src/main/java/com/dnd/runus/application/member/MemberEventHandler.java b/src/main/java/com/dnd/runus/application/member/MemberEventHandler.java new file mode 100644 index 00000000..5b5bcb8e --- /dev/null +++ b/src/main/java/com/dnd/runus/application/member/MemberEventHandler.java @@ -0,0 +1,25 @@ +package com.dnd.runus.application.member; + +import com.dnd.runus.application.member.event.SignupEvent; +import com.dnd.runus.application.member.event.WithdrawEvent; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class MemberEventHandler { + + private final MemberService memberService; + private final MemberWithdrawService memberWithdrawService; + + @EventListener + public void handleSignupEvent(SignupEvent signupEvent) { + memberService.initMember(signupEvent.member()); + } + + @EventListener + public void handleWithdrawEvent(WithdrawEvent withdrawEvent) { + memberWithdrawService.deleteAllDataAboutMember(withdrawEvent.memberId()); + } +} diff --git a/src/main/java/com/dnd/runus/application/member/MemberService.java b/src/main/java/com/dnd/runus/application/member/MemberService.java index 60904f10..bff5bcdb 100644 --- a/src/main/java/com/dnd/runus/application/member/MemberService.java +++ b/src/main/java/com/dnd/runus/application/member/MemberService.java @@ -1,6 +1,7 @@ package com.dnd.runus.application.member; import com.dnd.runus.domain.level.Level; +import com.dnd.runus.domain.member.Member; import com.dnd.runus.domain.member.MemberLevel; import com.dnd.runus.domain.member.MemberLevelRepository; import com.dnd.runus.presentation.v1.member.dto.response.MyProfileResponse; @@ -13,6 +14,11 @@ public class MemberService { private final MemberLevelRepository memberLevelRepository; + @Transactional + public void initMember(Member member) { + memberLevelRepository.save(new MemberLevel(member)); + } + @Transactional(readOnly = true) public MyProfileResponse getMyProfile(long memberId) { MemberLevel.Current memberCurrentLevel = memberLevelRepository.findByMemberIdWithLevel(memberId); diff --git a/src/main/java/com/dnd/runus/application/member/MemberWithdrawService.java b/src/main/java/com/dnd/runus/application/member/MemberWithdrawService.java index 2d54536c..1946747c 100644 --- a/src/main/java/com/dnd/runus/application/member/MemberWithdrawService.java +++ b/src/main/java/com/dnd/runus/application/member/MemberWithdrawService.java @@ -44,11 +44,15 @@ public void deleteAllDataAboutMember(long memberId) { scaleAchievementRepository.deleteByMemberId(member.memberId()); socialProfileRepository.deleteByMemberId(member.memberId()); - // running_record 조회 + deleteRunningRecordAndRelatedData(member); + + memberRepository.deleteById(member.memberId()); + log.info("멤버 삭제 완료: memberId={}", member.memberId()); + } + + private void deleteRunningRecordAndRelatedData(Member member) { List runningRecords = runningRecordRepository.findByMember(member); if (runningRecords.isEmpty()) { - // running_record가 없으면 멤버 삭제 후 리턴 - memberRepository.deleteById(member.memberId()); return; } @@ -63,11 +67,6 @@ public void deleteAllDataAboutMember(long memberId) { challengeAchievementRepository.deleteByIds(challengeAchievementIds); } - // running_record 삭제 runningRecordRepository.deleteByMemberId(member.memberId()); - - memberRepository.deleteById(member.memberId()); - - log.info("멤버 삭제 완료: memberId={}", member.memberId()); } } diff --git a/src/main/java/com/dnd/runus/application/member/event/SignupEvent.java b/src/main/java/com/dnd/runus/application/member/event/SignupEvent.java new file mode 100644 index 00000000..91294755 --- /dev/null +++ b/src/main/java/com/dnd/runus/application/member/event/SignupEvent.java @@ -0,0 +1,5 @@ +package com.dnd.runus.application.member.event; + +import com.dnd.runus.domain.member.Member; + +public record SignupEvent(Member member) {} diff --git a/src/main/java/com/dnd/runus/application/member/event/WithdrawEvent.java b/src/main/java/com/dnd/runus/application/member/event/WithdrawEvent.java new file mode 100644 index 00000000..fa299707 --- /dev/null +++ b/src/main/java/com/dnd/runus/application/member/event/WithdrawEvent.java @@ -0,0 +1,3 @@ +package com.dnd.runus.application.member.event; + +public record WithdrawEvent(long memberId) {} diff --git a/src/main/java/com/dnd/runus/application/oauth/OauthService.java b/src/main/java/com/dnd/runus/application/oauth/OauthService.java index 7c46dbf8..4e1587e6 100644 --- a/src/main/java/com/dnd/runus/application/oauth/OauthService.java +++ b/src/main/java/com/dnd/runus/application/oauth/OauthService.java @@ -1,17 +1,14 @@ package com.dnd.runus.application.oauth; -import com.dnd.runus.application.member.MemberWithdrawService; +import com.dnd.runus.application.member.event.SignupEvent; +import com.dnd.runus.application.member.event.WithdrawEvent; import com.dnd.runus.auth.exception.AuthException; import com.dnd.runus.auth.oidc.provider.OidcProvider; import com.dnd.runus.auth.oidc.provider.OidcProviderRegistry; import com.dnd.runus.auth.token.TokenProviderModule; import com.dnd.runus.auth.token.dto.AuthTokenDto; -import com.dnd.runus.domain.member.*; -import com.dnd.runus.global.constant.MemberRole; +import com.dnd.runus.domain.member.SocialProfile; import com.dnd.runus.global.constant.SocialType; -import com.dnd.runus.global.event.AfterTransactionEvent; -import com.dnd.runus.global.exception.BusinessException; -import com.dnd.runus.global.exception.NotFoundException; import com.dnd.runus.global.exception.type.ErrorType; import com.dnd.runus.presentation.v1.oauth.dto.request.SignInRequest; import com.dnd.runus.presentation.v1.oauth.dto.request.SignUpRequest; @@ -23,7 +20,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; @Slf4j @Service @@ -33,73 +29,56 @@ public class OauthService { private final OidcProviderRegistry oidcProviderRegistry; private final TokenProviderModule tokenProviderModule; - private final MemberRepository memberRepository; - private final SocialProfileRepository socialProfileRepository; - private final MemberLevelRepository memberLevelRepository; - - private final MemberWithdrawService memberWithdrawService; + private final SocialProfileService socialProfileService; private final ApplicationEventPublisher eventPublisher; - @Transactional public SignResponse signIn(SignInRequest request) { OidcProvider oidcProvider = oidcProviderRegistry.getOidcProviderBy(request.socialType()); Claims claim = oidcProvider.getClaimsBy(request.idToken()); String oauthId = claim.getSubject(); String email = extractAndValidateEmail(claim, request.socialType()); - SocialProfile socialProfile = socialProfileRepository - .findBySocialTypeAndOauthId(request.socialType(), oauthId) - .orElseThrow( - () -> new BusinessException(ErrorType.USER_NOT_FOUND, "socialType: " + request.socialType())); + SocialProfile socialProfile = socialProfileService.findOrThrow(request.socialType(), oauthId, email); - updateEmailIfChanged(socialProfile, email); AuthTokenDto tokenDto = tokenProviderModule.generate( String.valueOf(socialProfile.member().memberId())); return SignResponse.from(socialProfile.member().nickname(), socialProfile.oauthEmail(), tokenDto); } - @Transactional public SignResponse signUp(SignUpRequest request) { OidcProvider oidcProvider = oidcProviderRegistry.getOidcProviderBy(request.socialType()); Claims claim = oidcProvider.getClaimsBy(request.idToken()); String oauthId = claim.getSubject(); String email = extractAndValidateEmail(claim, request.socialType()); - // 기존 사용자 없을 경우 insert - SocialProfile socialProfile = socialProfileRepository - .findBySocialTypeAndOauthId(request.socialType(), oauthId) - .orElseGet(() -> createMember(oauthId, email, request.socialType(), request.nickname())); + SocialProfile socialProfile = + socialProfileService.findOrCreate(request.socialType(), oauthId, email, request.nickname()); - updateEmailIfChanged(socialProfile, email); AuthTokenDto tokenDto = tokenProviderModule.generate( String.valueOf(socialProfile.member().memberId())); + + eventPublisher.publishEvent(new SignupEvent(socialProfile.member())); + return SignResponse.from(socialProfile.member().nickname(), socialProfile.oauthEmail(), tokenDto); } - @Transactional(readOnly = true) public boolean revokeOauth(long memberId, WithdrawRequest request) { - - memberRepository.findById(memberId).orElseThrow(() -> new NotFoundException(Member.class, memberId)); - OidcProvider oidcProvider = oidcProviderRegistry.getOidcProviderBy(request.socialType()); String oauthId = oidcProvider.getClaimsBy(request.idToken()).getSubject(); - socialProfileRepository - .findBySocialTypeAndOauthId(request.socialType(), oauthId) - .filter(profile -> profile.member().memberId() == memberId) - .orElseThrow(() -> new AuthException( - ErrorType.INVALID_CREDENTIALS, - String.format( - "socialType: %s, oauthId: %s, memberId: %s", request.socialType(), oauthId, memberId))); + if (!socialProfileService.isSocialMemberExists(request.socialType(), oauthId, memberId)) { + String message = + String.format("socialType: %s, oauthId: %s, memberId: %s", request.socialType(), oauthId, memberId); + throw new AuthException(ErrorType.INVALID_CREDENTIALS, message); + } try { String accessToken = oidcProvider.getAccessToken(request.authorizationCode()); oidcProvider.revoke(accessToken); log.info("토큰 revoke 성공. memberId: {}, socialType: {}", memberId, request.socialType()); - AfterTransactionEvent withDrawEvent = () -> memberWithdrawService.deleteAllDataAboutMember(memberId); - eventPublisher.publishEvent(withDrawEvent); + eventPublisher.publishEvent(new WithdrawEvent(memberId)); return true; } catch (Exception e) { @@ -108,20 +87,6 @@ public boolean revokeOauth(long memberId, WithdrawRequest request) { } } - private SocialProfile createMember(String oauthId, String email, SocialType socialType, String nickname) { - Member member = memberRepository.save(new Member(MemberRole.USER, nickname)); - - // default level 설정 - memberLevelRepository.save(new MemberLevel(member)); - - return socialProfileRepository.save(SocialProfile.builder() - .member(member) - .socialType(socialType) - .oauthId(oauthId) - .oauthEmail(email) - .build()); - } - private String extractAndValidateEmail(Claims claim, SocialType socialType) { String email = (String) claim.get("email"); if (StringUtils.isBlank(email)) { @@ -130,10 +95,4 @@ private String extractAndValidateEmail(Claims claim, SocialType socialType) { } return email; } - - private void updateEmailIfChanged(SocialProfile socialProfile, String email) { - if (!email.equals(socialProfile.oauthEmail())) { - socialProfileRepository.updateOauthEmail(socialProfile.socialProfileId(), email); - } - } } diff --git a/src/main/java/com/dnd/runus/application/oauth/SocialProfileService.java b/src/main/java/com/dnd/runus/application/oauth/SocialProfileService.java new file mode 100644 index 00000000..9e0ffcb7 --- /dev/null +++ b/src/main/java/com/dnd/runus/application/oauth/SocialProfileService.java @@ -0,0 +1,65 @@ +package com.dnd.runus.application.oauth; + +import com.dnd.runus.domain.member.Member; +import com.dnd.runus.domain.member.MemberRepository; +import com.dnd.runus.domain.member.SocialProfile; +import com.dnd.runus.domain.member.SocialProfileRepository; +import com.dnd.runus.global.constant.MemberRole; +import com.dnd.runus.global.constant.SocialType; +import com.dnd.runus.global.exception.NotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class SocialProfileService { + + private final SocialProfileRepository socialProfileRepository; + private final MemberRepository memberRepository; + + @Transactional(readOnly = true) + public boolean isSocialMemberExists(SocialType socialType, String oauthId, long memberId) { + return socialProfileRepository + .findBySocialTypeAndOauthId(socialType, oauthId) + .filter(profile -> profile.member().memberId() == memberId) + .isPresent(); + } + + @Transactional + public SocialProfile findOrThrow(SocialType socialType, String oauthId, String email) { + SocialProfile socialProfile = socialProfileRepository + .findBySocialTypeAndOauthId(socialType, oauthId) + .orElseThrow(() -> new NotFoundException(SocialProfile.class, oauthId)); + + updateEmailIfChanged(socialProfile, email); + return socialProfile; + } + + @Transactional + public SocialProfile findOrCreate(SocialType socialType, String oauthId, String email, String nickname) { + Member member = memberRepository.save(new Member(MemberRole.USER, nickname)); + + SocialProfile socialProfile = socialProfileRepository + .findBySocialTypeAndOauthId(socialType, oauthId) + .orElseGet(() -> createSocialProfile(member, socialType, oauthId, email)); + + updateEmailIfChanged(socialProfile, email); + return socialProfile; + } + + private SocialProfile createSocialProfile(Member member, SocialType socialType, String oauthId, String email) { + return socialProfileRepository.save(SocialProfile.builder() + .member(member) + .socialType(socialType) + .oauthId(oauthId) + .oauthEmail(email) + .build()); + } + + private void updateEmailIfChanged(SocialProfile socialProfile, String email) { + if (!email.equals(socialProfile.oauthEmail())) { + socialProfileRepository.updateOauthEmail(socialProfile.socialProfileId(), email); + } + } +} diff --git a/src/main/java/com/dnd/runus/infrastructure/persistence/jpa/member/JpaSocialProfileRepository.java b/src/main/java/com/dnd/runus/infrastructure/persistence/jpa/member/JpaSocialProfileRepository.java index 8c0904fb..cb440b56 100644 --- a/src/main/java/com/dnd/runus/infrastructure/persistence/jpa/member/JpaSocialProfileRepository.java +++ b/src/main/java/com/dnd/runus/infrastructure/persistence/jpa/member/JpaSocialProfileRepository.java @@ -2,12 +2,14 @@ import com.dnd.runus.global.constant.SocialType; import com.dnd.runus.infrastructure.persistence.jpa.member.entity.SocialProfileEntity; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface JpaSocialProfileRepository extends JpaRepository { + @EntityGraph(attributePaths = {"member"}) Optional findBySocialTypeAndOauthId(SocialType socialType, String oauthId); void deleteByMemberId(long memberId); diff --git a/src/test/java/com/dnd/runus/application/oauth/OauthServiceTest.java b/src/test/java/com/dnd/runus/application/oauth/OauthServiceTest.java index 5331198a..50a9d8bc 100644 --- a/src/test/java/com/dnd/runus/application/oauth/OauthServiceTest.java +++ b/src/test/java/com/dnd/runus/application/oauth/OauthServiceTest.java @@ -5,11 +5,11 @@ import com.dnd.runus.auth.oidc.provider.OidcProviderRegistry; import com.dnd.runus.auth.token.TokenProviderModule; import com.dnd.runus.auth.token.dto.AuthTokenDto; -import com.dnd.runus.domain.member.*; +import com.dnd.runus.domain.member.Member; +import com.dnd.runus.domain.member.SocialProfile; import com.dnd.runus.global.constant.MemberRole; import com.dnd.runus.global.constant.SocialType; import com.dnd.runus.global.exception.BusinessException; -import com.dnd.runus.global.exception.NotFoundException; import com.dnd.runus.global.exception.type.ErrorType; import com.dnd.runus.presentation.v1.oauth.dto.request.SignInRequest; import com.dnd.runus.presentation.v1.oauth.dto.request.SignUpRequest; @@ -27,7 +27,6 @@ import org.springframework.context.ApplicationEventPublisher; import java.time.OffsetDateTime; -import java.util.Optional; import java.util.concurrent.CountDownLatch; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -46,17 +45,11 @@ class OauthServiceTest { private OidcProvider oidcProvider; @Mock - private SocialProfileRepository socialProfileRepository; - - @Mock - private MemberRepository memberRepository; + private SocialProfileService socialProfileService; @Mock private TokenProviderModule tokenProviderModule; - @Mock - private MemberLevelRepository memberLevelRepository; - @Mock private ApplicationEventPublisher eventPublisher; @@ -98,8 +91,8 @@ void socialProfile_exist_then_signIn_success() { given(oidcProvider.getClaimsBy(idToken)).willReturn(claims); given(claims.getSubject()).willReturn(oauthId); given(claims.get("email")).willReturn(email); - given(socialProfileRepository.findBySocialTypeAndOauthId(socialType, oauthId)) - .willReturn(Optional.of(new SocialProfile(1L, member, socialType, oauthId, email))); + given(socialProfileService.findOrThrow(socialType, oauthId, email)) + .willReturn(new SocialProfile(1L, member, socialType, oauthId, email)); AuthTokenDto tokenDto = new AuthTokenDto("access-token", "refresh-token", "bearer"); given(tokenProviderModule.generate(String.valueOf(member.memberId()))) .willReturn(tokenDto); @@ -123,8 +116,8 @@ void socialProfile_not_exist_then_signIn_fail() { given(oidcProvider.getClaimsBy(idToken)).willReturn(claims); given(claims.getSubject()).willReturn(oauthId); given(claims.get("email")).willReturn(email); - given(socialProfileRepository.findBySocialTypeAndOauthId(socialType, oauthId)) - .willReturn(Optional.empty()); + given(socialProfileService.findOrThrow(socialType, oauthId, email)) + .willThrow(new BusinessException(ErrorType.USER_NOT_FOUND)); // when, then BusinessException exception = assertThrows(BusinessException.class, () -> oauthService.signIn(request)); @@ -141,8 +134,8 @@ void socialProfile_not_exist_then_signUp_success() { given(claims.getSubject()).willReturn(oauthId); given(claims.get("email")).willReturn(email); SocialProfile socialProfile = new SocialProfile(1L, member, socialType, oauthId, email); - given(socialProfileRepository.findBySocialTypeAndOauthId(socialType, oauthId)) - .willReturn(Optional.of(socialProfile)); + given(socialProfileService.findOrCreate(socialType, oauthId, email, request.nickname())) + .willReturn(socialProfile); AuthTokenDto tokenDto = new AuthTokenDto("access-token", "refresh-token", "bearer"); given(tokenProviderModule.generate(String.valueOf(member.memberId()))) .willReturn(tokenDto); @@ -158,7 +151,7 @@ void socialProfile_not_exist_then_signUp_success() { } @Test - @DisplayName("sign-up 시 socialProfile이 없다면 socialProfileRepository.save() 호출") + @DisplayName("sign-up 시 socialProfile이 없다면 socialProfile을 생성") void socialProfile_not_exist_then_signUp_save_social_profile() { // given SignUpRequest request = new SignUpRequest(socialType, idToken, "nickname"); @@ -166,13 +159,13 @@ void socialProfile_not_exist_then_signUp_save_social_profile() { given(oidcProvider.getClaimsBy(idToken)).willReturn(claims); given(claims.getSubject()).willReturn(oauthId); given(claims.get("email")).willReturn(email); - given(socialProfileRepository.findBySocialTypeAndOauthId(socialType, oauthId)) - .willReturn(Optional.empty()); Member newMember = new Member(2L, MemberRole.USER, request.nickname(), OffsetDateTime.now(), OffsetDateTime.now()); SocialProfile socialProfile = new SocialProfile(1L, newMember, socialType, oauthId, email); - given(socialProfileRepository.save(any(SocialProfile.class))).willReturn(socialProfile); + + given(socialProfileService.findOrCreate(socialType, oauthId, email, request.nickname())) + .willReturn(socialProfile); AuthTokenDto tokenDto = new AuthTokenDto("access-token", "refresh-token", "bearer"); given(tokenProviderModule.generate(String.valueOf(newMember.memberId()))) @@ -187,7 +180,7 @@ void socialProfile_not_exist_then_signUp_save_social_profile() { assertEquals(email, signResponse.email()); assertEquals(tokenDto.accessToken(), signResponse.accessToken()); - then(socialProfileRepository).should().save(any(SocialProfile.class)); + then(socialProfileService).should().findOrCreate(socialType, oauthId, email, request.nickname()); } @DisplayName("소셜 로그인 연동 해제: 성공") @@ -196,14 +189,12 @@ void revokeOauth_Success() throws InterruptedException { // given WithdrawRequest request = new WithdrawRequest(socialType, authorizationCode, idToken); - SocialProfile socialProfileMock = new SocialProfile(1L, member, request.socialType(), oauthId, email); - given(memberRepository.findById(member.memberId())).willReturn(Optional.of(member)); given(oidcProviderRegistry.getOidcProviderBy(request.socialType())).willReturn(oidcProvider); given(oidcProvider.getClaimsBy(request.idToken())).willReturn(claims); given(claims.getSubject()).willReturn(oauthId); - given(socialProfileRepository.findBySocialTypeAndOauthId(request.socialType(), oauthId)) - .willReturn(Optional.of(socialProfileMock)); + given(socialProfileService.isSocialMemberExists(request.socialType(), oauthId, member.memberId())) + .willReturn(true); CountDownLatch latch = new CountDownLatch(2); @@ -228,28 +219,17 @@ void revokeOauth_Success() throws InterruptedException { assertTrue(completed); } - @DisplayName("소셜 로그인 연동 해제: member_id가 없을 경우 NotFoundException을 발생한다.") - @Test - void revokeOauth_NotFound_MemberID() { - // given - WithdrawRequest request = new WithdrawRequest(socialType, authorizationCode, idToken); - given(memberRepository.findById(member.memberId())).willReturn(Optional.empty()); - - // when, then - assertThrows(NotFoundException.class, () -> oauthService.revokeOauth(member.memberId(), request)); - } - @DisplayName("소셜 로그인 연동 해제: oauthId와 socialType에 해당하는 socialProfile 없을 경우 AuthException을 발생한다.") @Test void revokeOauth_NotFound_SocialProfile() { // given WithdrawRequest request = new WithdrawRequest(socialType, authorizationCode, idToken); - given(memberRepository.findById(member.memberId())).willReturn(Optional.of(member)); + given(oidcProviderRegistry.getOidcProviderBy(request.socialType())).willReturn(oidcProvider); given(oidcProvider.getClaimsBy(request.idToken())).willReturn(claims); given(claims.getSubject()).willReturn(oauthId); - given(socialProfileRepository.findBySocialTypeAndOauthId(request.socialType(), oauthId)) - .willReturn(Optional.empty()); + given(socialProfileService.isSocialMemberExists(request.socialType(), oauthId, member.memberId())) + .willReturn(false); // when, then assertThrows(AuthException.class, () -> oauthService.revokeOauth(member.memberId(), request)); @@ -260,19 +240,12 @@ void revokeOauth_NotFound_SocialProfile() { void revokeOauth_MissMatch_socialProfileAndMemberId() { // given WithdrawRequest request = new WithdrawRequest(socialType, authorizationCode, idToken); - SocialProfile socialProfileMock = new SocialProfile( - 1L, - new Member(2L, MemberRole.USER, "nickname", OffsetDateTime.now(), OffsetDateTime.now()), - request.socialType(), - oauthId, - email); - - given(memberRepository.findById(member.memberId())).willReturn(Optional.of(member)); + given(oidcProviderRegistry.getOidcProviderBy(request.socialType())).willReturn(oidcProvider); given(oidcProvider.getClaimsBy(request.idToken())).willReturn(claims); given(claims.getSubject()).willReturn(oauthId); - given(socialProfileRepository.findBySocialTypeAndOauthId(request.socialType(), oauthId)) - .willReturn(Optional.of(socialProfileMock)); + given(socialProfileService.isSocialMemberExists(request.socialType(), oauthId, member.memberId())) + .willReturn(false); // when, then assertThrows(AuthException.class, () -> oauthService.revokeOauth(member.memberId(), request));