From a67899a23671f95b0f6c4f7660022794081bc8a0 Mon Sep 17 00:00:00 2001 From: myqewr Date: Tue, 24 Jun 2025 17:40:11 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor=20:=20=ED=9A=8C=EC=9B=90=20?= =?UTF-8?q?=EB=B3=B5=EA=B5=AC=EC=97=90=20=EB=94=B0=EB=A5=B8=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85=20=EC=A0=88=EC=B0=A8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95(#136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...deVerificationResponse_20250407231748.java | 13 ++ ...deVerificationResponse_20250622204707.java | 14 ++ ...deVerificationResponse_20250622204923.java | 14 ++ .../DeleteByEmailCommand_20250622213953.java | 1 + .../DeleteByEmailCommand_20250622213956.java | 12 + ...odeVerificationService_20250407231748.java | 35 +++ ...odeVerificationService_20250622204700.java | 43 ++++ ...odeVerificationService_20250622210129.java | 41 ++++ ...odeVerificationService_20250622210202.java | 43 ++++ ...uplicationCheckService_20250407231748.java | 20 ++ ...uplicationCheckService_20250622210504.java | 20 ++ ...neralUserSignupService_20250414190939.java | 67 ++++++ ...neralUserSignupService_20250622213609.java | 73 +++++++ ...neralUserSignupService_20250622213705.java | 73 +++++++ ...neralUserSignupService_20250622214029.java | 73 +++++++ ...neralUserSignupService_20250622214036.java | 74 +++++++ ...neralUserSignupService_20250622214043.java | 74 +++++++ ...neralUserSignupService_20250622214051.java | 74 +++++++ ...mailCodeVerificationVo_20250407231748.java | 12 + ...mailCodeVerificationVo_20250622204648.java | 17 ++ ...mailCodeVerificationVo_20250622204931.java | 17 ++ .../ftm/server/BaseTest_20250528010752.java | 196 +++++++++++++++++ .../ftm/server/BaseTest_20250622205652.java | 206 ++++++++++++++++++ .../ftm/server/BaseTest_20250622210207.java | 197 +++++++++++++++++ ...ilCodeVerificationTest_20250407231748.java | 89 ++++++++ ...ilCodeVerificationTest_20250622204717.java | 92 ++++++++ ...ilCodeVerificationTest_20250622205425.java | 92 ++++++++ ...ilCodeVerificationTest_20250622205721.java | 151 +++++++++++++ ...ilCodeVerificationTest_20250622210254.java | 160 ++++++++++++++ ...ilCodeVerificationTest_20250622211329.java | 134 ++++++++++++ ...ilCodeVerificationTest_20250622213651.java | 202 +++++++++++++++++ ...ilCodeVerificationTest_20250622213710.java | 205 +++++++++++++++++ .../EmailCodeVerificationResponse.java | 3 +- .../cache/LoadTrendingPostsTestAdapter.java | 87 ++++++++ .../user/UserDomainPersistenceAdapter.java | 22 ++ .../EmailVerificationLogsRepository.java | 7 + .../repository/UserRepository.java | 4 + .../command/user/DeleteByEmailCommand.java | 12 + .../user/DeleteUserByEmailCommand.java | 13 ++ .../in/user/UserHardDeleteByEmailUseCase.java | 10 + .../out/persistence/user/CheckUserPort.java | 4 + .../user/DeleteEmailVerificationLogPort.java | 9 + .../out/persistence/user/LoadUserPort.java | 3 + .../user/EmailCodeVerificationService.java | 10 +- .../user/EmailDuplicationCheckService.java | 2 +- .../user/GeneralUserSignupService.java | 19 +- .../user/UserHardDeleteByEmailService.java | 60 +++++ .../vo/user/EmailCodeVerificationVo.java | 7 +- src/test/java/com/ftm/server/BaseTest.java | 1 + .../user/EmailCodeVerificationTest.java | 32 ++- 50 files changed, 2833 insertions(+), 6 deletions(-) create mode 100644 .history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250407231748.java create mode 100644 .history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204707.java create mode 100644 .history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204923.java create mode 100644 .history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213953.java create mode 100644 .history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213956.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250407231748.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622204700.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210129.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210202.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250407231748.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250622210504.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250414190939.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213609.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213705.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214029.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214036.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214043.java create mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214051.java create mode 100644 .history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250407231748.java create mode 100644 .history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204648.java create mode 100644 .history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204931.java create mode 100644 .history/src/test/java/com/ftm/server/BaseTest_20250528010752.java create mode 100644 .history/src/test/java/com/ftm/server/BaseTest_20250622205652.java create mode 100644 .history/src/test/java/com/ftm/server/BaseTest_20250622210207.java create mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250407231748.java create mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622204717.java create mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205425.java create mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205721.java create mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622210254.java create mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622211329.java create mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213651.java create mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213710.java create mode 100644 src/main/java/com/ftm/server/adapter/out/cache/LoadTrendingPostsTestAdapter.java create mode 100644 src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand.java create mode 100644 src/main/java/com/ftm/server/application/command/user/DeleteUserByEmailCommand.java create mode 100644 src/main/java/com/ftm/server/application/port/in/user/UserHardDeleteByEmailUseCase.java create mode 100644 src/main/java/com/ftm/server/application/port/out/persistence/user/DeleteEmailVerificationLogPort.java create mode 100644 src/main/java/com/ftm/server/application/service/user/UserHardDeleteByEmailService.java diff --git a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250407231748.java b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250407231748.java new file mode 100644 index 0000000..034acd6 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250407231748.java @@ -0,0 +1,13 @@ +package com.ftm.server.adapter.in.web.user.dto.response; + +import com.ftm.server.application.vo.user.EmailCodeVerificationVo; +import lombok.Data; + +@Data +public class EmailCodeVerificationResponse { + private final Boolean isVerified; + + public static EmailCodeVerificationResponse from(EmailCodeVerificationVo vo) { + return new EmailCodeVerificationResponse(vo.getIsVerified()); + } +} diff --git a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204707.java b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204707.java new file mode 100644 index 0000000..26fe9de --- /dev/null +++ b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204707.java @@ -0,0 +1,14 @@ +package com.ftm.server.adapter.in.web.user.dto.response; + +import com.ftm.server.application.vo.user.EmailCodeVerificationVo; +import lombok.Data; + +@Data +public class EmailCodeVerificationResponse { + private final Boolean isVerified; + private final Boolean isRecoverable; + + public static EmailCodeVerificationResponse from(EmailCodeVerificationVo vo) { + return new EmailCodeVerificationResponse(vo.getIsVerified(), vo.getIsRecoverable()); + } +} diff --git a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204923.java b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204923.java new file mode 100644 index 0000000..26fe9de --- /dev/null +++ b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204923.java @@ -0,0 +1,14 @@ +package com.ftm.server.adapter.in.web.user.dto.response; + +import com.ftm.server.application.vo.user.EmailCodeVerificationVo; +import lombok.Data; + +@Data +public class EmailCodeVerificationResponse { + private final Boolean isVerified; + private final Boolean isRecoverable; + + public static EmailCodeVerificationResponse from(EmailCodeVerificationVo vo) { + return new EmailCodeVerificationResponse(vo.getIsVerified(), vo.getIsRecoverable()); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213953.java b/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213953.java new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213953.java @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213956.java b/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213956.java new file mode 100644 index 0000000..a1ddbe4 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213956.java @@ -0,0 +1,12 @@ +package com.ftm.server.application.command.user; + +import lombok.Data; + +@Data +public class DeleteByEmailCommand { + private final String email; + + public static DeleteByEmailCommand of(String email) { + return new DeleteByEmailCommand(email); + } +} \ No newline at end of file diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250407231748.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250407231748.java new file mode 100644 index 0000000..ab0c6f9 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250407231748.java @@ -0,0 +1,35 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; +import com.ftm.server.application.query.EmailCodeVerificationQuery; +import com.ftm.server.application.vo.user.EmailCodeVerificationVo; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class EmailCodeVerificationService implements EmailCodeVerificationUseCase { + + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; + + @Override + @Transactional + public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { + + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmailAndCode(query); + + if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 + return EmailCodeVerificationVo.of(false); + } + emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 + updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); + return EmailCodeVerificationVo.of(true); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622204700.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622204700.java new file mode 100644 index 0000000..7aa9f56 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622204700.java @@ -0,0 +1,43 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; +import com.ftm.server.application.query.EmailCodeVerificationQuery; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.application.vo.user.EmailCodeVerificationVo; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class EmailCodeVerificationService implements EmailCodeVerificationUseCase { + + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; + private final CheckUserPort checkUserPort; + + @Override + @Transactional + public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { + + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmailAndCode(query); + + if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 + return EmailCodeVerificationVo.of(false); + } + + emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 + updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); + + // 해당 이메일의 계정 상태 확인 (soft delete 여부) + Boolean isRecoverable = !checkUserPort.checksNotDeletedUserByEmail(FindByEmailQuery.of(query.getEmail())); + + return EmailCodeVerificationVo.of(true, isRecoverable); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210129.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210129.java new file mode 100644 index 0000000..6da83c7 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210129.java @@ -0,0 +1,41 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; +import com.ftm.server.application.query.EmailCodeVerificationQuery; +import com.ftm.server.application.vo.user.EmailCodeVerificationVo; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class EmailCodeVerificationService implements EmailCodeVerificationUseCase { + + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; + private final CheckUserPort checkUserPort; + + @Override + @Transactional + public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { + + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmailAndCode(query); + + if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 + return EmailCodeVerificationVo.of(false); + } + + emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 + updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); + + // 해당 이메일의 계정 상태 확인 (soft delete 여부) + Boolean isRecoverable = checkUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(query.getEmail())); + + return EmailCodeVerificationVo.of(true, isRecoverable); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210202.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210202.java new file mode 100644 index 0000000..464378e --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210202.java @@ -0,0 +1,43 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; +import com.ftm.server.application.query.EmailCodeVerificationQuery; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.application.vo.user.EmailCodeVerificationVo; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class EmailCodeVerificationService implements EmailCodeVerificationUseCase { + + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; + private final CheckUserPort checkUserPort; + + @Override + @Transactional + public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { + + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmailAndCode(query); + + if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 + return EmailCodeVerificationVo.of(false); + } + + emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 + updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); + + // 해당 이메일의 계정 상태 확인 (soft delete 여부) + Boolean isRecoverable = checkUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(query.getEmail())); + + return EmailCodeVerificationVo.of(true, isRecoverable); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250407231748.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250407231748.java new file mode 100644 index 0000000..ba96dc9 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250407231748.java @@ -0,0 +1,20 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.application.port.in.user.EmailDuplicationCheckUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.application.vo.user.EmailDuplicationVo; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class EmailDuplicationCheckService implements EmailDuplicationCheckUseCase { + + private final CheckUserPort checkUserPort; + + @Override + public EmailDuplicationVo execute(FindByEmailQuery query) { + return EmailDuplicationVo.of(checkUserPort.checksUserByEmail(query)); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250622210504.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250622210504.java new file mode 100644 index 0000000..d1b7fd5 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250622210504.java @@ -0,0 +1,20 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.application.port.in.user.EmailDuplicationCheckUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.application.vo.user.EmailDuplicationVo; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class EmailDuplicationCheckService implements EmailDuplicationCheckUseCase { + + private final CheckUserPort checkUserPort; + + @Override + public EmailDuplicationVo execute(FindByEmailQuery query) { + return EmailDuplicationVo.of(checkUserPort.checksNotDeletedUserByEmail(query)); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250414190939.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250414190939.java new file mode 100644 index 0000000..a3f77ef --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250414190939.java @@ -0,0 +1,67 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.command.user.GeneralUserSignupCommand; +import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import com.ftm.server.common.utils.RandomNickNameCreator; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GeneralUserSignupService implements GeneralUserSignupUseCase { + + // service + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final CheckUserPort checksUserPort; + private final SaveUserPort saveUserPort; + private final SaveUserImagePort saveUserImagePort; + + // gateway + private final SecurityAuthenticationPort authenticationPort; + + @Transactional + @Override + public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { + String email = command.getEmail(); + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( + FindByEmailQuery.of(email)); + + if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 + throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); + } + + if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. + throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); + } + + String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 + + GeneralUserCreationCommand convertedCommand = + GeneralUserCreationCommand.of( + command.getEmail(), + authenticationPort.passwordEncode(command.getPassword()), + nickname, + command.getAge(), + command.getHashtags()); + + User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); + return GeneralUserSignupResponse.of(user.getId()); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213609.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213609.java new file mode 100644 index 0000000..19fc9c5 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213609.java @@ -0,0 +1,73 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.command.user.GeneralUserSignupCommand; +import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import com.ftm.server.common.utils.RandomNickNameCreator; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GeneralUserSignupService implements GeneralUserSignupUseCase { + + // service + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; + private final CheckUserPort checksUserPort; + private final SaveUserPort saveUserPort; + private final SaveUserImagePort saveUserImagePort; + + // gateway + private final SecurityAuthenticationPort authenticationPort; + + @Transactional + @Override + public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { + String email = command.getEmail(); + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( + FindByEmailQuery.of(email)); + + if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 + throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); + } + + if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. + throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); + } + + String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 + + GeneralUserCreationCommand convertedCommand = + GeneralUserCreationCommand.of( + command.getEmail(), + authenticationPort.passwordEncode(command.getPassword()), + nickname, + command.getAge(), + command.getHashtags()); + + User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); + + // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 + deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(FindByEmailQuery.of(email)); + + return GeneralUserSignupResponse.of(user.getId()); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213705.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213705.java new file mode 100644 index 0000000..19fc9c5 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213705.java @@ -0,0 +1,73 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.command.user.GeneralUserSignupCommand; +import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import com.ftm.server.common.utils.RandomNickNameCreator; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GeneralUserSignupService implements GeneralUserSignupUseCase { + + // service + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; + private final CheckUserPort checksUserPort; + private final SaveUserPort saveUserPort; + private final SaveUserImagePort saveUserImagePort; + + // gateway + private final SecurityAuthenticationPort authenticationPort; + + @Transactional + @Override + public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { + String email = command.getEmail(); + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( + FindByEmailQuery.of(email)); + + if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 + throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); + } + + if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. + throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); + } + + String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 + + GeneralUserCreationCommand convertedCommand = + GeneralUserCreationCommand.of( + command.getEmail(), + authenticationPort.passwordEncode(command.getPassword()), + nickname, + command.getAge(), + command.getHashtags()); + + User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); + + // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 + deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(FindByEmailQuery.of(email)); + + return GeneralUserSignupResponse.of(user.getId()); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214029.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214029.java new file mode 100644 index 0000000..19fc9c5 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214029.java @@ -0,0 +1,73 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.command.user.GeneralUserSignupCommand; +import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import com.ftm.server.common.utils.RandomNickNameCreator; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GeneralUserSignupService implements GeneralUserSignupUseCase { + + // service + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; + private final CheckUserPort checksUserPort; + private final SaveUserPort saveUserPort; + private final SaveUserImagePort saveUserImagePort; + + // gateway + private final SecurityAuthenticationPort authenticationPort; + + @Transactional + @Override + public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { + String email = command.getEmail(); + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( + FindByEmailQuery.of(email)); + + if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 + throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); + } + + if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. + throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); + } + + String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 + + GeneralUserCreationCommand convertedCommand = + GeneralUserCreationCommand.of( + command.getEmail(), + authenticationPort.passwordEncode(command.getPassword()), + nickname, + command.getAge(), + command.getHashtags()); + + User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); + + // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 + deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(FindByEmailQuery.of(email)); + + return GeneralUserSignupResponse.of(user.getId()); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214036.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214036.java new file mode 100644 index 0000000..a49ae03 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214036.java @@ -0,0 +1,74 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; +import com.ftm.server.application.command.user.DeleteByEmailCommand; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.command.user.GeneralUserSignupCommand; +import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import com.ftm.server.common.utils.RandomNickNameCreator; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GeneralUserSignupService implements GeneralUserSignupUseCase { + + // service + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; + private final CheckUserPort checksUserPort; + private final SaveUserPort saveUserPort; + private final SaveUserImagePort saveUserImagePort; + + // gateway + private final SecurityAuthenticationPort authenticationPort; + + @Transactional + @Override + public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { + String email = command.getEmail(); + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( + FindByEmailQuery.of(email)); + + if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 + throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); + } + + if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. + throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); + } + + String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 + + GeneralUserCreationCommand convertedCommand = + GeneralUserCreationCommand.of( + command.getEmail(), + authenticationPort.passwordEncode(command.getPassword()), + nickname, + command.getAge(), + command.getHashtags()); + + User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); + + // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 + deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(FindByEmailQuery.of(email)); + + return GeneralUserSignupResponse.of(user.getId()); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214043.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214043.java new file mode 100644 index 0000000..5edb0a1 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214043.java @@ -0,0 +1,74 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; +import com.ftm.server.application.command.user.DeleteByEmailCommand; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.command.user.GeneralUserSignupCommand; +import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import com.ftm.server.common.utils.RandomNickNameCreator; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GeneralUserSignupService implements GeneralUserSignupUseCase { + + // service + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; + private final CheckUserPort checksUserPort; + private final SaveUserPort saveUserPort; + private final SaveUserImagePort saveUserImagePort; + + // gateway + private final SecurityAuthenticationPort authenticationPort; + + @Transactional + @Override + public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { + String email = command.getEmail(); + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( + FindByEmailQuery.of(email)); + + if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 + throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); + } + + if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. + throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); + } + + String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 + + GeneralUserCreationCommand convertedCommand = + GeneralUserCreationCommand.of( + command.getEmail(), + authenticationPort.passwordEncode(command.getPassword()), + nickname, + command.getAge(), + command.getHashtags()); + + User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); + + // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 + deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(DeleteByEmailCommand.of(email)); + + return GeneralUserSignupResponse.of(user.getId()); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214051.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214051.java new file mode 100644 index 0000000..5edb0a1 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214051.java @@ -0,0 +1,74 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; +import com.ftm.server.application.command.user.DeleteByEmailCommand; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.command.user.GeneralUserSignupCommand; +import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.common.exception.CustomException; +import com.ftm.server.common.response.enums.ErrorResponseCode; +import com.ftm.server.common.utils.RandomNickNameCreator; +import com.ftm.server.domain.entity.EmailVerificationLogs; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import jakarta.transaction.Transactional; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GeneralUserSignupService implements GeneralUserSignupUseCase { + + // service + private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; + private final CheckUserPort checksUserPort; + private final SaveUserPort saveUserPort; + private final SaveUserImagePort saveUserImagePort; + + // gateway + private final SecurityAuthenticationPort authenticationPort; + + @Transactional + @Override + public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { + String email = command.getEmail(); + Optional emailVerificationLogs = + loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( + FindByEmailQuery.of(email)); + + if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 + throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); + } + + if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. + throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); + } + + String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 + + GeneralUserCreationCommand convertedCommand = + GeneralUserCreationCommand.of( + command.getEmail(), + authenticationPort.passwordEncode(command.getPassword()), + nickname, + command.getAge(), + command.getHashtags()); + + User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); + + // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 + deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(DeleteByEmailCommand.of(email)); + + return GeneralUserSignupResponse.of(user.getId()); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250407231748.java b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250407231748.java new file mode 100644 index 0000000..022e946 --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250407231748.java @@ -0,0 +1,12 @@ +package com.ftm.server.application.vo.user; + +import lombok.Data; + +@Data +public class EmailCodeVerificationVo { + private final Boolean isVerified; + + public static EmailCodeVerificationVo of(Boolean isVerified) { + return new EmailCodeVerificationVo(isVerified); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204648.java b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204648.java new file mode 100644 index 0000000..d7988fd --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204648.java @@ -0,0 +1,17 @@ +package com.ftm.server.application.vo.user; + +import lombok.Data; + +@Data +public class EmailCodeVerificationVo { + private final Boolean isVerified; + private final Boolean isRecoverable; // 계정 복구 가능 여부 (soft delete 상태인지) + + public static EmailCodeVerificationVo of(Boolean isVerified) { + return new EmailCodeVerificationVo(isVerified, false); + } + + public static EmailCodeVerificationVo of(Boolean isVerified, Boolean isRecoverable) { + return new EmailCodeVerificationVo(isVerified, isRecoverable); + } +} diff --git a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204931.java b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204931.java new file mode 100644 index 0000000..d7988fd --- /dev/null +++ b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204931.java @@ -0,0 +1,17 @@ +package com.ftm.server.application.vo.user; + +import lombok.Data; + +@Data +public class EmailCodeVerificationVo { + private final Boolean isVerified; + private final Boolean isRecoverable; // 계정 복구 가능 여부 (soft delete 상태인지) + + public static EmailCodeVerificationVo of(Boolean isVerified) { + return new EmailCodeVerificationVo(isVerified, false); + } + + public static EmailCodeVerificationVo of(Boolean isVerified, Boolean isRecoverable) { + return new EmailCodeVerificationVo(isVerified, isRecoverable); + } +} diff --git a/.history/src/test/java/com/ftm/server/BaseTest_20250528010752.java b/.history/src/test/java/com/ftm/server/BaseTest_20250528010752.java new file mode 100644 index 0000000..6e4bfc4 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/BaseTest_20250528010752.java @@ -0,0 +1,196 @@ +package com.ftm.server; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyHeaders; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.port.out.persistence.auth.LoadUserForAuthPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import com.ftm.server.domain.enums.AgeGroup; +import com.ftm.server.domain.enums.HashTag; +import com.ftm.server.domain.enums.UserRole; +import com.ftm.server.infrastructure.security.UserPrincipal; +import groovy.util.logging.Slf4j; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.operation.preprocess.HeadersModifyingOperationPreprocessor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +@Slf4j +@AutoConfigureMockMvc +@AutoConfigureRestDocs +@SpringBootTest(classes = {ServerApplication.class}) +@ActiveProfiles("test") +@ExtendWith({RestDocumentationExtension.class}) +@AutoConfigureTestDatabase( + replace = AutoConfigureTestDatabase.Replace.NONE) // 테스트 시 내장된 인메모리 DB를 사용하지 않는다는 설정 +@TestPropertySource(locations = "file:.env") +public class BaseTest { + + @Autowired protected MockMvc mockMvc; + + protected final ObjectMapper mapper = new ObjectMapper(); + + @Autowired private SaveUserPort saveUserPort; + @Autowired private SaveUserImagePort saveUserImagePort; + @Autowired private LoadUserForAuthPort loadUserForAuthPort; + + @BeforeEach + void setup(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) { + this.mockMvc = + MockMvcBuilders.webAppContextSetup(context) + .apply(SecurityMockMvcConfigurers.springSecurity()) // secrutiy filter 적용 + .apply(documentationConfiguration(restDocumentation)) + .build(); + } + + // 블필요한 header 제거 함수 + protected HeadersModifyingOperationPreprocessor getModifiedHeader() { + return modifyHeaders() + .remove("X-Content-Type-Options") + .remove("X-XSS-Protection") + .remove("Cache-Control") + .remove("Pragma") + .remove("Expires") + .remove("Content-Length") + .remove("X-Frame-Options") + .remove("Vary"); + } + + // 사용자 생성 및 저장 + protected User createTestUser(String email, String password) { + String nickname = "test " + UUID.randomUUID(); + User user = + User.createGeneralUser( + GeneralUserCreationCommand.of( + email, + password, + nickname, + AgeGroup.FIFTIES, + List.of(HashTag.PERFUME))); + User testUser = saveUserPort.saveUser(user); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(testUser.getId())); + return testUser; + } + + protected MockHttpSession createUserAndLogin() { + return createUserAndLogin("test@gmail.com", "123456qwe!"); + } + + // test 사용자 생성 후 mock session 생성 + protected MockHttpSession createUserAndLogin(String email, String password) { + + // 사용자 생성 + User user = createTestUser(email, password); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } + + protected MockHttpSession login(String email) { + User user = loadUserForAuthPort.loadUserByEmail(FindByEmailQuery.of(email)).get(); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } + + public record SessionAndUser(MockHttpSession mockHttpSession, User user) {} + + // Session과 함께 User도 반환 + protected SessionAndUser createUserAndLoginAndReturnUser() { + return createUserAndLoginAndReturnUser("test@gmail.com", "123456qwe!"); + } + + protected SessionAndUser createUserAndLoginAndReturnUser(String email, String password) { + + // 사용자 생성 + User user = createTestUser(email, password); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return new SessionAndUser(session, user); + } + + protected MockHttpSession createAdminUserAndLogin() { + String email = "admin@gmail.com"; + String password = "admin1234!"; + String nickname = "admintest"; + + User admin = User.createAdminUser(email, password, nickname); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(admin), + null, + List.of(new SimpleGrantedAuthority("ROLE_" + UserRole.ADMIN.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } +} diff --git a/.history/src/test/java/com/ftm/server/BaseTest_20250622205652.java b/.history/src/test/java/com/ftm/server/BaseTest_20250622205652.java new file mode 100644 index 0000000..3943899 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/BaseTest_20250622205652.java @@ -0,0 +1,206 @@ +package com.ftm.server; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyHeaders; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.port.out.persistence.auth.LoadUserForAuthPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import com.ftm.server.domain.enums.AgeGroup; +import com.ftm.server.domain.enums.HashTag; +import com.ftm.server.domain.enums.UserRole; +import com.ftm.server.infrastructure.security.UserPrincipal; +import groovy.util.logging.Slf4j; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.operation.preprocess.HeadersModifyingOperationPreprocessor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +@Slf4j +@AutoConfigureMockMvc +@AutoConfigureRestDocs +@SpringBootTest(classes = {ServerApplication.class}) +@ActiveProfiles("test") +@ExtendWith({RestDocumentationExtension.class}) +@AutoConfigureTestDatabase( + replace = AutoConfigureTestDatabase.Replace.NONE) // 테스트 시 내장된 인메모리 DB를 사용하지 않는다는 설정 +@TestPropertySource(locations = "file:.env") +public class BaseTest { + + @Autowired protected MockMvc mockMvc; + + protected final ObjectMapper mapper = new ObjectMapper(); + + @Autowired private SaveUserPort saveUserPort; + @Autowired private SaveUserImagePort saveUserImagePort; + @Autowired private LoadUserForAuthPort loadUserForAuthPort; + + @BeforeEach + void setup(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) { + this.mockMvc = + MockMvcBuilders.webAppContextSetup(context) + .apply(SecurityMockMvcConfigurers.springSecurity()) // secrutiy filter 적용 + .apply(documentationConfiguration(restDocumentation)) + .build(); + } + + // 블필요한 header 제거 함수 + protected HeadersModifyingOperationPreprocessor getModifiedHeader() { + return modifyHeaders() + .remove("X-Content-Type-Options") + .remove("X-XSS-Protection") + .remove("Cache-Control") + .remove("Pragma") + .remove("Expires") + .remove("Content-Length") + .remove("X-Frame-Options") + .remove("Vary"); + } + + // 사용자 생성 및 저장 + protected User createTestUser(String email, String password) { + String nickname = "test " + UUID.randomUUID(); + User user = + User.createGeneralUser( + GeneralUserCreationCommand.of( + email, + password, + nickname, + AgeGroup.FIFTIES, + List.of(HashTag.PERFUME))); + User testUser = saveUserPort.saveUser(user); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(testUser.getId())); + return testUser; + } + + // 사용자를 soft delete 상태로 만드는 헬퍼 메서드 + protected User createSoftDeletedUser(String email, String password) { + User user = createTestUser(email, password); + user.updateIsDeleted(true); + user.updateDeletedAt(LocalDateTime.now()); + saveUserPort.saveUser(user); + return user; + } + + protected MockHttpSession createUserAndLogin() { + return createUserAndLogin("test@gmail.com", "123456qwe!"); + } + + // test 사용자 생성 후 mock session 생성 + protected MockHttpSession createUserAndLogin(String email, String password) { + + // 사용자 생성 + User user = createTestUser(email, password); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } + + protected MockHttpSession login(String email) { + User user = loadUserForAuthPort.loadUserByEmail(FindByEmailQuery.of(email)).get(); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } + + public record SessionAndUser(MockHttpSession mockHttpSession, User user) {} + + // Session과 함께 User도 반환 + protected SessionAndUser createUserAndLoginAndReturnUser() { + return createUserAndLoginAndReturnUser("test@gmail.com", "123456qwe!"); + } + + protected SessionAndUser createUserAndLoginAndReturnUser(String email, String password) { + + // 사용자 생성 + User user = createTestUser(email, password); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return new SessionAndUser(session, user); + } + + protected MockHttpSession createAdminUserAndLogin() { + String email = "admin@gmail.com"; + String password = "admin1234!"; + String nickname = "admintest"; + + User admin = User.createAdminUser(email, password, nickname); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(admin), + null, + List.of(new SimpleGrantedAuthority("ROLE_" + UserRole.ADMIN.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } +} diff --git a/.history/src/test/java/com/ftm/server/BaseTest_20250622210207.java b/.history/src/test/java/com/ftm/server/BaseTest_20250622210207.java new file mode 100644 index 0000000..72b2ff2 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/BaseTest_20250622210207.java @@ -0,0 +1,197 @@ +package com.ftm.server; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyHeaders; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ftm.server.application.command.user.GeneralUserCreationCommand; +import com.ftm.server.application.port.out.persistence.auth.LoadUserForAuthPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.entity.UserImage; +import com.ftm.server.domain.enums.AgeGroup; +import com.ftm.server.domain.enums.HashTag; +import com.ftm.server.domain.enums.UserRole; +import com.ftm.server.infrastructure.security.UserPrincipal; +import groovy.util.logging.Slf4j; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.operation.preprocess.HeadersModifyingOperationPreprocessor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +@Slf4j +@AutoConfigureMockMvc +@AutoConfigureRestDocs +@SpringBootTest(classes = {ServerApplication.class}) +@ActiveProfiles("test") +@ExtendWith({RestDocumentationExtension.class}) +@AutoConfigureTestDatabase( + replace = AutoConfigureTestDatabase.Replace.NONE) // 테스트 시 내장된 인메모리 DB를 사용하지 않는다는 설정 +@TestPropertySource(locations = "file:.env") +public class BaseTest { + + @Autowired protected MockMvc mockMvc; + + protected final ObjectMapper mapper = new ObjectMapper(); + + @Autowired private SaveUserPort saveUserPort; + @Autowired private SaveUserImagePort saveUserImagePort; + @Autowired private LoadUserForAuthPort loadUserForAuthPort; + + @BeforeEach + void setup(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) { + this.mockMvc = + MockMvcBuilders.webAppContextSetup(context) + .apply(SecurityMockMvcConfigurers.springSecurity()) // secrutiy filter 적용 + .apply(documentationConfiguration(restDocumentation)) + .build(); + } + + // 블필요한 header 제거 함수 + protected HeadersModifyingOperationPreprocessor getModifiedHeader() { + return modifyHeaders() + .remove("X-Content-Type-Options") + .remove("X-XSS-Protection") + .remove("Cache-Control") + .remove("Pragma") + .remove("Expires") + .remove("Content-Length") + .remove("X-Frame-Options") + .remove("Vary"); + } + + // 사용자 생성 및 저장 + protected User createTestUser(String email, String password) { + String nickname = "test " + UUID.randomUUID(); + User user = + User.createGeneralUser( + GeneralUserCreationCommand.of( + email, + password, + nickname, + AgeGroup.FIFTIES, + List.of(HashTag.PERFUME))); + User testUser = saveUserPort.saveUser(user); + saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(testUser.getId())); + return testUser; + } + + protected MockHttpSession createUserAndLogin() { + return createUserAndLogin("test@gmail.com", "123456qwe!"); + } + + // test 사용자 생성 후 mock session 생성 + protected MockHttpSession createUserAndLogin(String email, String password) { + + // 사용자 생성 + User user = createTestUser(email, password); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } + + protected MockHttpSession login(String email) { + User user = loadUserForAuthPort.loadUserByEmail(FindByEmailQuery.of(email)).get(); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } + + public record SessionAndUser(MockHttpSession mockHttpSession, User user) {} + + // Session과 함께 User도 반환 + protected SessionAndUser createUserAndLoginAndReturnUser() { + return createUserAndLoginAndReturnUser("test@gmail.com", "123456qwe!"); + } + + protected SessionAndUser createUserAndLoginAndReturnUser(String email, String password) { + + // 사용자 생성 + User user = createTestUser(email, password); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(user), + null, + List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return new SessionAndUser(session, user); + } + + protected MockHttpSession createAdminUserAndLogin() { + String email = "admin@gmail.com"; + String password = "admin1234!"; + String nickname = "admintest"; + + User admin = User.createAdminUser(email, password, nickname); + + // session 생성 + SecurityContext context = SecurityContextHolder.createEmptyContext(); + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + UserPrincipal.of(admin), + null, + List.of(new SimpleGrantedAuthority("ROLE_" + UserRole.ADMIN.name()))); + context.setAuthentication(auth); + + MockHttpSession session = new MockHttpSession(); + session.setAttribute( + HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); + + return session; + } +} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250407231748.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250407231748.java new file mode 100644 index 0000000..d8a08a2 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250407231748.java @@ -0,0 +1,89 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; +import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import jakarta.transaction.Transactional; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailCodeVerificationTest extends BaseTest { + + @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + + private final List requestFieldDescriptors = + List.of( + fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), + fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); + + private final List responseFieldDescriptors = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isVerified") + .type(JsonFieldType.BOOLEAN) + .description("검증 성공 여부")); + + private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") + .contentType(MediaType.APPLICATION_JSON) // request body content type + .content(mapper.writeValueAsString(request))); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "emailCodeVerification/" + identifier, + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint(), getModifiedHeader()), + responseFields(responseFieldDescriptors), + requestFields(requestFieldDescriptors), + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 인증 코드 검증 api") + .description("이메일 인증 코드를 검증하는 api입니다.") + .responseFields(responseFieldDescriptors) + .requestFields(requestFieldDescriptors) + .build())); + } + + @Test + @Transactional + void 이메일_인증코드_검증_성공() throws Exception { + + String email = "test@gmail.com"; + String code = "123456"; + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } +} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622204717.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622204717.java new file mode 100644 index 0000000..da02fc6 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622204717.java @@ -0,0 +1,92 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; +import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import jakarta.transaction.Transactional; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailCodeVerificationTest extends BaseTest { + + @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + + private final List requestFieldDescriptors = + List.of( + fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), + fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); + + private final List responseFieldDescriptors = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isVerified") + .type(JsonFieldType.BOOLEAN) + .description("검증 성공 여부"), + fieldWithPath("data.isRecoverable") + .type(JsonFieldType.BOOLEAN) + .description("계정 복구 가능 여부 (soft delete 상태인지)")); + + private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") + .contentType(MediaType.APPLICATION_JSON) // request body content type + .content(mapper.writeValueAsString(request))); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "emailCodeVerification/" + identifier, + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint(), getModifiedHeader()), + responseFields(responseFieldDescriptors), + requestFields(requestFieldDescriptors), + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 인증 코드 검증 api") + .description("이메일 인증 코드를 검증하는 api입니다.") + .responseFields(responseFieldDescriptors) + .requestFields(requestFieldDescriptors) + .build())); + } + + @Test + @Transactional + void 이메일_인증코드_검증_성공() throws Exception { + + String email = "test@gmail.com"; + String code = "123456"; + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } +} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205425.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205425.java new file mode 100644 index 0000000..da02fc6 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205425.java @@ -0,0 +1,92 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; +import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import jakarta.transaction.Transactional; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailCodeVerificationTest extends BaseTest { + + @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + + private final List requestFieldDescriptors = + List.of( + fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), + fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); + + private final List responseFieldDescriptors = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isVerified") + .type(JsonFieldType.BOOLEAN) + .description("검증 성공 여부"), + fieldWithPath("data.isRecoverable") + .type(JsonFieldType.BOOLEAN) + .description("계정 복구 가능 여부 (soft delete 상태인지)")); + + private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") + .contentType(MediaType.APPLICATION_JSON) // request body content type + .content(mapper.writeValueAsString(request))); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "emailCodeVerification/" + identifier, + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint(), getModifiedHeader()), + responseFields(responseFieldDescriptors), + requestFields(requestFieldDescriptors), + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 인증 코드 검증 api") + .description("이메일 인증 코드를 검증하는 api입니다.") + .responseFields(responseFieldDescriptors) + .requestFields(requestFieldDescriptors) + .build())); + } + + @Test + @Transactional + void 이메일_인증코드_검증_성공() throws Exception { + + String email = "test@gmail.com"; + String code = "123456"; + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } +} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205721.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205721.java new file mode 100644 index 0000000..bc60406 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205721.java @@ -0,0 +1,151 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; +import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.domain.entity.User; +import jakarta.transaction.Transactional; +import java.time.LocalDateTime; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailCodeVerificationTest extends BaseTest { + + @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + @Autowired private SaveUserPort saveUserPort; + + private final List requestFieldDescriptors = + List.of( + fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), + fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); + + private final List responseFieldDescriptors = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isVerified") + .type(JsonFieldType.BOOLEAN) + .description("검증 성공 여부"), + fieldWithPath("data.isRecoverable") + .type(JsonFieldType.BOOLEAN) + .description("계정 복구 가능 여부")); + + private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") + .contentType(MediaType.APPLICATION_JSON) // request body content type + .content(mapper.writeValueAsString(request))); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "emailCodeVerification/" + identifier, + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint(), getModifiedHeader()), + responseFields(responseFieldDescriptors), + requestFields(requestFieldDescriptors), + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 인증 코드 검증 api") + .description("이메일 인증 코드를 검증하는 api입니다.") + .responseFields(responseFieldDescriptors) + .requestFields(requestFieldDescriptors) + .build())); + } + + @Test + @Transactional + void 이메일_인증코드_검증_성공() throws Exception { + + String email = "test@gmail.com"; + String code = "123456"; + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_실패() throws Exception { + + String email = "test@gmail.com"; + String correctCode = "123456"; + String wrongCode = "654321"; + + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, correctCode)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(false)) + .andExpect(jsonPath("$.data.isRecoverable").value(false)); + + // documentation + resultActions.andDo(getDocument(2)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_성공_soft_delete_사용자_복구_가능() throws Exception { + + String email = "softdeleted@gmail.com"; + String code = "123456"; + + // given - soft delete된 사용자 생성 + User softDeletedUser = createSoftDeletedUser(email, "password123!"); + + // given - 이메일 인증 로그 생성 + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(true)) + .andExpect(jsonPath("$.data.isRecoverable").value(true)); + + // documentation + resultActions.andDo(getDocument(3)); + } +} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622210254.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622210254.java new file mode 100644 index 0000000..27d1629 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622210254.java @@ -0,0 +1,160 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; +import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.domain.entity.User; +import jakarta.transaction.Transactional; +import java.time.LocalDateTime; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailCodeVerificationTest extends BaseTest { + + @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + @Autowired private SaveUserPort saveUserPort; + + private final List requestFieldDescriptors = + List.of( + fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), + fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); + + private final List responseFieldDescriptors = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isVerified") + .type(JsonFieldType.BOOLEAN) + .description("검증 성공 여부"), + fieldWithPath("data.isRecoverable") + .type(JsonFieldType.BOOLEAN) + .description("계정 복구 가능 여부")); + + private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") + .contentType(MediaType.APPLICATION_JSON) // request body content type + .content(mapper.writeValueAsString(request))); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "emailCodeVerification/" + identifier, + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint(), getModifiedHeader()), + responseFields(responseFieldDescriptors), + requestFields(requestFieldDescriptors), + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 인증 코드 검증 api") + .description("이메일 인증 코드를 검증하는 api입니다.") + .responseFields(responseFieldDescriptors) + .requestFields(requestFieldDescriptors) + .build())); + } + + protected User createSoftDeletedUser(String email, String password) { + User user = createTestUser(email, password); + user.updateIsDeleted(true); + user.updateDeletedAt(LocalDateTime.now()); + saveUserPort.saveUser(user); + return user; + } + + + @Test + @Transactional + void 이메일_인증코드_검증_성공() throws Exception { + + String email = "test@gmail.com"; + String code = "123456"; + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_실패() throws Exception { + + String email = "test@gmail.com"; + String correctCode = "123456"; + String wrongCode = "654321"; + + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, correctCode)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(false)) + .andExpect(jsonPath("$.data.isRecoverable").value(false)); + + // documentation + resultActions.andDo(getDocument(2)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_성공_soft_delete_사용자_복구_가능() throws Exception { + + String email = "softdeleted@gmail.com"; + String code = "123456"; + + // given - soft delete된 사용자 생성 + User softDeletedUser = createSoftDeletedUser(email, "password123!"); + + // given - 이메일 인증 로그 생성 + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(true)) + .andExpect(jsonPath("$.data.isRecoverable").value(true)); + + // documentation + resultActions.andDo(getDocument(3)); + } +} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622211329.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622211329.java new file mode 100644 index 0000000..92d499b --- /dev/null +++ b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622211329.java @@ -0,0 +1,134 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; +import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.domain.entity.User; +import jakarta.transaction.Transactional; +import java.time.LocalDateTime; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailCodeVerificationTest extends BaseTest { + + @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + @Autowired private SaveUserPort saveUserPort; + + private final List requestFieldDescriptors = + List.of( + fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), + fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); + + private final List responseFieldDescriptors = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isVerified") + .type(JsonFieldType.BOOLEAN) + .description("검증 성공 여부"), + fieldWithPath("data.isRecoverable") + .type(JsonFieldType.BOOLEAN) + .description("계정 복구 가능 여부")); + + private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") + .contentType(MediaType.APPLICATION_JSON) // request body content type + .content(mapper.writeValueAsString(request))); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "emailCodeVerification/" + identifier, + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint(), getModifiedHeader()), + responseFields(responseFieldDescriptors), + requestFields(requestFieldDescriptors), + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 인증 코드 검증 api") + .description("이메일 인증 코드를 검증하는 api입니다.") + .responseFields(responseFieldDescriptors) + .requestFields(requestFieldDescriptors) + .build())); + } + + protected User createSoftDeletedUser(String email, String password) { + User user = createTestUser(email, password); + user.updateIsDeleted(true); + user.updateDeletedAt(LocalDateTime.now()); + saveUserPort.saveUser(user); + return user; + } + + + @Test + @Transactional + void 이메일_인증코드_검증_성공() throws Exception { + + String email = "test@gmail.com"; + String code = "123456"; + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_실패() throws Exception { + + String email = "test@gmail.com"; + String correctCode = "123456"; + String wrongCode = "654321"; + + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, correctCode)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(false)) + .andExpect(jsonPath("$.data.isRecoverable").value(false)); + + // documentation + resultActions.andDo(getDocument(2)); + } + + +} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213651.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213651.java new file mode 100644 index 0000000..38b48f5 --- /dev/null +++ b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213651.java @@ -0,0 +1,202 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; +import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.domain.entity.User; +import jakarta.transaction.Transactional; +import java.time.LocalDateTime; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailCodeVerificationTest extends BaseTest { + + @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + @Autowired private SaveUserPort saveUserPort; + + private final List requestFieldDescriptors = + List.of( + fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), + fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); + + private final List responseFieldDescriptors = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isVerified") + .type(JsonFieldType.BOOLEAN) + .description("검증 성공 여부"), + fieldWithPath("data.isRecoverable") + .type(JsonFieldType.BOOLEAN) + .description("계정 복구 가능 여부")); + + private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") + .contentType(MediaType.APPLICATION_JSON) // request body content type + .content(mapper.writeValueAsString(request))); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "emailCodeVerification/" + identifier, + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint(), getModifiedHeader()), + responseFields(responseFieldDescriptors), + requestFields(requestFieldDescriptors), + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 인증 코드 검증 api") + .description("이메일 인증 코드를 검증하는 api입니다.") + .responseFields(responseFieldDescriptors) + .requestFields(requestFieldDescriptors) + .build())); + } + + protected User createSoftDeletedUser(String email, String password) { + User user = createTestUser(email, password); + user.updateIsDeleted(true); + user.updateDeletedAt(LocalDateTime.now()); + saveUserPort.saveUser(user); + return user; + } + + + @Test + @Transactional + void 이메일_인증코드_검증_성공() throws Exception { + + String email = "test@gmail.com"; + String code = "123456"; + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_실패() throws Exception { + + String email = "test@gmail.com"; + String correctCode = "123456"; + String wrongCode = "654321"; + + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, correctCode)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(false)) + .andExpect(jsonPath("$.data.isRecoverable").value(false)); + + // documentation + resultActions.andDo(getDocument(2)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_성공_soft_delete_사용자_복구_가능() throws Exception { + + String email = "softdeleted@gmail.com"; + String code = "123456"; + + // given - soft delete된 사용자 생성 + User softDeletedUser = createSoftDeletedUser(email, "password123!"); + + // given - 이메일 인증 로그 생성 + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(true)) + .andExpect(jsonPath("$.data.isRecoverable").value(true)); + + // documentation + resultActions.andDo(getDocument(3)); + } + + @Test + @Transactional + void 회원가입_완료_후_이메일_인증_로그_삭제_확인() throws Exception { + + String email = "signup@gmail.com"; + String code = "123456"; + + // given - 이메일 인증 로그 생성 + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // given - 이메일 인증 코드 검증 + getResultActions(new EmailCodeVerificationRequest(email, code)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(true)); + + // when - 회원가입 진행 + GeneralUserSignupRequest signupRequest = new GeneralUserSignupRequest( + email, "password123!", AgeGroup.TWENTIES, List.of(HashTag.PERFUME)); + + ResultActions signupResult = mockMvc.perform( + RestDocumentationRequestBuilders.post("/api/users/signup") + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(signupRequest))); + + // then - 회원가입 성공 + signupResult.andExpect(status().isCreated()); + + // then - 이메일 인증 로그가 삭제되었는지 확인 (다시 인증 코드 검증 시도) + ResultActions verificationResult = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + verificationResult + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(false)) + .andExpect(jsonPath("$.data.isRecoverable").value(false)); + + // documentation + verificationResult.andDo(getDocument(4)); + } + +} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213710.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213710.java new file mode 100644 index 0000000..fd191ce --- /dev/null +++ b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213710.java @@ -0,0 +1,205 @@ +package com.ftm.server.user; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import com.ftm.server.BaseTest; +import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.adapter.in.web.user.dto.request.GeneralUserSignupRequest; +import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; +import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.enums.AgeGroup; +import com.ftm.server.domain.enums.HashTag; +import jakarta.transaction.Transactional; +import java.time.LocalDateTime; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +public class EmailCodeVerificationTest extends BaseTest { + + @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + @Autowired private SaveUserPort saveUserPort; + + private final List requestFieldDescriptors = + List.of( + fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), + fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); + + private final List responseFieldDescriptors = + List.of( + fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), + fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), + fieldWithPath("data.isVerified") + .type(JsonFieldType.BOOLEAN) + .description("검증 성공 여부"), + fieldWithPath("data.isRecoverable") + .type(JsonFieldType.BOOLEAN) + .description("계정 복구 가능 여부")); + + private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { + return mockMvc.perform( // api 실행 + RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") + .contentType(MediaType.APPLICATION_JSON) // request body content type + .content(mapper.writeValueAsString(request))); + } + + // 문서화 반환 함수 + private RestDocumentationResultHandler getDocument(Integer identifier) { + return document( + "emailCodeVerification/" + identifier, + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint(), getModifiedHeader()), + responseFields(responseFieldDescriptors), + requestFields(requestFieldDescriptors), + resource( + ResourceSnippetParameters.builder() + .tag("회원") + .summary("이메일 인증 코드 검증 api") + .description("이메일 인증 코드를 검증하는 api입니다.") + .responseFields(responseFieldDescriptors) + .requestFields(requestFieldDescriptors) + .build())); + } + + protected User createSoftDeletedUser(String email, String password) { + User user = createTestUser(email, password); + user.updateIsDeleted(true); + user.updateDeletedAt(LocalDateTime.now()); + saveUserPort.saveUser(user); + return user; + } + + + @Test + @Transactional + void 이메일_인증코드_검증_성공() throws Exception { + + String email = "test@gmail.com"; + String code = "123456"; + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions.andExpect(status().isOk()); + + // documentation + resultActions.andDo(getDocument(1)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_실패() throws Exception { + + String email = "test@gmail.com"; + String correctCode = "123456"; + String wrongCode = "654321"; + + // given + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, correctCode)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(false)) + .andExpect(jsonPath("$.data.isRecoverable").value(false)); + + // documentation + resultActions.andDo(getDocument(2)); + } + + @Test + @Transactional + void 이메일_인증코드_검증_성공_soft_delete_사용자_복구_가능() throws Exception { + + String email = "softdeleted@gmail.com"; + String code = "123456"; + + // given - soft delete된 사용자 생성 + User softDeletedUser = createSoftDeletedUser(email, "password123!"); + + // given - 이메일 인증 로그 생성 + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // when + ResultActions resultActions = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + // then + resultActions + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(true)) + .andExpect(jsonPath("$.data.isRecoverable").value(true)); + + // documentation + resultActions.andDo(getDocument(3)); + } + + @Test + @Transactional + void 회원가입_완료_후_이메일_인증_로그_삭제_확인() throws Exception { + + String email = "signup@gmail.com"; + String code = "123456"; + + // given - 이메일 인증 로그 생성 + saveEmailVerificationLogPort.saveEmailVerificationLogs( + EmailVerificationLogCreationCommand.of(email, code)); + + // given - 이메일 인증 코드 검증 + getResultActions(new EmailCodeVerificationRequest(email, code)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(true)); + + // when - 회원가입 진행 + GeneralUserSignupRequest signupRequest = new GeneralUserSignupRequest( + email, "password123!", AgeGroup.TWENTIES, List.of(HashTag.PERFUME)); + + ResultActions signupResult = mockMvc.perform( + RestDocumentationRequestBuilders.post("/api/users/signup") + .contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(signupRequest))); + + // then - 회원가입 성공 + signupResult.andExpect(status().isCreated()); + + // then - 이메일 인증 로그가 삭제되었는지 확인 (다시 인증 코드 검증 시도) + ResultActions verificationResult = + getResultActions(new EmailCodeVerificationRequest(email, code)); + + verificationResult + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.isVerified").value(false)) + .andExpect(jsonPath("$.data.isRecoverable").value(false)); + + // documentation + verificationResult.andDo(getDocument(4)); + } + +} diff --git a/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse.java b/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse.java index 034acd6..26fe9de 100644 --- a/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse.java +++ b/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse.java @@ -6,8 +6,9 @@ @Data public class EmailCodeVerificationResponse { private final Boolean isVerified; + private final Boolean isRecoverable; public static EmailCodeVerificationResponse from(EmailCodeVerificationVo vo) { - return new EmailCodeVerificationResponse(vo.getIsVerified()); + return new EmailCodeVerificationResponse(vo.getIsVerified(), vo.getIsRecoverable()); } } diff --git a/src/main/java/com/ftm/server/adapter/out/cache/LoadTrendingPostsTestAdapter.java b/src/main/java/com/ftm/server/adapter/out/cache/LoadTrendingPostsTestAdapter.java new file mode 100644 index 0000000..1b61aaf --- /dev/null +++ b/src/main/java/com/ftm/server/adapter/out/cache/LoadTrendingPostsTestAdapter.java @@ -0,0 +1,87 @@ +package com.ftm.server.adapter.out.cache; + +import com.ftm.server.application.port.out.cache.LoadTrendingPostsWithCachePort; +import com.ftm.server.application.port.out.persistence.post.LoadPostImagePort; +import com.ftm.server.application.port.out.persistence.post.LoadPostWithBookmarkCountPort; +import com.ftm.server.application.query.FindByIdsQuery; +import com.ftm.server.application.query.FindPostsByCreatedDateQuery; +import com.ftm.server.application.vo.post.PostWithBookmarkCountVo; +import com.ftm.server.application.vo.post.TrendingPostVo; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.IntStream; + +@Service +@RequiredArgsConstructor +@Primary +public class LoadTrendingPostsTestAdapter implements LoadTrendingPostsWithCachePort { + + private final LoadPostWithBookmarkCountPort loadPostPort; + private final LoadPostImagePort loadPostImagePort; + + private static final int N = 15; + + @Override + public List loadTrendingPosts() { + + // 현재보다 1주일 이전에 작성된 게시물만 조회(북마크 조회수 포함) (예전 게시물은 포함x) + List rawPosts = + loadPostPort.loadAllPostsWithBookmarkCount( + FindPostsByCreatedDateQuery.of(LocalDate.now())); + + if (rawPosts.isEmpty()) return List.of(); + + // 1. 최대값 계산 (정규화를 위해) + long maxView = 1, maxLike = 1, maxScrap = 1; + for (PostWithBookmarkCountVo post : rawPosts) { + maxView = Math.max(maxView, post.getViewCount()); + maxLike = Math.max(maxLike, post.getLikeCount()); + maxScrap = Math.max(maxScrap, post.getScrapCount()); + } + + // 2. 점수 계산 후 정렬 + long finalMaxView = maxView; + long finalMaxLike = maxLike; + long finalMaxScrap = maxScrap; + List topN = + rawPosts.stream() + .sorted( + Comparator.comparingDouble( + p -> + -((double) p.getViewCount() / finalMaxView + + (double) p.getLikeCount() + / finalMaxLike + + (double) p.getScrapCount() + / finalMaxScrap) + / 3.0)) + .limit(N) + .toList(); + + // 3. 각 게시물 이미지 조회 (없으면 null) + List postIds = topN.stream().map(PostWithBookmarkCountVo::getPostId).toList(); + + Map imageMap = new HashMap<>(); + postIds.forEach(p -> imageMap.put(p, null)); + loadPostImagePort + .loadRepresentativeImagesByPostIds(FindByIdsQuery.from(postIds)) + .forEach( + postImage -> imageMap.put(postImage.getPostId(), postImage.getObjectKey())); + + // 4. 결과 조합 (순위 부여) + return IntStream.range(0, topN.size()) + .mapToObj( + i -> { + PostWithBookmarkCountVo post = topN.get(i); + String imageKey = imageMap.get(post.getPostId()); + return TrendingPostVo.from(post, i + 1, imageKey); // rank = i+1 + }) + .toList(); + } +} diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/adapter/user/UserDomainPersistenceAdapter.java b/src/main/java/com/ftm/server/adapter/out/persistence/adapter/user/UserDomainPersistenceAdapter.java index 283a8dc..c451e7f 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/adapter/user/UserDomainPersistenceAdapter.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/adapter/user/UserDomainPersistenceAdapter.java @@ -25,6 +25,7 @@ public class UserDomainPersistenceAdapter implements LoadEmailVerificationLogPort, SaveEmailVerificationLogPort, UpdateEmailVerificationLogPort, + DeleteEmailVerificationLogPort, CheckUserPort, SaveUserPort, SaveUserImagePort, @@ -91,6 +92,11 @@ public void updateEmailVerificationLog(EmailVerificationLogs emailVerificationLo emailVerificationLogsJpaEntity.updateFromDomainEntity(emailVerificationLogs); } + @Override + public void deleteEmailVerificationLogsByEmail(DeleteByEmailCommand command) { + emailVerificationLogsRepository.deleteAllByEmail(command.getEmail()); + } + @Override public Boolean checksUserByEmail(FindByEmailQuery query) { return userRepository.existsByEmail(query.getEmail()); @@ -154,6 +160,12 @@ public List loadUserByDeleteOption(FindUserByDeleteOptionQuery query) { .toList(); } + @Override + public Optional loadDeletedUserByEmail(FindByEmailQuery query) { + Optional user = userRepository.findByEmailAndIsDeleted(query.getEmail(),true); + return user.map(userMapper::toDomainEntity); + } + @Override public UserImage loadUserImageByUserId(FindByUserIdQuery query) { UserImageJpaEntity userImageJpaEntity = @@ -307,4 +319,14 @@ public List loadUserImagesByUserIdIn(FindUserImagesByIdsQuery query) .map(userImageMapper::toDomainEntity) .toList(); } + + @Override + public Boolean checksNotDeletedUserByEmail(FindByEmailQuery query) { + return userRepository.existsByEmailAndIsDeleted(query.getEmail(), false); + } + + @Override + public Boolean checksUserSoftDeletedByEmail(FindByEmailQuery query) { + return userRepository.existsByEmailAndIsDeleted(query.getEmail(), true); + } } diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/repository/EmailVerificationLogsRepository.java b/src/main/java/com/ftm/server/adapter/out/persistence/repository/EmailVerificationLogsRepository.java index ea40898..183a62f 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/repository/EmailVerificationLogsRepository.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/repository/EmailVerificationLogsRepository.java @@ -3,6 +3,9 @@ import com.ftm.server.adapter.out.persistence.model.EmailVerificationLogsJpaEntity; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository @@ -16,4 +19,8 @@ Optional findByVerificationCodeAndEmail( Optional findByEmailAndIsVerified( String email, Boolean isVerified); + + @Modifying + @Query("DELETE FROM EmailVerificationLogsJpaEntity e WHERE e.email = :email") + void deleteAllByEmail(@Param("email") String email); } diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/repository/UserRepository.java b/src/main/java/com/ftm/server/adapter/out/persistence/repository/UserRepository.java index 0597624..b2e90e1 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/repository/UserRepository.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/repository/UserRepository.java @@ -15,6 +15,8 @@ public interface UserRepository extends JpaRepository { Optional findByIdAndIsDeleted(Long userId, Boolean isDeleted); + Optional findByEmailAndIsDeleted(String email, Boolean isDeleted); + Boolean existsByEmail(String email); Optional findByEmail(String email); @@ -33,4 +35,6 @@ Optional findBySocialProviderAndSocialId( @Query("SELECT u FROM UserJpaEntity u WHERE u.isDeleted = :isDeleted And u.deletedAt <=:end") List findAllByDeletedBefore( @Param("isDeleted") Boolean isDeleted, @Param("end") LocalDateTime end); + + Boolean existsByEmailAndIsDeleted(String email, boolean b); } diff --git a/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand.java b/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand.java new file mode 100644 index 0000000..a1ddbe4 --- /dev/null +++ b/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand.java @@ -0,0 +1,12 @@ +package com.ftm.server.application.command.user; + +import lombok.Data; + +@Data +public class DeleteByEmailCommand { + private final String email; + + public static DeleteByEmailCommand of(String email) { + return new DeleteByEmailCommand(email); + } +} \ No newline at end of file diff --git a/src/main/java/com/ftm/server/application/command/user/DeleteUserByEmailCommand.java b/src/main/java/com/ftm/server/application/command/user/DeleteUserByEmailCommand.java new file mode 100644 index 0000000..3577947 --- /dev/null +++ b/src/main/java/com/ftm/server/application/command/user/DeleteUserByEmailCommand.java @@ -0,0 +1,13 @@ +package com.ftm.server.application.command.user; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class DeleteUserByEmailCommand { + private final String email; + public static DeleteUserByEmailCommand of(String email){ + return new DeleteUserByEmailCommand(email); + } +} diff --git a/src/main/java/com/ftm/server/application/port/in/user/UserHardDeleteByEmailUseCase.java b/src/main/java/com/ftm/server/application/port/in/user/UserHardDeleteByEmailUseCase.java new file mode 100644 index 0000000..db94977 --- /dev/null +++ b/src/main/java/com/ftm/server/application/port/in/user/UserHardDeleteByEmailUseCase.java @@ -0,0 +1,10 @@ +package com.ftm.server.application.port.in.user; + +import com.ftm.server.application.command.user.DeleteUserByEmailCommand; +import com.ftm.server.common.annotation.Port; +import org.springframework.security.core.parameters.P; + +@Port +public interface UserHardDeleteByEmailUseCase { + void execute(DeleteUserByEmailCommand command); +} diff --git a/src/main/java/com/ftm/server/application/port/out/persistence/user/CheckUserPort.java b/src/main/java/com/ftm/server/application/port/out/persistence/user/CheckUserPort.java index 1444af9..5d03fab 100644 --- a/src/main/java/com/ftm/server/application/port/out/persistence/user/CheckUserPort.java +++ b/src/main/java/com/ftm/server/application/port/out/persistence/user/CheckUserPort.java @@ -12,4 +12,8 @@ public interface CheckUserPort { Boolean checksUserBySocialValue(FindBySocialValueQuery query); Boolean checksUserById(FindByUserIdQuery query); + + Boolean checksNotDeletedUserByEmail(FindByEmailQuery query); + + Boolean checksUserSoftDeletedByEmail(FindByEmailQuery query); } diff --git a/src/main/java/com/ftm/server/application/port/out/persistence/user/DeleteEmailVerificationLogPort.java b/src/main/java/com/ftm/server/application/port/out/persistence/user/DeleteEmailVerificationLogPort.java new file mode 100644 index 0000000..3339459 --- /dev/null +++ b/src/main/java/com/ftm/server/application/port/out/persistence/user/DeleteEmailVerificationLogPort.java @@ -0,0 +1,9 @@ +package com.ftm.server.application.port.out.persistence.user; + +import com.ftm.server.application.command.user.DeleteByEmailCommand; +import com.ftm.server.common.annotation.Port; + +@Port +public interface DeleteEmailVerificationLogPort { + void deleteEmailVerificationLogsByEmail(DeleteByEmailCommand command); +} \ No newline at end of file diff --git a/src/main/java/com/ftm/server/application/port/out/persistence/user/LoadUserPort.java b/src/main/java/com/ftm/server/application/port/out/persistence/user/LoadUserPort.java index 012f4de..015bbd7 100644 --- a/src/main/java/com/ftm/server/application/port/out/persistence/user/LoadUserPort.java +++ b/src/main/java/com/ftm/server/application/port/out/persistence/user/LoadUserPort.java @@ -1,5 +1,6 @@ package com.ftm.server.application.port.out.persistence.user; +import com.ftm.server.application.query.FindByEmailQuery; import com.ftm.server.application.query.FindByUserIdQuery; import com.ftm.server.application.query.FindUserByDeleteOptionQuery; import com.ftm.server.application.query.FindUserByRoleQuery; @@ -14,4 +15,6 @@ public interface LoadUserPort { User loadUserByRole(FindUserByRoleQuery query); List loadUserByDeleteOption(FindUserByDeleteOptionQuery query); + + Optional loadDeletedUserByEmail(FindByEmailQuery query); } diff --git a/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService.java b/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService.java index ab0c6f9..464378e 100644 --- a/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService.java +++ b/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService.java @@ -1,9 +1,11 @@ package com.ftm.server.application.service.user; import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; +import com.ftm.server.application.port.out.persistence.user.CheckUserPort; import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; import com.ftm.server.application.query.EmailCodeVerificationQuery; +import com.ftm.server.application.query.FindByEmailQuery; import com.ftm.server.application.vo.user.EmailCodeVerificationVo; import com.ftm.server.domain.entity.EmailVerificationLogs; import jakarta.transaction.Transactional; @@ -17,6 +19,7 @@ public class EmailCodeVerificationService implements EmailCodeVerificationUseCas private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; + private final CheckUserPort checkUserPort; @Override @Transactional @@ -28,8 +31,13 @@ public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 return EmailCodeVerificationVo.of(false); } + emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); - return EmailCodeVerificationVo.of(true); + + // 해당 이메일의 계정 상태 확인 (soft delete 여부) + Boolean isRecoverable = checkUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(query.getEmail())); + + return EmailCodeVerificationVo.of(true, isRecoverable); } } diff --git a/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService.java b/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService.java index ba96dc9..d1b7fd5 100644 --- a/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService.java +++ b/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService.java @@ -15,6 +15,6 @@ public class EmailDuplicationCheckService implements EmailDuplicationCheckUseCas @Override public EmailDuplicationVo execute(FindByEmailQuery query) { - return EmailDuplicationVo.of(checkUserPort.checksUserByEmail(query)); + return EmailDuplicationVo.of(checkUserPort.checksNotDeletedUserByEmail(query)); } } diff --git a/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService.java b/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService.java index a3f77ef..b8b3f83 100644 --- a/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService.java +++ b/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService.java @@ -1,10 +1,14 @@ package com.ftm.server.application.service.user; import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; +import com.ftm.server.application.command.user.DeleteByEmailCommand; +import com.ftm.server.application.command.user.DeleteUserByEmailCommand; import com.ftm.server.application.command.user.GeneralUserCreationCommand; import com.ftm.server.application.command.user.GeneralUserSignupCommand; import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; +import com.ftm.server.application.port.in.user.UserHardDeleteByEmailUseCase; import com.ftm.server.application.port.out.persistence.user.CheckUserPort; +import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; import com.ftm.server.application.port.out.persistence.user.SaveUserPort; @@ -25,8 +29,12 @@ @RequiredArgsConstructor public class GeneralUserSignupService implements GeneralUserSignupUseCase { + //usecase + private final UserHardDeleteByEmailUseCase userHardDeleteByEmailUseCase; + // service private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; + private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; private final CheckUserPort checksUserPort; private final SaveUserPort saveUserPort; private final SaveUserImagePort saveUserImagePort; @@ -42,7 +50,7 @@ public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( FindByEmailQuery.of(email)); - if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 + if (checksUserPort.checksNotDeletedUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사(삭제되지 않은 user 에 한해서) throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); } @@ -50,6 +58,11 @@ public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); } + //회원 탈퇴 후 복구 없이 재가입하는 경우, 기존의 계정 정보 즉시 삭제 + if(checksUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(email))){ + userHardDeleteByEmailUseCase.execute(DeleteUserByEmailCommand.of(email)); + } + String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 GeneralUserCreationCommand convertedCommand = @@ -62,6 +75,10 @@ public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); + + // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 + deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(DeleteByEmailCommand.of(email)); + return GeneralUserSignupResponse.of(user.getId()); } } diff --git a/src/main/java/com/ftm/server/application/service/user/UserHardDeleteByEmailService.java b/src/main/java/com/ftm/server/application/service/user/UserHardDeleteByEmailService.java new file mode 100644 index 0000000..a0fd31c --- /dev/null +++ b/src/main/java/com/ftm/server/application/service/user/UserHardDeleteByEmailService.java @@ -0,0 +1,60 @@ +package com.ftm.server.application.service.user; + +import com.ftm.server.application.command.user.*; +import com.ftm.server.application.port.in.user.UserHardDeleteByEmailUseCase; +import com.ftm.server.application.port.out.persistence.user.*; +import com.ftm.server.application.port.out.s3.S3ImageDeletePort; +import com.ftm.server.application.port.out.transcation.AfterCommitExecutorPort; +import com.ftm.server.application.query.FindByEmailQuery; +import com.ftm.server.application.query.FindUserByDeleteOptionQuery; +import com.ftm.server.domain.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class UserHardDeleteByEmailService implements UserHardDeleteByEmailUseCase { + + private final LoadUserPort loadUserPort; + + private final DeleteBookmarkPort deleteBookmarkPort; + private final DeleteGroomingTestResultPort deleteGroomingTestResultPort; + private final DeleteUserImagePort deleteUserImagePort; + private final DeleteUserPort deleteUserPort; + + private final AfterCommitExecutorPort afterCommitExecutorPort; + private final S3ImageDeletePort s3ImageDeletePort; + + @Override + public void execute(DeleteUserByEmailCommand command) { + // 삭제 대상 user 조회 + Optional deletedUser = + loadUserPort.loadDeletedUserByEmail(FindByEmailQuery.of(command.getEmail())); + + if (deletedUser.isEmpty()){return;} + + List userId = List.of(deletedUser.get().getId()); + + // user 관련 엔티티 모두 삭제 + // 1. 북마크 삭제 + deleteBookmarkPort.deleteBookmarkByUserList( + DeleteBookmarkByUserIdCommand.of(userId)); + // 2. 그루밍 결과 삭제 + deleteGroomingTestResultPort.deleteGroomingTestResultByUserList( + DeleteGroomingTestResultByUserIdCommand.of(userId)); + // 3. user 이미지 삭제 + List imageKeyList = + deleteUserImagePort.deleteUserImageByUserList( + DeleteUserImageByUserIdCommand.of(userId)); + afterCommitExecutorPort.doAfterCommit( + () -> + s3ImageDeletePort.deleteImages( + imageKeyList)); // transaction commit 이후에 s3에 이미지 삭제 요청 + // 4. user 삭제 + deleteUserPort.deleteAllUserByIdList(DeleteAllUserByIdListCommand.of(userId)); + } +} diff --git a/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo.java b/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo.java index 022e946..d7988fd 100644 --- a/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo.java +++ b/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo.java @@ -5,8 +5,13 @@ @Data public class EmailCodeVerificationVo { private final Boolean isVerified; + private final Boolean isRecoverable; // 계정 복구 가능 여부 (soft delete 상태인지) public static EmailCodeVerificationVo of(Boolean isVerified) { - return new EmailCodeVerificationVo(isVerified); + return new EmailCodeVerificationVo(isVerified, false); + } + + public static EmailCodeVerificationVo of(Boolean isVerified, Boolean isRecoverable) { + return new EmailCodeVerificationVo(isVerified, isRecoverable); } } diff --git a/src/test/java/com/ftm/server/BaseTest.java b/src/test/java/com/ftm/server/BaseTest.java index 6e4bfc4..72b2ff2 100644 --- a/src/test/java/com/ftm/server/BaseTest.java +++ b/src/test/java/com/ftm/server/BaseTest.java @@ -16,6 +16,7 @@ import com.ftm.server.domain.enums.UserRole; import com.ftm.server.infrastructure.security.UserPrincipal; import groovy.util.logging.Slf4j; +import java.time.LocalDateTime; import java.util.List; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/com/ftm/server/user/EmailCodeVerificationTest.java b/src/test/java/com/ftm/server/user/EmailCodeVerificationTest.java index d8a08a2..2bf4134 100644 --- a/src/test/java/com/ftm/server/user/EmailCodeVerificationTest.java +++ b/src/test/java/com/ftm/server/user/EmailCodeVerificationTest.java @@ -1,17 +1,28 @@ package com.ftm.server.user; import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static io.restassured.RestAssured.when; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.ftm.server.BaseTest; import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; +import com.ftm.server.adapter.in.web.user.dto.request.GeneralUserSignupRequest; import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; +import com.ftm.server.application.port.out.persistence.user.SaveUserPort; +import com.ftm.server.application.port.out.smtp.MailSenderPort; +import com.ftm.server.domain.entity.User; +import com.ftm.server.domain.enums.AgeGroup; +import com.ftm.server.domain.enums.HashTag; import jakarta.transaction.Transactional; +import java.time.LocalDateTime; import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -20,11 +31,16 @@ import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; import org.springframework.restdocs.payload.FieldDescriptor; import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.web.servlet.ResultActions; public class EmailCodeVerificationTest extends BaseTest { @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; + @Autowired private SaveUserPort saveUserPort; + + @MockitoBean + private MailSenderPort mailSenderPort; private final List requestFieldDescriptors = List.of( @@ -39,7 +55,10 @@ public class EmailCodeVerificationTest extends BaseTest { fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), fieldWithPath("data.isVerified") .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부")); + .description("검증 성공 여부"), + fieldWithPath("data.isRecoverable") + .type(JsonFieldType.BOOLEAN) + .description("계정 복구 가능 여부 : true 일 경우 계정 복구 요청 가능")); private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { return mockMvc.perform( // api 실행 @@ -66,6 +85,15 @@ private RestDocumentationResultHandler getDocument(Integer identifier) { .build())); } + protected User createSoftDeletedUser(String email, String password) { + User user = createTestUser(email, password); + user.updateIsDeleted(true); + user.updateDeletedAt(LocalDateTime.now()); + saveUserPort.saveUser(user); + return user; + } + + @Test @Transactional void 이메일_인증코드_검증_성공() throws Exception { @@ -75,6 +103,8 @@ private RestDocumentationResultHandler getDocument(Integer identifier) { // given saveEmailVerificationLogPort.saveEmailVerificationLogs( EmailVerificationLogCreationCommand.of(email, code)); + //stub 객체 생성 + doNothing().when(mailSenderPort).sendEmail(email,code); // when ResultActions resultActions = From b895d1c28854c4c725e99de5a1796d1070ace5bf Mon Sep 17 00:00:00 2001 From: Minyoung Kim Date: Tue, 24 Jun 2025 17:57:18 +0900 Subject: [PATCH 2/2] fix : Delete .history/src directory --- ...deVerificationResponse_20250407231748.java | 13 -- ...deVerificationResponse_20250622204707.java | 14 -- ...deVerificationResponse_20250622204923.java | 14 -- .../DeleteByEmailCommand_20250622213953.java | 1 - .../DeleteByEmailCommand_20250622213956.java | 12 - ...odeVerificationService_20250407231748.java | 35 --- ...odeVerificationService_20250622204700.java | 43 ---- ...odeVerificationService_20250622210129.java | 41 ---- ...odeVerificationService_20250622210202.java | 43 ---- ...uplicationCheckService_20250407231748.java | 20 -- ...uplicationCheckService_20250622210504.java | 20 -- ...neralUserSignupService_20250414190939.java | 67 ------ ...neralUserSignupService_20250622213609.java | 73 ------- ...neralUserSignupService_20250622213705.java | 73 ------- ...neralUserSignupService_20250622214029.java | 73 ------- ...neralUserSignupService_20250622214036.java | 74 ------- ...neralUserSignupService_20250622214043.java | 74 ------- ...neralUserSignupService_20250622214051.java | 74 ------- ...mailCodeVerificationVo_20250407231748.java | 12 - ...mailCodeVerificationVo_20250622204648.java | 17 -- ...mailCodeVerificationVo_20250622204931.java | 17 -- .../ftm/server/BaseTest_20250528010752.java | 196 ----------------- .../ftm/server/BaseTest_20250622205652.java | 206 ------------------ .../ftm/server/BaseTest_20250622210207.java | 197 ----------------- ...ilCodeVerificationTest_20250407231748.java | 89 -------- ...ilCodeVerificationTest_20250622204717.java | 92 -------- ...ilCodeVerificationTest_20250622205425.java | 92 -------- ...ilCodeVerificationTest_20250622205721.java | 151 ------------- ...ilCodeVerificationTest_20250622210254.java | 160 -------------- ...ilCodeVerificationTest_20250622211329.java | 134 ------------ ...ilCodeVerificationTest_20250622213651.java | 202 ----------------- ...ilCodeVerificationTest_20250622213710.java | 205 ----------------- .../cache/LoadTrendingPostsTestAdapter.java | 15 +- .../user/UserDomainPersistenceAdapter.java | 7 +- .../command/user/DeleteByEmailCommand.java | 2 +- .../user/DeleteUserByEmailCommand.java | 3 +- .../in/user/UserHardDeleteByEmailUseCase.java | 1 - .../user/DeleteEmailVerificationLogPort.java | 2 +- .../user/EmailCodeVerificationService.java | 9 +- .../user/GeneralUserSignupService.java | 16 +- .../user/UserHardDeleteByEmailService.java | 16 +- src/test/java/com/ftm/server/BaseTest.java | 1 - .../user/EmailCodeVerificationTest.java | 14 +- 43 files changed, 39 insertions(+), 2581 deletions(-) delete mode 100644 .history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250407231748.java delete mode 100644 .history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204707.java delete mode 100644 .history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204923.java delete mode 100644 .history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213953.java delete mode 100644 .history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213956.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250407231748.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622204700.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210129.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210202.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250407231748.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250622210504.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250414190939.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213609.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213705.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214029.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214036.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214043.java delete mode 100644 .history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214051.java delete mode 100644 .history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250407231748.java delete mode 100644 .history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204648.java delete mode 100644 .history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204931.java delete mode 100644 .history/src/test/java/com/ftm/server/BaseTest_20250528010752.java delete mode 100644 .history/src/test/java/com/ftm/server/BaseTest_20250622205652.java delete mode 100644 .history/src/test/java/com/ftm/server/BaseTest_20250622210207.java delete mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250407231748.java delete mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622204717.java delete mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205425.java delete mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205721.java delete mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622210254.java delete mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622211329.java delete mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213651.java delete mode 100644 .history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213710.java diff --git a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250407231748.java b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250407231748.java deleted file mode 100644 index 034acd6..0000000 --- a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250407231748.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ftm.server.adapter.in.web.user.dto.response; - -import com.ftm.server.application.vo.user.EmailCodeVerificationVo; -import lombok.Data; - -@Data -public class EmailCodeVerificationResponse { - private final Boolean isVerified; - - public static EmailCodeVerificationResponse from(EmailCodeVerificationVo vo) { - return new EmailCodeVerificationResponse(vo.getIsVerified()); - } -} diff --git a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204707.java b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204707.java deleted file mode 100644 index 26fe9de..0000000 --- a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204707.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.ftm.server.adapter.in.web.user.dto.response; - -import com.ftm.server.application.vo.user.EmailCodeVerificationVo; -import lombok.Data; - -@Data -public class EmailCodeVerificationResponse { - private final Boolean isVerified; - private final Boolean isRecoverable; - - public static EmailCodeVerificationResponse from(EmailCodeVerificationVo vo) { - return new EmailCodeVerificationResponse(vo.getIsVerified(), vo.getIsRecoverable()); - } -} diff --git a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204923.java b/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204923.java deleted file mode 100644 index 26fe9de..0000000 --- a/.history/src/main/java/com/ftm/server/adapter/in/web/user/dto/response/EmailCodeVerificationResponse_20250622204923.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.ftm.server.adapter.in.web.user.dto.response; - -import com.ftm.server.application.vo.user.EmailCodeVerificationVo; -import lombok.Data; - -@Data -public class EmailCodeVerificationResponse { - private final Boolean isVerified; - private final Boolean isRecoverable; - - public static EmailCodeVerificationResponse from(EmailCodeVerificationVo vo) { - return new EmailCodeVerificationResponse(vo.getIsVerified(), vo.getIsRecoverable()); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213953.java b/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213953.java deleted file mode 100644 index 0519ecb..0000000 --- a/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213953.java +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213956.java b/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213956.java deleted file mode 100644 index a1ddbe4..0000000 --- a/.history/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand_20250622213956.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.ftm.server.application.command.user; - -import lombok.Data; - -@Data -public class DeleteByEmailCommand { - private final String email; - - public static DeleteByEmailCommand of(String email) { - return new DeleteByEmailCommand(email); - } -} \ No newline at end of file diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250407231748.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250407231748.java deleted file mode 100644 index ab0c6f9..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250407231748.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; -import com.ftm.server.application.query.EmailCodeVerificationQuery; -import com.ftm.server.application.vo.user.EmailCodeVerificationVo; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class EmailCodeVerificationService implements EmailCodeVerificationUseCase { - - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; - - @Override - @Transactional - public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { - - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmailAndCode(query); - - if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 - return EmailCodeVerificationVo.of(false); - } - emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 - updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); - return EmailCodeVerificationVo.of(true); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622204700.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622204700.java deleted file mode 100644 index 7aa9f56..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622204700.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; -import com.ftm.server.application.query.EmailCodeVerificationQuery; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.application.vo.user.EmailCodeVerificationVo; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class EmailCodeVerificationService implements EmailCodeVerificationUseCase { - - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; - private final CheckUserPort checkUserPort; - - @Override - @Transactional - public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { - - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmailAndCode(query); - - if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 - return EmailCodeVerificationVo.of(false); - } - - emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 - updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); - - // 해당 이메일의 계정 상태 확인 (soft delete 여부) - Boolean isRecoverable = !checkUserPort.checksNotDeletedUserByEmail(FindByEmailQuery.of(query.getEmail())); - - return EmailCodeVerificationVo.of(true, isRecoverable); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210129.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210129.java deleted file mode 100644 index 6da83c7..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210129.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; -import com.ftm.server.application.query.EmailCodeVerificationQuery; -import com.ftm.server.application.vo.user.EmailCodeVerificationVo; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class EmailCodeVerificationService implements EmailCodeVerificationUseCase { - - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; - private final CheckUserPort checkUserPort; - - @Override - @Transactional - public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { - - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmailAndCode(query); - - if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 - return EmailCodeVerificationVo.of(false); - } - - emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 - updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); - - // 해당 이메일의 계정 상태 확인 (soft delete 여부) - Boolean isRecoverable = checkUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(query.getEmail())); - - return EmailCodeVerificationVo.of(true, isRecoverable); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210202.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210202.java deleted file mode 100644 index 464378e..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService_20250622210202.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.application.port.in.user.EmailCodeVerificationUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.UpdateEmailVerificationLogPort; -import com.ftm.server.application.query.EmailCodeVerificationQuery; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.application.vo.user.EmailCodeVerificationVo; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class EmailCodeVerificationService implements EmailCodeVerificationUseCase { - - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final UpdateEmailVerificationLogPort updateEmailVerificationLogPort; - private final CheckUserPort checkUserPort; - - @Override - @Transactional - public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { - - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmailAndCode(query); - - if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 - return EmailCodeVerificationVo.of(false); - } - - emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 - updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); - - // 해당 이메일의 계정 상태 확인 (soft delete 여부) - Boolean isRecoverable = checkUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(query.getEmail())); - - return EmailCodeVerificationVo.of(true, isRecoverable); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250407231748.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250407231748.java deleted file mode 100644 index ba96dc9..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250407231748.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.application.port.in.user.EmailDuplicationCheckUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.application.vo.user.EmailDuplicationVo; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class EmailDuplicationCheckService implements EmailDuplicationCheckUseCase { - - private final CheckUserPort checkUserPort; - - @Override - public EmailDuplicationVo execute(FindByEmailQuery query) { - return EmailDuplicationVo.of(checkUserPort.checksUserByEmail(query)); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250622210504.java b/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250622210504.java deleted file mode 100644 index d1b7fd5..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/EmailDuplicationCheckService_20250622210504.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.application.port.in.user.EmailDuplicationCheckUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.application.vo.user.EmailDuplicationVo; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class EmailDuplicationCheckService implements EmailDuplicationCheckUseCase { - - private final CheckUserPort checkUserPort; - - @Override - public EmailDuplicationVo execute(FindByEmailQuery query) { - return EmailDuplicationVo.of(checkUserPort.checksNotDeletedUserByEmail(query)); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250414190939.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250414190939.java deleted file mode 100644 index a3f77ef..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250414190939.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.command.user.GeneralUserSignupCommand; -import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.common.exception.CustomException; -import com.ftm.server.common.response.enums.ErrorResponseCode; -import com.ftm.server.common.utils.RandomNickNameCreator; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class GeneralUserSignupService implements GeneralUserSignupUseCase { - - // service - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final CheckUserPort checksUserPort; - private final SaveUserPort saveUserPort; - private final SaveUserImagePort saveUserImagePort; - - // gateway - private final SecurityAuthenticationPort authenticationPort; - - @Transactional - @Override - public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { - String email = command.getEmail(); - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( - FindByEmailQuery.of(email)); - - if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 - throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); - } - - if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. - throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); - } - - String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 - - GeneralUserCreationCommand convertedCommand = - GeneralUserCreationCommand.of( - command.getEmail(), - authenticationPort.passwordEncode(command.getPassword()), - nickname, - command.getAge(), - command.getHashtags()); - - User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); - return GeneralUserSignupResponse.of(user.getId()); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213609.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213609.java deleted file mode 100644 index 19fc9c5..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213609.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.command.user.GeneralUserSignupCommand; -import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.common.exception.CustomException; -import com.ftm.server.common.response.enums.ErrorResponseCode; -import com.ftm.server.common.utils.RandomNickNameCreator; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class GeneralUserSignupService implements GeneralUserSignupUseCase { - - // service - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; - private final CheckUserPort checksUserPort; - private final SaveUserPort saveUserPort; - private final SaveUserImagePort saveUserImagePort; - - // gateway - private final SecurityAuthenticationPort authenticationPort; - - @Transactional - @Override - public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { - String email = command.getEmail(); - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( - FindByEmailQuery.of(email)); - - if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 - throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); - } - - if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. - throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); - } - - String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 - - GeneralUserCreationCommand convertedCommand = - GeneralUserCreationCommand.of( - command.getEmail(), - authenticationPort.passwordEncode(command.getPassword()), - nickname, - command.getAge(), - command.getHashtags()); - - User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); - - // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 - deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(FindByEmailQuery.of(email)); - - return GeneralUserSignupResponse.of(user.getId()); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213705.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213705.java deleted file mode 100644 index 19fc9c5..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622213705.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.command.user.GeneralUserSignupCommand; -import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.common.exception.CustomException; -import com.ftm.server.common.response.enums.ErrorResponseCode; -import com.ftm.server.common.utils.RandomNickNameCreator; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class GeneralUserSignupService implements GeneralUserSignupUseCase { - - // service - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; - private final CheckUserPort checksUserPort; - private final SaveUserPort saveUserPort; - private final SaveUserImagePort saveUserImagePort; - - // gateway - private final SecurityAuthenticationPort authenticationPort; - - @Transactional - @Override - public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { - String email = command.getEmail(); - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( - FindByEmailQuery.of(email)); - - if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 - throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); - } - - if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. - throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); - } - - String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 - - GeneralUserCreationCommand convertedCommand = - GeneralUserCreationCommand.of( - command.getEmail(), - authenticationPort.passwordEncode(command.getPassword()), - nickname, - command.getAge(), - command.getHashtags()); - - User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); - - // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 - deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(FindByEmailQuery.of(email)); - - return GeneralUserSignupResponse.of(user.getId()); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214029.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214029.java deleted file mode 100644 index 19fc9c5..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214029.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.command.user.GeneralUserSignupCommand; -import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.common.exception.CustomException; -import com.ftm.server.common.response.enums.ErrorResponseCode; -import com.ftm.server.common.utils.RandomNickNameCreator; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class GeneralUserSignupService implements GeneralUserSignupUseCase { - - // service - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; - private final CheckUserPort checksUserPort; - private final SaveUserPort saveUserPort; - private final SaveUserImagePort saveUserImagePort; - - // gateway - private final SecurityAuthenticationPort authenticationPort; - - @Transactional - @Override - public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { - String email = command.getEmail(); - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( - FindByEmailQuery.of(email)); - - if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 - throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); - } - - if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. - throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); - } - - String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 - - GeneralUserCreationCommand convertedCommand = - GeneralUserCreationCommand.of( - command.getEmail(), - authenticationPort.passwordEncode(command.getPassword()), - nickname, - command.getAge(), - command.getHashtags()); - - User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); - - // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 - deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(FindByEmailQuery.of(email)); - - return GeneralUserSignupResponse.of(user.getId()); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214036.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214036.java deleted file mode 100644 index a49ae03..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214036.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; -import com.ftm.server.application.command.user.DeleteByEmailCommand; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.command.user.GeneralUserSignupCommand; -import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.common.exception.CustomException; -import com.ftm.server.common.response.enums.ErrorResponseCode; -import com.ftm.server.common.utils.RandomNickNameCreator; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class GeneralUserSignupService implements GeneralUserSignupUseCase { - - // service - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; - private final CheckUserPort checksUserPort; - private final SaveUserPort saveUserPort; - private final SaveUserImagePort saveUserImagePort; - - // gateway - private final SecurityAuthenticationPort authenticationPort; - - @Transactional - @Override - public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { - String email = command.getEmail(); - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( - FindByEmailQuery.of(email)); - - if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 - throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); - } - - if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. - throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); - } - - String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 - - GeneralUserCreationCommand convertedCommand = - GeneralUserCreationCommand.of( - command.getEmail(), - authenticationPort.passwordEncode(command.getPassword()), - nickname, - command.getAge(), - command.getHashtags()); - - User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); - - // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 - deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(FindByEmailQuery.of(email)); - - return GeneralUserSignupResponse.of(user.getId()); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214043.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214043.java deleted file mode 100644 index 5edb0a1..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214043.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; -import com.ftm.server.application.command.user.DeleteByEmailCommand; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.command.user.GeneralUserSignupCommand; -import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.common.exception.CustomException; -import com.ftm.server.common.response.enums.ErrorResponseCode; -import com.ftm.server.common.utils.RandomNickNameCreator; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class GeneralUserSignupService implements GeneralUserSignupUseCase { - - // service - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; - private final CheckUserPort checksUserPort; - private final SaveUserPort saveUserPort; - private final SaveUserImagePort saveUserImagePort; - - // gateway - private final SecurityAuthenticationPort authenticationPort; - - @Transactional - @Override - public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { - String email = command.getEmail(); - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( - FindByEmailQuery.of(email)); - - if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 - throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); - } - - if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. - throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); - } - - String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 - - GeneralUserCreationCommand convertedCommand = - GeneralUserCreationCommand.of( - command.getEmail(), - authenticationPort.passwordEncode(command.getPassword()), - nickname, - command.getAge(), - command.getHashtags()); - - User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); - - // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 - deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(DeleteByEmailCommand.of(email)); - - return GeneralUserSignupResponse.of(user.getId()); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214051.java b/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214051.java deleted file mode 100644 index 5edb0a1..0000000 --- a/.history/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService_20250622214051.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.ftm.server.application.service.user; - -import com.ftm.server.adapter.in.web.user.dto.response.GeneralUserSignupResponse; -import com.ftm.server.application.command.user.DeleteByEmailCommand; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.command.user.GeneralUserSignupCommand; -import com.ftm.server.application.port.in.user.GeneralUserSignupUseCase; -import com.ftm.server.application.port.out.persistence.user.CheckUserPort; -import com.ftm.server.application.port.out.persistence.user.DeleteEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.LoadEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.port.out.security.SecurityAuthenticationPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.common.exception.CustomException; -import com.ftm.server.common.response.enums.ErrorResponseCode; -import com.ftm.server.common.utils.RandomNickNameCreator; -import com.ftm.server.domain.entity.EmailVerificationLogs; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import jakarta.transaction.Transactional; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class GeneralUserSignupService implements GeneralUserSignupUseCase { - - // service - private final LoadEmailVerificationLogPort loadEmailVerificationLogPort; - private final DeleteEmailVerificationLogPort deleteEmailVerificationLogPort; - private final CheckUserPort checksUserPort; - private final SaveUserPort saveUserPort; - private final SaveUserImagePort saveUserImagePort; - - // gateway - private final SecurityAuthenticationPort authenticationPort; - - @Transactional - @Override - public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { - String email = command.getEmail(); - Optional emailVerificationLogs = - loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( - FindByEmailQuery.of(email)); - - if (checksUserPort.checksUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사 - throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); - } - - if (emailVerificationLogs.isEmpty()) { // 이메일 인증이 완료되지 않음. - throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); - } - - String nickname = RandomNickNameCreator.generateNickname(); // random 닉네임 생성 - - GeneralUserCreationCommand convertedCommand = - GeneralUserCreationCommand.of( - command.getEmail(), - authenticationPort.passwordEncode(command.getPassword()), - nickname, - command.getAge(), - command.getHashtags()); - - User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); - - // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 - deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(DeleteByEmailCommand.of(email)); - - return GeneralUserSignupResponse.of(user.getId()); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250407231748.java b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250407231748.java deleted file mode 100644 index 022e946..0000000 --- a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250407231748.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.ftm.server.application.vo.user; - -import lombok.Data; - -@Data -public class EmailCodeVerificationVo { - private final Boolean isVerified; - - public static EmailCodeVerificationVo of(Boolean isVerified) { - return new EmailCodeVerificationVo(isVerified); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204648.java b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204648.java deleted file mode 100644 index d7988fd..0000000 --- a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204648.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ftm.server.application.vo.user; - -import lombok.Data; - -@Data -public class EmailCodeVerificationVo { - private final Boolean isVerified; - private final Boolean isRecoverable; // 계정 복구 가능 여부 (soft delete 상태인지) - - public static EmailCodeVerificationVo of(Boolean isVerified) { - return new EmailCodeVerificationVo(isVerified, false); - } - - public static EmailCodeVerificationVo of(Boolean isVerified, Boolean isRecoverable) { - return new EmailCodeVerificationVo(isVerified, isRecoverable); - } -} diff --git a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204931.java b/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204931.java deleted file mode 100644 index d7988fd..0000000 --- a/.history/src/main/java/com/ftm/server/application/vo/user/EmailCodeVerificationVo_20250622204931.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ftm.server.application.vo.user; - -import lombok.Data; - -@Data -public class EmailCodeVerificationVo { - private final Boolean isVerified; - private final Boolean isRecoverable; // 계정 복구 가능 여부 (soft delete 상태인지) - - public static EmailCodeVerificationVo of(Boolean isVerified) { - return new EmailCodeVerificationVo(isVerified, false); - } - - public static EmailCodeVerificationVo of(Boolean isVerified, Boolean isRecoverable) { - return new EmailCodeVerificationVo(isVerified, isRecoverable); - } -} diff --git a/.history/src/test/java/com/ftm/server/BaseTest_20250528010752.java b/.history/src/test/java/com/ftm/server/BaseTest_20250528010752.java deleted file mode 100644 index 6e4bfc4..0000000 --- a/.history/src/test/java/com/ftm/server/BaseTest_20250528010752.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.ftm.server; - -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyHeaders; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.port.out.persistence.auth.LoadUserForAuthPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import com.ftm.server.domain.enums.AgeGroup; -import com.ftm.server.domain.enums.HashTag; -import com.ftm.server.domain.enums.UserRole; -import com.ftm.server.infrastructure.security.UserPrincipal; -import groovy.util.logging.Slf4j; -import java.util.List; -import java.util.UUID; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.restdocs.RestDocumentationContextProvider; -import org.springframework.restdocs.RestDocumentationExtension; -import org.springframework.restdocs.operation.preprocess.HeadersModifyingOperationPreprocessor; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -@Slf4j -@AutoConfigureMockMvc -@AutoConfigureRestDocs -@SpringBootTest(classes = {ServerApplication.class}) -@ActiveProfiles("test") -@ExtendWith({RestDocumentationExtension.class}) -@AutoConfigureTestDatabase( - replace = AutoConfigureTestDatabase.Replace.NONE) // 테스트 시 내장된 인메모리 DB를 사용하지 않는다는 설정 -@TestPropertySource(locations = "file:.env") -public class BaseTest { - - @Autowired protected MockMvc mockMvc; - - protected final ObjectMapper mapper = new ObjectMapper(); - - @Autowired private SaveUserPort saveUserPort; - @Autowired private SaveUserImagePort saveUserImagePort; - @Autowired private LoadUserForAuthPort loadUserForAuthPort; - - @BeforeEach - void setup(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) { - this.mockMvc = - MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) // secrutiy filter 적용 - .apply(documentationConfiguration(restDocumentation)) - .build(); - } - - // 블필요한 header 제거 함수 - protected HeadersModifyingOperationPreprocessor getModifiedHeader() { - return modifyHeaders() - .remove("X-Content-Type-Options") - .remove("X-XSS-Protection") - .remove("Cache-Control") - .remove("Pragma") - .remove("Expires") - .remove("Content-Length") - .remove("X-Frame-Options") - .remove("Vary"); - } - - // 사용자 생성 및 저장 - protected User createTestUser(String email, String password) { - String nickname = "test " + UUID.randomUUID(); - User user = - User.createGeneralUser( - GeneralUserCreationCommand.of( - email, - password, - nickname, - AgeGroup.FIFTIES, - List.of(HashTag.PERFUME))); - User testUser = saveUserPort.saveUser(user); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(testUser.getId())); - return testUser; - } - - protected MockHttpSession createUserAndLogin() { - return createUserAndLogin("test@gmail.com", "123456qwe!"); - } - - // test 사용자 생성 후 mock session 생성 - protected MockHttpSession createUserAndLogin(String email, String password) { - - // 사용자 생성 - User user = createTestUser(email, password); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } - - protected MockHttpSession login(String email) { - User user = loadUserForAuthPort.loadUserByEmail(FindByEmailQuery.of(email)).get(); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } - - public record SessionAndUser(MockHttpSession mockHttpSession, User user) {} - - // Session과 함께 User도 반환 - protected SessionAndUser createUserAndLoginAndReturnUser() { - return createUserAndLoginAndReturnUser("test@gmail.com", "123456qwe!"); - } - - protected SessionAndUser createUserAndLoginAndReturnUser(String email, String password) { - - // 사용자 생성 - User user = createTestUser(email, password); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return new SessionAndUser(session, user); - } - - protected MockHttpSession createAdminUserAndLogin() { - String email = "admin@gmail.com"; - String password = "admin1234!"; - String nickname = "admintest"; - - User admin = User.createAdminUser(email, password, nickname); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(admin), - null, - List.of(new SimpleGrantedAuthority("ROLE_" + UserRole.ADMIN.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } -} diff --git a/.history/src/test/java/com/ftm/server/BaseTest_20250622205652.java b/.history/src/test/java/com/ftm/server/BaseTest_20250622205652.java deleted file mode 100644 index 3943899..0000000 --- a/.history/src/test/java/com/ftm/server/BaseTest_20250622205652.java +++ /dev/null @@ -1,206 +0,0 @@ -package com.ftm.server; - -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyHeaders; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.port.out.persistence.auth.LoadUserForAuthPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import com.ftm.server.domain.enums.AgeGroup; -import com.ftm.server.domain.enums.HashTag; -import com.ftm.server.domain.enums.UserRole; -import com.ftm.server.infrastructure.security.UserPrincipal; -import groovy.util.logging.Slf4j; -import java.time.LocalDateTime; -import java.util.List; -import java.util.UUID; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.restdocs.RestDocumentationContextProvider; -import org.springframework.restdocs.RestDocumentationExtension; -import org.springframework.restdocs.operation.preprocess.HeadersModifyingOperationPreprocessor; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -@Slf4j -@AutoConfigureMockMvc -@AutoConfigureRestDocs -@SpringBootTest(classes = {ServerApplication.class}) -@ActiveProfiles("test") -@ExtendWith({RestDocumentationExtension.class}) -@AutoConfigureTestDatabase( - replace = AutoConfigureTestDatabase.Replace.NONE) // 테스트 시 내장된 인메모리 DB를 사용하지 않는다는 설정 -@TestPropertySource(locations = "file:.env") -public class BaseTest { - - @Autowired protected MockMvc mockMvc; - - protected final ObjectMapper mapper = new ObjectMapper(); - - @Autowired private SaveUserPort saveUserPort; - @Autowired private SaveUserImagePort saveUserImagePort; - @Autowired private LoadUserForAuthPort loadUserForAuthPort; - - @BeforeEach - void setup(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) { - this.mockMvc = - MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) // secrutiy filter 적용 - .apply(documentationConfiguration(restDocumentation)) - .build(); - } - - // 블필요한 header 제거 함수 - protected HeadersModifyingOperationPreprocessor getModifiedHeader() { - return modifyHeaders() - .remove("X-Content-Type-Options") - .remove("X-XSS-Protection") - .remove("Cache-Control") - .remove("Pragma") - .remove("Expires") - .remove("Content-Length") - .remove("X-Frame-Options") - .remove("Vary"); - } - - // 사용자 생성 및 저장 - protected User createTestUser(String email, String password) { - String nickname = "test " + UUID.randomUUID(); - User user = - User.createGeneralUser( - GeneralUserCreationCommand.of( - email, - password, - nickname, - AgeGroup.FIFTIES, - List.of(HashTag.PERFUME))); - User testUser = saveUserPort.saveUser(user); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(testUser.getId())); - return testUser; - } - - // 사용자를 soft delete 상태로 만드는 헬퍼 메서드 - protected User createSoftDeletedUser(String email, String password) { - User user = createTestUser(email, password); - user.updateIsDeleted(true); - user.updateDeletedAt(LocalDateTime.now()); - saveUserPort.saveUser(user); - return user; - } - - protected MockHttpSession createUserAndLogin() { - return createUserAndLogin("test@gmail.com", "123456qwe!"); - } - - // test 사용자 생성 후 mock session 생성 - protected MockHttpSession createUserAndLogin(String email, String password) { - - // 사용자 생성 - User user = createTestUser(email, password); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } - - protected MockHttpSession login(String email) { - User user = loadUserForAuthPort.loadUserByEmail(FindByEmailQuery.of(email)).get(); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } - - public record SessionAndUser(MockHttpSession mockHttpSession, User user) {} - - // Session과 함께 User도 반환 - protected SessionAndUser createUserAndLoginAndReturnUser() { - return createUserAndLoginAndReturnUser("test@gmail.com", "123456qwe!"); - } - - protected SessionAndUser createUserAndLoginAndReturnUser(String email, String password) { - - // 사용자 생성 - User user = createTestUser(email, password); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return new SessionAndUser(session, user); - } - - protected MockHttpSession createAdminUserAndLogin() { - String email = "admin@gmail.com"; - String password = "admin1234!"; - String nickname = "admintest"; - - User admin = User.createAdminUser(email, password, nickname); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(admin), - null, - List.of(new SimpleGrantedAuthority("ROLE_" + UserRole.ADMIN.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } -} diff --git a/.history/src/test/java/com/ftm/server/BaseTest_20250622210207.java b/.history/src/test/java/com/ftm/server/BaseTest_20250622210207.java deleted file mode 100644 index 72b2ff2..0000000 --- a/.history/src/test/java/com/ftm/server/BaseTest_20250622210207.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.ftm.server; - -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyHeaders; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ftm.server.application.command.user.GeneralUserCreationCommand; -import com.ftm.server.application.port.out.persistence.auth.LoadUserForAuthPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserImagePort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.entity.UserImage; -import com.ftm.server.domain.enums.AgeGroup; -import com.ftm.server.domain.enums.HashTag; -import com.ftm.server.domain.enums.UserRole; -import com.ftm.server.infrastructure.security.UserPrincipal; -import groovy.util.logging.Slf4j; -import java.time.LocalDateTime; -import java.util.List; -import java.util.UUID; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.restdocs.RestDocumentationContextProvider; -import org.springframework.restdocs.RestDocumentationExtension; -import org.springframework.restdocs.operation.preprocess.HeadersModifyingOperationPreprocessor; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -@Slf4j -@AutoConfigureMockMvc -@AutoConfigureRestDocs -@SpringBootTest(classes = {ServerApplication.class}) -@ActiveProfiles("test") -@ExtendWith({RestDocumentationExtension.class}) -@AutoConfigureTestDatabase( - replace = AutoConfigureTestDatabase.Replace.NONE) // 테스트 시 내장된 인메모리 DB를 사용하지 않는다는 설정 -@TestPropertySource(locations = "file:.env") -public class BaseTest { - - @Autowired protected MockMvc mockMvc; - - protected final ObjectMapper mapper = new ObjectMapper(); - - @Autowired private SaveUserPort saveUserPort; - @Autowired private SaveUserImagePort saveUserImagePort; - @Autowired private LoadUserForAuthPort loadUserForAuthPort; - - @BeforeEach - void setup(WebApplicationContext context, RestDocumentationContextProvider restDocumentation) { - this.mockMvc = - MockMvcBuilders.webAppContextSetup(context) - .apply(SecurityMockMvcConfigurers.springSecurity()) // secrutiy filter 적용 - .apply(documentationConfiguration(restDocumentation)) - .build(); - } - - // 블필요한 header 제거 함수 - protected HeadersModifyingOperationPreprocessor getModifiedHeader() { - return modifyHeaders() - .remove("X-Content-Type-Options") - .remove("X-XSS-Protection") - .remove("Cache-Control") - .remove("Pragma") - .remove("Expires") - .remove("Content-Length") - .remove("X-Frame-Options") - .remove("Vary"); - } - - // 사용자 생성 및 저장 - protected User createTestUser(String email, String password) { - String nickname = "test " + UUID.randomUUID(); - User user = - User.createGeneralUser( - GeneralUserCreationCommand.of( - email, - password, - nickname, - AgeGroup.FIFTIES, - List.of(HashTag.PERFUME))); - User testUser = saveUserPort.saveUser(user); - saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(testUser.getId())); - return testUser; - } - - protected MockHttpSession createUserAndLogin() { - return createUserAndLogin("test@gmail.com", "123456qwe!"); - } - - // test 사용자 생성 후 mock session 생성 - protected MockHttpSession createUserAndLogin(String email, String password) { - - // 사용자 생성 - User user = createTestUser(email, password); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } - - protected MockHttpSession login(String email) { - User user = loadUserForAuthPort.loadUserByEmail(FindByEmailQuery.of(email)).get(); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } - - public record SessionAndUser(MockHttpSession mockHttpSession, User user) {} - - // Session과 함께 User도 반환 - protected SessionAndUser createUserAndLoginAndReturnUser() { - return createUserAndLoginAndReturnUser("test@gmail.com", "123456qwe!"); - } - - protected SessionAndUser createUserAndLoginAndReturnUser(String email, String password) { - - // 사용자 생성 - User user = createTestUser(email, password); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(user), - null, - List.of(new SimpleGrantedAuthority(UserRole.USER.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return new SessionAndUser(session, user); - } - - protected MockHttpSession createAdminUserAndLogin() { - String email = "admin@gmail.com"; - String password = "admin1234!"; - String nickname = "admintest"; - - User admin = User.createAdminUser(email, password, nickname); - - // session 생성 - SecurityContext context = SecurityContextHolder.createEmptyContext(); - UsernamePasswordAuthenticationToken auth = - new UsernamePasswordAuthenticationToken( - UserPrincipal.of(admin), - null, - List.of(new SimpleGrantedAuthority("ROLE_" + UserRole.ADMIN.name()))); - context.setAuthentication(auth); - - MockHttpSession session = new MockHttpSession(); - session.setAttribute( - HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - - return session; - } -} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250407231748.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250407231748.java deleted file mode 100644 index d8a08a2..0000000 --- a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250407231748.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.ftm.server.user; - -import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.ftm.server.BaseTest; -import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; -import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; -import jakarta.transaction.Transactional; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.web.servlet.ResultActions; - -public class EmailCodeVerificationTest extends BaseTest { - - @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; - - private final List requestFieldDescriptors = - List.of( - fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), - fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); - - private final List responseFieldDescriptors = - List.of( - fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), - fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), - fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), - fieldWithPath("data.isVerified") - .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부")); - - private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { - return mockMvc.perform( // api 실행 - RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") - .contentType(MediaType.APPLICATION_JSON) // request body content type - .content(mapper.writeValueAsString(request))); - } - - // 문서화 반환 함수 - private RestDocumentationResultHandler getDocument(Integer identifier) { - return document( - "emailCodeVerification/" + identifier, - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint(), getModifiedHeader()), - responseFields(responseFieldDescriptors), - requestFields(requestFieldDescriptors), - resource( - ResourceSnippetParameters.builder() - .tag("회원") - .summary("이메일 인증 코드 검증 api") - .description("이메일 인증 코드를 검증하는 api입니다.") - .responseFields(responseFieldDescriptors) - .requestFields(requestFieldDescriptors) - .build())); - } - - @Test - @Transactional - void 이메일_인증코드_검증_성공() throws Exception { - - String email = "test@gmail.com"; - String code = "123456"; - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions.andExpect(status().isOk()); - - // documentation - resultActions.andDo(getDocument(1)); - } -} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622204717.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622204717.java deleted file mode 100644 index da02fc6..0000000 --- a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622204717.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.ftm.server.user; - -import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.ftm.server.BaseTest; -import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; -import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; -import jakarta.transaction.Transactional; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.web.servlet.ResultActions; - -public class EmailCodeVerificationTest extends BaseTest { - - @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; - - private final List requestFieldDescriptors = - List.of( - fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), - fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); - - private final List responseFieldDescriptors = - List.of( - fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), - fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), - fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), - fieldWithPath("data.isVerified") - .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부"), - fieldWithPath("data.isRecoverable") - .type(JsonFieldType.BOOLEAN) - .description("계정 복구 가능 여부 (soft delete 상태인지)")); - - private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { - return mockMvc.perform( // api 실행 - RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") - .contentType(MediaType.APPLICATION_JSON) // request body content type - .content(mapper.writeValueAsString(request))); - } - - // 문서화 반환 함수 - private RestDocumentationResultHandler getDocument(Integer identifier) { - return document( - "emailCodeVerification/" + identifier, - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint(), getModifiedHeader()), - responseFields(responseFieldDescriptors), - requestFields(requestFieldDescriptors), - resource( - ResourceSnippetParameters.builder() - .tag("회원") - .summary("이메일 인증 코드 검증 api") - .description("이메일 인증 코드를 검증하는 api입니다.") - .responseFields(responseFieldDescriptors) - .requestFields(requestFieldDescriptors) - .build())); - } - - @Test - @Transactional - void 이메일_인증코드_검증_성공() throws Exception { - - String email = "test@gmail.com"; - String code = "123456"; - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions.andExpect(status().isOk()); - - // documentation - resultActions.andDo(getDocument(1)); - } -} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205425.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205425.java deleted file mode 100644 index da02fc6..0000000 --- a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205425.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.ftm.server.user; - -import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.ftm.server.BaseTest; -import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; -import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; -import jakarta.transaction.Transactional; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.web.servlet.ResultActions; - -public class EmailCodeVerificationTest extends BaseTest { - - @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; - - private final List requestFieldDescriptors = - List.of( - fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), - fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); - - private final List responseFieldDescriptors = - List.of( - fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), - fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), - fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), - fieldWithPath("data.isVerified") - .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부"), - fieldWithPath("data.isRecoverable") - .type(JsonFieldType.BOOLEAN) - .description("계정 복구 가능 여부 (soft delete 상태인지)")); - - private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { - return mockMvc.perform( // api 실행 - RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") - .contentType(MediaType.APPLICATION_JSON) // request body content type - .content(mapper.writeValueAsString(request))); - } - - // 문서화 반환 함수 - private RestDocumentationResultHandler getDocument(Integer identifier) { - return document( - "emailCodeVerification/" + identifier, - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint(), getModifiedHeader()), - responseFields(responseFieldDescriptors), - requestFields(requestFieldDescriptors), - resource( - ResourceSnippetParameters.builder() - .tag("회원") - .summary("이메일 인증 코드 검증 api") - .description("이메일 인증 코드를 검증하는 api입니다.") - .responseFields(responseFieldDescriptors) - .requestFields(requestFieldDescriptors) - .build())); - } - - @Test - @Transactional - void 이메일_인증코드_검증_성공() throws Exception { - - String email = "test@gmail.com"; - String code = "123456"; - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions.andExpect(status().isOk()); - - // documentation - resultActions.andDo(getDocument(1)); - } -} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205721.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205721.java deleted file mode 100644 index bc60406..0000000 --- a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622205721.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.ftm.server.user; - -import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.ftm.server.BaseTest; -import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; -import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.domain.entity.User; -import jakarta.transaction.Transactional; -import java.time.LocalDateTime; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.web.servlet.ResultActions; - -public class EmailCodeVerificationTest extends BaseTest { - - @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; - @Autowired private SaveUserPort saveUserPort; - - private final List requestFieldDescriptors = - List.of( - fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), - fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); - - private final List responseFieldDescriptors = - List.of( - fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), - fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), - fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), - fieldWithPath("data.isVerified") - .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부"), - fieldWithPath("data.isRecoverable") - .type(JsonFieldType.BOOLEAN) - .description("계정 복구 가능 여부")); - - private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { - return mockMvc.perform( // api 실행 - RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") - .contentType(MediaType.APPLICATION_JSON) // request body content type - .content(mapper.writeValueAsString(request))); - } - - // 문서화 반환 함수 - private RestDocumentationResultHandler getDocument(Integer identifier) { - return document( - "emailCodeVerification/" + identifier, - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint(), getModifiedHeader()), - responseFields(responseFieldDescriptors), - requestFields(requestFieldDescriptors), - resource( - ResourceSnippetParameters.builder() - .tag("회원") - .summary("이메일 인증 코드 검증 api") - .description("이메일 인증 코드를 검증하는 api입니다.") - .responseFields(responseFieldDescriptors) - .requestFields(requestFieldDescriptors) - .build())); - } - - @Test - @Transactional - void 이메일_인증코드_검증_성공() throws Exception { - - String email = "test@gmail.com"; - String code = "123456"; - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions.andExpect(status().isOk()); - - // documentation - resultActions.andDo(getDocument(1)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_실패() throws Exception { - - String email = "test@gmail.com"; - String correctCode = "123456"; - String wrongCode = "654321"; - - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, correctCode)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(false)) - .andExpect(jsonPath("$.data.isRecoverable").value(false)); - - // documentation - resultActions.andDo(getDocument(2)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_성공_soft_delete_사용자_복구_가능() throws Exception { - - String email = "softdeleted@gmail.com"; - String code = "123456"; - - // given - soft delete된 사용자 생성 - User softDeletedUser = createSoftDeletedUser(email, "password123!"); - - // given - 이메일 인증 로그 생성 - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(true)) - .andExpect(jsonPath("$.data.isRecoverable").value(true)); - - // documentation - resultActions.andDo(getDocument(3)); - } -} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622210254.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622210254.java deleted file mode 100644 index 27d1629..0000000 --- a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622210254.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.ftm.server.user; - -import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.ftm.server.BaseTest; -import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; -import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.domain.entity.User; -import jakarta.transaction.Transactional; -import java.time.LocalDateTime; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.web.servlet.ResultActions; - -public class EmailCodeVerificationTest extends BaseTest { - - @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; - @Autowired private SaveUserPort saveUserPort; - - private final List requestFieldDescriptors = - List.of( - fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), - fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); - - private final List responseFieldDescriptors = - List.of( - fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), - fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), - fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), - fieldWithPath("data.isVerified") - .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부"), - fieldWithPath("data.isRecoverable") - .type(JsonFieldType.BOOLEAN) - .description("계정 복구 가능 여부")); - - private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { - return mockMvc.perform( // api 실행 - RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") - .contentType(MediaType.APPLICATION_JSON) // request body content type - .content(mapper.writeValueAsString(request))); - } - - // 문서화 반환 함수 - private RestDocumentationResultHandler getDocument(Integer identifier) { - return document( - "emailCodeVerification/" + identifier, - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint(), getModifiedHeader()), - responseFields(responseFieldDescriptors), - requestFields(requestFieldDescriptors), - resource( - ResourceSnippetParameters.builder() - .tag("회원") - .summary("이메일 인증 코드 검증 api") - .description("이메일 인증 코드를 검증하는 api입니다.") - .responseFields(responseFieldDescriptors) - .requestFields(requestFieldDescriptors) - .build())); - } - - protected User createSoftDeletedUser(String email, String password) { - User user = createTestUser(email, password); - user.updateIsDeleted(true); - user.updateDeletedAt(LocalDateTime.now()); - saveUserPort.saveUser(user); - return user; - } - - - @Test - @Transactional - void 이메일_인증코드_검증_성공() throws Exception { - - String email = "test@gmail.com"; - String code = "123456"; - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions.andExpect(status().isOk()); - - // documentation - resultActions.andDo(getDocument(1)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_실패() throws Exception { - - String email = "test@gmail.com"; - String correctCode = "123456"; - String wrongCode = "654321"; - - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, correctCode)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(false)) - .andExpect(jsonPath("$.data.isRecoverable").value(false)); - - // documentation - resultActions.andDo(getDocument(2)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_성공_soft_delete_사용자_복구_가능() throws Exception { - - String email = "softdeleted@gmail.com"; - String code = "123456"; - - // given - soft delete된 사용자 생성 - User softDeletedUser = createSoftDeletedUser(email, "password123!"); - - // given - 이메일 인증 로그 생성 - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(true)) - .andExpect(jsonPath("$.data.isRecoverable").value(true)); - - // documentation - resultActions.andDo(getDocument(3)); - } -} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622211329.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622211329.java deleted file mode 100644 index 92d499b..0000000 --- a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622211329.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.ftm.server.user; - -import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.ftm.server.BaseTest; -import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; -import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.domain.entity.User; -import jakarta.transaction.Transactional; -import java.time.LocalDateTime; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.web.servlet.ResultActions; - -public class EmailCodeVerificationTest extends BaseTest { - - @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; - @Autowired private SaveUserPort saveUserPort; - - private final List requestFieldDescriptors = - List.of( - fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), - fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); - - private final List responseFieldDescriptors = - List.of( - fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), - fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), - fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), - fieldWithPath("data.isVerified") - .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부"), - fieldWithPath("data.isRecoverable") - .type(JsonFieldType.BOOLEAN) - .description("계정 복구 가능 여부")); - - private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { - return mockMvc.perform( // api 실행 - RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") - .contentType(MediaType.APPLICATION_JSON) // request body content type - .content(mapper.writeValueAsString(request))); - } - - // 문서화 반환 함수 - private RestDocumentationResultHandler getDocument(Integer identifier) { - return document( - "emailCodeVerification/" + identifier, - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint(), getModifiedHeader()), - responseFields(responseFieldDescriptors), - requestFields(requestFieldDescriptors), - resource( - ResourceSnippetParameters.builder() - .tag("회원") - .summary("이메일 인증 코드 검증 api") - .description("이메일 인증 코드를 검증하는 api입니다.") - .responseFields(responseFieldDescriptors) - .requestFields(requestFieldDescriptors) - .build())); - } - - protected User createSoftDeletedUser(String email, String password) { - User user = createTestUser(email, password); - user.updateIsDeleted(true); - user.updateDeletedAt(LocalDateTime.now()); - saveUserPort.saveUser(user); - return user; - } - - - @Test - @Transactional - void 이메일_인증코드_검증_성공() throws Exception { - - String email = "test@gmail.com"; - String code = "123456"; - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions.andExpect(status().isOk()); - - // documentation - resultActions.andDo(getDocument(1)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_실패() throws Exception { - - String email = "test@gmail.com"; - String correctCode = "123456"; - String wrongCode = "654321"; - - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, correctCode)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(false)) - .andExpect(jsonPath("$.data.isRecoverable").value(false)); - - // documentation - resultActions.andDo(getDocument(2)); - } - - -} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213651.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213651.java deleted file mode 100644 index 38b48f5..0000000 --- a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213651.java +++ /dev/null @@ -1,202 +0,0 @@ -package com.ftm.server.user; - -import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.ftm.server.BaseTest; -import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; -import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.domain.entity.User; -import jakarta.transaction.Transactional; -import java.time.LocalDateTime; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.web.servlet.ResultActions; - -public class EmailCodeVerificationTest extends BaseTest { - - @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; - @Autowired private SaveUserPort saveUserPort; - - private final List requestFieldDescriptors = - List.of( - fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), - fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); - - private final List responseFieldDescriptors = - List.of( - fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), - fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), - fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), - fieldWithPath("data.isVerified") - .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부"), - fieldWithPath("data.isRecoverable") - .type(JsonFieldType.BOOLEAN) - .description("계정 복구 가능 여부")); - - private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { - return mockMvc.perform( // api 실행 - RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") - .contentType(MediaType.APPLICATION_JSON) // request body content type - .content(mapper.writeValueAsString(request))); - } - - // 문서화 반환 함수 - private RestDocumentationResultHandler getDocument(Integer identifier) { - return document( - "emailCodeVerification/" + identifier, - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint(), getModifiedHeader()), - responseFields(responseFieldDescriptors), - requestFields(requestFieldDescriptors), - resource( - ResourceSnippetParameters.builder() - .tag("회원") - .summary("이메일 인증 코드 검증 api") - .description("이메일 인증 코드를 검증하는 api입니다.") - .responseFields(responseFieldDescriptors) - .requestFields(requestFieldDescriptors) - .build())); - } - - protected User createSoftDeletedUser(String email, String password) { - User user = createTestUser(email, password); - user.updateIsDeleted(true); - user.updateDeletedAt(LocalDateTime.now()); - saveUserPort.saveUser(user); - return user; - } - - - @Test - @Transactional - void 이메일_인증코드_검증_성공() throws Exception { - - String email = "test@gmail.com"; - String code = "123456"; - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions.andExpect(status().isOk()); - - // documentation - resultActions.andDo(getDocument(1)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_실패() throws Exception { - - String email = "test@gmail.com"; - String correctCode = "123456"; - String wrongCode = "654321"; - - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, correctCode)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(false)) - .andExpect(jsonPath("$.data.isRecoverable").value(false)); - - // documentation - resultActions.andDo(getDocument(2)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_성공_soft_delete_사용자_복구_가능() throws Exception { - - String email = "softdeleted@gmail.com"; - String code = "123456"; - - // given - soft delete된 사용자 생성 - User softDeletedUser = createSoftDeletedUser(email, "password123!"); - - // given - 이메일 인증 로그 생성 - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(true)) - .andExpect(jsonPath("$.data.isRecoverable").value(true)); - - // documentation - resultActions.andDo(getDocument(3)); - } - - @Test - @Transactional - void 회원가입_완료_후_이메일_인증_로그_삭제_확인() throws Exception { - - String email = "signup@gmail.com"; - String code = "123456"; - - // given - 이메일 인증 로그 생성 - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // given - 이메일 인증 코드 검증 - getResultActions(new EmailCodeVerificationRequest(email, code)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(true)); - - // when - 회원가입 진행 - GeneralUserSignupRequest signupRequest = new GeneralUserSignupRequest( - email, "password123!", AgeGroup.TWENTIES, List.of(HashTag.PERFUME)); - - ResultActions signupResult = mockMvc.perform( - RestDocumentationRequestBuilders.post("/api/users/signup") - .contentType(MediaType.APPLICATION_JSON) - .content(mapper.writeValueAsString(signupRequest))); - - // then - 회원가입 성공 - signupResult.andExpect(status().isCreated()); - - // then - 이메일 인증 로그가 삭제되었는지 확인 (다시 인증 코드 검증 시도) - ResultActions verificationResult = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - verificationResult - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(false)) - .andExpect(jsonPath("$.data.isRecoverable").value(false)); - - // documentation - verificationResult.andDo(getDocument(4)); - } - -} diff --git a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213710.java b/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213710.java deleted file mode 100644 index fd191ce..0000000 --- a/.history/src/test/java/com/ftm/server/user/EmailCodeVerificationTest_20250622213710.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.ftm.server.user; - -import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.ftm.server.BaseTest; -import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.adapter.in.web.user.dto.request.GeneralUserSignupRequest; -import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; -import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; -import com.ftm.server.application.port.out.persistence.user.SaveUserPort; -import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.enums.AgeGroup; -import com.ftm.server.domain.enums.HashTag; -import jakarta.transaction.Transactional; -import java.time.LocalDateTime; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.restdocs.payload.FieldDescriptor; -import org.springframework.restdocs.payload.JsonFieldType; -import org.springframework.test.web.servlet.ResultActions; - -public class EmailCodeVerificationTest extends BaseTest { - - @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; - @Autowired private SaveUserPort saveUserPort; - - private final List requestFieldDescriptors = - List.of( - fieldWithPath("email").type(JsonFieldType.STRING).description("인증 email"), - fieldWithPath("code").type(JsonFieldType.STRING).description("인증 코드")); - - private final List responseFieldDescriptors = - List.of( - fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태"), - fieldWithPath("code").type(JsonFieldType.STRING).description("상태 코드"), - fieldWithPath("message").type(JsonFieldType.STRING).description("메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).optional().description("data"), - fieldWithPath("data.isVerified") - .type(JsonFieldType.BOOLEAN) - .description("검증 성공 여부"), - fieldWithPath("data.isRecoverable") - .type(JsonFieldType.BOOLEAN) - .description("계정 복구 가능 여부")); - - private ResultActions getResultActions(EmailCodeVerificationRequest request) throws Exception { - return mockMvc.perform( // api 실행 - RestDocumentationRequestBuilders.post("/api/users/email/authentication/code") - .contentType(MediaType.APPLICATION_JSON) // request body content type - .content(mapper.writeValueAsString(request))); - } - - // 문서화 반환 함수 - private RestDocumentationResultHandler getDocument(Integer identifier) { - return document( - "emailCodeVerification/" + identifier, - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint(), getModifiedHeader()), - responseFields(responseFieldDescriptors), - requestFields(requestFieldDescriptors), - resource( - ResourceSnippetParameters.builder() - .tag("회원") - .summary("이메일 인증 코드 검증 api") - .description("이메일 인증 코드를 검증하는 api입니다.") - .responseFields(responseFieldDescriptors) - .requestFields(requestFieldDescriptors) - .build())); - } - - protected User createSoftDeletedUser(String email, String password) { - User user = createTestUser(email, password); - user.updateIsDeleted(true); - user.updateDeletedAt(LocalDateTime.now()); - saveUserPort.saveUser(user); - return user; - } - - - @Test - @Transactional - void 이메일_인증코드_검증_성공() throws Exception { - - String email = "test@gmail.com"; - String code = "123456"; - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions.andExpect(status().isOk()); - - // documentation - resultActions.andDo(getDocument(1)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_실패() throws Exception { - - String email = "test@gmail.com"; - String correctCode = "123456"; - String wrongCode = "654321"; - - // given - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, correctCode)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, wrongCode)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(false)) - .andExpect(jsonPath("$.data.isRecoverable").value(false)); - - // documentation - resultActions.andDo(getDocument(2)); - } - - @Test - @Transactional - void 이메일_인증코드_검증_성공_soft_delete_사용자_복구_가능() throws Exception { - - String email = "softdeleted@gmail.com"; - String code = "123456"; - - // given - soft delete된 사용자 생성 - User softDeletedUser = createSoftDeletedUser(email, "password123!"); - - // given - 이메일 인증 로그 생성 - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // when - ResultActions resultActions = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - // then - resultActions - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(true)) - .andExpect(jsonPath("$.data.isRecoverable").value(true)); - - // documentation - resultActions.andDo(getDocument(3)); - } - - @Test - @Transactional - void 회원가입_완료_후_이메일_인증_로그_삭제_확인() throws Exception { - - String email = "signup@gmail.com"; - String code = "123456"; - - // given - 이메일 인증 로그 생성 - saveEmailVerificationLogPort.saveEmailVerificationLogs( - EmailVerificationLogCreationCommand.of(email, code)); - - // given - 이메일 인증 코드 검증 - getResultActions(new EmailCodeVerificationRequest(email, code)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(true)); - - // when - 회원가입 진행 - GeneralUserSignupRequest signupRequest = new GeneralUserSignupRequest( - email, "password123!", AgeGroup.TWENTIES, List.of(HashTag.PERFUME)); - - ResultActions signupResult = mockMvc.perform( - RestDocumentationRequestBuilders.post("/api/users/signup") - .contentType(MediaType.APPLICATION_JSON) - .content(mapper.writeValueAsString(signupRequest))); - - // then - 회원가입 성공 - signupResult.andExpect(status().isCreated()); - - // then - 이메일 인증 로그가 삭제되었는지 확인 (다시 인증 코드 검증 시도) - ResultActions verificationResult = - getResultActions(new EmailCodeVerificationRequest(email, code)); - - verificationResult - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.isVerified").value(false)) - .andExpect(jsonPath("$.data.isRecoverable").value(false)); - - // documentation - verificationResult.andDo(getDocument(4)); - } - -} diff --git a/src/main/java/com/ftm/server/adapter/out/cache/LoadTrendingPostsTestAdapter.java b/src/main/java/com/ftm/server/adapter/out/cache/LoadTrendingPostsTestAdapter.java index 1b61aaf..c7f5483 100644 --- a/src/main/java/com/ftm/server/adapter/out/cache/LoadTrendingPostsTestAdapter.java +++ b/src/main/java/com/ftm/server/adapter/out/cache/LoadTrendingPostsTestAdapter.java @@ -7,16 +7,15 @@ import com.ftm.server.application.query.FindPostsByCreatedDateQuery; import com.ftm.server.application.vo.post.PostWithBookmarkCountVo; import com.ftm.server.application.vo.post.TrendingPostVo; -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; - import java.time.LocalDate; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.IntStream; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor @@ -56,10 +55,10 @@ public List loadTrendingPosts() { Comparator.comparingDouble( p -> -((double) p.getViewCount() / finalMaxView - + (double) p.getLikeCount() - / finalMaxLike - + (double) p.getScrapCount() - / finalMaxScrap) + + (double) p.getLikeCount() + / finalMaxLike + + (double) p.getScrapCount() + / finalMaxScrap) / 3.0)) .limit(N) .toList(); diff --git a/src/main/java/com/ftm/server/adapter/out/persistence/adapter/user/UserDomainPersistenceAdapter.java b/src/main/java/com/ftm/server/adapter/out/persistence/adapter/user/UserDomainPersistenceAdapter.java index c451e7f..b214d2f 100644 --- a/src/main/java/com/ftm/server/adapter/out/persistence/adapter/user/UserDomainPersistenceAdapter.java +++ b/src/main/java/com/ftm/server/adapter/out/persistence/adapter/user/UserDomainPersistenceAdapter.java @@ -162,7 +162,8 @@ public List loadUserByDeleteOption(FindUserByDeleteOptionQuery query) { @Override public Optional loadDeletedUserByEmail(FindByEmailQuery query) { - Optional user = userRepository.findByEmailAndIsDeleted(query.getEmail(),true); + Optional user = + userRepository.findByEmailAndIsDeleted(query.getEmail(), true); return user.map(userMapper::toDomainEntity); } @@ -322,11 +323,11 @@ public List loadUserImagesByUserIdIn(FindUserImagesByIdsQuery query) @Override public Boolean checksNotDeletedUserByEmail(FindByEmailQuery query) { - return userRepository.existsByEmailAndIsDeleted(query.getEmail(), false); + return userRepository.existsByEmailAndIsDeleted(query.getEmail(), false); } @Override public Boolean checksUserSoftDeletedByEmail(FindByEmailQuery query) { - return userRepository.existsByEmailAndIsDeleted(query.getEmail(), true); + return userRepository.existsByEmailAndIsDeleted(query.getEmail(), true); } } diff --git a/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand.java b/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand.java index a1ddbe4..ee33c25 100644 --- a/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand.java +++ b/src/main/java/com/ftm/server/application/command/user/DeleteByEmailCommand.java @@ -9,4 +9,4 @@ public class DeleteByEmailCommand { public static DeleteByEmailCommand of(String email) { return new DeleteByEmailCommand(email); } -} \ No newline at end of file +} diff --git a/src/main/java/com/ftm/server/application/command/user/DeleteUserByEmailCommand.java b/src/main/java/com/ftm/server/application/command/user/DeleteUserByEmailCommand.java index 3577947..05b72ae 100644 --- a/src/main/java/com/ftm/server/application/command/user/DeleteUserByEmailCommand.java +++ b/src/main/java/com/ftm/server/application/command/user/DeleteUserByEmailCommand.java @@ -7,7 +7,8 @@ @Getter public class DeleteUserByEmailCommand { private final String email; - public static DeleteUserByEmailCommand of(String email){ + + public static DeleteUserByEmailCommand of(String email) { return new DeleteUserByEmailCommand(email); } } diff --git a/src/main/java/com/ftm/server/application/port/in/user/UserHardDeleteByEmailUseCase.java b/src/main/java/com/ftm/server/application/port/in/user/UserHardDeleteByEmailUseCase.java index db94977..258dcc0 100644 --- a/src/main/java/com/ftm/server/application/port/in/user/UserHardDeleteByEmailUseCase.java +++ b/src/main/java/com/ftm/server/application/port/in/user/UserHardDeleteByEmailUseCase.java @@ -2,7 +2,6 @@ import com.ftm.server.application.command.user.DeleteUserByEmailCommand; import com.ftm.server.common.annotation.Port; -import org.springframework.security.core.parameters.P; @Port public interface UserHardDeleteByEmailUseCase { diff --git a/src/main/java/com/ftm/server/application/port/out/persistence/user/DeleteEmailVerificationLogPort.java b/src/main/java/com/ftm/server/application/port/out/persistence/user/DeleteEmailVerificationLogPort.java index 3339459..6a70a61 100644 --- a/src/main/java/com/ftm/server/application/port/out/persistence/user/DeleteEmailVerificationLogPort.java +++ b/src/main/java/com/ftm/server/application/port/out/persistence/user/DeleteEmailVerificationLogPort.java @@ -6,4 +6,4 @@ @Port public interface DeleteEmailVerificationLogPort { void deleteEmailVerificationLogsByEmail(DeleteByEmailCommand command); -} \ No newline at end of file +} diff --git a/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService.java b/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService.java index 464378e..b781cb4 100644 --- a/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService.java +++ b/src/main/java/com/ftm/server/application/service/user/EmailCodeVerificationService.java @@ -31,13 +31,14 @@ public EmailCodeVerificationVo execute(EmailCodeVerificationQuery query) { if (emailVerificationLogs.isEmpty()) { // 검증 코드가 일치하지 않음 return EmailCodeVerificationVo.of(false); } - + emailVerificationLogs.get().updateVerificationStatus(true); // 검증 코드가 일치함 updateEmailVerificationLogPort.updateEmailVerificationLog(emailVerificationLogs.get()); - + // 해당 이메일의 계정 상태 확인 (soft delete 여부) - Boolean isRecoverable = checkUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(query.getEmail())); - + Boolean isRecoverable = + checkUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(query.getEmail())); + return EmailCodeVerificationVo.of(true, isRecoverable); } } diff --git a/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService.java b/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService.java index b8b3f83..ada92dc 100644 --- a/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService.java +++ b/src/main/java/com/ftm/server/application/service/user/GeneralUserSignupService.java @@ -29,7 +29,7 @@ @RequiredArgsConstructor public class GeneralUserSignupService implements GeneralUserSignupUseCase { - //usecase + // usecase private final UserHardDeleteByEmailUseCase userHardDeleteByEmailUseCase; // service @@ -50,7 +50,8 @@ public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { loadEmailVerificationLogPort.loadEmailVerificationLogByEmail( FindByEmailQuery.of(email)); - if (checksUserPort.checksNotDeletedUserByEmail(FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사(삭제되지 않은 user 에 한해서) + if (checksUserPort.checksNotDeletedUserByEmail( + FindByEmailQuery.of(email))) { // 기존에 가입된 회원인지 검사(삭제되지 않은 user 에 한해서) throw new CustomException(ErrorResponseCode.USER_ALREADY_EXISTS); } @@ -58,8 +59,8 @@ public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { throw new CustomException(ErrorResponseCode.EMAIL_NOT_VERIFIED); } - //회원 탈퇴 후 복구 없이 재가입하는 경우, 기존의 계정 정보 즉시 삭제 - if(checksUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(email))){ + // 회원 탈퇴 후 복구 없이 재가입하는 경우, 기존의 계정 정보 즉시 삭제 + if (checksUserPort.checksUserSoftDeletedByEmail(FindByEmailQuery.of(email))) { userHardDeleteByEmailUseCase.execute(DeleteUserByEmailCommand.of(email)); } @@ -75,10 +76,11 @@ public GeneralUserSignupResponse execute(GeneralUserSignupCommand command) { User user = saveUserPort.saveUser(User.createGeneralUser(convertedCommand)); saveUserImagePort.saveUserDefaultImage(UserImage.createUserImage(user.getId())); - + // 회원가입 완료 후 해당 이메일의 인증 로그 삭제 - deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail(DeleteByEmailCommand.of(email)); - + deleteEmailVerificationLogPort.deleteEmailVerificationLogsByEmail( + DeleteByEmailCommand.of(email)); + return GeneralUserSignupResponse.of(user.getId()); } } diff --git a/src/main/java/com/ftm/server/application/service/user/UserHardDeleteByEmailService.java b/src/main/java/com/ftm/server/application/service/user/UserHardDeleteByEmailService.java index a0fd31c..6b60a92 100644 --- a/src/main/java/com/ftm/server/application/service/user/UserHardDeleteByEmailService.java +++ b/src/main/java/com/ftm/server/application/service/user/UserHardDeleteByEmailService.java @@ -6,14 +6,11 @@ import com.ftm.server.application.port.out.s3.S3ImageDeletePort; import com.ftm.server.application.port.out.transcation.AfterCommitExecutorPort; import com.ftm.server.application.query.FindByEmailQuery; -import com.ftm.server.application.query.FindUserByDeleteOptionQuery; import com.ftm.server.domain.entity.User; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.time.LocalDate; import java.util.List; import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor @@ -32,17 +29,18 @@ public class UserHardDeleteByEmailService implements UserHardDeleteByEmailUseCas @Override public void execute(DeleteUserByEmailCommand command) { // 삭제 대상 user 조회 - Optional deletedUser = + Optional deletedUser = loadUserPort.loadDeletedUserByEmail(FindByEmailQuery.of(command.getEmail())); - if (deletedUser.isEmpty()){return;} + if (deletedUser.isEmpty()) { + return; + } List userId = List.of(deletedUser.get().getId()); // user 관련 엔티티 모두 삭제 // 1. 북마크 삭제 - deleteBookmarkPort.deleteBookmarkByUserList( - DeleteBookmarkByUserIdCommand.of(userId)); + deleteBookmarkPort.deleteBookmarkByUserList(DeleteBookmarkByUserIdCommand.of(userId)); // 2. 그루밍 결과 삭제 deleteGroomingTestResultPort.deleteGroomingTestResultByUserList( DeleteGroomingTestResultByUserIdCommand.of(userId)); diff --git a/src/test/java/com/ftm/server/BaseTest.java b/src/test/java/com/ftm/server/BaseTest.java index 72b2ff2..6e4bfc4 100644 --- a/src/test/java/com/ftm/server/BaseTest.java +++ b/src/test/java/com/ftm/server/BaseTest.java @@ -16,7 +16,6 @@ import com.ftm.server.domain.enums.UserRole; import com.ftm.server.infrastructure.security.UserPrincipal; import groovy.util.logging.Slf4j; -import java.time.LocalDateTime; import java.util.List; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/com/ftm/server/user/EmailCodeVerificationTest.java b/src/test/java/com/ftm/server/user/EmailCodeVerificationTest.java index 2bf4134..b81fc10 100644 --- a/src/test/java/com/ftm/server/user/EmailCodeVerificationTest.java +++ b/src/test/java/com/ftm/server/user/EmailCodeVerificationTest.java @@ -1,26 +1,20 @@ package com.ftm.server.user; import static com.epages.restdocs.apispec.ResourceDocumentation.resource; -import static io.restassured.RestAssured.when; import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.ftm.server.BaseTest; import com.ftm.server.adapter.in.web.user.dto.request.EmailCodeVerificationRequest; -import com.ftm.server.adapter.in.web.user.dto.request.GeneralUserSignupRequest; import com.ftm.server.application.command.user.EmailVerificationLogCreationCommand; import com.ftm.server.application.port.out.persistence.user.SaveEmailVerificationLogPort; import com.ftm.server.application.port.out.persistence.user.SaveUserPort; import com.ftm.server.application.port.out.smtp.MailSenderPort; import com.ftm.server.domain.entity.User; -import com.ftm.server.domain.enums.AgeGroup; -import com.ftm.server.domain.enums.HashTag; import jakarta.transaction.Transactional; import java.time.LocalDateTime; import java.util.List; @@ -39,8 +33,7 @@ public class EmailCodeVerificationTest extends BaseTest { @Autowired private SaveEmailVerificationLogPort saveEmailVerificationLogPort; @Autowired private SaveUserPort saveUserPort; - @MockitoBean - private MailSenderPort mailSenderPort; + @MockitoBean private MailSenderPort mailSenderPort; private final List requestFieldDescriptors = List.of( @@ -93,7 +86,6 @@ protected User createSoftDeletedUser(String email, String password) { return user; } - @Test @Transactional void 이메일_인증코드_검증_성공() throws Exception { @@ -103,8 +95,8 @@ protected User createSoftDeletedUser(String email, String password) { // given saveEmailVerificationLogPort.saveEmailVerificationLogs( EmailVerificationLogCreationCommand.of(email, code)); - //stub 객체 생성 - doNothing().when(mailSenderPort).sendEmail(email,code); + // stub 객체 생성 + doNothing().when(mailSenderPort).sendEmail(email, code); // when ResultActions resultActions =