From 12f8c7d7cd6fa7cb0e06b9291005f0be541a2086 Mon Sep 17 00:00:00 2001 From: whitem4rk <65115045+whitem4rk@users.noreply.github.com> Date: Sun, 17 Dec 2023 21:47:20 +0900 Subject: [PATCH] =?UTF-8?q?Revert=20"[refactor/#179]=20SignUp=20=EA=B0=9C?= =?UTF-8?q?=ED=8E=B8=20=EB=B0=8F=20=EA=B4=80=EB=A0=A8=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8fa85f1050c91e0a3ae406a58d8c229e8783518d. --- .../oauth2/CustomOAuth2UserService.java | 2 + .../oauth2/member/domain/entity/Member.java | 23 +- .../member/domain/service/MemberService.java | 7 +- .../domain/service/MemberServiceImpl.java | 25 +- .../member/domain/valueObject/Grade.java | 2 +- .../domain/valueObject/SchoolInformation.java | 1 - .../oauth2/member/dto/UpdateRequestDto.java | 2 +- .../member/repository/MemberRepository.java | 5 + .../repository/MemberRepositoryCustom.java | 3 +- .../repository/MemberRepositoryImpl.java | 5 +- .../security/MemberAuthorityProvider.java | 13 +- .../security/MemberPrincipalService.java | 13 +- .../security/masking/CustomObjectMapper.java | 3 - .../socialAccount/MemberSocialAccount.java | 4 +- .../MemberSocialAccountRepository.java | 2 +- .../MemberSocialAccountRepositoryCustom.java | 3 +- .../MemberSocialAccountRepositoryImpl.java | 5 +- .../oauth2/socialAccount/SocialAccount.java | 74 ++++ .../SocialAccountRepository.java | 12 + .../socialAccount/SocialAccountService.java | 12 + .../SocialAccountServiceImpl.java | 28 ++ .../member/domain/entity/MemberTest.java | 121 +++-- .../domain/service/MemberServiceTest.java | 62 +++ .../member/domain/valueObject/GradeTest.java | 4 + .../repository/MemberRepositoryTest.java | 46 +- .../SocialAccountRepositoryTest.java | 56 +++ .../SocialAccountServiceTest.java | 97 ++++ .../inhabas/api/config/WebSecurityConfig.java | 113 ++++- .../com/inhabas/api/domain/BaseEntity.java | 6 +- .../domain/comment/dto/CommentDetailDto.java | 2 +- .../domain/member/domain/entity/Answer.java | 36 ++ .../exception/NotWriteAnswersException.java | 2 +- .../exception/NotWriteProfileException.java | 2 +- .../{signUp => member}/dto/AnswerDto.java | 13 +- .../api/domain/member/dto/SignUpDto.java | 49 +++ .../member/repository/AnswerRepository.java | 14 + .../domain/member/usecase/AnswerService.java | 15 + .../member/usecase/AnswerServiceImpl.java | 44 ++ .../domain/member/usecase/SignUpService.java | 31 ++ .../member/usecase/SignUpServiceImpl.java | 149 +++++++ .../questionaire/domain/Questionnaire.java | 25 ++ .../questionaire/dto/QuestionnaireDto.java | 18 + .../repository/QuestionnaireRepository.java | 7 + .../usecase/QuestionnaireService.java | 10 + .../usecase/QuestionnaireServiceImpl.java | 8 +- .../questionnaire/domain/Questionnaire.java | 24 - .../questionnaire/dto/QuestionnaireDto.java | 16 - .../repository/QuestionnaireRepository.java | 12 - .../usecase/QuestionnaireService.java | 10 - .../domain/signUp/domain/entity/Answer.java | 44 -- .../api/domain/signUp/dto/SignUpDto.java | 55 --- .../signUp/repository/AnswerRepository.java | 12 - .../domain/signUp/usecase/AnswerService.java | 13 - .../signUp/usecase/AnswerServiceImpl.java | 100 ----- .../domain/signUp/usecase/SignUpService.java | 26 -- .../signUp/usecase/SignUpServiceImpl.java | 145 ------ .../SignUpAvailabilityChecker.java | 2 +- .../SignUpAvailabilityCheckerImpl.java | 2 +- .../domain/{usecase => }/SignUpScheduler.java | 2 +- .../{usecase => }/SignUpSchedulerStrict.java | 9 +- .../domain/entity/SignUpSchedule.java | 16 +- .../signUpSchedule/dto/SignUpScheduleDto.java | 35 +- .../com/inhabas/api/web/MemberController.java | 4 +- .../com/inhabas/api/web/SignUpController.java | 112 +++-- .../api/web/SignUpScheduleController.java | 20 +- .../LoginMemberArgumentResolver.java | 48 +- .../web/interceptor/InterceptorConfig.java | 2 +- .../SignUpControllerInterceptor.java | 2 +- .../SignUpIntegrationTest.java | 273 ++++++------ .../member/domain/entity/MemberTest.java | 123 +++--- .../MemberSocialAccountRepositoryTest.java | 43 +- .../security/MemberAuthorityProviderTest.java | 72 +-- .../security/MemberPrincipalServiceTest.java | 79 +++- .../member/usecase/AnswerServiceTest.java | 122 +++++ .../member/usecase/SignUpServiceTest.java | 381 ++++++++++++++++ .../menu/repository/MenuRepositoryTest.java | 45 +- .../QuestionnaireServiceTest.java | 19 +- .../QuestionnaireRepositoryTest.java | 43 -- .../domain}/SignUpScheduleTest.java | 12 +- .../domain}/StrictSignUpSchedulerTest.java | 20 +- .../signUp/domain/entity/AnswerTest.java | 31 -- .../repository/AnswerRepositoryTest.java | 56 --- .../signUp/usecase/AnswerServiceTest.java | 107 ----- .../signUp/usecase/SignUpServiceTest.java | 282 ------------ .../inhabas/api/web/MemberControllerTest.java | 104 ++--- .../inhabas/api/web/MenuControllerTest.java | 28 +- .../inhabas/api/web/SignUpControllerTest.java | 415 ++++++++++++------ .../api/web/SignUpScheduleControllerTest.java | 10 +- .../ArgumentResolverTest.java | 140 +++++- .../testAnnotataion/CustomSpringBootTest.java | 2 +- .../testAnnotataion/DefaultWebMvcTest.java | 4 +- .../WithMockJwtAuthenticationToken.java | 10 +- ...enticationTokenSecurityContextFactory.java | 21 +- .../TestConfigurationForSecurity.java | 45 +- 94 files changed, 2521 insertions(+), 1851 deletions(-) create mode 100644 module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccount.java create mode 100644 module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountRepository.java create mode 100644 module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountService.java create mode 100644 module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountServiceImpl.java create mode 100644 module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/socialaccount/SocialAccountRepositoryTest.java create mode 100644 module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/socialaccount/SocialAccountServiceTest.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/member/domain/entity/Answer.java rename resource-server/src/main/java/com/inhabas/api/domain/{signUp => member}/domain/exception/NotWriteAnswersException.java (88%) rename resource-server/src/main/java/com/inhabas/api/domain/{signUp => member}/domain/exception/NotWriteProfileException.java (88%) rename resource-server/src/main/java/com/inhabas/api/domain/{signUp => member}/dto/AnswerDto.java (51%) create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/member/dto/SignUpDto.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/member/repository/AnswerRepository.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/member/usecase/AnswerService.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/member/usecase/AnswerServiceImpl.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/member/usecase/SignUpService.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/member/usecase/SignUpServiceImpl.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/questionaire/domain/Questionnaire.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/questionaire/dto/QuestionnaireDto.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/questionaire/repository/QuestionnaireRepository.java create mode 100644 resource-server/src/main/java/com/inhabas/api/domain/questionaire/usecase/QuestionnaireService.java rename resource-server/src/main/java/com/inhabas/api/domain/{questionnaire => questionaire}/usecase/QuestionnaireServiceImpl.java (68%) delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/questionnaire/domain/Questionnaire.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/questionnaire/dto/QuestionnaireDto.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/questionnaire/repository/QuestionnaireRepository.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireService.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/entity/Answer.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/signUp/dto/SignUpDto.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/signUp/repository/AnswerRepository.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/AnswerService.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/AnswerServiceImpl.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/SignUpService.java delete mode 100644 resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/SignUpServiceImpl.java rename resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/{usecase => }/SignUpAvailabilityChecker.java (55%) rename resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/{usecase => }/SignUpAvailabilityCheckerImpl.java (90%) rename resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/{usecase => }/SignUpScheduler.java (77%) rename resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/{usecase => }/SignUpSchedulerStrict.java (95%) rename resource-server/src/test/java/com/inhabas/api/domain/{signUp => member}/SignUpIntegrationTest.java (55%) create mode 100644 resource-server/src/test/java/com/inhabas/api/domain/member/usecase/AnswerServiceTest.java create mode 100644 resource-server/src/test/java/com/inhabas/api/domain/member/usecase/SignUpServiceTest.java rename resource-server/src/test/java/com/inhabas/api/domain/questionnaire/{usecase => }/QuestionnaireServiceTest.java (64%) delete mode 100644 resource-server/src/test/java/com/inhabas/api/domain/questionnaire/repository/QuestionnaireRepositoryTest.java rename resource-server/src/test/java/com/inhabas/api/domain/{signUpSchedule/domain/entity => signUp/domain}/SignUpScheduleTest.java (97%) rename resource-server/src/test/java/com/inhabas/api/domain/{signUpSchedule/domain/usecase => signUp/domain}/StrictSignUpSchedulerTest.java (96%) delete mode 100644 resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/entity/AnswerTest.java delete mode 100644 resource-server/src/test/java/com/inhabas/api/domain/signUp/repository/AnswerRepositoryTest.java delete mode 100644 resource-server/src/test/java/com/inhabas/api/domain/signUp/usecase/AnswerServiceTest.java delete mode 100644 resource-server/src/test/java/com/inhabas/api/domain/signUp/usecase/SignUpServiceTest.java diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/CustomOAuth2UserService.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/CustomOAuth2UserService.java index 24401eb6..61f802a6 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/CustomOAuth2UserService.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/CustomOAuth2UserService.java @@ -2,6 +2,7 @@ import com.inhabas.api.auth.domain.exception.InvalidUserInfoException; import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; +import com.inhabas.api.auth.domain.oauth2.socialAccount.SocialAccountService; import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; import com.inhabas.api.auth.domain.oauth2.userAuthorityProvider.UserAuthorityProvider; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; @@ -24,6 +25,7 @@ @RequiredArgsConstructor public class CustomOAuth2UserService extends DefaultOAuth2UserService { + private final SocialAccountService socialAccountService; private final UserAuthorityProvider userAuthorityProvider; private final MemberService memberService; private final MemberRepository memberRepository; diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/entity/Member.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/entity/Member.java index c61ceefa..3e2ff9c0 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/entity/Member.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/entity/Member.java @@ -95,20 +95,12 @@ public Member(String name, String email, Role role) { this.email = new Email(email); this.ibasInformation = new IbasInformation(role); } - - public String getStudentId() { - return this.studentId != null ? this.studentId.getValue() : null; - } - public String getName() { - return this.name != null ? this.name.getValue() : null; + return this.name.getValue(); } public String getPhone() { - return this.phone != null ? this.phone.getValue() : null; - } - public SchoolInformation getSchoolInformation() { - return this.schoolInformation != null ? this.schoolInformation : null; + return this.phone.getValue(); } public String getEmail() { @@ -128,21 +120,10 @@ public void setName(String name) { this.name = new Name(name); } - public void setStudentId(String studentId) { - this.studentId = new StudentId(studentId); - } - public void setPhone(String phone) { - this.phone = new Phone(phone); - } - public void setEmail(String email) { this.email = new Email(email); } - public void setSchoolInformation(SchoolInformation schoolInformation) { - this.schoolInformation = schoolInformation; - } - public void setRole(Role role) { this.ibasInformation.setRole(role); } diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberService.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberService.java index eac80d40..653c0ac2 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberService.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberService.java @@ -2,9 +2,10 @@ import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; -import com.inhabas.api.auth.domain.oauth2.member.dto.ApprovedMemberManagementDto; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.dto.ContactDto; import com.inhabas.api.auth.domain.oauth2.member.dto.NotApprovedMemberManagementDto; +import com.inhabas.api.auth.domain.oauth2.member.dto.ApprovedMemberManagementDto; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; import org.springframework.data.domain.Pageable; @@ -16,6 +17,8 @@ public interface MemberService { // 가입 관련 void save(Member member); + Member findById(StudentId studentId); + Optional updateMember(Member member); void changeRole(Member member, Role role); @@ -28,7 +31,7 @@ public interface MemberService { List getApprovedMembersBySearchAndRole(String search); - void updateUnapprovedMembers(List memberIdList, String state); + void updateUnapprovedMembers(List memberIdList, String state); void updateApprovedMembers(List memberIdList, Role role); diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberServiceImpl.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberServiceImpl.java index 5669b7c9..678fe991 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberServiceImpl.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberServiceImpl.java @@ -2,10 +2,12 @@ import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; import com.inhabas.api.auth.domain.oauth2.member.domain.exception.DuplicatedMemberFieldException; +import com.inhabas.api.auth.domain.oauth2.member.domain.exception.MemberNotFoundException; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; -import com.inhabas.api.auth.domain.oauth2.member.dto.ApprovedMemberManagementDto; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.dto.ContactDto; import com.inhabas.api.auth.domain.oauth2.member.dto.NotApprovedMemberManagementDto; +import com.inhabas.api.auth.domain.oauth2.member.dto.ApprovedMemberManagementDto; import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; @@ -50,6 +52,14 @@ public void save(Member member) { memberRepository.save(member); } + + @Override + @Transactional(readOnly = true) + public Member findById(StudentId studentId) { + return memberRepository.findByStudentId(studentId) + .orElseThrow(MemberNotFoundException::new); + } + @Override @Transactional public Optional updateMember(Member member) { @@ -86,7 +96,7 @@ public List getNotApprovedMembersBySearchAndRole .map(member -> new NotApprovedMemberManagementDto( member.getName(), member.getId(), - member.getStudentId(), + member.getStudentId().getValue(), member.getPhone(), member.getEmail(), member.getSchoolInformation().getGrade(), @@ -106,7 +116,7 @@ public List getApprovedMembersBySearchAndRole(Strin .map(member -> new ApprovedMemberManagementDto( member.getName(), member.getId(), - member.getStudentId(), + member.getStudentId().getValue(), member.getPhone(), member.getRole(), member.getSchoolInformation().getGeneration(), @@ -117,9 +127,13 @@ public List getApprovedMembersBySearchAndRole(Strin @Override @Transactional - public void updateUnapprovedMembers(List memberIdList, String state) { + public void updateUnapprovedMembers(List memberIdList, String state) { - List members = memberRepository.findAllById(memberIdList); + List memberLongList = memberIdList.stream() + .map(Long::valueOf) + .collect(Collectors.toList()); + + List members = memberRepository.findAllById(memberLongList); boolean allNewMembers = members.stream().allMatch( member -> DEFAULT_ROLE_AFTER_FINISH_SIGNUP.equals(member.getRole())); @@ -128,6 +142,7 @@ public void updateUnapprovedMembers(List memberIdList, String state) { } if (state.equals(PASS_STATE)) { + for (Member member : members) member.setRole(DEACTIVATED); diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/Grade.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/Grade.java index 89b81210..23fbd68a 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/Grade.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/Grade.java @@ -26,7 +26,7 @@ boolean validate(Object value) { if (Objects.isNull(value)) return true; if (!(value instanceof Integer)) return false; int o = (Integer) value; - return 0 <= o && o <= 5; // 1학년부터 5학년(초과학기)까지 가능, 0학년은 학생이 아닐때 + return 1 <= o && o <= 5; // 1학년부터 5학년(초과학기)까지 가능, 0학년은 학생이 아닐때 } } diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/SchoolInformation.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/SchoolInformation.java index b5ba0333..9014dd58 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/SchoolInformation.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/SchoolInformation.java @@ -37,7 +37,6 @@ public SchoolInformation(String major, Integer generation, MemberType memberType this.major = new Major(major); this.generation = new Generation(generation); this.memberType = memberType; - this.grade = new Grade(DEFAULT_GRADE); } diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/dto/UpdateRequestDto.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/dto/UpdateRequestDto.java index 1eec7675..ff487787 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/dto/UpdateRequestDto.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/dto/UpdateRequestDto.java @@ -11,7 +11,7 @@ @AllArgsConstructor public class UpdateRequestDto { - private List memberIdList; + private List memberIdList; @Schema(example = "pass, fail") private String state; diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepository.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepository.java index 0afa5849..7979d863 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepository.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepository.java @@ -13,9 +13,14 @@ public interface MemberRepository extends JpaRepository, MemberRepositoryCustom { List findAllById(Iterable memberIdList); + Member getByStudentId(StudentId studentId); + + Optional findByStudentId(StudentId studentId); + Member findByIbasInformation_Role(Role role); + // OAuth boolean existsByProviderAndUid(OAuth2Provider provider, UID uid); Optional findByProviderAndUid(OAuth2Provider provider, UID uid); diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryCustom.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryCustom.java index 8c599539..6f14eddd 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryCustom.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryCustom.java @@ -2,6 +2,7 @@ import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.dto.MemberDuplicationQueryCondition; import com.inhabas.api.auth.domain.oauth2.member.security.MemberAuthorityProvider; @@ -10,7 +11,7 @@ public interface MemberRepositoryCustom { - MemberAuthorityProvider.RoleDto fetchRoleByStudentId(Long id); + MemberAuthorityProvider.RoleDto fetchRoleByStudentId(StudentId studentId); boolean isDuplicated(MemberDuplicationQueryCondition condition); diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryImpl.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryImpl.java index e402294e..9e7fce8e 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryImpl.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryImpl.java @@ -3,6 +3,7 @@ import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.dto.MemberDuplicationQueryCondition; import com.inhabas.api.auth.domain.oauth2.member.security.MemberAuthorityProvider; import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; @@ -28,10 +29,10 @@ public class MemberRepositoryImpl implements MemberRepositoryCustom { private final JPAQueryFactory queryFactory; @Override - public MemberAuthorityProvider.RoleDto fetchRoleByStudentId(Long id) { + public MemberAuthorityProvider.RoleDto fetchRoleByStudentId(StudentId studentId) { Role role = queryFactory .select(member.ibasInformation.role).from(member) - .where(member.id.eq(id)) + .where(member.studentId.eq(studentId)) .fetchOne(); return new MemberAuthorityProvider.RoleDto(role); diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/MemberAuthorityProvider.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/MemberAuthorityProvider.java index a4bfe9e1..b5032d65 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/MemberAuthorityProvider.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/MemberAuthorityProvider.java @@ -2,21 +2,20 @@ import com.inhabas.api.auth.domain.exception.InvalidUserInfoException; import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; import com.inhabas.api.auth.domain.oauth2.userAuthorityProvider.UserAuthorityProvider; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; import com.inhabas.api.auth.domain.token.securityFilter.UserPrincipalService; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; import lombok.RequiredArgsConstructor; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; +import java.util.*; import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role.SIGNING_UP; @@ -34,9 +33,9 @@ public Collection determineAuthorities(OAuth2UserInfo oA OAuth2UserInfoAuthentication authentication = new OAuth2UserInfoAuthentication(oAuth2UserInfo.getId(), oAuth2UserInfo.getProvider().toString(), oAuth2UserInfo.getEmail()); - Long memberId = (Long) userPrincipalService.loadUserPrincipal(authentication); + StudentId studentId = (StudentId) userPrincipalService.loadUserPrincipal(authentication); - if (Objects.isNull(memberId)) { // 기존회원이 아니면, member 테이블에 임시데이터 저장 + if (Objects.isNull(studentId)) { // 기존회원이 아니면, member 테이블에 임시데이터 저장 Member member = memberRepository.findByProviderAndUid( oAuth2UserInfo.getProvider(), new UID(oAuth2UserInfo.getId())) .orElseThrow(InvalidUserInfoException::new); @@ -47,7 +46,7 @@ public Collection determineAuthorities(OAuth2UserInfo oA } else { // 기존회원이면, - RoleDto roleDto = memberRepository.fetchRoleByStudentId(memberId); + RoleDto roleDto = memberRepository.fetchRoleByStudentId(studentId); if (roleDto.isEmpty()) throw new InvalidUserInfoException(); // 가입된 소셜 계정으로 회원 프로필을 찾을 수 없는 경우. diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/MemberPrincipalService.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/MemberPrincipalService.java index 196d20ea..b0a79b78 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/MemberPrincipalService.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/MemberPrincipalService.java @@ -2,12 +2,13 @@ import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Email; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccount; -import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccountRepository; import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; import com.inhabas.api.auth.domain.token.securityFilter.UserPrincipalNotFoundException; import com.inhabas.api.auth.domain.token.securityFilter.UserPrincipalService; +import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccountRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; @@ -42,8 +43,8 @@ public Object loadUserPrincipal(Authentication authentication) { Email email = new Email(oauth2UserInfoToken.getEmail()); try { - Long memberId = this.getMemberId(provider, uid, email).orElseThrow(UserPrincipalNotFoundException::new); - return memberId; + StudentId studentId = this.getMemberId(provider, uid, email).orElseThrow(UserPrincipalNotFoundException::new); + return studentId; } catch (UserPrincipalNotFoundException e) { log.info(e.getMessage()); return null; @@ -51,14 +52,14 @@ public Object loadUserPrincipal(Authentication authentication) { } - private Optional getMemberId(OAuth2Provider provider, UID uid, Email email) { + private Optional getMemberId(OAuth2Provider provider, UID uid, Email email) { return memberSocialAccountRepository.findMemberIdByUidAndProvider(uid, provider) .or(() -> this.findByEmailAndProviderForLegacy(email, provider, uid)); } - private Optional findByEmailAndProviderForLegacy(Email email, OAuth2Provider provider, UID uid) { + private Optional findByEmailAndProviderForLegacy(Email email, OAuth2Provider provider, UID uid) { Optional memberSocialAccount = memberSocialAccountRepository.findMemberSocialAccountByEmailAndProvider(email, provider); @@ -68,7 +69,7 @@ private Optional findByEmailAndProviderForLegacy(Email email, OAuth2Provid MemberSocialAccount socialAccount = memberSocialAccount.get(); socialAccount.SetUID(uid); memberSocialAccountRepository.save(socialAccount); - return Optional.of(socialAccount.getMember().getId()); + return Optional.of(socialAccount.getMember().getStudentId()); } else { diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/masking/CustomObjectMapper.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/masking/CustomObjectMapper.java index 6d6a6c55..31f4952e 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/masking/CustomObjectMapper.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/masking/CustomObjectMapper.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -17,8 +16,6 @@ public ObjectMapper objectMapper() { module.addSerializer(String.class, new StringPropertyMasker()); objectMapper.registerModule(module); - objectMapper.registerModule(new JavaTimeModule()); - return objectMapper; } } \ No newline at end of file diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccount.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccount.java index 2bd0dba1..45427def 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccount.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccount.java @@ -16,7 +16,7 @@ public class MemberSocialAccount { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + private Integer id; @OneToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "USER_ID") @@ -48,7 +48,7 @@ public MemberSocialAccount(Member member, String email, String uid, OAuth2Provid this.provider = provider; } - public Long getId() { + public Integer getId() { return this.id; } diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepository.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepository.java index e7eb8d16..f1d8fdb0 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepository.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepository.java @@ -7,7 +7,7 @@ import java.util.Optional; public interface MemberSocialAccountRepository - extends JpaRepository, MemberSocialAccountRepositoryCustom { + extends JpaRepository, MemberSocialAccountRepositoryCustom { /** * 레거시 호환성을 위해 존재. "회원가입 되어있지만 uid가 존재하지 않는 경우"에만 사용할 것. diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepositoryCustom.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepositoryCustom.java index c7b31b5c..123bbb89 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepositoryCustom.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepositoryCustom.java @@ -1,11 +1,12 @@ package com.inhabas.api.auth.domain.oauth2.member.security.socialAccount; import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; import java.util.Optional; public interface MemberSocialAccountRepositoryCustom { - Optional findMemberIdByUidAndProvider(UID uid, OAuth2Provider provider); + Optional findMemberIdByUidAndProvider(UID uid, OAuth2Provider provider); } diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepositoryImpl.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepositoryImpl.java index 429435c8..b44d18a3 100644 --- a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepositoryImpl.java +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/member/security/socialAccount/MemberSocialAccountRepositoryImpl.java @@ -1,6 +1,7 @@ package com.inhabas.api.auth.domain.oauth2.member.security.socialAccount; import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -16,9 +17,9 @@ public class MemberSocialAccountRepositoryImpl implements MemberSocialAccountRep private final JPAQueryFactory jpaQueryFactory; @Override - public Optional findMemberIdByUidAndProvider(UID uid, OAuth2Provider provider) { + public Optional findMemberIdByUidAndProvider(UID uid, OAuth2Provider provider) { return Optional.ofNullable(jpaQueryFactory - .select(memberSocialAccount.member.id) + .select(memberSocialAccount.member.studentId) .where(eqSocialAccount(uid, provider)) .from(memberSocialAccount) .fetchOne()); diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccount.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccount.java new file mode 100644 index 00000000..5e0e71fc --- /dev/null +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccount.java @@ -0,0 +1,74 @@ +package com.inhabas.api.auth.domain.oauth2.socialAccount; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; +import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Entity @Getter +@Table(name = "SOCIALACCOUNT", + uniqueConstraints = { @UniqueConstraint(name = "unique_socialaccount", columnNames = {"PROVIDER", "UID"})}) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class SocialAccount { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Enumerated(value = EnumType.STRING) + private OAuth2Provider provider; + + @Embedded + private UID uid; + + private LocalDateTime lastLogin; + + // 최초 로그인 날짜 + private LocalDateTime dateJoined; + + @Lob + private String extraData; + + @Column(length = 1000) + private String profileImageUrl; + + public SocialAccount(OAuth2Provider provider, String uid, LocalDateTime lastLogin, LocalDateTime dateJoined, String extraData) { + this.provider = provider; + this.uid = new UID(uid); + this.lastLogin = lastLogin; + this.dateJoined = dateJoined; + this.extraData = extraData; + } + + public SocialAccount(OAuth2UserInfo userInfo) { + this.provider = userInfo.getProvider(); + this.uid = new UID(userInfo.getId()); + this.lastLogin = LocalDateTime.now(); + this.dateJoined = LocalDateTime.now(); + this.profileImageUrl = userInfo.getImageUrl(); + try { + this.extraData = new ObjectMapper().writeValueAsString(userInfo.getExtraData()); + } catch (JsonProcessingException ignored) {} + } + + + public String getUid() { + return uid.getValue(); + } + + public OAuth2Provider getOAuth2Provider() { + return provider; + } + + public SocialAccount setLastLoginTime(LocalDateTime time) { + this.lastLogin = time; + return this; + } +} diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountRepository.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountRepository.java new file mode 100644 index 00000000..8d28ac12 --- /dev/null +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountRepository.java @@ -0,0 +1,12 @@ +package com.inhabas.api.auth.domain.oauth2.socialAccount; + +import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; +import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface SocialAccountRepository extends JpaRepository { + + Optional findByUidAndProvider(UID uid, OAuth2Provider provider); +} diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountService.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountService.java new file mode 100644 index 00000000..58ad9a26 --- /dev/null +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountService.java @@ -0,0 +1,12 @@ +package com.inhabas.api.auth.domain.oauth2.socialAccount; + +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; + +public interface SocialAccountService { + + /** + * OAuth2 인증이 정상적으로 완료된 {@code SocialAccount} 의 정보를 db에 저장한다. + * @param oAuth2UserInfo 인증 완료 후 가공된 소셜계정 정보 + */ + void updateSocialAccountInfo(OAuth2UserInfo oAuth2UserInfo); +} diff --git a/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountServiceImpl.java b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountServiceImpl.java new file mode 100644 index 00000000..f4c38117 --- /dev/null +++ b/module-auth/src/main/java/com/inhabas/api/auth/domain/oauth2/socialAccount/SocialAccountServiceImpl.java @@ -0,0 +1,28 @@ +package com.inhabas.api.auth.domain.oauth2.socialAccount; + +import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; + +@Service +@RequiredArgsConstructor +public class SocialAccountServiceImpl implements SocialAccountService { + + private final SocialAccountRepository socialAccountRepository; + + @Override + @Transactional + public void updateSocialAccountInfo(OAuth2UserInfo oAuth2UserInfo) { + + SocialAccount socialAccount = socialAccountRepository + .findByUidAndProvider(new UID(oAuth2UserInfo.getId()), oAuth2UserInfo.getProvider()) + .orElse(new SocialAccount(oAuth2UserInfo)) + .setLastLoginTime(LocalDateTime.now()); + + socialAccountRepository.save(socialAccount); + } +} diff --git a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/entity/MemberTest.java b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/entity/MemberTest.java index a4dd1120..bed99366 100644 --- a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/entity/MemberTest.java +++ b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/entity/MemberTest.java @@ -1,20 +1,59 @@ package com.inhabas.api.auth.domain.oauth2.member.domain.entity; -import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.IbasInformation; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.SchoolInformation; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.userInfo.GoogleOAuth2UserInfo; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; import java.util.HashMap; import java.util.Map; -import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType.UNDERGRADUATE; import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role.*; public class MemberTest { + + public static Member chiefMember() { + return new Member( + new StudentId("12171707"), "김회장", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(CHIEF)); + } + + public static Member executivesMember() { + return new Member( + new StudentId("12201122"), "박임원", "010-2222-2222", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(EXECUTIVES)); + } + + public static Member secretaryMember() { + return new Member( + new StudentId("12219882"), "이총무", "010-3333-3333", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(SECRETARY)); + } + + public static Member signingUpMember1() { + + Map attributes = new HashMap<>() {{ + put("provider", "GOOGLE"); + put("sub", "1249846925629348"); + put("picture", "/static/image.jpg"); + put("email", "my@gmail.com"); + put("name", "유동현"); + put("locale", "ko"); + }}; + OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); + Member member = new Member(user); + member.setRole(SIGNING_UP); - private static Member afterSignUpMember(Role role) { + return member; + } + + + public static Member signingUpMember2() { Map attributes = new HashMap<>() {{ put("provider", "GOOGLE"); @@ -26,46 +65,34 @@ private static Member afterSignUpMember(Role role) { }}; OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); Member member = new Member(user); - member.setRole(role); + member.setRole(SIGNING_UP); - // 회원정보 저장 - member.setStudentId("12171707"); - member.setPhone("010-1111-1111"); - member.setName("유동현"); - member.setSchoolInformation(new SchoolInformation("컴퓨터공학과", 1, 1, UNDERGRADUATE)); return member; - } - public static Member chiefMember() { - return afterSignUpMember(CHIEF); - } - public static Member executivesMember() { - return afterSignUpMember(EXECUTIVES); - } - - public static Member secretaryMember() { - return afterSignUpMember(SECRETARY); + public static Member basicMember1() { + return new Member( + new StudentId("12171234"), "유동현", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("건축공학과", 3) + , new IbasInformation(BASIC)); } - public static Member basicMember() { - return afterSignUpMember(BASIC); + public static Member basicMember2() { + return new Member( + new StudentId("12114321"), "김민겸", "010-2222-2222", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("경영학과", 2) + , new IbasInformation(BASIC)); } public static Member deactivatedMember() { - return afterSignUpMember(DEACTIVATED); + return new Member( + new StudentId("12171707"), "최비활", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(DEACTIVATED)); } public static Member notapprovedMember() { - return afterSignUpMember(NOT_APPROVED); - } - - public static Member signingUpMemberAfterProfile() { - return afterSignUpMember(SIGNING_UP); - } - - public static Member signingUpMember1() { Map attributes = new HashMap<>() {{ put("provider", "GOOGLE"); @@ -77,26 +104,30 @@ public static Member signingUpMember1() { }}; OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); Member member = new Member(user); - member.setRole(SIGNING_UP); + member.setEmail("my@gmail.com"); + member.setName("유동현"); - return member; + + return new Member( + new StudentId("12171707"), "김미승인", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(NOT_APPROVED)); } - public static Member signingUpMember2() { - Map attributes = new HashMap<>() {{ - put("provider", "GOOGLE"); - put("sub", "3232322332323223"); - put("picture", "/static/image.jpg"); - put("email", "my2@gmail.com"); - put("name", "조승현"); - put("locale", "ko"); - }}; - OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); - Member member = new Member(user); - member.setRole(SIGNING_UP); + public static Member getTestBasicMember(String id) { + return new Member( + new StudentId(id), "유동현", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("건축공학과", 3) + , new IbasInformation(BASIC)); + } - return member; + public static Member getTestBasicMember(String id, String phoneNumber) { + return new Member( + new StudentId(id), "유동현", phoneNumber, "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("건축공학과", 3) + , new IbasInformation(BASIC)); } + } diff --git a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberServiceTest.java b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberServiceTest.java index 9f87c9b7..b6fb9d2c 100644 --- a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberServiceTest.java +++ b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/service/MemberServiceTest.java @@ -24,10 +24,48 @@ public class MemberServiceTest { @InjectMocks MemberServiceImpl memberService; + + @Mock + MemberDuplicationChecker memberDuplicationChecker; + @Mock MemberRepository memberRepository; +// @DisplayName("교수 회원가입을 성공한다.") +// @Test +// public void 교수_회원가입() { +// //given +// ProfessorSignUpDto signUpForm = ProfessorSignUpDto.builder() +// .name("유동현") +// .major("컴퓨터공학과") +// .phoneNumber("010-0000-1111") +// .memberId(12345678) +// .build(); +// +// Member expected = Member.builder() +// .id(signUpForm.getMemberId()) +// .phoneNumber(signUpForm.getPhoneNumber()) +// .name(signUpForm.getName()) +// .picture("") +// .schoolInformation(SchoolInformation.ofProfessor(signUpForm.getMajor())) +// .ibasInformation(new IbasInformation(Role.ANONYMOUS, "", 0)) +// .build(); +// ReflectionTestUtils.setField(expected.getIbasInformation(), "joined", LocalDateTime.now()); +// given(memberRepository.save(any(Member.class))).willReturn(expected); +// +// //when +// Member newMember = memberService.saveSignUpForm(signUpForm); +// +// //then +// assertThat(newMember) +// .usingRecursiveComparison() +// .ignoringFields("joined") +// .isEqualTo(expected); +// assertThat(newMember.getIbasInformation().getJoined()).isNotNull(); +// } + + @DisplayName("회원의 권한을 변경한다.") @Test public void changeRoleTest() { @@ -64,6 +102,30 @@ public void changeRoleTest() { .isEqualTo(NOT_APPROVED); } +// @DisplayName("권한변경 시도 시에, 회원이 존재하지 않는 경우 MemberNotExistException 발생") +// @Test +// public void failToChangeRoleTest() { +// +// //given +// StudentId studentId = new StudentId("12171652"); +// Member member = Member.builder() +// .studentId(studentId) +// .picture("") +// .name("유동현") +// .email("my@gmail.com") +// .phone("010-0000-0000") +// .schoolInformation(SchoolInformation.ofUnderGraduate("정보통신공학과", 1)) +// .ibasInformation(new IbasInformation(ANONYMOUS)) +// .build(); +// +// given(memberRepository.findById(any())) +// .willReturn(Optional.empty()); +// +// +// assertThrows(MemberNotFoundException.class, +// () -> memberService.changeRole(member, Role.BASIC)); +// } + @DisplayName("회장 연락처 불러오기") @Test public void getChiefContact() { diff --git a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/GradeTest.java b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/GradeTest.java index ab94a006..3d1a7f48 100644 --- a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/GradeTest.java +++ b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/domain/valueObject/GradeTest.java @@ -28,5 +28,9 @@ public void No_Such_Grade() { IllegalArgumentException.class, () -> new Grade(-1) ); + assertThrows( + IllegalArgumentException.class, + () -> new Grade(0) + ); } } diff --git a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryTest.java b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryTest.java index abb69e14..cb184bd4 100644 --- a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryTest.java +++ b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/member/repository/MemberRepositoryTest.java @@ -6,12 +6,14 @@ import com.inhabas.api.auth.domain.oauth2.userInfo.GoogleOAuth2UserInfo; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; import com.inhabas.api.auth.testAnnotation.DefaultDataJpaTest; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.transaction.annotation.Transactional; import java.util.HashMap; import java.util.List; @@ -20,9 +22,8 @@ import java.util.stream.Collectors; import static com.inhabas.api.auth.domain.oauth2.OAuth2Provider.GOOGLE; -import static com.inhabas.api.auth.domain.oauth2.member.domain.entity.MemberTest.*; import static com.inhabas.api.auth.domain.oauth2.member.domain.entity.MemberTest.signingUpMember1; -import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role.NOT_APPROVED; +import static com.inhabas.api.auth.domain.oauth2.member.domain.entity.MemberTest.signingUpMember2; import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role.SIGNING_UP; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -36,9 +37,13 @@ public class MemberRepositoryTest { TestEntityManager em; + @BeforeEach + public void setUp() { + memberRepository.deleteAll(); + } + @DisplayName("저장 후 반환 값은 처음과 같다.") @Test - @Transactional public void save() { //when @@ -54,7 +59,6 @@ public void save() { @DisplayName("idList 로 사용자를 찾을 수 있다.") @Test - @Transactional public void find_all_by_id() { //given @@ -74,7 +78,6 @@ public void find_all_by_id() { @DisplayName("Role로 하나의 사용자를 조회한다.") @Test - @Transactional public void findAll() { //given @@ -90,19 +93,30 @@ public void findAll() { @DisplayName("같은 provider_uid 저장 시 DataIntegrityViolationException 예외") @Test - @Transactional public void 같은_provider_uid_저장_예외() { //given memberRepository.save(signingUpMember1()); + //when + Map attributes = new HashMap<>() {{ + put("provider", "GOOGLE"); + put("uid", "123321123321123"); + put("sub", "1249846925629348"); + put("picture", "/static/image.jpg"); + put("email", "my@gmail.com"); + put("name", "유동현"); + put("locale", "ko"); + }}; + OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); + Member sameProviderAndUid = new Member(user); + //then assertThrows(DataIntegrityViolationException.class, - () -> memberRepository.saveAndFlush(signingUpMember1())); + () -> memberRepository.saveAndFlush(sameProviderAndUid)); } @DisplayName("provider_uid 중복검사 시 true 를 반환") @Test - @Transactional public void provider_uid_존재한다() { //given @@ -128,7 +142,6 @@ public void findAll() { @DisplayName("provider_uid 중복검사 시 false 를 반환") @Test - @Transactional public void provider_uid_존재하지_않는다() { //when @@ -141,7 +154,6 @@ public void findAll() { @DisplayName("provider_uid 로 사용자를 찾는다") @Test - @Transactional public void find_by_provider_uid() { //given @@ -162,7 +174,6 @@ public void find_by_provider_uid() { // Custom @DisplayName("중복 검사 쿼리 provider 없는 경우") @Test - @Transactional public void validateNoneFields() { //given @@ -177,7 +188,6 @@ public void validateNoneFields() { @DisplayName("모든 필드 중복되는 경우") @Test - @Transactional public void validateAllFields() { //given @@ -194,13 +204,15 @@ public void validateAllFields() { // 회원가입 이후 구현 @DisplayName("Role, StudentId 로 회원 검색") @Test - @Transactional + @Disabled public void search_by_role_studentId() { + //given - memberRepository.save(notapprovedMember()); + memberRepository.save(signingUpMember1()); + memberRepository.save(signingUpMember2()); //when - List members = memberRepository.findAllByRoleAndStudentIdLike(NOT_APPROVED, "12171707"); + List members = memberRepository.findAllByRoleAndStudentIdLike(SIGNING_UP, "12171707"); //then assertThat(members.size()).isEqualTo(1); diff --git a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/socialaccount/SocialAccountRepositoryTest.java b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/socialaccount/SocialAccountRepositoryTest.java new file mode 100644 index 00000000..7c8cb790 --- /dev/null +++ b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/socialaccount/SocialAccountRepositoryTest.java @@ -0,0 +1,56 @@ +package com.inhabas.api.auth.domain.oauth2.socialaccount; + +import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; +import com.inhabas.api.auth.domain.oauth2.socialAccount.SocialAccount; +import com.inhabas.api.auth.domain.oauth2.socialAccount.SocialAccountRepository; +import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; +import com.inhabas.api.auth.testAnnotation.DefaultDataJpaTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.dao.DataIntegrityViolationException; + +import javax.persistence.EntityNotFoundException; +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + + +@DefaultDataJpaTest +public class SocialAccountRepositoryTest { + + @Autowired + private SocialAccountRepository socialAccountRepository; + + @Test + @DisplayName("소셜 계정을 uid 와 provider 로 조회한다.") + public void findBySocialAccountByUidAndProvider() { + //given + SocialAccount socialAccount = + new SocialAccount(OAuth2Provider.GOOGLE, "1234", LocalDateTime.now(), LocalDateTime.now(), ""); + socialAccountRepository.save(socialAccount); + + //when + SocialAccount find = socialAccountRepository.findByUidAndProvider(new UID("1234"), OAuth2Provider.GOOGLE) + .orElseThrow(EntityNotFoundException::new); + + //then + assertThat(find.getUid()).isEqualTo("1234"); + assertThat(find.getProvider()).isEqualTo(OAuth2Provider.GOOGLE); + } + + @Test + @DisplayName("소셜 계정은 uid와 provider 가 unique 한 조합이어야 한다.") + public void failToSaveTheSameSocialAccount() { + //given + SocialAccount socialAccount = + new SocialAccount(OAuth2Provider.GOOGLE, "1234", LocalDateTime.now(), LocalDateTime.now(), ""); + socialAccountRepository.save(socialAccount); + + //when + assertThrows(DataIntegrityViolationException.class, + () -> socialAccountRepository.save(new SocialAccount(OAuth2Provider.GOOGLE, "1234", LocalDateTime.now(), LocalDateTime.now(), ""))); + } +} diff --git a/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/socialaccount/SocialAccountServiceTest.java b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/socialaccount/SocialAccountServiceTest.java new file mode 100644 index 00000000..fefab2dd --- /dev/null +++ b/module-auth/src/test/java/com/inhabas/api/auth/domain/oauth2/socialaccount/SocialAccountServiceTest.java @@ -0,0 +1,97 @@ +package com.inhabas.api.auth.domain.oauth2.socialaccount; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; +import com.inhabas.api.auth.domain.oauth2.userInfo.GoogleOAuth2UserInfo; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; +import com.inhabas.api.auth.domain.oauth2.socialAccount.SocialAccount; +import com.inhabas.api.auth.domain.oauth2.socialAccount.SocialAccountRepository; +import com.inhabas.api.auth.domain.oauth2.socialAccount.SocialAccountServiceImpl; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.time.LocalDateTime; +import java.util.Map; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.times; + +@ExtendWith(MockitoExtension.class) +public class SocialAccountServiceTest { + + @InjectMocks + private SocialAccountServiceImpl socialAccountService; + + @Mock + private SocialAccountRepository socialAccountRepository; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + + @DisplayName("처음 소셜로그인 시도할 때, 새로운 소셜계정 객체를 생성한다.") + @Test + @SuppressWarnings({"unchecked"}) + public void saveSocialAccountInfo() throws JsonProcessingException { + //given + Map attributes = objectMapper.readValue("{\n" + + " \"sub\" : \"1234567889\",\n" + + " \"name\" : \"유동현\",\n" + + " \"given_name\" : \"동현\",\n" + + " \"family_name\" : \"유\",\n" + + " \"picture\" : \"https://lh3.googleusercontent.com/a/AATXAJzeE07A14_4sjavMyRvRpuG7gcVa5O8imNA37pe=s96-c\",\n" + + " \"email\" : \"my@gmail.com\",\n" + + " \"email_verified\" : true,\n" + + " \"locale\" : \"ko\"\n" + + "}", Map.class); + OAuth2UserInfo userInfo = new GoogleOAuth2UserInfo(attributes); + + given(socialAccountRepository.findByUidAndProvider(any(), any())) + .willReturn(Optional.empty()); // 소셜로그인이 처음이다. + + //when + socialAccountService.updateSocialAccountInfo(userInfo); + + //then + then(socialAccountRepository).should(times(1)).findByUidAndProvider(any(), any()); + then(socialAccountRepository).should(times(1)).save(any()); + } + + @DisplayName("소셜로그인 시도가 첫번째가 아니면, 마지막 로그인 시간만 수정한다.") + @Test + @SuppressWarnings({"unchecked"}) + public void updateSocialAccountInfo() throws JsonProcessingException { + //given + String extraData = "{\n" + + " \"sub\" : \"1234567889\",\n" + + " \"name\" : \"유동현\",\n" + + " \"given_name\" : \"동현\",\n" + + " \"family_name\" : \"유\",\n" + + " \"picture\" : \"https://lh3.googleusercontent.com/a/AATXAJzeE07A14_4sjavMyRvRpuG7gcVa5O8imNA37pe=s96-c\",\n" + + " \"email\" : \"my@gmail.com\",\n" + + " \"email_verified\" : true,\n" + + " \"locale\" : \"ko\"\n" + + "}"; + Map attributes = objectMapper.readValue(extraData, Map.class); + OAuth2UserInfo userInfo = new GoogleOAuth2UserInfo(attributes); + + SocialAccount existAccount = new SocialAccount(OAuth2Provider.GOOGLE, userInfo.getId(), LocalDateTime.of(2020, 1, 1, 12, 0, 0), + LocalDateTime.of(2020, 1, 1, 13, 0, 0), extraData); + given(socialAccountRepository.findByUidAndProvider(any(), any())) + .willReturn(Optional.of(existAccount)); // 소셜로그인을 전에 한 적이 있다. + + //when + socialAccountService.updateSocialAccountInfo(userInfo); + + //then + then(socialAccountRepository).should(times(1)).findByUidAndProvider(any(), any()); + then(socialAccountRepository).should(times(1)).save(any()); + } +} diff --git a/resource-server/src/main/java/com/inhabas/api/config/WebSecurityConfig.java b/resource-server/src/main/java/com/inhabas/api/config/WebSecurityConfig.java index 1778ae21..963cc487 100644 --- a/resource-server/src/main/java/com/inhabas/api/config/WebSecurityConfig.java +++ b/resource-server/src/main/java/com/inhabas/api/config/WebSecurityConfig.java @@ -12,12 +12,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Profile; import org.springframework.core.annotation.Order; -import org.springframework.http.HttpMethod; import org.springframework.security.access.expression.SecurityExpressionHandler; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; @@ -42,16 +40,15 @@ public class WebSecurityConfig { private static final String[] AUTH_WHITELIST_SWAGGER = {"/swagger-ui/**", "/swagger/**", "/docs/**"}; private static final String[] AUTH_WHITELIST_STATIC = {"/static/css/**", "/static/js/**", "*.ico"}; private static final String[] AUTH_WHITELIST_TOKEN = {"/token/**"}; - private static final String[] AUTH_WHITELIST_PATH = {"/menu/**", "/menus", "/member/chief", "/error"}; - private static final String[] AUTH_WHITELIST_SIGNUP = {"/signUp/schedule", "/signUp/questionnaires", "/signUp/majorInfo"}; - + private static final String[] AUTH_WHITELIST_PATH = {"/menu/**", "/menus", "/signUp/schedule", + "/member/chief", "/error"}; @Order(1) @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) @EnableWebSecurity @RequiredArgsConstructor - @Profile({"local", "dev", "default_mvc_test", "production"}) - public static class ApiSecurityForDev extends WebSecurityConfigurerAdapter { + @Profile({"production"}) + public static class ApiSecurityForProduction extends WebSecurityConfigurerAdapter { private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; private final JwtAccessDeniedHandler jwtAccessDeniedHandler; @@ -60,19 +57,98 @@ public static class ApiSecurityForDev extends WebSecurityConfigurerAdapter { private final JwtAuthenticationProvider jwtAuthenticationProvider; private final AuthBeansConfig authBeansConfig; - @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(jwtAuthenticationProvider); } @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring() - .antMatchers(HttpMethod.GET, AUTH_WHITELIST_SIGNUP) - .antMatchers(AUTH_WHITELIST_SWAGGER) - .antMatchers(AUTH_WHITELIST_STATIC) - .antMatchers(AUTH_WHITELIST_PATH); + protected void configure(HttpSecurity http) throws Exception { + http + .httpBasic().disable() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + + .csrf() + .disable() + + + .exceptionHandling() + .authenticationEntryPoint(jwtAuthenticationEntryPoint) + .accessDeniedHandler(jwtAccessDeniedHandler) + .and() + .authorizeRequests() + // 권한 부여 표현식 + .expressionHandler(expressionHandler()) + // Preflight 방식 + .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() + + // 회원 관리 + .antMatchers("/members/**", "/member/**").hasAnyRole(SECRETARY.toString(), EXECUTIVES.toString()) + + // 회계내역 + .antMatchers("/budget/history/**", "/budget/histories", + "/budget/application/**", "/budget/applications").hasRole(SECRETARY.toString()) + // 강의 + .antMatchers("/lecture/**/status").hasRole(EXECUTIVES.toString()) + .antMatchers("/lecture/**").hasRole(DEACTIVATED.toString()) + + // 회원가입은 ANONYMOUS 권한은 명시적으로 부여받은 상태에서만 가능 + .antMatchers("/signUp/**").hasRole(SIGNING_UP.toString()) + + // 그 외 + .anyRequest().hasRole(ANONYMOUS.toString()); + http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); + } + + @Bean + public SecurityExpressionHandler expressionHandler() { + DefaultWebSecurityExpressionHandler webSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler(); + webSecurityExpressionHandler.setRoleHierarchy(hierarchy.getHierarchy()); + return webSecurityExpressionHandler; + } + + @Bean + public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception { + final List skipPaths = new ArrayList<>(); + skipPaths.addAll(Arrays.stream(AUTH_WHITELIST_PATH).collect(Collectors.toList())); + skipPaths.addAll(Arrays.stream(AUTH_WHITELIST_STATIC).collect(Collectors.toList())); + skipPaths.addAll(Arrays.stream(AUTH_WHITELIST_SWAGGER).collect(Collectors.toList())); + skipPaths.addAll(Arrays.stream(AUTH_WHITELIST_TOKEN).collect(Collectors.toList())); + + final RequestMatcher requestMatcher = new CustomRequestMatcher(skipPaths); + final JwtAuthenticationFilter filter = new JwtAuthenticationFilter( + requestMatcher, + jwtTokenUtil, + authBeansConfig.tokenResolver() + ); + + filter.setAuthenticationManager(super.authenticationManager()); + return filter; + } + + } + + + @Order(1) + @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) + @EnableWebSecurity + @RequiredArgsConstructor + @Profile({"local", "dev", "default_mvc_test"}) + public static class ApiSecurityForDev extends WebSecurityConfigurerAdapter { + + private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; + private final JwtAccessDeniedHandler jwtAccessDeniedHandler; + private final Hierarchical hierarchy; + private final JwtTokenUtil jwtTokenUtil; + private final JwtAuthenticationProvider jwtAuthenticationProvider; + private final AuthBeansConfig authBeansConfig; + + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(jwtAuthenticationProvider); } @Override @@ -105,8 +181,6 @@ protected void configure(HttpSecurity http) throws Exception { .expressionHandler(expressionHandler()) // Preflight 방식 .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() - // 회원 관리 - .antMatchers("/members/**", "/member/**").hasAnyRole(SECRETARY.toString(), EXECUTIVES.toString()) // 회계내역 .antMatchers("/budget/history/**", "/budget/histories", "/budget/application/**", "/budget/applications").hasRole(SECRETARY.toString()) @@ -114,9 +188,6 @@ protected void configure(HttpSecurity http) throws Exception { .antMatchers("/lecture/**/status").hasRole(EXECUTIVES.toString()) .antMatchers("/lecture/**").hasRole(DEACTIVATED.toString()) - // 회원가입 일정 수정 - .antMatchers(HttpMethod.PUT,"/signUp/schedule").hasAnyRole(CHIEF.toString(), VICE_CHIEF.toString()) - // 회원가입은 ANONYMOUS 권한은 명시적으로 부여받은 상태에서만 가능 .antMatchers("/signUp/**").hasRole(SIGNING_UP.toString()) @@ -134,8 +205,12 @@ public SecurityExpressionHandler expressionHandler() { return webSecurityExpressionHandler; } + @Bean public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception { final List skipPaths = new ArrayList<>(); + skipPaths.addAll(Arrays.stream(AUTH_WHITELIST_PATH).collect(Collectors.toList())); + skipPaths.addAll(Arrays.stream(AUTH_WHITELIST_STATIC).collect(Collectors.toList())); + skipPaths.addAll(Arrays.stream(AUTH_WHITELIST_SWAGGER).collect(Collectors.toList())); skipPaths.addAll(Arrays.stream(AUTH_WHITELIST_TOKEN).collect(Collectors.toList())); final RequestMatcher requestMatcher = new CustomRequestMatcher(skipPaths); diff --git a/resource-server/src/main/java/com/inhabas/api/domain/BaseEntity.java b/resource-server/src/main/java/com/inhabas/api/domain/BaseEntity.java index 9d655b92..53a8f8c9 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/BaseEntity.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/BaseEntity.java @@ -1,9 +1,11 @@ package com.inhabas.api.domain; import lombok.Getter; +import org.hibernate.annotations.UpdateTimestamp; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import javax.persistence.Column; import javax.persistence.EntityListeners; @@ -16,10 +18,10 @@ public abstract class BaseEntity { @CreatedDate - @Column(nullable = false, updatable = false, insertable = false, columnDefinition = "DATETIME(0) DEFAULT CURRENT_TIMESTAMP") + @Column(nullable = false, updatable = false, insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") private LocalDateTime dateCreated; @LastModifiedDate - @Column(columnDefinition = "DATETIME(0)") + @Column private LocalDateTime dateUpdated; } diff --git a/resource-server/src/main/java/com/inhabas/api/domain/comment/dto/CommentDetailDto.java b/resource-server/src/main/java/com/inhabas/api/domain/comment/dto/CommentDetailDto.java index c864c03e..2952be9a 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/comment/dto/CommentDetailDto.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/comment/dto/CommentDetailDto.java @@ -28,7 +28,7 @@ public static CommentDetailDto fromEntity(Comment comment) { return new CommentDetailDto( comment.getId(), comment.getContents(), - new StudentId("11121212"), // 임시방편, 수정 필요 + comment.getWriter().getStudentId(), comment.getWriter().getName(), comment.getWriter().getSchoolInformation().getMajor(), comment.getDateCreated() diff --git a/resource-server/src/main/java/com/inhabas/api/domain/member/domain/entity/Answer.java b/resource-server/src/main/java/com/inhabas/api/domain/member/domain/entity/Answer.java new file mode 100644 index 00000000..02ffef7e --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/domain/entity/Answer.java @@ -0,0 +1,36 @@ +package com.inhabas.api.domain.member.domain.entity; + +import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; +import com.inhabas.api.domain.BaseEntity; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Table(name = "ANSWER") +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Answer extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "NO") + private Integer no; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "USER_STUDENT_ID", foreignKey = @ForeignKey(name = "FK_ANSWER_OF_MEMBER")) + private Member member; + + @Column(name = "QUESTION_NO", nullable = false) + private Integer questionNo; + + @Column(name = "CONTENT", nullable = false, length = 1000) + private String content; + + public Answer(Member member, Integer questionNo, String content) { + this.member = member; + this.questionNo = questionNo; + this.content = content; + } +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/exception/NotWriteAnswersException.java b/resource-server/src/main/java/com/inhabas/api/domain/member/domain/exception/NotWriteAnswersException.java similarity index 88% rename from resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/exception/NotWriteAnswersException.java rename to resource-server/src/main/java/com/inhabas/api/domain/member/domain/exception/NotWriteAnswersException.java index 1b08a24b..d71c1665 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/exception/NotWriteAnswersException.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/domain/exception/NotWriteAnswersException.java @@ -1,4 +1,4 @@ -package com.inhabas.api.domain.signUp.domain.exception; +package com.inhabas.api.domain.member.domain.exception; import org.springframework.security.access.AccessDeniedException; diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/exception/NotWriteProfileException.java b/resource-server/src/main/java/com/inhabas/api/domain/member/domain/exception/NotWriteProfileException.java similarity index 88% rename from resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/exception/NotWriteProfileException.java rename to resource-server/src/main/java/com/inhabas/api/domain/member/domain/exception/NotWriteProfileException.java index 978ec11a..c332aa75 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/exception/NotWriteProfileException.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/domain/exception/NotWriteProfileException.java @@ -1,4 +1,4 @@ -package com.inhabas.api.domain.signUp.domain.exception; +package com.inhabas.api.domain.member.domain.exception; import org.springframework.security.access.AccessDeniedException; diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/dto/AnswerDto.java b/resource-server/src/main/java/com/inhabas/api/domain/member/dto/AnswerDto.java similarity index 51% rename from resource-server/src/main/java/com/inhabas/api/domain/signUp/dto/AnswerDto.java rename to resource-server/src/main/java/com/inhabas/api/domain/member/dto/AnswerDto.java index 3b94dc16..6fb2674a 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/dto/AnswerDto.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/dto/AnswerDto.java @@ -1,21 +1,22 @@ -package com.inhabas.api.domain.signUp.dto; +package com.inhabas.api.domain.member.dto; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.Positive; -@Data -@NoArgsConstructor -@AllArgsConstructor +@Data @NoArgsConstructor public class AnswerDto { @Positive - private Long questionId; + private Integer questionNo; @Length(max = 1000) private String content; + public AnswerDto(Integer questionNo, String content) { + this.questionNo = questionNo; + this.content = content; + } } diff --git a/resource-server/src/main/java/com/inhabas/api/domain/member/dto/SignUpDto.java b/resource-server/src/main/java/com/inhabas/api/domain/member/dto/SignUpDto.java new file mode 100644 index 00000000..3fdc6496 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/dto/SignUpDto.java @@ -0,0 +1,49 @@ +package com.inhabas.api.domain.member.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.*; + +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@NoArgsConstructor +public class SignUpDto { + + @NotBlank + @Length(max = 50) + private String name; + + @NotBlank + @Length(max = 50) + private String major; + + @Pattern(regexp = "^(010)-\\d{4}-\\d{4}$") + private String phoneNumber; + + @Email + private String email; + + @JsonUnwrapped + @NotNull @Positive + private StudentId studentId; + + @NotNull + private MemberType memberType; + + @Builder + public SignUpDto(String name, String major, String phoneNumber, String email, StudentId studentId, MemberType memberType) { + this.name = name; + this.major = major; + this.phoneNumber = phoneNumber; + this.email = email; + this.studentId = studentId; + this.memberType = memberType; + } +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/member/repository/AnswerRepository.java b/resource-server/src/main/java/com/inhabas/api/domain/member/repository/AnswerRepository.java new file mode 100644 index 00000000..67b5d29c --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/repository/AnswerRepository.java @@ -0,0 +1,14 @@ +package com.inhabas.api.domain.member.repository; + +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.domain.member.domain.entity.Answer; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface AnswerRepository extends JpaRepository { + + List findByMember_Id(Long memberId); + + boolean existsByMember_id(StudentId studentId); +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/AnswerService.java b/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/AnswerService.java new file mode 100644 index 00000000..40f40aed --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/AnswerService.java @@ -0,0 +1,15 @@ +package com.inhabas.api.domain.member.usecase; + +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.domain.member.dto.AnswerDto; + +import java.util.List; + +public interface AnswerService { + + void saveAnswers(List submittedAnswers, StudentId studentId); + + List getAnswers(Long memberId); + + boolean existAnswersWrittenBy(StudentId studentId); +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/AnswerServiceImpl.java b/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/AnswerServiceImpl.java new file mode 100644 index 00000000..61b123b2 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/AnswerServiceImpl.java @@ -0,0 +1,44 @@ +package com.inhabas.api.domain.member.usecase; + +import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; +import com.inhabas.api.domain.member.domain.entity.Answer; +import com.inhabas.api.domain.member.dto.AnswerDto; +import com.inhabas.api.domain.member.repository.AnswerRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class AnswerServiceImpl implements AnswerService { + + private final AnswerRepository answerRepository; + private final MemberRepository memberRepository; + + public void saveAnswers(List submittedAnswers, StudentId studentId) { + + Member currentMember = memberRepository.getByStudentId(studentId); + + List answers = submittedAnswers.stream() + .map(a -> new Answer(currentMember, a.getQuestionNo(), a.getContent())) + .collect(Collectors.toList()); + + answerRepository.saveAll(answers); + } + + public List getAnswers(Long memberId) { + + return answerRepository.findByMember_Id(memberId).stream() + .map(a-> new AnswerDto(a.getQuestionNo(), a.getContent())) + .collect(Collectors.toList()); + } + + @Override + public boolean existAnswersWrittenBy(StudentId studentId) { + return answerRepository.existsByMember_id(studentId); + } +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/SignUpService.java b/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/SignUpService.java new file mode 100644 index 00000000..957f9546 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/SignUpService.java @@ -0,0 +1,31 @@ +package com.inhabas.api.domain.member.usecase; + +import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.auth.domain.oauth2.member.dto.MemberDuplicationQueryCondition; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; +import com.inhabas.api.domain.member.dto.AnswerDto; +import com.inhabas.api.domain.member.dto.SignUpDto; +import com.inhabas.api.domain.questionaire.dto.QuestionnaireDto; + +import java.util.List; + +public interface SignUpService { + + void saveSignUpForm(SignUpDto signUpDto, OAuth2UserInfoAuthentication authentication); // 수정 필요함. + + SignUpDto loadSignUpForm(StudentId studentId, OAuth2UserInfoAuthentication authentication); + + boolean validateFieldsDuplication(MemberDuplicationQueryCondition condition); + + void completeSignUp(StudentId studentId); + + List getQuestionnaire(); + + void saveAnswers(List answerDtoList, StudentId studentId); + + List getAnswers(Long memberId); + + List getMajorInfo(); + +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/SignUpServiceImpl.java b/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/SignUpServiceImpl.java new file mode 100644 index 00000000..ad698221 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/member/usecase/SignUpServiceImpl.java @@ -0,0 +1,149 @@ +package com.inhabas.api.domain.member.usecase; + +import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; +import com.inhabas.api.auth.domain.oauth2.majorInfo.usecase.MajorInfoService; +import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; +import com.inhabas.api.auth.domain.oauth2.member.domain.exception.MemberNotFoundException; +import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberDuplicationChecker; +import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberService; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.*; +import com.inhabas.api.auth.domain.oauth2.member.dto.MemberDuplicationQueryCondition; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; + + +import com.inhabas.api.domain.member.domain.exception.NotWriteAnswersException; +import com.inhabas.api.domain.member.domain.exception.NotWriteProfileException; +import com.inhabas.api.domain.member.dto.AnswerDto; +import com.inhabas.api.domain.member.dto.SignUpDto; +import com.inhabas.api.domain.questionaire.dto.QuestionnaireDto; +import com.inhabas.api.domain.questionaire.usecase.QuestionnaireService; +import com.inhabas.api.domain.signUpSchedule.domain.SignUpScheduler; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.NotImplementedException; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; + +import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType.UNDERGRADUATE; +import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role.ANONYMOUS; + +@Service +@RequiredArgsConstructor +public class SignUpServiceImpl implements SignUpService { + + private final AnswerService answerService; + private final MemberService memberService; + private final MajorInfoService majorInfoService; + private final QuestionnaireService questionnaireService; + private final SignUpScheduler signUpScheduler; + private final MemberDuplicationChecker memberDuplicationChecker; + + private static final MemberType DEFAULT_MEMBER_TYPE = UNDERGRADUATE; + private static final Role DEFAULT_ROLE_BEFORE_FINISH_SIGNUP = ANONYMOUS; + + + @Override + @Transactional + public void saveSignUpForm(SignUpDto signUpForm, OAuth2UserInfoAuthentication authentication) { + Integer generation = signUpScheduler.getSchedule().getGeneration(); + IbasInformation ibasInformation = new IbasInformation(DEFAULT_ROLE_BEFORE_FINISH_SIGNUP); + SchoolInformation schoolInformation = new SchoolInformation(signUpForm.getMajor(), generation, signUpForm.getMemberType()); + + Member member = Member.builder() + .studentId(signUpForm.getStudentId()) + .name(signUpForm.getName()) + .phone(signUpForm.getPhoneNumber()) + .email(authentication.getEmail()) + .ibasInformation(ibasInformation) + .schoolInformation(schoolInformation) + .build(); + + memberService.save(member); + throw new NotImplementedException("소셜 계정과 회원을 연결하는 로직 추가해야함"); + } + + @Override + public void completeSignUp(StudentId studentId) { + + Member member = memberService.findById(studentId); + + if (notYetWroteProfile(member)) { + throw new NotWriteProfileException(); + } + else if (notYetWroteAnswers(member)) { + throw new NotWriteAnswersException(); + } + + memberService.finishSignUp(member); + } + + private boolean notYetWroteProfile(Member member) { + return Objects.isNull(member); + } + + private boolean notYetWroteAnswers(Member member) { + return member.isUnderGraduate() + && !answerService.existAnswersWrittenBy(member.getStudentId()); + } + + @Override + public List getQuestionnaire() { + return questionnaireService.getQuestionnaire(); + } + + @Override + public void saveAnswers(List answerDtoList, StudentId studentId) { + answerService.saveAnswers(answerDtoList, studentId); + } + + @Override + public List getAnswers(Long memberId) { + return answerService.getAnswers(memberId); + } + + @Override + public List getMajorInfo() { + return majorInfoService.getAllMajorInfo(); + } + + @Override + @Transactional(readOnly = true) + public SignUpDto loadSignUpForm(StudentId studentId, OAuth2UserInfoAuthentication authentication) { + + try { + Member member = memberService.findById(studentId); + + return SignUpDto.builder() + .studentId(studentId) + .phoneNumber(member.getPhone()) + .email(member.getEmail()) + .name(member.getName()) + .major(member.getSchoolInformation().getMajor()) + .memberType(member.getSchoolInformation().getMemberType()) + .build(); + } + catch (MemberNotFoundException | InvalidDataAccessApiUsageException | IllegalArgumentException e) { + return SignUpDto.builder() + .studentId(null) + .phoneNumber(null) + .email(authentication.getEmail()) + .name(null) + .major(null) + .memberType(DEFAULT_MEMBER_TYPE) + .build(); + } + } + + @Override + public boolean validateFieldsDuplication(MemberDuplicationQueryCondition condition) { + + condition.verifyTwoParameters(); + + return memberDuplicationChecker.isDuplicatedMember(condition); + } + + +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionaire/domain/Questionnaire.java b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/domain/Questionnaire.java new file mode 100644 index 00000000..5fd861cd --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/domain/Questionnaire.java @@ -0,0 +1,25 @@ +package com.inhabas.api.domain.questionaire.domain; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity @Getter +@Table(name = "question_form") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Questionnaire { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "question_no") + private Integer no; + + @Column(name = "question_name", nullable = false, length = 255) + private String item; + + public Questionnaire(Integer no, String item) { + this.no = no; + this.item = item; + } +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionaire/dto/QuestionnaireDto.java b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/dto/QuestionnaireDto.java new file mode 100644 index 00000000..21c44b9c --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/dto/QuestionnaireDto.java @@ -0,0 +1,18 @@ +package com.inhabas.api.domain.questionaire.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class QuestionnaireDto { + + private Integer id; + + private String question; + + public QuestionnaireDto(Integer id, String question) { + this.id = id; + this.question = question; + } +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionaire/repository/QuestionnaireRepository.java b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/repository/QuestionnaireRepository.java new file mode 100644 index 00000000..238fdfe5 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/repository/QuestionnaireRepository.java @@ -0,0 +1,7 @@ +package com.inhabas.api.domain.questionaire.repository; + +import com.inhabas.api.domain.questionaire.domain.Questionnaire; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface QuestionnaireRepository extends JpaRepository { +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionaire/usecase/QuestionnaireService.java b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/usecase/QuestionnaireService.java new file mode 100644 index 00000000..20b14a77 --- /dev/null +++ b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/usecase/QuestionnaireService.java @@ -0,0 +1,10 @@ +package com.inhabas.api.domain.questionaire.usecase; + +import com.inhabas.api.domain.questionaire.dto.QuestionnaireDto; + +import java.util.List; + +public interface QuestionnaireService { + + List getQuestionnaire(); +} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireServiceImpl.java b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/usecase/QuestionnaireServiceImpl.java similarity index 68% rename from resource-server/src/main/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireServiceImpl.java rename to resource-server/src/main/java/com/inhabas/api/domain/questionaire/usecase/QuestionnaireServiceImpl.java index 2e4c5a9c..16812204 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireServiceImpl.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/questionaire/usecase/QuestionnaireServiceImpl.java @@ -1,7 +1,7 @@ -package com.inhabas.api.domain.questionnaire.usecase; +package com.inhabas.api.domain.questionaire.usecase; -import com.inhabas.api.domain.questionnaire.repository.QuestionnaireRepository; -import com.inhabas.api.domain.questionnaire.dto.QuestionnaireDto; +import com.inhabas.api.domain.questionaire.repository.QuestionnaireRepository; +import com.inhabas.api.domain.questionaire.dto.QuestionnaireDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,7 +19,7 @@ public class QuestionnaireServiceImpl implements QuestionnaireService { public List getQuestionnaire() { return questionnaireRepository.findAll().stream() - .map(q->new QuestionnaireDto(q.getId(), q.getQuestion())) + .map(q->new QuestionnaireDto(q.getNo(), q.getItem())) .collect(Collectors.toList()); } } diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/domain/Questionnaire.java b/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/domain/Questionnaire.java deleted file mode 100644 index 6472b38f..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/domain/Questionnaire.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.inhabas.api.domain.questionnaire.domain; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@Entity @Getter -@Table(name = "QUESTIONNAIRE") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Questionnaire { - - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "QUESTION", nullable = false) - private String question; - - public Questionnaire(Long id, String question) { - this.id = id; - this.question = question; - } -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/dto/QuestionnaireDto.java b/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/dto/QuestionnaireDto.java deleted file mode 100644 index b09d192c..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/dto/QuestionnaireDto.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.inhabas.api.domain.questionnaire.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class QuestionnaireDto { - - private Long id; - - private String question; - -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/repository/QuestionnaireRepository.java b/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/repository/QuestionnaireRepository.java deleted file mode 100644 index e7c53b58..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/repository/QuestionnaireRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.inhabas.api.domain.questionnaire.repository; - -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface QuestionnaireRepository extends JpaRepository { - - Long countByIdIn(List idList); - -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireService.java b/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireService.java deleted file mode 100644 index 63902fcf..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.inhabas.api.domain.questionnaire.usecase; - -import com.inhabas.api.domain.questionnaire.dto.QuestionnaireDto; - -import java.util.List; - -public interface QuestionnaireService { - - List getQuestionnaire(); -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/entity/Answer.java b/resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/entity/Answer.java deleted file mode 100644 index fc8f366a..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/domain/entity/Answer.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.inhabas.api.domain.signUp.domain.entity; - -import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.domain.BaseEntity; -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@Entity - @Table(name = "ANSWER", - uniqueConstraints = { @UniqueConstraint(name = "UNIQUE_USER_ID_QUESTIONNAIRE_ID", - columnNames = {"USER_ID", "QUESTIONNAIRE_ID"})}) -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Answer extends BaseEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne(fetch = FetchType.LAZY, optional = false) - @JoinColumn(name = "USER_ID", foreignKey = @ForeignKey(name = "FK_ANSWER_OF_MEMBER")) - private Member member; - - @ManyToOne(fetch = FetchType.LAZY, optional = false) - @JoinColumn(name = "QUESTIONNAIRE_ID", foreignKey = @ForeignKey(name = "FK_ANSWER_OF_QUESTION_ID")) - private Questionnaire questionnaire; - - @Column(name = "CONTENT", length = 1000) - private String content; - - public void setContent(String content) { - this.content = content; - } - - - public Answer(Member member, Questionnaire questionnaire, String content) { - this.member = member; - this.questionnaire = questionnaire; - this.content = content; - } -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/dto/SignUpDto.java b/resource-server/src/main/java/com/inhabas/api/domain/signUp/dto/SignUpDto.java deleted file mode 100644 index 2dc987f8..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/dto/SignUpDto.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.inhabas.api.domain.signUp.dto; - -import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Positive; - -@Data -@NoArgsConstructor -public class SignUpDto { - - @NotBlank - @Length(max = 50) - @Schema(example = "조승현") - private String name; - - @NotBlank - @Length(max = 50) - @Schema(example = "컴퓨터공학과") - private String major; - - @Pattern(regexp = "^(010)-\\d{4}-\\d{4}$") - @Schema(example = "010-0101-0101") - private String phoneNumber; - - @NotNull - @Pattern(regexp = "\\d+") - @Schema(example = "12171707") - private String studentId; - - @NotNull - @Schema(example = "UNDERGRADUATE", allowableValues = {"UNDERGRADUATE", "BACHELOR", "GRADUATED", "PROFESSOR", "OTHER"} ) - private MemberType memberType; - - @Positive - @Schema(example = "1") - private Integer grade; - - @Builder - public SignUpDto(String name, String major, String phoneNumber, String studentId, MemberType memberType, Integer grade) { - this.name = name; - this.major = major; - this.phoneNumber = phoneNumber; - this.studentId = studentId; - this.memberType = memberType; - this.grade = grade; - } -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/repository/AnswerRepository.java b/resource-server/src/main/java/com/inhabas/api/domain/signUp/repository/AnswerRepository.java deleted file mode 100644 index 3470bb45..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/repository/AnswerRepository.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.inhabas.api.domain.signUp.repository; - -import com.inhabas.api.domain.signUp.domain.entity.Answer; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface AnswerRepository extends JpaRepository { - - List findByMember_Id(Long memberId); - -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/AnswerService.java b/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/AnswerService.java deleted file mode 100644 index a58a5cfa..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/AnswerService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.inhabas.api.domain.signUp.usecase; - -import com.inhabas.api.domain.signUp.dto.AnswerDto; - -import java.util.List; - -public interface AnswerService { - - void saveAnswers(List submittedAnswers, Long memberId); - - List getAnswers(Long memberId); - -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/AnswerServiceImpl.java b/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/AnswerServiceImpl.java deleted file mode 100644 index 15098a00..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/AnswerServiceImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.inhabas.api.domain.signUp.usecase; - -import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.auth.domain.oauth2.member.domain.exception.MemberNotFoundException; -import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; -import com.inhabas.api.domain.signUp.domain.entity.Answer; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.repository.AnswerRepository; -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import com.inhabas.api.domain.questionnaire.repository.QuestionnaireRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.persistence.EntityNotFoundException; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class AnswerServiceImpl implements AnswerService { - - private final AnswerRepository answerRepository; - private final MemberRepository memberRepository; - private final QuestionnaireRepository questionnaireRepository; - - - @Override - @Transactional - public void saveAnswers(List submittedAnswers, Long memberId) { - - Member currentMember = memberRepository.findById(memberId).orElseThrow(MemberNotFoundException::new); - - this.questionnaireIdsCheck(submittedAnswers); - - // 기존 답변 가져오기 - Map existingAnswers = answerRepository.findByMember_Id(memberId).stream() - .collect(Collectors.toMap(answer -> answer.getQuestionnaire().getId(), answer -> answer)); - - // 새 답변 또는 업데이트된 답변 준비 - List answersToUpdate = submittedAnswers.stream() - .map(dto -> { - Questionnaire questionnaire = questionnaireRepository.findById(dto.getQuestionId()) - .orElseThrow(() -> new EntityNotFoundException("Questionnaire not found with id: " + dto.getQuestionId())); - - Answer existingAnswer = existingAnswers.get(dto.getQuestionId()); - if (existingAnswer != null) { - existingAnswer.setContent(dto.getContent()); - return existingAnswer; - } else { - return new Answer(currentMember, questionnaire, dto.getContent()); - } - }) - .collect(Collectors.toList()); - - answerRepository.saveAll(answersToUpdate); - - } - - private void questionnaireIdsCheck(List submittedAnswers) throws IllegalArgumentException{ - - List questionIds = submittedAnswers.stream() - .map(AnswerDto::getQuestionId) - .collect(Collectors.toList()); - - List questionnaireList = questionnaireRepository.findAll(); - List questionnaireIdList = questionnaireList.stream() - .map(Questionnaire::getId) - .collect(Collectors.toList()); - - if (questionnaireRepository.countByIdIn(questionIds) != questionnaireIdList.size()) { - throw new IllegalArgumentException("Some question IDs are invalid"); - } - } - - @Override - public List getAnswers(Long memberId) { - - Member member = memberRepository.findById(memberId).orElseThrow(MemberNotFoundException::new); - - List questionnaires = questionnaireRepository.findAll(); - - Map answersByQuestionnaire = answerRepository.findByMember_Id(memberId) - .stream() - .collect(Collectors.toMap( - answer -> answer.getQuestionnaire().getId(), - answer -> answer - )); - - return questionnaires.stream() - .map(questionnaire -> { - Long questionnaireId = questionnaire.getId(); - Answer answer = answersByQuestionnaire.getOrDefault(questionnaireId, new Answer(member, questionnaire, null)); - return new AnswerDto(questionnaireId, answer.getContent()); - }) - .collect(Collectors.toList()); - } - -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/SignUpService.java b/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/SignUpService.java deleted file mode 100644 index 5fe02488..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/SignUpService.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.inhabas.api.domain.signUp.usecase; - -import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.dto.SignUpDto; -import com.inhabas.api.domain.questionnaire.dto.QuestionnaireDto; - -import java.util.List; - -public interface SignUpService { - - void saveSignUpForm(SignUpDto signUpDto, Long memberId); - - SignUpDto loadSignUpForm(Long memberId); - - void completeSignUp(List answerDtoList, Long memberId); - - List getQuestionnaire(); - - void saveAnswers(List answerDtoList, Long memberId); - - List getAnswers(Long memberId); - - List getMajorInfo(); - -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/SignUpServiceImpl.java b/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/SignUpServiceImpl.java deleted file mode 100644 index a63214ad..00000000 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUp/usecase/SignUpServiceImpl.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.inhabas.api.domain.signUp.usecase; - -import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; -import com.inhabas.api.auth.domain.oauth2.majorInfo.usecase.MajorInfoService; -import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.auth.domain.oauth2.member.domain.exception.MemberNotFoundException; -import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberService; -import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.SchoolInformation; -import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; -import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccount; -import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccountRepository; -import com.inhabas.api.domain.questionnaire.dto.QuestionnaireDto; -import com.inhabas.api.domain.questionnaire.usecase.QuestionnaireService; -import com.inhabas.api.domain.signUp.domain.exception.NotWriteAnswersException; -import com.inhabas.api.domain.signUp.domain.exception.NotWriteProfileException; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.dto.SignUpDto; -import com.inhabas.api.domain.signUpSchedule.domain.usecase.SignUpScheduler; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType.PROFESSOR; - -@Service -@RequiredArgsConstructor -public class SignUpServiceImpl implements SignUpService { - - private final MajorInfoService majorInfoService; - private final MemberRepository memberRepository; - private final MemberSocialAccountRepository memberSocialAccountRepository; - private final MemberService memberService; - private final SignUpScheduler signUpScheduler; - private final QuestionnaireService questionnaireService; - private final AnswerService answerService; - - - @Override - @Transactional - public void saveSignUpForm(SignUpDto signUpForm, Long memberId) { - - Integer generation = signUpScheduler.getSchedule().getGeneration(); - Member member = memberRepository.findById(memberId).orElseThrow(MemberNotFoundException::new); - - member.setName(signUpForm.getName()); - member.setPhone(signUpForm.getPhoneNumber()); - member.setStudentId(signUpForm.getStudentId()); - - if (signUpForm.getGrade() != null) { - member.setSchoolInformation(new SchoolInformation(signUpForm.getMajor(), signUpForm.getGrade(), - generation, signUpForm.getMemberType())); - } else { - // 교수 - member.setSchoolInformation(new SchoolInformation(signUpForm.getMajor(), - generation, signUpForm.getMemberType())); - completeSignUp(null, memberId); - } - - } - - @Override - public void completeSignUp(List answerDtoList, Long memberId) { - - Member member = memberRepository.findById(memberId).orElseThrow(MemberNotFoundException::new); - - if (notYetWroteProfile(member)) { - throw new NotWriteProfileException(); - } - - // 교수일 경우 이 과정 스킵 - if (member.getSchoolInformation().getMemberType() != PROFESSOR - && isContentNullInAnyDto(answerDtoList)) { - throw new NotWriteAnswersException(); - } else if (member.getSchoolInformation().getMemberType() != PROFESSOR - && !isContentNullInAnyDto(answerDtoList)) { - saveAnswers(answerDtoList, memberId); - } - - memberSocialAccountRepository.save(new MemberSocialAccount(member, member.getEmail(), - member.getUid().getValue(), member.getProvider())); - memberService.finishSignUp(member); - - } - - public boolean isContentNullInAnyDto(List answerDtoList) { - if (answerDtoList == null || answerDtoList.isEmpty()) { - return true; - } - for (AnswerDto dto : answerDtoList) { - if (dto.getContent() == null) { - return true; - } - } - return false; - } - - private boolean notYetWroteProfile(Member member) { - - return member.getSchoolInformation() == null - || member.getSchoolInformation().getMemberType() == null - || member.getSchoolInformation().getMajor() == null - || member.getStudentId() == null || member.getPhone() == null; - - } - - @Override - public List getQuestionnaire() { - return questionnaireService.getQuestionnaire(); - } - - @Override - public void saveAnswers(List answerDtoList, Long memberId) { - answerService.saveAnswers(answerDtoList, memberId); - } - - @Override - public List getAnswers(Long memberId) { - return answerService.getAnswers(memberId); - } - - @Override - public List getMajorInfo() { - return majorInfoService.getAllMajorInfo(); - } - - @Override - @Transactional(readOnly = true) - public SignUpDto loadSignUpForm(Long memberId) { - - Member member = memberRepository.findById(memberId).orElseThrow(MemberNotFoundException::new); - - return SignUpDto.builder() - .studentId(member.getStudentId()) - .phoneNumber(member.getPhone()) - .name(member.getName()) - .major(member.getSchoolInformation() == null ? null : member.getSchoolInformation().getMajor()) - .memberType(member.getSchoolInformation() == null ? null : member.getSchoolInformation().getMemberType()) - .grade(member.getSchoolInformation() == null ? null : member.getSchoolInformation().getGrade()) - .build(); - - } - -} diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpAvailabilityChecker.java b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpAvailabilityChecker.java similarity index 55% rename from resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpAvailabilityChecker.java rename to resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpAvailabilityChecker.java index ec0859f6..e0cd0c3b 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpAvailabilityChecker.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpAvailabilityChecker.java @@ -1,4 +1,4 @@ -package com.inhabas.api.domain.signUpSchedule.domain.usecase; +package com.inhabas.api.domain.signUpSchedule.domain; public interface SignUpAvailabilityChecker { diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpAvailabilityCheckerImpl.java b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpAvailabilityCheckerImpl.java similarity index 90% rename from resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpAvailabilityCheckerImpl.java rename to resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpAvailabilityCheckerImpl.java index dc6ee607..f60bbd87 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpAvailabilityCheckerImpl.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpAvailabilityCheckerImpl.java @@ -1,4 +1,4 @@ -package com.inhabas.api.domain.signUpSchedule.domain.usecase; +package com.inhabas.api.domain.signUpSchedule.domain; import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; import java.time.LocalDateTime; diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpScheduler.java b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpScheduler.java similarity index 77% rename from resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpScheduler.java rename to resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpScheduler.java index abdcc72b..0131bdd2 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpScheduler.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpScheduler.java @@ -1,4 +1,4 @@ -package com.inhabas.api.domain.signUpSchedule.domain.usecase; +package com.inhabas.api.domain.signUpSchedule.domain; import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpSchedulerStrict.java b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpSchedulerStrict.java similarity index 95% rename from resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpSchedulerStrict.java rename to resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpSchedulerStrict.java index 927dc0bf..3ba088cd 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/SignUpSchedulerStrict.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/SignUpSchedulerStrict.java @@ -1,14 +1,13 @@ -package com.inhabas.api.domain.signUpSchedule.domain.usecase; +package com.inhabas.api.domain.signUpSchedule.domain; import com.inhabas.api.domain.signUpSchedule.domain.entity.SignUpSchedule; -import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; import com.inhabas.api.domain.signUpSchedule.repository.SignUpScheduleRepository; +import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; +import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; - /** * This Scheduler has a strict duty to leave only one signup-schedule. */ @@ -34,10 +33,12 @@ public void updateSchedule(SignUpScheduleDto signUpScheduleDto) { } @Override + @Transactional(readOnly = true) public SignUpScheduleDto getSchedule() { SignUpSchedule signUpSchedule = this.getScheduleEntity(); return new SignUpScheduleDto( + signUpSchedule.getId(), signUpSchedule.getGeneration(), signUpSchedule.getSignupStartDate(), signUpSchedule.getSignupEndDate(), diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/entity/SignUpSchedule.java b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/entity/SignUpSchedule.java index 60da0102..582be97a 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/entity/SignUpSchedule.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/domain/entity/SignUpSchedule.java @@ -15,29 +15,29 @@ * Be cautious not to make multi schedule or remove all the schedules. Do offer really necessary api. */ @Entity @Getter -@Table(name = "SIGNUP_SCHEDULE") +@Table(name = "signup_schedule") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class SignUpSchedule { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + private Integer id; - @Column(name = "GENERATION", nullable = false) + @Column(name = "generation", nullable = false) private Integer generation; - @Column(name = "SIGNUP_START", nullable = false) + @Column(name = "signup_start", nullable = false) private LocalDateTime signupStartDate; - @Column(name = "SIGNUP_END", nullable = false) + @Column(name = "signup_end", nullable = false) private LocalDateTime signupEndDate; - @Column(name = "INTERVIEW_START", nullable = false) + @Column(name = "interview_start", nullable = false) private LocalDateTime interviewStartDate; - @Column(name = "INTERVIEW_END", nullable = false) + @Column(name = "interview_end", nullable = false) private LocalDateTime interviewEndDate; - @Column(name = "RESULT_ANNOUNCE_DATE", nullable = false) + @Column(name = "result_announce_date", nullable = false) private LocalDateTime resultAnnounceDate; public SignUpSchedule(Integer generation, LocalDateTime signupStartDate, LocalDateTime signupEndDate, diff --git a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/dto/SignUpScheduleDto.java b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/dto/SignUpScheduleDto.java index bf1366dc..13ac8013 100644 --- a/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/dto/SignUpScheduleDto.java +++ b/resource-server/src/main/java/com/inhabas/api/domain/signUpSchedule/dto/SignUpScheduleDto.java @@ -2,8 +2,6 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.inhabas.api.domain.signUpSchedule.domain.entity.SignUpSchedule; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -13,40 +11,49 @@ @Data @NoArgsConstructor -@AllArgsConstructor public class SignUpScheduleDto { + @NotNull + private Integer id; + @NotNull @Positive - @Schema(defaultValue = "1") private Integer generation; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss") - @Schema(type="string" , example = "2023-11-01T00:00:00") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime signupStartDate; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss") - @Schema(type="string" , example = "2024-11-01T00:00:00") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime signupEndDate; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss") - @Schema(type="string" , example = "2024-11-01T00:00:00") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime interviewStartDate; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss") - @Schema(type="string" , example = "2024-11-01T00:00:00") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime interviewEndDate; @NotNull - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss") - @Schema(type="string" , example = "2024-11-01T00:00:00") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime resultAnnounceDate; + + public SignUpScheduleDto(Integer id, Integer generation, LocalDateTime signupStartDate, LocalDateTime signupEndDate, + LocalDateTime interviewStartDate, LocalDateTime interviewEndDate, LocalDateTime resultAnnounceDate) { + this.id = id; + this.generation = generation; + this.signupStartDate = signupStartDate; + this.signupEndDate = signupEndDate; + this.interviewStartDate = interviewStartDate; + this.interviewEndDate = interviewEndDate; + this.resultAnnounceDate = resultAnnounceDate; + } + public static SignUpScheduleDto from(SignUpSchedule signUpSchedule) { return new SignUpScheduleDto( + signUpSchedule.getId(), signUpSchedule.getGeneration(), signUpSchedule.getSignupStartDate(), signUpSchedule.getSignupEndDate(), diff --git a/resource-server/src/main/java/com/inhabas/api/web/MemberController.java b/resource-server/src/main/java/com/inhabas/api/web/MemberController.java index 00c31693..5162c328 100644 --- a/resource-server/src/main/java/com/inhabas/api/web/MemberController.java +++ b/resource-server/src/main/java/com/inhabas/api/web/MemberController.java @@ -2,8 +2,8 @@ import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberService; import com.inhabas.api.auth.domain.oauth2.member.dto.*; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.usecase.AnswerService; +import com.inhabas.api.domain.member.dto.AnswerDto; +import com.inhabas.api.domain.member.usecase.AnswerService; import com.inhabas.api.global.dto.PageInfoDto; import com.inhabas.api.global.dto.PagedMemberResponseDto; import io.swagger.v3.oas.annotations.Operation; diff --git a/resource-server/src/main/java/com/inhabas/api/web/SignUpController.java b/resource-server/src/main/java/com/inhabas/api/web/SignUpController.java index 42b5793d..b49dd188 100644 --- a/resource-server/src/main/java/com/inhabas/api/web/SignUpController.java +++ b/resource-server/src/main/java/com/inhabas/api/web/SignUpController.java @@ -1,25 +1,25 @@ package com.inhabas.api.web; -import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; -import com.inhabas.api.domain.questionnaire.dto.QuestionnaireDto; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.dto.SignUpDto; -import com.inhabas.api.domain.signUp.usecase.SignUpService; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.domain.member.dto.AnswerDto; +import com.inhabas.api.domain.member.dto.SignUpDto; +import com.inhabas.api.domain.member.usecase.SignUpService; import com.inhabas.api.web.argumentResolver.Authenticated; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; +import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; +import com.inhabas.api.auth.domain.oauth2.member.dto.MemberDuplicationQueryCondition; +import com.inhabas.api.domain.questionaire.dto.QuestionnaireDto; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; -import java.util.ArrayList; import java.util.List; -import java.util.Optional; @Tag(name = "회원가입", description = "회원가입 기간이 아니면 403 Forbidden") @RestController @@ -28,75 +28,71 @@ public class SignUpController { private final SignUpService signUpService; - /* profile */ - @GetMapping("/signUp") - @Operation(summary = "자신이 임시저장한 개인정보를 불러온다.", - description = "저장한 이력이 없다면 모두 null 반환") + @PostMapping("/signUp") + @Operation(summary = "회원가입 시 개인정보를 저장한다.") @ApiResponses({ - @ApiResponse(responseCode = "200", content = @Content( - schema = @Schema(implementation = SignUpDto.class))), - @ApiResponse(responseCode = "403", description = "권한이 없습니다.") + @ApiResponse(responseCode = "204"), + @ApiResponse(responseCode = "400", description = "잘못된 폼 데이터") }) - public ResponseEntity loadProfile( - @Authenticated Long memberId) { + public ResponseEntity saveStudentProfile( + @Authenticated OAuth2UserInfoAuthentication authentication, @Valid @RequestBody SignUpDto form) { - SignUpDto form = signUpService.loadSignUpForm(memberId); - - return ResponseEntity.ok(form); + signUpService.saveSignUpForm(form, authentication); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } - @Operation(summary = "회원가입 시 자신의 개인정보를 저장한다.") - @ApiResponses({ - @ApiResponse(responseCode = "204"), - @ApiResponse(responseCode = "400", description = "유효하지 않은 입력입니다."), - @ApiResponse(responseCode = "403", description = "권한이 없습니다.") - }) - @PostMapping("/signUp") - public ResponseEntity saveStudentProfile( - @Authenticated Long memberId, @Valid @RequestBody SignUpDto form) { - - signUpService.saveSignUpForm(form, memberId); + @GetMapping("/signUp") + @Operation(summary = "임시저장한 학생의 개인정보를 불러온다.") + @ApiResponse(responseCode = "200") + public ResponseEntity loadProfile( + @Authenticated OAuth2UserInfoAuthentication authentication, @Authenticated StudentId studentId) { - return ResponseEntity.noContent().build(); + SignUpDto form = signUpService.loadSignUpForm(studentId, authentication); + return ResponseEntity.ok(form); } - @Operation(summary = "회원가입에 필요한 전공 정보를 모두 불러온다. (권한 필요 X)") - @ApiResponse(responseCode = "200", content = @Content( - schema = @Schema(implementation = SignUpDto.class))) @GetMapping("/signUp/majorInfo") + @Operation(summary = "회원가입에 필요한 전공 정보를 모두 불러온다.") + @ApiResponse(responseCode = "200") public ResponseEntity> loadAllMajorInfo() { return ResponseEntity.ok(signUpService.getMajorInfo()); - } + @GetMapping("/signUp/isDuplicated") + @Operation(summary = "회원가입 시 필요한 중복검사를 진행한다.") + @ApiResponses({ + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "400", description = "하나도 안넘기거나, 타입이 잘못된 경우") + }) + public ResponseEntity validateDuplication( + MemberDuplicationQueryCondition condition) { + + boolean isDuplicated = signUpService.validateFieldsDuplication(condition); + + return ResponseEntity.ok(isDuplicated); + } /* questionnaire */ - @Operation(summary = "회원가입에 필요한 질문들을 불러온다. (권한 필요 X)") - @ApiResponse(responseCode = "200", content = @Content( - schema = @Schema(implementation = QuestionnaireDto.class))) @GetMapping("/signUp/questionnaires") + @Operation(summary = "회원가입에 필요한 질문들을 불러온다.") + @ApiResponse(responseCode = "200") public ResponseEntity> loadQuestionnaire() { return ResponseEntity.ok(signUpService.getQuestionnaire()); - } /* answer */ @GetMapping("/signUp/answers") - @Operation(summary = "회원가입 도중 자신이 임시 저장한 질문지 답변을 불러온다.") - @ApiResponses({ - @ApiResponse(responseCode = "200", content = @Content( - schema = @Schema(implementation = AnswerDto.class))), - @ApiResponse(responseCode = "403", description = "권한이 없습니다.") - }) + @Operation(summary = "회원가입 도중 임시 저장한 질문지 답변을 불러온다.") + @ApiResponse(responseCode = "200") public ResponseEntity> loadAnswers(@Authenticated Long memberId) { List answers = signUpService.getAnswers(memberId); @@ -105,30 +101,26 @@ public ResponseEntity> loadAnswers(@Authenticated Long memberId) } @PostMapping("/signUp/answers") - @Operation(summary = "회원가입 시 자신이 작성한 답변을 임시 저장한다.") + @Operation(summary = "회원가입 시 작성한 답변을 저장한다.") @ApiResponses({ - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "400", description = "답변이 길이제한을 초과했을 경우"), - @ApiResponse(responseCode = "403", description = "권한이 없습니다.") + @ApiResponse(responseCode = "204"), + @ApiResponse(responseCode = "400", description = "답변이 길이제한을 초과했을 경우") }) public ResponseEntity saveAnswers( - @Authenticated Long memberId, @Valid @RequestBody List answers) { - - signUpService.saveAnswers(answers, memberId); + @Authenticated StudentId studentId, @Valid @RequestBody List answers) { - return ResponseEntity.ok().build(); + signUpService.saveAnswers(answers, studentId); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } /* finish signUp */ @PutMapping("/signUp") @Operation(summary = "회원가입을 완료한다") @ApiResponse(responseCode = "204") - public ResponseEntity finishSignUp(@Authenticated Long memberId, @Valid @RequestBody Optional> answers) { - - signUpService.completeSignUp(answers.orElse(new ArrayList<>()), memberId); - return ResponseEntity.noContent().build(); + public ResponseEntity finishSignUp(@Authenticated StudentId studentId) { + signUpService.completeSignUp(studentId); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } - } diff --git a/resource-server/src/main/java/com/inhabas/api/web/SignUpScheduleController.java b/resource-server/src/main/java/com/inhabas/api/web/SignUpScheduleController.java index 6e2076c4..acfc766e 100644 --- a/resource-server/src/main/java/com/inhabas/api/web/SignUpScheduleController.java +++ b/resource-server/src/main/java/com/inhabas/api/web/SignUpScheduleController.java @@ -1,10 +1,8 @@ package com.inhabas.api.web; import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; -import com.inhabas.api.domain.signUpSchedule.domain.usecase.SignUpScheduler; +import com.inhabas.api.domain.signUpSchedule.domain.SignUpScheduler; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; @@ -14,7 +12,7 @@ import javax.validation.Valid; -@Tag(name="회원가입 일정", description = "회원가입 일정 조회, 수정 / 회장만") +@Tag(name="회원가입 일정") @RestController @RequestMapping("/signUp/schedule") @RequiredArgsConstructor @@ -22,31 +20,25 @@ public class SignUpScheduleController { private final SignUpScheduler signUpScheduler; - - @Operation(summary = "회원가입 관련 일정을 조회한다. (권한 필요X)", - description = "일정은 하나만 반환한다.") - @ApiResponse(responseCode = "200", content = { - @Content(schema = @Schema(implementation = SignUpScheduleDto.class)) - }) @GetMapping + @Operation(summary = "회원가입 관련 일정을 조회한다.") + @ApiResponse(responseCode = "200") public ResponseEntity getSignUpSchedule() { return ResponseEntity.ok(signUpScheduler.getSchedule()); - } + @PutMapping @Operation(summary = "회원가입 관련 일정을 수정한다.") @ApiResponses({ @ApiResponse(responseCode = "204"), - @ApiResponse(responseCode = "403", description = "권한이 없습니다.") + @ApiResponse(responseCode = "401", description = "회장만 변경 가능하다.") }) - @PutMapping public ResponseEntity updateSignUpSchedule(@Valid @RequestBody SignUpScheduleDto signUpScheduleDto) { signUpScheduler.updateSchedule(signUpScheduleDto); return ResponseEntity.noContent().build(); - } } diff --git a/resource-server/src/main/java/com/inhabas/api/web/argumentResolver/LoginMemberArgumentResolver.java b/resource-server/src/main/java/com/inhabas/api/web/argumentResolver/LoginMemberArgumentResolver.java index 34e5eaea..e9441412 100644 --- a/resource-server/src/main/java/com/inhabas/api/web/argumentResolver/LoginMemberArgumentResolver.java +++ b/resource-server/src/main/java/com/inhabas/api/web/argumentResolver/LoginMemberArgumentResolver.java @@ -1,9 +1,13 @@ package com.inhabas.api.web.argumentResolver; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.NotImplementedException; import org.springframework.core.MethodParameter; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.stereotype.Component; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; @@ -22,9 +26,10 @@ public boolean supportsParameter(MethodParameter parameter) { } /** - * SecurityContextHolder에서 받아온 authentication을 기준으로 memberId를 찾아 반환한다. + * SecurityContextHolder에서 받아온 authentication을 기준으로 AuthUserDetail을 찾아 반환한다. * @param parameter @Authenticated 어노테이션에 의해 받아온 파라미터. - * @return Long memberId / null일 경우 null을 반환할 수 있음. + * @return Integer / AuthUserDetail - 파라미터의 타입에 따라 다른 형태로 반환. + * memberId에 의해 조회한 profileId가 null일 경우 null을 반환할 수 있음. */ @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { @@ -32,8 +37,45 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (Objects.isNull(authentication)) return null; // login not processed, anonymous user! - return (Long) authentication.getPrincipal(); + if (isMemberIdType(parameter)) + return resolveMemberId(authentication); + else if (isOAuth2UserInfoAuthenticationType(parameter)) + return authentication; + else + throw new IllegalArgumentException("지원하지 않는 타입입니다"); } + private StudentId resolveMemberId(Authentication authentication) { + + StudentId studentId = null; + + if (isOAuth2UserInfoAuthenticationType(authentication)) { // jwt 토큰 인증 이후 + studentId = (StudentId) authentication.getPrincipal(); + + } else if (authentication instanceof OAuth2AuthenticationToken) { // 소셜 로그인 인증 이후 + throw new NotImplementedException("소셜로그인 구현 완료 후에 작업해야됨!"); + } + else { + log.warn("{} - cannot resolve authenticated User's Id!", this.getClass()); + } + + return studentId; + } + + private boolean isMemberIdType(MethodParameter parameter) { + + return parameter.getParameterType().equals(StudentId.class); + } + + private boolean isOAuth2UserInfoAuthenticationType(MethodParameter parameter) { + + return OAuth2UserInfoAuthentication.class + .isAssignableFrom(parameter.getParameterType()); + } + private boolean isOAuth2UserInfoAuthenticationType(Authentication authentication) { + + return OAuth2UserInfoAuthentication.class + .isAssignableFrom(authentication.getClass()); + } } diff --git a/resource-server/src/main/java/com/inhabas/api/web/interceptor/InterceptorConfig.java b/resource-server/src/main/java/com/inhabas/api/web/interceptor/InterceptorConfig.java index da911554..936e33ff 100644 --- a/resource-server/src/main/java/com/inhabas/api/web/interceptor/InterceptorConfig.java +++ b/resource-server/src/main/java/com/inhabas/api/web/interceptor/InterceptorConfig.java @@ -1,6 +1,6 @@ package com.inhabas.api.web.interceptor; -import com.inhabas.api.domain.signUpSchedule.domain.usecase.SignUpAvailabilityChecker; +import com.inhabas.api.domain.signUpSchedule.domain.SignUpAvailabilityChecker; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/resource-server/src/main/java/com/inhabas/api/web/interceptor/SignUpControllerInterceptor.java b/resource-server/src/main/java/com/inhabas/api/web/interceptor/SignUpControllerInterceptor.java index b16ec95c..809e313b 100644 --- a/resource-server/src/main/java/com/inhabas/api/web/interceptor/SignUpControllerInterceptor.java +++ b/resource-server/src/main/java/com/inhabas/api/web/interceptor/SignUpControllerInterceptor.java @@ -1,6 +1,6 @@ package com.inhabas.api.web.interceptor; -import com.inhabas.api.domain.signUpSchedule.domain.usecase.SignUpAvailabilityChecker; +import com.inhabas.api.domain.signUpSchedule.domain.SignUpAvailabilityChecker; import com.inhabas.api.domain.signUpSchedule.SignUpNotAvailableException; import lombok.RequiredArgsConstructor; import org.springframework.web.servlet.HandlerInterceptor; diff --git a/resource-server/src/test/java/com/inhabas/api/domain/signUp/SignUpIntegrationTest.java b/resource-server/src/test/java/com/inhabas/api/domain/member/SignUpIntegrationTest.java similarity index 55% rename from resource-server/src/test/java/com/inhabas/api/domain/signUp/SignUpIntegrationTest.java rename to resource-server/src/test/java/com/inhabas/api/domain/member/SignUpIntegrationTest.java index f012605b..de8738d6 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/signUp/SignUpIntegrationTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/member/SignUpIntegrationTest.java @@ -1,167 +1,153 @@ -package com.inhabas.api.domain.signUp; +package com.inhabas.api.domain.member; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.inhabas.api.ApiApplication; -import com.inhabas.api.auth.domain.oauth2.CustomOAuth2User; -import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; import com.inhabas.api.auth.domain.oauth2.majorInfo.domain.MajorInfo; import com.inhabas.api.auth.domain.oauth2.majorInfo.repository.MajorInfoRepository; import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberService; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; -import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; -import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; -import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoFactory; import com.inhabas.api.auth.domain.token.TokenUtil; -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import com.inhabas.api.domain.questionnaire.repository.QuestionnaireRepository; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.dto.SignUpDto; +import com.inhabas.api.domain.member.dto.AnswerDto; +import com.inhabas.api.domain.member.dto.SignUpDto; +import com.inhabas.api.domain.questionaire.domain.Questionnaire; +import com.inhabas.api.domain.questionaire.repository.QuestionnaireRepository; import com.inhabas.api.domain.signUpSchedule.domain.entity.SignUpSchedule; import com.inhabas.api.domain.signUpSchedule.repository.SignUpScheduleRepository; import com.inhabas.testAnnotataion.CustomSpringBootTest; -import com.inhabas.testAnnotataion.WithMockJwtAuthenticationToken; -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.RequestPostProcessor; -import org.springframework.transaction.annotation.Transactional; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.util.Arrays; -import java.util.List; -import java.util.Map; -import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role.*; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +@Disabled @CustomSpringBootTest(classes = ApiApplication.class) -@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class SignUpIntegrationTest { @Autowired private MockMvc mockMvc; - @Autowired - private TokenUtil tokenUtil; - @Autowired - private ObjectMapper objectMapper; - @Autowired - private QuestionnaireRepository questionnaireRepository; - @Autowired - private MajorInfoRepository majorInfoRepository; - @Autowired - private MemberRepository memberRepository; - @Autowired - private MemberService memberService; - @Autowired - private SignUpScheduleRepository scheduleRepository; - - private static final String ROLE_PREFIX = "ROLE_"; + @Autowired private TokenUtil tokenUtil; + @Autowired private ObjectMapper objectMapper; + @Autowired private QuestionnaireRepository questionnaireRepository; + @Autowired private MajorInfoRepository majorInfoRepository; + @Autowired private MemberRepository memberRepository; + @Autowired private SignUpScheduleRepository scheduleRepository; - private String token; + private Integer memberId; + private Integer muId; - @BeforeAll + @BeforeEach public void setUp() { - 면접질문_설정(); - 전공정보_설정(); - 회원가입_가능한_기간(); - token = OAuth인증된_JWT_TOKEN(SIGNING_UP); + /*authUserId = authUserRepository.save(new AuthUser("google", "my@gmail.com")).getId();*/ } - @Test - @Transactional - @WithMockJwtAuthenticationToken(memberRole = NOT_APPROVED) - public void 미승인회원_회원가입_비정상_접근() throws Exception { - forbiddenWhenAccessEverySignUpApi(NOT_APPROVED); + public void 기존_일반회원_회원가입_비정상_접근() throws Exception { + forbiddenWhenAccessEverySignUpApi(Role.BASIC); } - @Test - @Transactional - @WithMockJwtAuthenticationToken(memberRole = DEACTIVATED) public void 비활동회원_회원가입_비정상_접근() throws Exception { - forbiddenWhenAccessEverySignUpApi(DEACTIVATED); + forbiddenWhenAccessEverySignUpApi(Role.DEACTIVATED); } - @Test - @Transactional - @WithMockJwtAuthenticationToken(memberRole = BASIC) - public void 기존_일반회원_회원가입_비정상_접근() throws Exception { - forbiddenWhenAccessEverySignUpApi(BASIC); + public void 미승인회원_회원가입_비정상_접근() throws Exception { + forbiddenWhenAccessEverySignUpApi(Role.NOT_APPROVED); } - @Test - @Transactional - @WithMockJwtAuthenticationToken(memberRole = EXECUTIVES) public void 회장단_회원가입_비정상_접근() throws Exception { - forbiddenWhenAccessEverySignUpApi(EXECUTIVES); + forbiddenWhenAccessEverySignUpApi(Role.EXECUTIVES); + } + @Test + public void 관리자_회원가입_비정상_접근() throws Exception { + forbiddenWhenAccessEverySignUpApi(Role.ADMIN); } + @Disabled @Test - @Transactional - @WithMockJwtAuthenticationToken(memberRole = SIGNING_UP) public void 회원가입_기간이_아닙니다() throws Exception { /* 유동현은 IBAS 에 회원 가입하기 위해 - 소셜 로그인 후 회원 가입용 임시 토큰을 발급 받았다. - 회원가입이 불가능한 때에 요청을 보낸경우 */ - scheduleRepository.deleteAll(); - 회원가입_불가능한_기간(); + 소셜 로그인 후 회원 가입용 임시 토큰을 발급 받았다.*/ + String token = tokenUtil.createAccessToken(null); /* OAuth2 인증이 완료되면 자동으로 회원가입 페이지로 리다이렉트 된다. - 이 때, 회원가입을 완료하지 않고 임시저장했던 프로필 정보가 있는지 불러온다. */ + 이 때, 회원가입을 완료하지 않고 임시저장했던 프로필 정보가 있는지 불러오길 시도하지만 + 신규회원 가입이기 때문에, 소셜 이메일을 제외하고는 아무것도 받지 못한다. */ String response = mockMvc.perform(get("/signUp").with(accessToken(token))) .andExpect(status().isForbidden()) .andReturn().getResponse().getContentAsString(StandardCharsets.UTF_8); assertThat(response).isEqualTo("회원가입 기간이 아닙니다."); } + @Disabled @Test - @Transactional - @WithMockJwtAuthenticationToken(memberRole = SIGNING_UP) public void OAuth2_인증_후_비회원_신규_학생_회원가입() throws Exception { + + //given + 면접질문_설정(); + 전공정보_설정(); + 회원가입_가능한_기간(); + + /* 유동현은 IBAS 에 회원 가입하기 위해 소셜 로그인 후 회원 가입용 임시 토큰을 발급 받았다.*/ + String token = tokenUtil.createAccessToken(null); /* OAuth2 인증이 완료되면 자동으로 회원가입 페이지로 리다이렉트 된다. 이 때, 회원가입을 완료하지 않고 임시저장했던 프로필 정보가 있는지 불러오길 시도하지만 신규회원 가입이기 때문에, 소셜 이메일을 제외하고는 아무것도 받지 못한다. */ mockMvc.perform(get("/signUp").with(accessToken(token))) - .andExpect(status().isOk()) - .andExpect(content().string("{\"name\":null,\"major\":null,\"phoneNumber\":null,\"studentId\":null,\"memberType\":null,\"grade\":null}")); + .andExpect(status().isOk()) + .andExpect(content().string("{\"email\":\"my@gmail.com\",\"memberType\":\"UNDERGRADUATE\"}")); /* 개인정보 입력을 위해, 전공 정보들이 로딩된다. */ mockMvc.perform(get("/signUp/majorInfo").with(accessToken(token))) .andExpect(status().isOk()); + /* 프로필 입력 중에 학번이 중복되는 지 검사한다. + 중복되는 학번이 없다고 응답한다. */ + mockMvc.perform(get("/signUp/isDuplicated") + .param("memberId", "12171652")) + .andExpect(status().isOk()) + .andExpect(content().string("false")); + + /* 프로필 입력 중에 전화번호가 중복되는 지 검사한다. + 중복되는 전화번호가 없다고 응답한다. */ + mockMvc.perform(get("/signUp/isDuplicated") + .param("phoneNumber", "010-0000-0000")) + .andExpect(status().isOk()) + .andExpect(content().string("false")); + /* 프로필 입력을 완료하여 다음 버튼을 누르면, 개인정보가 임시저장된다. */ mockMvc.perform(post("/signUp").with(accessToken(token)) .contentType(MediaType.APPLICATION_JSON) .content(jsonOf(SignUpDto.builder() + .email("my@gmail.com") + .studentId(new StudentId("12171652")) .name("유동현") - .major("컴퓨터공학과") .phoneNumber("010-0000-0000") - .studentId("12171652") + .major("컴퓨터공학과") .memberType(MemberType.UNDERGRADUATE) - .grade(1) .build()))) .andExpect(status().isNoContent()); /* 다음 페이지에서 면접용 질문 리스트가 로딩된다. */ - String questionList = mockMvc.perform(get("/signUp/questionnaires").with(accessToken(token))) + String questionList = mockMvc.perform(get("/signUp/questionnaire").with(accessToken(token))) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(StandardCharsets.UTF_8); assertThat(questionList).isEqualTo("[" + @@ -173,45 +159,45 @@ public void setUp() { "]"); /* 기존에 작성했던 답변을 가져오지만, 기존 답변이 없다. */ - mockMvc.perform(get("/signUp/answers").with(accessToken(token))) + mockMvc.perform(get("/signUp/answer").with(accessToken(token))) .andExpect(status().isOk()) - .andExpect(content().string("[{\"questionId\":1,\"content\":null},{\"questionId\":2,\"content\":null},{\"questionId\":3,\"content\":null},{\"questionId\":4,\"content\":null},{\"questionId\":5,\"content\":null}]")); + .andExpect(content().string("[]")); /* 면접 질문에 대답하고 임시저장 버튼을 클릭한다. */ - mockMvc.perform(post("/signUp/answers").with(accessToken(token)) + mockMvc.perform(post("/signUp/answer").with(accessToken(token)) .contentType(MediaType.APPLICATION_JSON) .content(jsonOf(Arrays.asList( - new AnswerDto(1L, "몰랑"), - new AnswerDto(2L, "아몰랑"), - new AnswerDto(3L, "아아몰랑"), - new AnswerDto(4L, "아모른다구"), - new AnswerDto(5L, "ㅎ"))))) - .andExpect(status().isOk()); + new AnswerDto(1, "몰랑"), + new AnswerDto(2, "아몰랑"), + new AnswerDto(3, "아아몰랑"), + new AnswerDto(4, "아모른다구"), + new AnswerDto(5, "ㅎ"))))) + .andExpect(status().isNoContent()); /* 회원가입 신청을 완료한다. */ - mockMvc.perform(put("/signUp").with(accessToken(token)) - .contentType(MediaType.APPLICATION_JSON) - .content(jsonOf(Arrays.asList( - new AnswerDto(1L, ""), - new AnswerDto(2L, "아몰랑"), - new AnswerDto(3L, "아아몰랑"), - new AnswerDto(4L, "아모른다구"), - new AnswerDto(5L, "ㅎ"))))) + mockMvc.perform(put("/signUp/finish").with(accessToken(token))) .andExpect(status().isNoContent()); //then - Member 유동현 = memberRepository.findByProviderAndUid(OAuth2Provider.NAVER, new UID("N8ojJQXxxSxtO0CmEH3xtt5Y6ER09UEsRozkpbGAdOI")).orElseThrow(); - assertThat(유동현.getIbasInformation().getRole()).isEqualTo(NOT_APPROVED); - + Member 유동현 = memberRepository.getByStudentId(new StudentId("12171652")); + assertThat(유동현.getIbasInformation().getRole()).isEqualTo(Role.NOT_APPROVED); +// AuthUser 유동현_소셜_계정 = authUserRepository.findById(authUserId).orElseThrow(AuthUserNotFoundException::new); +// assertThat(유동현_소셜_계정.getProfileId()).isEqualTo(12171652); +// assertThat(유동현_소셜_계정.hasJoined()).isEqualTo(true); } + @Disabled @Test - @Transactional - @WithMockJwtAuthenticationToken(memberRole = SIGNING_UP) public void OAuth2_인증_후_비회원_신규_교수_회원가입() throws Exception { + + //given + 전공정보_설정(); + 회원가입_가능한_기간(); + /* 유동현 교수는 IBAS 에 회원 가입하기 위해 소셜 로그인 후 회원 가입용 임시 토큰을 발급 받았다.*/ + String token = tokenUtil.createAccessToken(null); /* OAuth2 인증이 완료되면 자동으로 회원가입 페이지로 리다이렉트 된다. */ @@ -225,12 +211,26 @@ public void setUp() { "{\"id\":3,\"college\":\"경영대학\",\"major\":\"경영학과\"}" + "]"); + /* 프로필 입력 중에 학번이 중복되는 지 검사한다. + 중복되는 학번이 없다고 응답한다. */ + mockMvc.perform(get("/signUp/isDuplicated") + .param("memberId", "228761")) + .andExpect(status().isOk()) + .andExpect(content().string("false")); + + /* 프로필 입력 중에 전화번호가 중복되는 지 검사한다. + 중복되는 전화번호가 없다고 응답한다. */ + mockMvc.perform(get("/signUp/isDuplicated") + .param("phoneNumber", "010-0000-0000")) + .andExpect(status().isOk()) + .andExpect(content().string("false")); + /* 프로필 입력을 완료하여 다음 버튼을 누르면, 개인정보가 임시저장된다. */ mockMvc.perform(post("/signUp").with(accessToken(token)) .contentType(MediaType.APPLICATION_JSON) .content(jsonOf(SignUpDto.builder() - .grade(1) - .studentId("228761") + .email("my@gmail.com") + .studentId(new StudentId("228761")) .name("유동현") .phoneNumber("010-0000-0000") .major("컴퓨터공학과") @@ -240,30 +240,40 @@ public void setUp() { /* 회원가입 신청을 완료한다. */ - mockMvc.perform(put("/signUp").with(accessToken(token))) - .andExpect(status().isNoContent()); + mockMvc.perform(put("/signUp/finish").with(accessToken(token))) + .andExpect(status().isNoContent()); + //then - Member 유동현_교수 = memberRepository.findByProviderAndUid(OAuth2Provider.NAVER, new UID("N8ojJQXxxSxtO0CmEH3xtt5Y6ER09UEsRozkpbGAdOI")).orElseThrow(); - assertThat(유동현_교수.getIbasInformation().getRole()).isEqualTo(NOT_APPROVED); + Member 유동현_교수 = memberRepository.getByStudentId(new StudentId("228761")); + assertThat(유동현_교수.getIbasInformation().getRole()).isEqualTo(Role.NOT_APPROVED); +// AuthUser 유동현_소셜_계정 = authUserRepository.findById(authUserId).orElseThrow(AuthUserNotFoundException::new); +// assertThat(유동현_소셜_계정.getProfileId()).isEqualTo(228761); +// assertThat(유동현_소셜_계정.hasJoined()).isEqualTo(true); } private void forbiddenWhenAccessEverySignUpApi(Role role) throws Exception { - //given - String token = OAuth인증된_JWT_TOKEN(role); + String token = tokenUtil.createAccessToken(null); - mockMvc.perform(get("/signUp").with(accessToken(token))) + mockMvc.perform(get("/signUp/student").with(accessToken(token))) + .andExpect(status().isForbidden()); + mockMvc.perform(post("/signUp/student").with(accessToken(token))) + .andExpect(status().isForbidden()); + mockMvc.perform(post("/signUp/professor").with(accessToken(token))) .andExpect(status().isForbidden()); - mockMvc.perform(post("/signUp").with(accessToken(token))) + mockMvc.perform(get("/signUp/answer").with(accessToken(token))) .andExpect(status().isForbidden()); - mockMvc.perform(get("/signUp/answers").with(accessToken(token))) + mockMvc.perform(post("/signUp/answer").with(accessToken(token))) .andExpect(status().isForbidden()); - mockMvc.perform(post("/signUp/answers").with(accessToken(token))) + mockMvc.perform(get("/signUp/questionnaire").with(accessToken(token))) + .andExpect(status().isForbidden()); + mockMvc.perform(get("/signUp/majorInfo").with(accessToken(token))) + .andExpect(status().isForbidden()); + mockMvc.perform(get("/signUp/isDuplicated").with(accessToken(token))) + .andExpect(status().isForbidden()); + mockMvc.perform(put("/signUp/finish").with(accessToken(token))) .andExpect(status().isForbidden()); } - - - // setUp public static RequestPostProcessor accessToken(String accessToken) { return request -> { request.addHeader("Authorization", "Bearer " + accessToken); @@ -271,35 +281,15 @@ public static RequestPostProcessor accessToken(String accessToken) { }; } - private String OAuth인증된_JWT_TOKEN(Role role) { - List grantedAuthorities = List.of(new SimpleGrantedAuthority(ROLE_PREFIX+ role.toString())); - Map nameAttributeKey = Map.of( - "message", "success", - "response", Map.of( - "id", "N8ojJQXxxSxtO0CmEH3xtt5Y6ER09UEsRozkpbGAdOI", - "profile_image", "https://ssl.pstatic.net/static/pwe/address/img_profile.png", - "email", "5177jsh@naver.com", - "name", "조승현" - ) - ); - OAuth2UserInfo oAuth2UserInfo = OAuth2UserInfoFactory.getOAuth2UserInfo("NAVER", nameAttributeKey); - memberService.updateSocialAccountInfo(oAuth2UserInfo); - CustomOAuth2User customOAuth2User = new CustomOAuth2User(grantedAuthorities, nameAttributeKey, "response", 1L); - - return tokenUtil.createAccessToken(new OAuth2AuthenticationToken(customOAuth2User, grantedAuthorities, "NAVER")); - - } - private void 면접질문_설정() { questionnaireRepository.saveAll( Arrays.asList( - new Questionnaire(1L, "지원동기 및 목표를 기술해주세요."), - new Questionnaire(2L, "프로그래밍 관련 언어를 다루어 본 적이 있다면 적어주세요."), - new Questionnaire(3L, "빅데이터 관련 활동 혹은 공모전 관련 경험이 있다면 적어주세요."), - new Questionnaire(4L, "추후 희망하는 진로가 무엇이며, 동아리 활동이 진로에 어떠한 영향을 줄 것이라고 생각하나요?"), - new Questionnaire(5L, "어떤 경로로 IBAS를 알게 되셨나요?"))); + new Questionnaire(1, "지원동기 및 목표를 기술해주세요."), + new Questionnaire(2, "프로그래밍 관련 언어를 다루어 본 적이 있다면 적어주세요."), + new Questionnaire(3, "빅데이터 관련 활동 혹은 공모전 관련 경험이 있다면 적어주세요."), + new Questionnaire(4, "추후 희망하는 진로가 무엇이며, 동아리 활동이 진로에 어떠한 영향을 줄 것이라고 생각하나요?"), + new Questionnaire(5, "어떤 경로로 IBAS를 알게 되셨나요?"))); } - private void 전공정보_설정() { majorInfoRepository.saveAll( Arrays.asList( @@ -319,9 +309,4 @@ private String jsonOf(Object o) throws JsonProcessingException { new SignUpSchedule(1, now.minusDays(1L), now.plusDays(1L), now.plusDays(1L), now.plusDays(2L), now.plusDays(3L))); } - private void 회원가입_불가능한_기간() { - LocalDateTime now = LocalDateTime.now(); - scheduleRepository.save( - new SignUpSchedule(1, now.minusDays(2L), now.minusDays(1L), now.plusDays(1L), now.plusDays(2L), now.plusDays(3L))); - } } diff --git a/resource-server/src/test/java/com/inhabas/api/domain/member/domain/entity/MemberTest.java b/resource-server/src/test/java/com/inhabas/api/domain/member/domain/entity/MemberTest.java index 81f51e90..38881ffa 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/member/domain/entity/MemberTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/member/domain/entity/MemberTest.java @@ -3,7 +3,6 @@ import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.IbasInformation; -import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.SchoolInformation; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.userInfo.GoogleOAuth2UserInfo; @@ -12,58 +11,36 @@ import java.util.HashMap; import java.util.Map; -import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType.UNDERGRADUATE; import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role.*; public class MemberTest { - - private static Member afterSignUpMember(Role role) { - - Map attributes = new HashMap<>() {{ - put("provider", "GOOGLE"); - put("sub", "3232322332323223"); - put("picture", "/static/image.jpg"); - put("email", "my@gmail.com"); - put("name", "조승현"); - put("locale", "ko"); - }}; - OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); - Member member = new Member(user); - member.setRole(role); - - // 회원정보 저장 - member.setStudentId("12171234"); - member.setPhone("010-1111-1111"); - member.setName("유동현"); - member.setSchoolInformation(new SchoolInformation("컴퓨터공학과", 1, 1, UNDERGRADUATE)); - return member; - - } - + public static Member chiefMember() { - return afterSignUpMember(CHIEF); + return new Member( + new StudentId("12171707"), "김회장", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(CHIEF)); } public static Member executivesMember() { - return afterSignUpMember(EXECUTIVES); + return new Member( + new StudentId("12201122"), "박임원", "010-2222-2222", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(EXECUTIVES)); } - + public static Member secretaryMember() { - return afterSignUpMember(SECRETARY); - } - - public static Member deactivatedMember() { - return afterSignUpMember(DEACTIVATED); + return new Member( + new StudentId("12219882"), "이총무", "010-3333-3333", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(SECRETARY)); } - public static Member notapprovedMember() { - return afterSignUpMember(NOT_APPROVED); - } + public static Member signingUpMember1() { - public static Member basicMember1() { Map attributes = new HashMap<>() {{ put("provider", "GOOGLE"); - put("sub", "3232322332323223"); + put("sub", "1249846925629348"); put("picture", "/static/image.jpg"); put("email", "my@gmail.com"); put("name", "유동현"); @@ -71,17 +48,14 @@ public static Member basicMember1() { }}; OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); Member member = new Member(user); - member.setRole(BASIC); + member.setRole(SIGNING_UP); - // 회원정보 저장 - member.setStudentId("12171234"); - member.setPhone("010-1111-1111"); - member.setName("유동현"); - member.setSchoolInformation(new SchoolInformation("컴퓨터공학과", 1, 1, UNDERGRADUATE)); return member; } - public static Member basicMember2() { + + public static Member signingUpMember2() { + Map attributes = new HashMap<>() {{ put("provider", "GOOGLE"); put("sub", "3232322332323223"); @@ -92,21 +66,34 @@ public static Member basicMember2() { }}; OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); Member member = new Member(user); - member.setRole(BASIC); + member.setRole(SIGNING_UP); - // 회원정보 저장 - member.setStudentId("12171234"); - member.setPhone("010-1111-1111"); - member.setName("조승현"); - member.setSchoolInformation(new SchoolInformation("컴퓨터공학과", 1, 1, UNDERGRADUATE)); return member; } - public static Member signingUpMemberAfterProfile() { - return afterSignUpMember(SIGNING_UP); + + public static Member basicMember1() { + return new Member( + new StudentId("12171234"), "유동현", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("건축공학과", 3) + , new IbasInformation(BASIC)); } - public static Member signingUpMember1() { + public static Member basicMember2() { + return new Member( + new StudentId("12114321"), "김민겸", "010-2222-2222", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("경영학과", 2) + , new IbasInformation(BASIC)); + } + + public static Member deactivatedMember() { + return new Member( + new StudentId("12171707"), "최비활", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(DEACTIVATED)); + } + + public static Member notapprovedMember() { Map attributes = new HashMap<>() {{ put("provider", "GOOGLE"); @@ -118,28 +105,17 @@ public static Member signingUpMember1() { }}; OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); Member member = new Member(user); - member.setRole(SIGNING_UP); - - return member; - } - - public static Member signingUpMember2() { + member.setEmail("my@gmail.com"); + member.setName("유동현"); - Map attributes = new HashMap<>() {{ - put("provider", "GOOGLE"); - put("sub", "3232322332323223"); - put("picture", "/static/image.jpg"); - put("email", "my2@gmail.com"); - put("name", "조승현"); - put("locale", "ko"); - }}; - OAuth2UserInfo user = new GoogleOAuth2UserInfo(attributes); - Member member = new Member(user); - member.setRole(SIGNING_UP); - return member; + return new Member( + new StudentId("12171707"), "김미승인", "010-1111-1111", "my@gmail.com", "" + , SchoolInformation.ofUnderGraduate("컴퓨터공학과", 2) + , new IbasInformation(NOT_APPROVED)); } + public static Member getTestBasicMember(String id) { return new Member( new StudentId(id), "유동현", "010-1111-1111", "my@gmail.com", "" @@ -154,4 +130,5 @@ public static Member getTestBasicMember(String id, String phoneNumber) { , new IbasInformation(BASIC)); } + } diff --git a/resource-server/src/test/java/com/inhabas/api/domain/member/repository/MemberSocialAccountRepositoryTest.java b/resource-server/src/test/java/com/inhabas/api/domain/member/repository/MemberSocialAccountRepositoryTest.java index 96b9a6cf..7bc0df4f 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/member/repository/MemberSocialAccountRepositoryTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/member/repository/MemberSocialAccountRepositoryTest.java @@ -1,22 +1,22 @@ package com.inhabas.api.domain.member.repository; +import static com.inhabas.api.domain.member.domain.entity.MemberTest.basicMember1; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccount; import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccountRepository; import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; import com.inhabas.testAnnotataion.DefaultDataJpaTest; +import java.util.Optional; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; -import java.util.Optional; - -import static com.inhabas.api.domain.member.domain.entity.MemberTest.signingUpMember1; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertTrue; - @DefaultDataJpaTest public class MemberSocialAccountRepositoryTest { @@ -26,20 +26,19 @@ public class MemberSocialAccountRepositoryTest { @Autowired private TestEntityManager em; - @DisplayName("소셜계정으로 회원의 학번을 가져온다.") - @Test - public void getStudentIdBySocialAccount() { - //given - Member member = em.persist(signingUpMember1()); - memberSocialAccountRepository.save(new MemberSocialAccount(member, "my@gmail.com", "1234", OAuth2Provider.GOOGLE)); - - //when - Optional id = - memberSocialAccountRepository.findMemberIdByUidAndProvider(new UID("1234"), OAuth2Provider.GOOGLE); - - //then - assertTrue(id.isPresent()); - assertThat(id.get()).isEqualTo(member.getId()); - } - +// @DisplayName("소셜계정으로 회원의 학번을 가져온다.") +// @Test +// public void getStudentIdBySocialAccount() { +// //given +// Member member = em.persist(basicMember1()); +// memberSocialAccountRepository.save(new MemberSocialAccount(member, "my@gmail.com", "1234", OAuth2Provider.GOOGLE)); +// +// //when +// Optional id = +// memberSocialAccountRepository.findMemberIdByUidAndProvider(new UID("1234"), OAuth2Provider.GOOGLE); +// +// //then +// assertTrue(id.isPresent()); +// assertThat(id.get()).isEqualTo(member.getId()); +// } } diff --git a/resource-server/src/test/java/com/inhabas/api/domain/member/security/MemberAuthorityProviderTest.java b/resource-server/src/test/java/com/inhabas/api/domain/member/security/MemberAuthorityProviderTest.java index 7922bfc4..1866468d 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/member/security/MemberAuthorityProviderTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/member/security/MemberAuthorityProviderTest.java @@ -1,12 +1,16 @@ package com.inhabas.api.domain.member.security; +import com.inhabas.api.auth.domain.exception.InvalidUserInfoException; +import com.inhabas.api.auth.domain.exception.UserNotFoundException; import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; +import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; import com.inhabas.api.auth.domain.oauth2.member.security.MemberAuthorityProvider; import com.inhabas.api.auth.domain.oauth2.member.security.MemberPrincipalService; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfo; -import com.inhabas.api.domain.member.domain.entity.MemberTest; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -16,8 +20,8 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import java.util.Arrays; import java.util.Collection; -import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -38,6 +42,8 @@ public class MemberAuthorityProviderTest { @Mock private OAuth2UserInfo oAuth2UserInfo; + @Mock + private Member member; @BeforeEach public void setUp() { @@ -46,36 +52,46 @@ public void setUp() { given(oAuth2UserInfo.getProvider()).willReturn(OAuth2Provider.GOOGLE); } +// @Test +// @DisplayName("회원가입하지 않은 사용자가 로그인 시도하면 UserNotFoundException 을 발생시킨다.") +// public void NonMemberLoginRaisesExceptionTest() { +// +// given(memberPrincipalService.loadUserPrincipal(any())).willReturn(null); +// +// //when +// Assertions.assertThrows(UserNotFoundException.class, +// ()->memberAuthorityProvider.determineAuthorities(oAuth2UserInfo)); +// } + +// @Test +// @DisplayName("기존회원의 권한을 들고온다.") +// public void memberLoginTest() { +// +// given(memberPrincipalService.loadUserPrincipal(any())).willReturn(new StudentId("12171652")); +// MemberAuthorityProvider.RoleDto roleDto = +// new MemberAuthorityProvider.RoleDto(Role.BASIC); +// given(memberRepository.fetchRoleByStudentId(any())).willReturn(roleDto); +// +// //when +// Collection simpleGrantedAuthorities = +// memberAuthorityProvider.determineAuthorities(oAuth2UserInfo); +// +// //then +// assertThat(simpleGrantedAuthorities) +// .hasSize(3) +// .extracting("role") +// .contains("ROLE_BASIC", "TEAM_회계", "TEAM_운영"); +// } @Test - @DisplayName("기존회원의 권한을 들고온다.") - public void memberLoginTest() { - - given(memberPrincipalService.loadUserPrincipal(any())).willReturn(1L); - MemberAuthorityProvider.RoleDto roleDto = - new MemberAuthorityProvider.RoleDto(Role.BASIC); - given(memberRepository.fetchRoleByStudentId(any())).willReturn(roleDto); - - //when - Collection simpleGrantedAuthorities = - memberAuthorityProvider.determineAuthorities(oAuth2UserInfo); - - //then - assertThat(simpleGrantedAuthorities).containsExactly(new SimpleGrantedAuthority("ROLE_BASIC")); - - } - - @Test - @DisplayName("OAuth 인증을 했지만 회원가입을 완료하지 않았다면 SIGNING_UP 권한 부여") + @DisplayName("회원의 소셜계정 정보는 있지만, 회원프로필이 존재하지 않으면 오류발생") public void cannotFindProfileMappedFromSocialAccount() { - given(memberPrincipalService.loadUserPrincipal(any())).willReturn(null); - given(memberRepository.findByProviderAndUid(any(), any())) - .willReturn(Optional.of(MemberTest.signingUpMember1())); - - Collection simpleGrantedAuthorities = - memberAuthorityProvider.determineAuthorities(oAuth2UserInfo); + given(memberPrincipalService.loadUserPrincipal(any())).willReturn(new StudentId("12171652")); + given(memberRepository.fetchRoleByStudentId(any())) + .willReturn(new MemberAuthorityProvider.RoleDto(null)); //then - assertThat(simpleGrantedAuthorities).containsExactly(new SimpleGrantedAuthority("ROLE_SIGNING_UP")); + Assertions.assertThrows(InvalidUserInfoException.class, + () -> memberAuthorityProvider.determineAuthorities(oAuth2UserInfo)); } } diff --git a/resource-server/src/test/java/com/inhabas/api/domain/member/security/MemberPrincipalServiceTest.java b/resource-server/src/test/java/com/inhabas/api/domain/member/security/MemberPrincipalServiceTest.java index 49019979..f98ad790 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/member/security/MemberPrincipalServiceTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/member/security/MemberPrincipalServiceTest.java @@ -1,14 +1,22 @@ package com.inhabas.api.domain.member.security; +import com.inhabas.api.auth.domain.oauth2.OAuth2Provider; +import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; import com.inhabas.api.auth.domain.oauth2.member.security.MemberPrincipalService; +import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccount; import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccountRepository; import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; +import com.inhabas.api.auth.domain.token.securityFilter.UserPrincipalNotFoundException; +import com.inhabas.api.domain.member.domain.entity.MemberTest; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; import java.util.Optional; @@ -27,21 +35,60 @@ public class MemberPrincipalServiceTest { @Mock private MemberSocialAccountRepository memberSocialAccountRepository; - @Test - @DisplayName("기존회원을 uid 와 provider 로 찾는다.") - public void findMemberByUidAndProvider() { - //given - given(memberSocialAccountRepository.findMemberIdByUidAndProvider(any(), any())) - .willReturn(Optional.of(1L)); - - //when - Long memberId - = (Long) memberPrincipalService.loadUserPrincipal(new OAuth2UserInfoAuthentication("1234579123", "KAKAO", "my@gmail.com")); - - //then - assertThat(memberId).isEqualTo(1L); - then(memberSocialAccountRepository).should(times(1)).findMemberIdByUidAndProvider(any(), any()); - then(memberSocialAccountRepository).should(times(0)).findMemberSocialAccountByEmailAndProvider(any(), any()); - } +// @Test +// @DisplayName("기존회원을 uid 와 provider 로 찾는다.") +// public void findMemberByUidAndProvider() { +// //given +// Member member = MemberTest.basicMember1(); +// given(memberSocialAccountRepository.findMemberIdByUidAndProvider(any(), any())) +// .willReturn(Optional.of(member.getId())); +// +// //when +// StudentId StudentId +// = (StudentId) memberPrincipalService.loadUserPrincipal(new OAuth2UserInfoAuthentication("1234579123", "KAKAO", "my@gmail.com")); +// +// //then +// assertThat(StudentId).isEqualTo(member.getId()); +// then(memberSocialAccountRepository).should(times(1)).findMemberIdByUidAndProvider(any(), any()); +// then(memberSocialAccountRepository).should(times(0)).findMemberSocialAccountByEmailAndProvider(any(), any()); +// } + +// @Test +// @DisplayName("기존회원의 uid 가 없어서 이메일과 provider 로 찾는다.") +// public void findMemberByEmailAndProvider() { +// //given +// Member member = MemberTest.basicMember1(); +// MemberSocialAccount memberSocialAccount = +// new MemberSocialAccount(member, "my@gmail.com", "1234579123", OAuth2Provider.KAKAO); +// ReflectionTestUtils.setField(memberSocialAccount, "id", 1); +// given(memberSocialAccountRepository.findMemberIdByUidAndProvider(any(), any())) +// .willReturn(Optional.empty()); +// given(memberSocialAccountRepository.findMemberSocialAccountByEmailAndProvider(any(), any())) +// .willReturn(Optional.of(memberSocialAccount)); +// given(memberSocialAccountRepository.save(any())).willReturn(null); +// +// //when +// StudentId StudentId +// = (StudentId) memberPrincipalService.loadUserPrincipal(new OAuth2UserInfoAuthentication("1234579123", "KAKAO", "my@gmail.com")); +// +// //then +// assertThat(StudentId).isEqualTo(member.getId()); +// then(memberSocialAccountRepository).should(times(1)).findMemberIdByUidAndProvider(any(), any()); +// then(memberSocialAccountRepository).should(times(1)).findMemberSocialAccountByEmailAndProvider(any(), any()); +// } +// +// @Test +// @DisplayName("기존회원이 아니라서 검색되지 않는다.") +// public void cannotFindMemberPrincipalTest() { +// //given +// given(memberSocialAccountRepository.findMemberIdByUidAndProvider(any(), any())) +// .willReturn(Optional.empty()); +// given(memberSocialAccountRepository.findMemberSocialAccountByEmailAndProvider(any(), any())) +// .willReturn(Optional.empty()); +// +// //then +// Assertions.assertThrows(UserPrincipalNotFoundException.class, +// () ->memberPrincipalService.loadUserPrincipal(new OAuth2UserInfoAuthentication("1234579123", "KAKAO", "my@gmail.com"))); +// } } diff --git a/resource-server/src/test/java/com/inhabas/api/domain/member/usecase/AnswerServiceTest.java b/resource-server/src/test/java/com/inhabas/api/domain/member/usecase/AnswerServiceTest.java new file mode 100644 index 00000000..061d469e --- /dev/null +++ b/resource-server/src/test/java/com/inhabas/api/domain/member/usecase/AnswerServiceTest.java @@ -0,0 +1,122 @@ +package com.inhabas.api.domain.member.usecase; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; +import com.inhabas.api.domain.member.domain.entity.Answer; +import com.inhabas.api.domain.member.domain.entity.MemberTest; +import com.inhabas.api.domain.member.dto.AnswerDto; +import java.util.ArrayList; +import java.util.List; + +import com.inhabas.api.domain.member.repository.AnswerRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class AnswerServiceTest { + + @InjectMocks + private AnswerServiceImpl answerService; + + @Mock + private AnswerRepository answerRepository; + + @Mock + private MemberRepository memberRepository; + + +// @DisplayName("사용자가 작성한 답변이 엔티티로 잘 변환되는지 확인한다.") +// @Test +// public void saveAnswersTest() { +// //given +// Member member = MemberTest.basicMember1(); +// StudentId currentUserId = member.getId(); +// given(memberRepository.getById(any())).willReturn(member); +// +// ArrayList submittedAnswers = new ArrayList<>() {{ +// add(new AnswerDto(1, "저는 꼭 이 동아리에 입부하고 싶습니다.")); +// add(new AnswerDto(2, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); +// add(new AnswerDto(3, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); +// add(new AnswerDto(4, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); +// }}; +// +// ArrayList expectedConvertedEntityList = new ArrayList<>() {{ +// add(new Answer(member, 1, "저는 꼭 이 동아리에 입부하고 싶습니다.")); +// add(new Answer(member, 2, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); +// add(new Answer(member, 3, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); +// add(new Answer(member, 4, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); +// }}; +// given(answerRepository.saveAll(any())).willReturn(expectedConvertedEntityList); +// +// //when +// answerService.saveAnswers(submittedAnswers, currentUserId); +// +// //then +// ArgumentCaptor> argumentCaptor = ArgumentCaptor.forClass(ArrayList.class); +// verify(answerRepository, times(1)).saveAll(argumentCaptor.capture()); +// +// assertThat(argumentCaptor.getValue()) +// .usingRecursiveFieldByFieldElementComparator() +// .isEqualTo(expectedConvertedEntityList); +// } + + +// @DisplayName("사용자가 저장한 답변을 dto로 변환해서 반환한다.") +// @Test +// public void loadAnswersTest() { +// //given +// Member member = MemberTest.basicMember1(); +// StudentId currentUserId = member.getId(); +// +// ArrayList savedAnswers = new ArrayList<>() {{ +// add(new Answer(member, 1, "저는 꼭 이 동아리에 입부하고 싶습니다.")); +// add(new Answer(member, 2, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); +// add(new Answer(member, 3, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); +// add(new Answer(member, 4, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); +// }}; +// given(answerRepository.findByMember_Id(any())).willReturn(savedAnswers); +// +// ArrayList expectedConvertedDTOs = new ArrayList<>() {{ +// add(new AnswerDto(1, "저는 꼭 이 동아리에 입부하고 싶습니다.")); +// add(new AnswerDto(2, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); +// add(new AnswerDto(3, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); +// add(new AnswerDto(4, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); +// }}; +// +// //when +// List returnedDTOs = answerService.getAnswers(currentUserId); +// +// //then +// assertThat(returnedDTOs) +// .usingRecursiveComparison() +// .isEqualTo(expectedConvertedDTOs); +// } + + @DisplayName("특정 회원이 작성한 답변이 있는지 확인한다.") + @Test + public void existAnswersWrittenByMemberTest() { + //given + given(answerRepository.existsByMember_id(any())).willReturn(true); + + //when + boolean result = answerService.existAnswersWrittenBy(new StudentId("12171652")); + + //then + assertTrue(result); + then(answerRepository).should(times(1)).existsByMember_id(any()); + } +} diff --git a/resource-server/src/test/java/com/inhabas/api/domain/member/usecase/SignUpServiceTest.java b/resource-server/src/test/java/com/inhabas/api/domain/member/usecase/SignUpServiceTest.java new file mode 100644 index 00000000..b5951683 --- /dev/null +++ b/resource-server/src/test/java/com/inhabas/api/domain/member/usecase/SignUpServiceTest.java @@ -0,0 +1,381 @@ +package com.inhabas.api.domain.member.usecase; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.times; + +import java.util.List; + +import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; +import com.inhabas.api.auth.domain.oauth2.majorInfo.usecase.MajorInfoService; +import com.inhabas.api.auth.domain.oauth2.member.domain.exception.NoQueryParameterException; +import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberDuplicationCheckerImpl; +import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberServiceImpl; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.auth.domain.oauth2.member.dto.MemberDuplicationQueryCondition; +import com.inhabas.api.domain.questionaire.usecase.QuestionnaireService; +import com.inhabas.api.domain.signUpSchedule.domain.SignUpSchedulerStrict; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class SignUpServiceTest { + + @InjectMocks + private SignUpServiceImpl signUpService; + + @Mock + private MemberServiceImpl memberService; + + @Mock + private MajorInfoService majorInfoService; + + @Mock + private AnswerService answerService; + + @Mock + private QuestionnaireService questionnaireService; + + @Mock + private MemberDuplicationCheckerImpl memberDuplicationChecker; + + @Mock + private SignUpSchedulerStrict signUpSchedulerStrict; + + @DisplayName("회원가입폼이 제출되면 저장한다.") + @Test + public void saveSignUpFormTest() { + //given +// SignUpDto signUpForm = SignUpDto.builder() +// .name("유동현") +// .major("컴퓨터공학과") +// .phoneNumber("010-0000-1111") +// .email("my@email.com") +// .memberId(12345678) +// .memberType(MemberType.UNDERGRADUATE) +// .build(); +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(12345678) +// .build(); +// doNothing().when(memberService).save(any(Member.class)); +// doNothing().when(authUserService).setProfileIdToSocialAccount(anyInt(), anyInt()); +// +// SignUpScheduleDto signUpScheduleDto = new SignUpScheduleDto(); +// ReflectionTestUtils.setField(signUpScheduleDto, "generation", 1); +// given(signUpSchedulerStrict.getSchedule()).willReturn(signUpScheduleDto); +// +// //when +// signUpService.saveSignUpForm(signUpForm, authUserDetail); +// +// //then +// then(memberService).should(times(1)).save(any(Member.class)); +// then(authUserService).should(times(1)).setProfileIdToSocialAccount(anyInt(), anyInt()); + } + + @Disabled + @DisplayName("임시저장된 회원 프로필 정보를 불러온다.") + @Test + public void loadMemberProfileTest() { + //given +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(12345678) +// .build(); +// Member storedMember = Member.builder() +// .id(12345678) +// .name("유동현") +// .phoneNumber("010-0000-0000") +// .email("my@email.com") +// .picture("") +// .ibasInformation(new IbasInformation(Role.BASIC)) +// .schoolInformation(SchoolInformation.ofUnderGraduate("전자공학과", 1)) +// .build(); +// given(memberService.findById(anyInt())).willReturn(storedMember); +// +// //when +// SignUpDto loadedForm = signUpService.loadSignUpForm(authUserDetail); +// +// //then +// SignUpDto expectResult = SignUpDto.builder() +// .name("유동현") +// .major("전자공학과") +// .phoneNumber("010-0000-0000") +// .email("my@gmail.com") +// .memberId(12345678) +// .memberType(MemberType.UNDERGRADUATE) +// .build(); +// +// assertThat(loadedForm) +// .usingRecursiveComparison() +// .isEqualTo(expectResult); + } + + @Disabled + @DisplayName("임시저장된 회원 프로필 정보가 없다.") + @Test + public void noSavedMemberProfileTest() { + //given +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(null) +// .build(); +// given(memberService.findById(any())).willThrow(IllegalArgumentException.class); +// +// //when +// SignUpDto loadedForm = signUpService.loadSignUpForm(authUserDetail); +// +// //then +// SignUpDto expectResult = SignUpDto.builder() +// .name(null) +// .major(null) +// .phoneNumber(null) +// .email("my@gmail.com") +// .memberId(null) +// .memberType(MemberType.UNDERGRADUATE) +// .build(); +// +// assertThat(loadedForm) +// .usingRecursiveComparison() +// .isEqualTo(expectResult); + } + + @Disabled + @DisplayName("소셜 계정 정보에 매핑된 학번으로 회원 데이터를 조회할 수 없으면, 깨끗한 폼을 반환한다.") + @Test + public void invalidMappingMemberProfileTest() { + //given +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(12171652) +// .build(); +// given(memberService.findById(any())).willThrow(MemberNotFoundException.class); +// +// //when +// SignUpDto loadedForm = signUpService.loadSignUpForm(authUserDetail); +// +// //then +// SignUpDto expectResult = SignUpDto.builder() +// .name(null) +// .major(null) +// .phoneNumber(null) +// .email("my@gmail.com") +// .memberId(null) +// .memberType(MemberType.UNDERGRADUATE) +// .build(); +// +// assertThat(loadedForm) +// .usingRecursiveComparison() +// .isEqualTo(expectResult); + } + + @Disabled + @DisplayName("중복검사를 위한 api 호출 시 파라미터가 하나도 없으면 오류") + @Test + public void noParamsForDuplicateValidation() { + //when + MemberDuplicationQueryCondition condition = new MemberDuplicationQueryCondition(); + + //then + assertThrows(NoQueryParameterException.class, + condition::verifyTwoParameters); + } + +// @Disabled +// @DisplayName("중복 검사 호출") +// @Test +// public void validateForStudentId() { +// //given +// MemberDuplicationQueryCondition condition = +// new MemberDuplicationQueryCondition(new StudentId("12171652"), "010-1111-1111"); +// given(memberDuplicationChecker.isDuplicatedMember(any(MemberDuplicationQueryCondition.class))).willReturn(true); +// +// //when +// signUpService.validateFieldsDuplication(condition); +// +// //then +// then(memberDuplicationChecker).should(times(1)).isDuplicatedMember(any(MemberDuplicationQueryCondition.class)); +// } + + @Disabled + @DisplayName("회원가입 완료 처리") + @Test + public void completeSignUpTest() { + //given +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(12171652) +// .build(); +// doNothing().when(authUserService).finishSignUp(anyInt()); +// doNothing().when(memberService).changeRole(anyInt(), any()); +// given(memberService.findById(anyInt())).willReturn(Member.builder() +// .id(12345678) +// .name("유동현") +// .phoneNumber("010-0000-0000") +// .email("my@email.com") +// .picture("") +// .ibasInformation(new IbasInformation(Role.BASIC)) +// .schoolInformation(SchoolInformation.ofProfessor("전자공학과", 1)) +// .build()); +// +// //when +// signUpService.completeSignUp(authUserDetail); +// +// //then +// then(authUserService).should(times(1)).finishSignUp(anyInt()); +// then(memberService).should(times(1)).changeRole(anyInt(), any()); + } + + @Disabled + @DisplayName("답변을 작성하지 않아서 회원가입이 완료되지 않는다.") + @Test + public void notYetWriteAnswersTests() { + //given +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(12171652) +// .build(); +// given(memberService.findById(anyInt())).willReturn(Member.builder() +// .id(12345678) +// .name("유동현") +// .phoneNumber("010-0000-0000") +// .email("my@gmail.com") +// .picture("") +// .ibasInformation(new IbasInformation(Role.BASIC)) +// .schoolInformation(SchoolInformation.ofUnderGraduate("전자공학과", 1)) +// .build()); +// given(answerService.existAnswersWrittenBy(anyInt())).willReturn(false); +// +// //then +// assertThrows(NotWriteAnswersException.class, +// ()->signUpService.completeSignUp(authUserDetail)); + } + + @Disabled + @DisplayName("회원정보를 입력하지 않아서 회원가입이 완료되지 않는다.") + @Test + public void notYetWriteProfileTests() { + //given +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(null) +// .build(); +// +// //then +// assertThrows(NotWriteProfileException.class, +// ()->signUpService.completeSignUp(authUserDetail)); + } + + @DisplayName("모든 전공 정보를 불러온다.") + @Test + public void getMajorInfoTest() { + //given + given(majorInfoService.getAllMajorInfo()).willReturn(List.of(new MajorInfoDto(2, "공대", "전기공학과"))); + + //when + signUpService.getMajorInfo(); + + //then + then(majorInfoService).should(times(1)).getAllMajorInfo(); + } + + @DisplayName("모든 질문지 리스트를 불러온다.") + @Test + public void getQuestionnaire() { + //given + given(questionnaireService.getQuestionnaire()).willReturn(List.of()); + + //when + signUpService.getQuestionnaire(); + + //then + then(questionnaireService).should(times(1)).getQuestionnaire(); + } + + @Disabled + @DisplayName("특정 회원이 작성한 답변 리스트를 불러온다.") + @Test + public void getAnswers() { + //given +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(12171652) +// .build(); +// given(answerService.getAnswers(anyInt())).willReturn(List.of()); +// +// //when +// signUpService.getAnswers(authUserDetail); +// +// //then +// then(answerService).should(times(1)).getAnswers(anyInt()); + } + + @Disabled + @DisplayName("특정 회원이 작성한 답변을 저장한다.") + @Test + public void saveAnswers() { + //given +// AuthUserDetail authUserDetail = AuthUserDetail.builder() +// .id(1) +// .email("my@gmail.com") +// .hasJoined(false) +// .isActive(true) +// .provider("google") +// .profileId(12171652) +// .build(); +// ArrayList submittedAnswers = new ArrayList<>() {{ +// add(new AnswerDto(1, "저는 꼭 이 동아리에 입부하고 싶습니다.")); +// add(new AnswerDto(2, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); +// add(new AnswerDto(3, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); +// add(new AnswerDto(4, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); +// }}; +// doNothing().when(answerService).saveAnswers(any(), anyInt()); +// +// //when +// signUpService.saveAnswers(submittedAnswers, authUserDetail); +// +// //then +// then(answerService).should(times(1)).saveAnswers(any(), anyInt()); + } + + +} diff --git a/resource-server/src/test/java/com/inhabas/api/domain/menu/repository/MenuRepositoryTest.java b/resource-server/src/test/java/com/inhabas/api/domain/menu/repository/MenuRepositoryTest.java index c0f393cc..3fc09c0b 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/menu/repository/MenuRepositoryTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/menu/repository/MenuRepositoryTest.java @@ -34,34 +34,35 @@ public void setUp() { } - @DisplayName("새로운 메뉴를 만든다.") - @Test - public void CreateNewMenu() { - //given - MenuGroup menuGroup1 = em.persist(new MenuGroup("IBAS")); - Menu activityBoardMenu = new Menu(menuGroup1, 1, MenuType.LIST, "동아리 활동", "동아리원의 활동을 기록하는 게시판입니다."); - - //when - Menu saveActivityMenu = menuRepository.save(activityBoardMenu); - em.flush(); - - //then - assertThat(saveActivityMenu.getId()).isNotNull(); - assertThat(saveActivityMenu.getDateCreated()).isNotNull(); - assertThat(saveActivityMenu.getDateUpdated()).isNotNull(); - assertThat(saveActivityMenu) - .usingRecursiveComparison() - .ignoringFields("id", "dateCreated", "dateUpdated") - .isEqualTo(activityBoardMenu); - } +// @DisplayName("새로운 메뉴를 만든다.") +// @Test +// public void CreateNewMenu() { +// //given +// MenuGroup menuGroup1 = em.persist(new MenuGroup("IBAS")); +// Menu activityBoardMenu = new Menu(menuGroup1, 1, MenuType.LIST, "동아리 활동", "동아리원의 활동을 기록하는 게시판입니다."); +// +// //when +// Menu saveActivityMenu = menuRepository.save(activityBoardMenu); +// em.flush(); +// +// //then +// assertThat(saveActivityMenu.getId()).isNotNull(); +// assertThat(saveActivityMenu.getDateCreated()).isNotNull(); +// assertThat(saveActivityMenu.getDateUpdated()).isNotNull(); +// assertThat(saveActivityMenu) +// .usingRecursiveComparison() +// .ignoringFields("id", "dateCreated", "dateUpdated") +// .isEqualTo(activityBoardMenu); +// } @Disabled @DisplayName("메뉴 이름을 수정한다.") @Test public void updateMenuName() { //given - MenuGroup menuGroup = em.persist(new MenuGroup("게시판 목록")); - Menu noticeMenu = menuRepository.save(new Menu(menuGroup, 1, MenuType.LIST, "공지사항", "동아리 공지를 게시하는 게시판입니다.")); + MenuGroup menuGroup1 = em.persist(new MenuGroup("IBAS")); + MenuGroup menuGroup2 = em.persist(new MenuGroup("게시판 목록")); + Menu noticeMenu = menuRepository.save(new Menu(menuGroup2, 1, MenuType.LIST, "공지사항", "동아리 공지를 게시하는 게시판입니다.")); //when String newName = "공지 사항"; diff --git a/resource-server/src/test/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireServiceTest.java b/resource-server/src/test/java/com/inhabas/api/domain/questionnaire/QuestionnaireServiceTest.java similarity index 64% rename from resource-server/src/test/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireServiceTest.java rename to resource-server/src/test/java/com/inhabas/api/domain/questionnaire/QuestionnaireServiceTest.java index fe9d5558..23fce649 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/questionnaire/usecase/QuestionnaireServiceTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/questionnaire/QuestionnaireServiceTest.java @@ -1,11 +1,12 @@ -package com.inhabas.api.domain.questionnaire.usecase; +package com.inhabas.api.domain.questionnaire; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import com.inhabas.api.domain.questionnaire.repository.QuestionnaireRepository; -import com.inhabas.api.domain.questionnaire.dto.QuestionnaireDto; +import com.inhabas.api.domain.questionaire.domain.Questionnaire; +import com.inhabas.api.domain.questionaire.repository.QuestionnaireRepository; +import com.inhabas.api.domain.questionaire.usecase.QuestionnaireServiceImpl; +import com.inhabas.api.domain.questionaire.dto.QuestionnaireDto; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.DisplayName; @@ -29,11 +30,11 @@ public class QuestionnaireServiceTest { public void getQuestionnaire() { //given ArrayList questionnaireInDatabase = new ArrayList<>(){{ - add(new Questionnaire(1L, "지원동기 및 목표를 기술해주세요.")); - add(new Questionnaire(2L, "프로그래밍 관련 언어를 다루어 본 적이 있다면 적어주세요.")); - add(new Questionnaire(3L, "빅데이터 관련 활동 혹은 공모전 관련 경험이 있다면 적어주세요.")); - add(new Questionnaire(4L, "추후 희망하는 진로가 무엇이며, 동아리 활동이 진로에 어떠한 영향을 줄 것이라고 생각하나요?")); - add(new Questionnaire(5L, "어떤 경로로 IBAS를 알게 되셨나요?")); + add(new Questionnaire(1, "지원동기 및 목표를 기술해주세요.")); + add(new Questionnaire(2, "프로그래밍 관련 언어를 다루어 본 적이 있다면 적어주세요.")); + add(new Questionnaire(3, "빅데이터 관련 활동 혹은 공모전 관련 경험이 있다면 적어주세요.")); + add(new Questionnaire(4, "추후 희망하는 진로가 무엇이며, 동아리 활동이 진로에 어떠한 영향을 줄 것이라고 생각하나요?")); + add(new Questionnaire(5, "어떤 경로로 IBAS를 알게 되셨나요?")); }}; given(questionnaireRepository.findAll()).willReturn(questionnaireInDatabase); diff --git a/resource-server/src/test/java/com/inhabas/api/domain/questionnaire/repository/QuestionnaireRepositoryTest.java b/resource-server/src/test/java/com/inhabas/api/domain/questionnaire/repository/QuestionnaireRepositoryTest.java deleted file mode 100644 index 7c9e9f8e..00000000 --- a/resource-server/src/test/java/com/inhabas/api/domain/questionnaire/repository/QuestionnaireRepositoryTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.inhabas.api.domain.questionnaire.repository; - -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import com.inhabas.testAnnotataion.DefaultDataJpaTest; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -@DefaultDataJpaTest -class QuestionnaireRepositoryTest { - - @Autowired - private QuestionnaireRepository questionnaireRepository; - - @Test - @DisplayName("idList와 일치하는것이 몇개 포함되어 있는지 확인한다.") - @Transactional - public void countByIdIn() { - //given - ArrayList questionnaireInDatabase = new ArrayList<>() {{ - add(new Questionnaire(1L, "지원동기 및 목표를 기술해주세요.")); - add(new Questionnaire(2L, "프로그래밍 관련 언어를 다루어 본 적이 있다면 적어주세요.")); - add(new Questionnaire(3L, "빅데이터 관련 활동 혹은 공모전 관련 경험이 있다면 적어주세요.")); - add(new Questionnaire(4L, "추후 희망하는 진로가 무엇이며, 동아리 활동이 진로에 어떠한 영향을 줄 것이라고 생각하나요?")); - add(new Questionnaire(5L, "어떤 경로로 IBAS를 알게 되셨나요?")); - }}; - questionnaireRepository.saveAll(questionnaireInDatabase); - - //when - List ids = List.of(1L, 2L, 3L); - Long shouldBeThree = questionnaireRepository.countByIdIn(ids); - - //then - assertThat(shouldBeThree).isEqualTo(3); - - } -} \ No newline at end of file diff --git a/resource-server/src/test/java/com/inhabas/api/domain/signUpSchedule/domain/entity/SignUpScheduleTest.java b/resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/SignUpScheduleTest.java similarity index 97% rename from resource-server/src/test/java/com/inhabas/api/domain/signUpSchedule/domain/entity/SignUpScheduleTest.java rename to resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/SignUpScheduleTest.java index 85a7cb5f..35d139bc 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/signUpSchedule/domain/entity/SignUpScheduleTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/SignUpScheduleTest.java @@ -1,14 +1,14 @@ -package com.inhabas.api.domain.signUpSchedule.domain.entity; +package com.inhabas.api.domain.signUp.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import com.inhabas.api.domain.signUpSchedule.InvalidDateException; +import com.inhabas.api.domain.signUpSchedule.domain.entity.SignUpSchedule; +import java.time.LocalDateTime; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.time.LocalDateTime; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; - public class SignUpScheduleTest { diff --git a/resource-server/src/test/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/StrictSignUpSchedulerTest.java b/resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/StrictSignUpSchedulerTest.java similarity index 96% rename from resource-server/src/test/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/StrictSignUpSchedulerTest.java rename to resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/StrictSignUpSchedulerTest.java index e52d2b5a..0b57713b 100644 --- a/resource-server/src/test/java/com/inhabas/api/domain/signUpSchedule/domain/usecase/StrictSignUpSchedulerTest.java +++ b/resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/StrictSignUpSchedulerTest.java @@ -1,9 +1,16 @@ -package com.inhabas.api.domain.signUpSchedule.domain.usecase; +package com.inhabas.api.domain.signUp.domain; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.times; + +import com.inhabas.api.domain.signUpSchedule.domain.SignUpSchedulerStrict; import com.inhabas.api.domain.signUpSchedule.domain.entity.SignUpSchedule; -import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; import com.inhabas.api.domain.signUpSchedule.repository.SignUpScheduleRepository; +import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; import com.inhabas.testAnnotataion.DefaultDataJpaTest; +import java.time.LocalDateTime; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -12,13 +19,6 @@ import org.springframework.context.annotation.Import; import org.springframework.test.annotation.DirtiesContext; -import java.time.LocalDateTime; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.times; - @DefaultDataJpaTest @Import(SignUpSchedulerStrict.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) @@ -96,7 +96,7 @@ public void updateScheduleTest() { public void updateBeforeInitializeScheduleTest() { //given SignUpScheduleDto signUpScheduleDto = new SignUpScheduleDto( - 1, LocalDateTime.of(2022, 1, 1, 0, 0, 0), + 1, 1, LocalDateTime.of(2022, 1, 1, 0, 0, 0), LocalDateTime.of(2022, 1, 2, 0, 0, 0), LocalDateTime.of(2022, 1, 3, 0, 0, 0), LocalDateTime.of(2022, 1, 4, 0, 0, 0), diff --git a/resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/entity/AnswerTest.java b/resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/entity/AnswerTest.java deleted file mode 100644 index 421ec589..00000000 --- a/resource-server/src/test/java/com/inhabas/api/domain/signUp/domain/entity/AnswerTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.inhabas.api.domain.signUp.domain.entity; - -import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.domain.member.domain.entity.MemberTest; -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class AnswerTest { - - @Test - @DisplayName("생성자 객체 생성") - public void Answer() { - //given - Member member = MemberTest.getTestBasicMember("12171707"); - Questionnaire questionnaire = new Questionnaire(1L, "hello"); - String content = "Ok... bye"; - - //when - Answer answer = new Answer(member, questionnaire, content); - - //then - assertThat(member).isEqualTo(answer.getMember()); - assertThat(questionnaire).isEqualTo(answer.getQuestionnaire()); - assertThat(content).isEqualTo(answer.getContent()); - - } - -} \ No newline at end of file diff --git a/resource-server/src/test/java/com/inhabas/api/domain/signUp/repository/AnswerRepositoryTest.java b/resource-server/src/test/java/com/inhabas/api/domain/signUp/repository/AnswerRepositoryTest.java deleted file mode 100644 index a275a411..00000000 --- a/resource-server/src/test/java/com/inhabas/api/domain/signUp/repository/AnswerRepositoryTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.inhabas.api.domain.signUp.repository; - -import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; -import com.inhabas.api.auth.domain.oauth2.socialAccount.type.UID; -import com.inhabas.api.domain.member.domain.entity.MemberTest; -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import com.inhabas.api.domain.questionnaire.repository.QuestionnaireRepository; -import com.inhabas.api.domain.signUp.domain.entity.Answer; -import com.inhabas.testAnnotataion.DefaultDataJpaTest; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -import static com.inhabas.api.auth.domain.oauth2.OAuth2Provider.GOOGLE; -import static org.assertj.core.api.Assertions.assertThat; - - -@DefaultDataJpaTest -class AnswerRepositoryTest { - - @Autowired - private QuestionnaireRepository questionnaireRepository; - - @Autowired - private AnswerRepository answerRepository; - - @Autowired - private MemberRepository memberRepository; - - - @Test - @Transactional - @DisplayName("memberId로 작성한 답변을 가져올 수 있다.") - void findByMember_Id() { - //given - Member member = MemberTest.signingUpMember1(); - memberRepository.save(member); - Questionnaire questionnaire = new Questionnaire(1L, "hello"); - questionnaireRepository.save(questionnaire); - String content = "Ok... bye"; - Answer answer = new Answer(member, questionnaire, content); - - //when - Member resultMember = memberRepository.findByProviderAndUid(GOOGLE, new UID("1249846925629348")).orElseThrow(); - answerRepository.save(answer); - List answers = answerRepository.findByMember_Id(resultMember.getId()); - - //then - assertThat(answers).contains(answer); - - } -} \ No newline at end of file diff --git a/resource-server/src/test/java/com/inhabas/api/domain/signUp/usecase/AnswerServiceTest.java b/resource-server/src/test/java/com/inhabas/api/domain/signUp/usecase/AnswerServiceTest.java deleted file mode 100644 index c9fbd56e..00000000 --- a/resource-server/src/test/java/com/inhabas/api/domain/signUp/usecase/AnswerServiceTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.inhabas.api.domain.signUp.usecase; - -import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import com.inhabas.api.domain.questionnaire.repository.QuestionnaireRepository; -import com.inhabas.api.domain.signUp.domain.entity.Answer; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.repository.AnswerRepository; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import static com.inhabas.api.domain.member.domain.entity.MemberTest.signingUpMemberAfterProfile; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -public class AnswerServiceTest { - - @InjectMocks - private AnswerServiceImpl answerService; - - @Mock - private AnswerRepository answerRepository; - - @Mock - private MemberRepository memberRepository; - - @Mock - private QuestionnaireRepository questionnaireRepository; - - private static final ArrayList questionnaires = new ArrayList<>() {{ - add(new Questionnaire(1L, "질문 1")); - add(new Questionnaire(2L, "질문 2")); - add(new Questionnaire(3L, "질문 3")); - }}; - - private static final Member member = signingUpMemberAfterProfile(); - - private static final ArrayList savedAnswers = new ArrayList<>() {{ - add(new Answer(member, questionnaires.get(0), "저는 꼭 이 동아리에 입부하고 싶습니다.")); - add(new Answer(member, questionnaires.get(1), "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); - add(new Answer(member, questionnaires.get(2), "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); - }}; - - private static final ArrayList submittedAnswers = new ArrayList<>() {{ - add(new AnswerDto(1L, "저는 꼭 이 동아리에 입부하고 싶습니다.")); - add(new AnswerDto(2L, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); - add(new AnswerDto(3L, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); - }}; - - @DisplayName("사용자가 작성한 답변이 엔티티로 잘 변환되는지 확인한다.") - @Test - public void saveAnswersTest() { - //given - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - given(answerRepository.findByMember_Id(any())).willReturn(savedAnswers); - given(questionnaireRepository.findAll()).willReturn(questionnaires); - given(questionnaireRepository.countByIdIn(any())).willReturn(3L); - given(questionnaireRepository.findById(1L)).willReturn(Optional.ofNullable(questionnaires.get(0))); - given(questionnaireRepository.findById(2L)).willReturn(Optional.ofNullable(questionnaires.get(1))); - given(questionnaireRepository.findById(3L)).willReturn(Optional.ofNullable(questionnaires.get(2))); - - //when - answerService.saveAnswers(submittedAnswers, member.getId()); - - //then - ArgumentCaptor> argumentCaptor = ArgumentCaptor.forClass(ArrayList.class); - verify(answerRepository, times(1)).saveAll(argumentCaptor.capture()); - - assertThat(argumentCaptor.getValue()) - .usingRecursiveFieldByFieldElementComparator() - .isEqualTo(savedAnswers); - } - - - @DisplayName("사용자가 저장한 답변을 dto로 변환해서 반환한다.") - @Test - public void getAnswersTest() { - //given - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - given(questionnaireRepository.findAll()).willReturn(questionnaires); - given(answerRepository.findByMember_Id(any())).willReturn(savedAnswers); - - //when - List returnedDTOs = answerService.getAnswers(member.getId()); - - //then - assertThat(returnedDTOs) - .usingRecursiveComparison() - .isEqualTo(submittedAnswers); - - } - -} diff --git a/resource-server/src/test/java/com/inhabas/api/domain/signUp/usecase/SignUpServiceTest.java b/resource-server/src/test/java/com/inhabas/api/domain/signUp/usecase/SignUpServiceTest.java deleted file mode 100644 index 51e01f82..00000000 --- a/resource-server/src/test/java/com/inhabas/api/domain/signUp/usecase/SignUpServiceTest.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.inhabas.api.domain.signUp.usecase; - -import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; -import com.inhabas.api.auth.domain.oauth2.majorInfo.usecase.MajorInfoService; -import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; -import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberService; -import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType; -import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; -import com.inhabas.api.auth.domain.oauth2.member.security.socialAccount.MemberSocialAccountRepository; -import com.inhabas.api.domain.questionnaire.usecase.QuestionnaireService; -import com.inhabas.api.domain.signUp.domain.exception.NotWriteAnswersException; -import com.inhabas.api.domain.signUp.domain.exception.NotWriteProfileException; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.dto.SignUpDto; -import com.inhabas.api.domain.signUpSchedule.domain.usecase.SignUpScheduler; -import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import static com.inhabas.api.domain.member.domain.entity.MemberTest.signingUpMember1; -import static com.inhabas.api.domain.member.domain.entity.MemberTest.signingUpMemberAfterProfile; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -public class SignUpServiceTest { - - @InjectMocks - private SignUpServiceImpl signUpService; - @Mock - private MajorInfoService majorInfoService; - @Mock - private MemberRepository memberRepository; - @Mock - private MemberSocialAccountRepository memberSocialAccountRepository; - @Mock - private MemberService memberService; - @Mock - private SignUpScheduler signUpScheduler; - @Mock - private QuestionnaireService questionnaireService; - @Mock - private AnswerService answerService; - - - @DisplayName("(학생) 개인정보 값이 모두 채워진 상태로 제출되면 저장한다.") - @Test - public void saveSignUpFormTest() { - //given - Member member = signingUpMember1(); - SignUpDto signUpForm = SignUpDto.builder() - .name("유동현") - .major("컴퓨터공학과") - .phoneNumber("010-0000-1111") - .grade(1) - .studentId("12345678") - .memberType(MemberType.UNDERGRADUATE) - .build(); - - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - SignUpScheduleDto signUpScheduleDto = new SignUpScheduleDto(); - ReflectionTestUtils.setField(signUpScheduleDto, "generation", 1); - given(signUpScheduler.getSchedule()).willReturn(signUpScheduleDto); - - //when - signUpService.saveSignUpForm(signUpForm, member.getId()); - - //then - assertThat(member.getName()).isEqualTo(signUpForm.getName()); - - } - - @DisplayName("(학생) 개인정보 값이 덜 채워진 상태로 제출되면 실패한다.") - @Test - public void doNotSaveSignUpFormTest() { - //given - Member member = signingUpMember1(); - SignUpDto signUpForm = SignUpDto.builder() - .name("유동현") - // .major("컴퓨터공학과") - .phoneNumber("010-0000-1111") - .grade(1) - .studentId("12345678") - .memberType(MemberType.UNDERGRADUATE) - .build(); - - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - SignUpScheduleDto signUpScheduleDto = new SignUpScheduleDto(); - ReflectionTestUtils.setField(signUpScheduleDto, "generation", 1); - given(signUpScheduler.getSchedule()).willReturn(signUpScheduleDto); - - //when - assertThrows(IllegalArgumentException.class, - () -> signUpService.saveSignUpForm(signUpForm, member.getId())); - - } - - @DisplayName("(교수) 개인정보 값이 모두 채워진 상태로 제출되면 회원가입과정이 바로 끝난다.") - @Test - public void profSaveSignUpFormTest() { - //given - Member member = signingUpMember1(); - SignUpDto signUpForm = SignUpDto.builder() - .name("유동현") - .major("컴퓨터공학과") - .phoneNumber("010-0000-1111") - .studentId("12345678") - .memberType(MemberType.PROFESSOR) - .build(); - - SignUpScheduleDto signUpScheduleDto = new SignUpScheduleDto(); - ReflectionTestUtils.setField(signUpScheduleDto, "generation", 1); - given(signUpScheduler.getSchedule()).willReturn(signUpScheduleDto); - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - - //when - signUpService.saveSignUpForm(signUpForm, member.getId()); - - //then - verify(memberService).finishSignUp(member); - - } - - @DisplayName("임시저장을 하지 않았던 회원 정보는 null 로 반환한다.") - @Test - public void noSavedMemberProfileTest() { - //given - Member member = signingUpMember1(); - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - - //when - SignUpDto loadedForm = signUpService.loadSignUpForm(member.getId()); - - //then - SignUpDto expectResult = SignUpDto.builder() - .name(null) - .major(null) - .grade(null) - .phoneNumber(null) - .studentId(null) - .memberType(null) - .build(); - - assertThat(loadedForm) - .usingRecursiveComparison() - .isEqualTo(expectResult); - } - - @DisplayName("임시저장을 수행했던 회원 정보를 불러온다.") - @Test - public void loadMemberProfileTest() { - //given - Member member = signingUpMemberAfterProfile(); - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - - //when - SignUpDto loadedForm = signUpService.loadSignUpForm(member.getId()); - - //then - SignUpDto expectResult = SignUpDto.builder() - .name(member.getName()) - .major(member.getSchoolInformation().getMajor()) - .grade(member.getSchoolInformation().getGrade()) - .phoneNumber(member.getPhone()) - .studentId(member.getStudentId()) - .memberType(member.getSchoolInformation().getMemberType()) - .build(); - - assertThat(loadedForm) - .usingRecursiveComparison() - .isEqualTo(expectResult); - } - - @DisplayName("모든 전공 정보를 불러온다.") - @Test - public void getMajorInfoTest() { - //given - given(majorInfoService.getAllMajorInfo()).willReturn(List.of(new MajorInfoDto(2, "공대", "전기공학과"))); - - //when - signUpService.getMajorInfo(); - - //then - then(majorInfoService).should(times(1)).getAllMajorInfo(); - } - - @DisplayName("모든 질문지 리스트를 불러온다.") - @Test - public void getQuestionnaire() { - //given - given(questionnaireService.getQuestionnaire()).willReturn(List.of()); - - //when - signUpService.getQuestionnaire(); - - //then - then(questionnaireService).should(times(1)).getQuestionnaire(); - } - - @DisplayName("답변을 작성하지 않아서 회원가입이 완료되지 않는다.") - @Test - public void notYetWriteAnswersTests() { - //given - Member member = signingUpMemberAfterProfile(); - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - - - //then - assertThrows(NotWriteAnswersException.class, - ()->signUpService.completeSignUp(new ArrayList<>(), member.getId())); - } - - @DisplayName("회원정보를 입력하지 않아서 회원가입이 완료되지 않는다.") - @Test - public void notYetWriteProfileTests() { - //given - Member member = signingUpMember1(); - - //when - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - - //then - assertThrows(NotWriteProfileException.class, - ()->signUpService.completeSignUp(null, member.getId())); - - } - - @DisplayName("특정 회원이 작성한 답변을 저장한다.") - @Test - public void saveAnswers() { - //given - Member member = signingUpMemberAfterProfile(); - ArrayList submittedAnswers = new ArrayList<>() {{ - add(new AnswerDto(1L, "저는 꼭 이 동아리에 입부하고 싶습니다.")); - add(new AnswerDto(2L, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); - add(new AnswerDto(3L, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); - add(new AnswerDto(4L, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); - }}; - - //when - signUpService.saveAnswers(submittedAnswers, member.getId()); - - //then - then(answerService).should(times(1)).saveAnswers(any(), any()); - - } - - @DisplayName("회원가입 완료 처리") - @Test - public void completeSignUpTest() { - //given - Member member = signingUpMemberAfterProfile(); - given(memberRepository.findById(any())).willReturn(Optional.of(member)); - ArrayList submittedAnswers = new ArrayList<>() {{ - add(new AnswerDto(1L, "저는 꼭 이 동아리에 입부하고 싶습니다.")); - add(new AnswerDto(2L, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); - add(new AnswerDto(3L, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); - add(new AnswerDto(4L, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); - }}; - - //when - signUpService.completeSignUp(submittedAnswers, member.getId()); - - //then - then(memberService).should(times(1)).finishSignUp(any()); - } - -} diff --git a/resource-server/src/test/java/com/inhabas/api/web/MemberControllerTest.java b/resource-server/src/test/java/com/inhabas/api/web/MemberControllerTest.java index cfe724f3..adf89e61 100644 --- a/resource-server/src/test/java/com/inhabas/api/web/MemberControllerTest.java +++ b/resource-server/src/test/java/com/inhabas/api/web/MemberControllerTest.java @@ -1,24 +1,17 @@ package com.inhabas.api.web; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; import com.inhabas.api.auth.domain.oauth2.member.domain.service.MemberService; -import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; -import com.inhabas.api.auth.domain.oauth2.member.dto.*; -import com.inhabas.api.auth.domain.oauth2.member.repository.MemberRepository; -import com.inhabas.api.domain.member.domain.entity.MemberTest; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.usecase.AnswerService; +import com.inhabas.api.auth.domain.oauth2.member.dto.ApprovedMemberManagementDto; +import com.inhabas.api.auth.domain.oauth2.member.dto.ContactDto; +import com.inhabas.api.auth.domain.oauth2.member.dto.NotApprovedMemberManagementDto; +import com.inhabas.api.domain.member.dto.AnswerDto; +import com.inhabas.api.domain.member.usecase.AnswerService; import com.inhabas.testAnnotataion.NoSecureWebMvcTest; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.domain.Pageable; -import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import java.util.ArrayList; @@ -26,11 +19,10 @@ import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role.BASIC; import static org.hamcrest.Matchers.equalTo; -import static org.mockito.ArgumentMatchers.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doThrow; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -39,14 +31,13 @@ public class MemberControllerTest { @Autowired private MockMvc mvc; + @MockBean private MemberService memberService; + @MockBean private AnswerService answerService; - @MockBean - private MemberRepository memberRepository; - @Autowired - private ObjectMapper objectMapper; + @DisplayName("(신입)미승인 멤버 정보 목록을 불러온다") @Test @@ -74,31 +65,18 @@ public void getUnapprovedMembers() throws Exception { } - @DisplayName("(신입)미승인 멤버 -> 비활동 멤버로 변경할때 state가 pass, fail이면 204를 반환하고 아니면 400를 반환한다..") - @ParameterizedTest - @ValueSource(strings = {"pass", "fail", "hacker"}) - public void passOrFailUnapprovedMembers(String state) throws Exception { - //given - List memberIdList = List.of(1L); - List members = List.of(MemberTest.notapprovedMember()); - - if (state.equals("pass") || state.equals("fail")) { - //when - given(memberRepository.findAllById(memberIdList)).willReturn(members); - //then - mvc.perform(post("/members/unapproved") - .contentType(MediaType.APPLICATION_JSON) - .content(jsonOf(new UpdateRequestDto(memberIdList, state)))) - .andExpect(status().isNoContent()); - } else { - //when - doThrow(new IllegalArgumentException()).when(memberService).updateUnapprovedMembers(anyList(), anyString()); - //then - mvc.perform(post("/members/unapproved") - .contentType(MediaType.APPLICATION_JSON) - .content(jsonOf(new UpdateRequestDto(memberIdList, state)))) - .andExpect(status().isBadRequest()); - } + @DisplayName("(신입)미승인 멤버 -> 비활동 멤버로 변경한다.") + @Test + public void passUnapprovedMembers() throws Exception { + + // 회원가입 이후 구현 + } + + @DisplayName("(신입)미승인 멤버 가입 거절 처리한다.") + @Test + public void failUnapprovedMembers() throws Exception { + + // 회원가입 이후 구현 } @DisplayName("특정 신입 멤버 지원서를 조회한다.") @@ -108,7 +86,7 @@ public void getUnapprovedMemberApplication() throws Exception { // given List dtoList = new ArrayList<>(); AnswerDto dto1 = new AnswerDto( - 1L, "안녕하세요. 예 안녕히계세요."); + 1, "안녕하세요. 예 안녕히계세요."); dtoList.add(dto1); given(answerService.getAnswers(any())).willReturn(dtoList); @@ -116,7 +94,7 @@ public void getUnapprovedMemberApplication() throws Exception { // then mvc.perform(get("/members/1/application")) .andExpect(status().isOk()) - .andExpect(jsonPath("$.[0].questionId").value(equalTo(1))) + .andExpect(jsonPath("$.[0].questionNo").value(equalTo(1))) .andExpect(jsonPath("$.[0].content").value(equalTo("안녕하세요. 예 안녕히계세요."))); } @@ -147,31 +125,11 @@ public void getApprovedMembers() throws Exception { } - @DisplayName("비활동 이상 멤버 권한을 변경할 때 가능한 권한이면 204, 아니면 400을 반환한다.") - @ParameterizedTest - @ValueSource(strings = {"ADMIN", "SIGNING_UP"}) - public void updateApprovedMembers(String roleString) throws Exception { - //given - List memberIdList = List.of(1L); - List members = List.of(MemberTest.deactivatedMember()); - - if (roleString.equals("ADMIN")) { - //when - given(memberRepository.findAllById(memberIdList)).willReturn(members); - //then - mvc.perform(post("/members/approved") - .contentType(MediaType.APPLICATION_JSON) - .content(jsonOf(new UpdateRoleRequestDto(memberIdList, Role.ADMIN)))) - .andExpect(status().isNoContent()); - } else if (roleString.equals("SIGNING_UP")) { - //when - doThrow(new IllegalArgumentException()).when(memberService).updateApprovedMembers(anyList(), any()); - //then - mvc.perform(post("/members/approved") - .contentType(MediaType.APPLICATION_JSON) - .content(jsonOf(new UpdateRoleRequestDto(memberIdList, Role.SIGNING_UP)))) - .andExpect(status().isBadRequest()); - } + @DisplayName("비활동 이상 멤버 권한 수정한다.") + @Test + public void updateApprovedMembers() throws Exception { + + // 회원가입 이후 구현 } @DisplayName("회장 연락처 정보를 불러온다") @@ -189,8 +147,4 @@ public void getChiefContact() throws Exception { } - private String jsonOf(Object o) throws JsonProcessingException { - return objectMapper.writeValueAsString(o); - } - } diff --git a/resource-server/src/test/java/com/inhabas/api/web/MenuControllerTest.java b/resource-server/src/test/java/com/inhabas/api/web/MenuControllerTest.java index 4cee0cae..7defaddb 100644 --- a/resource-server/src/test/java/com/inhabas/api/web/MenuControllerTest.java +++ b/resource-server/src/test/java/com/inhabas/api/web/MenuControllerTest.java @@ -31,20 +31,20 @@ public class MenuControllerTest { @Autowired private MockMvc mvc; - @DisplayName("모든 메뉴 정보를 조회한다.") - @Test - public void getTotalMenuInfoTest() throws Exception { - given(menuService.getAllMenuInfo()).willReturn( - List.of(new MenuGroupDto(1, "IBAS", List.of(new MenuDto(new MenuId(6),1,"동아리 소개",MenuType.INTRODUCE, ""))))); - - mvc.perform(get("/menus")) - .andDo(print()) - .andExpect(status().isOk()) - .andExpect(content().string("[{\"id\":1,\"groupName\":\"IBAS\",\"menuList\":[{\"menuId\":6,\"priority\":1,\"name\":\"ë\u008F\u0099ì\u0095\u0084리 ì\u0086\u008Cê°\u009C\",\"type\":\"INTRODUCE\",\"description\":\"\"}]}]")) - .andReturn(); - - then(menuService).should(times(1)).getAllMenuInfo(); - } +// @DisplayName("모든 메뉴 정보를 조회한다.") +// @Test +// public void getTotalMenuInfoTest() throws Exception { +// given(menuService.getAllMenuInfo()).willReturn( +// List.of(new MenuGroupDto(1, "IBAS", List.of(new MenuDto(new MenuId(6),1,"동아리 소개",MenuType.INTRODUCE, ""))))); +// +// mvc.perform(get("/menus")) +// .andDo(print()) +// .andExpect(status().isOk()) +// .andExpect(content().string("[{\"id\":1,\"groupName\":\"IBAS\",\"menuList\":[{\"menuId\":6,\"priority\":1,\"name\":\"ë\u008F\u0099ì\u0095\u0084리 ì\u0086\u008Cê°\u009C\",\"type\":\"INTRODUCE\",\"description\":\"\"}]}]")) +// .andReturn(); +// +// then(menuService).should(times(1)).getAllMenuInfo(); +// } @DisplayName("단일 메뉴 정보를 조회한다.") @Test diff --git a/resource-server/src/test/java/com/inhabas/api/web/SignUpControllerTest.java b/resource-server/src/test/java/com/inhabas/api/web/SignUpControllerTest.java index 6aead4d7..2f9a0ee9 100644 --- a/resource-server/src/test/java/com/inhabas/api/web/SignUpControllerTest.java +++ b/resource-server/src/test/java/com/inhabas/api/web/SignUpControllerTest.java @@ -1,38 +1,47 @@ package com.inhabas.api.web; +import static com.inhabas.api.domain.member.domain.entity.MemberTest.basicMember1; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.inhabas.api.auth.domain.oauth2.majorInfo.dto.MajorInfoDto; import com.inhabas.api.auth.domain.oauth2.member.domain.entity.Member; +import com.inhabas.api.auth.domain.oauth2.member.domain.exception.NoQueryParameterException; import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType; -import com.inhabas.api.domain.member.domain.entity.MemberTest; -import com.inhabas.api.domain.questionnaire.domain.Questionnaire; -import com.inhabas.api.domain.questionnaire.dto.QuestionnaireDto; -import com.inhabas.api.domain.signUp.domain.entity.Answer; -import com.inhabas.api.domain.signUp.dto.AnswerDto; -import com.inhabas.api.domain.signUp.dto.SignUpDto; -import com.inhabas.api.domain.signUp.usecase.SignUpService; -import com.inhabas.testAnnotataion.NoSecureWebMvcTest; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.Role; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.auth.domain.oauth2.member.dto.MemberDuplicationQueryCondition; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; +import com.inhabas.api.domain.member.domain.entity.Answer; +import com.inhabas.api.domain.member.dto.AnswerDto; +import com.inhabas.api.domain.member.dto.SignUpDto; +import com.inhabas.api.domain.member.usecase.SignUpService; +import com.inhabas.api.domain.questionaire.dto.QuestionnaireDto; +import com.inhabas.testAnnotataion.DefaultWebMvcTest; +import com.inhabas.testAnnotataion.WithMockJwtAuthenticationToken; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.web.servlet.MockMvc; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; - -import static com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.MemberType.PROFESSOR; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@NoSecureWebMvcTest(SignUpController.class) +@Disabled +@DefaultWebMvcTest(SignUpController.class) public class SignUpControllerTest { @Autowired @@ -45,46 +54,17 @@ public class SignUpControllerTest { private SignUpService signUpService; - private String jsonOf(Object response) throws JsonProcessingException { - return objectMapper.writeValueAsString(response); - } - - @DisplayName("임시 저장했던 개인정보를 불러온다.") - @Test - public void 임시저장했던_개인정보를_불러온다() throws Exception { - //given - SignUpDto expectedSavedForm = SignUpDto.builder() - .name("홍길동") - .major("의예과") - .phoneNumber("010-1234-5678") - .studentId("12121212") - .memberType(MemberType.UNDERGRADUATE) - .grade(1) - .build(); - - given(signUpService.loadSignUpForm(any())).willReturn(expectedSavedForm); - - //when - String response = mvc.perform(get("/signUp")) - .andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - - //then - assertThat(response).isEqualTo(jsonOf(expectedSavedForm)); - - } - @DisplayName("학생 회원가입 도중 개인정보를 저장한다.") @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) public void 학생_회원가입_도중_개인정보를_저장한다() throws Exception { //given SignUpDto signUpForm = SignUpDto.builder() .name("유동현") + .email("my@email.com") .major("컴퓨터공학과") .phoneNumber("010-0000-1111") - .studentId("11112222") + .studentId(new StudentId("11112222")) .memberType(MemberType.UNDERGRADUATE) .build(); @@ -96,12 +76,18 @@ private String jsonOf(Object response) throws JsonProcessingException { .andReturn(); } + private String jsonOf(Object response) throws JsonProcessingException { + return objectMapper.writeValueAsString(response); + } + @DisplayName("학생 개인정보를 빈칸으로 제출하면 안된다.") @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) public void 학생_개인정보를_빈칸으로_제출하면_안된다() throws Exception { //given SignUpDto signUpForm = SignUpDto.builder() .name("") + .email("") .major("") .phoneNumber("") .studentId(null) @@ -117,22 +103,24 @@ private String jsonOf(Object response) throws JsonProcessingException { .getResponse().getContentAsString(StandardCharsets.UTF_8); assertThat(response.split("\n")).containsExactlyInAnyOrder( - "[studentId](은)는 must not be null 입력된 값: [null]", + "[memberId](은)는 must not be null 입력된 값: [null]", "[major](은)는 must not be blank 입력된 값: []", "[name](은)는 must not be blank 입력된 값: []", - "[phoneNumber](은)는 must match \"^(010)-\\d{4}-\\d{4}$\" 입력된 값: []", + "[phoneNumber](은)는 must match \"\\d{3}-\\d{4}-\\d{4}\" 입력된 값: []", "[memberType](은)는 must not be null 입력된 값: [null]"); } @DisplayName("학생 개인정보 입력값이 정해진 범위를 초과하면 안된다.") @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) public void 학생_개인정보_입력값이_정해진_범위를_초과하면_안된다() throws Exception { //given SignUpDto signUpForm = SignUpDto.builder() - .name("홍길동만세".repeat(10) + ".") // 50자까지만 가능 - .major("금융데이터처리, 블록체인학과.") // 50자가지만 가능 - .phoneNumber("8210-1111-1111") // ^(010)-\d{4}-\d{4}$ - .studentId("123123123") + .name("홍길동만세".repeat(5) + ".") // 25자까지만 가능 + .email("") // 상관없음. + .major("금융데이터처리, 블록체인학과.") // 15자가지만 가능 + .phoneNumber("8210-1111-1111") + .studentId(new StudentId("-1")) .memberType(MemberType.UNDERGRADUATE) .build(); @@ -145,67 +133,130 @@ private String jsonOf(Object response) throws JsonProcessingException { .getResponse().getContentAsString(StandardCharsets.UTF_8); assertThat(response.split("\n")).containsExactlyInAnyOrder( - "[phoneNumber](은)는 must match \"^(010)-\\d{4}-\\d{4}$\" 입력된 값: [8210-1111-1111]", - "[name](은)는 length must be between 0 and 50 입력된 값: [홍길동만세홍길동만세홍길동만세홍길동만세홍길동만세홍길동만세홍길동만세홍길동만세홍길동만세홍길동만세.]"); - + "[memberId](은)는 must be greater than 0 입력된 값: [-1]", + "[phoneNumber](은)는 must match \"\\d{3}-\\d{4}-\\d{4}\" 입력된 값: [8210-1111-1111]", + "[name](은)는 length must be between 0 and 25 입력된 값: [홍길동만세홍길동만세홍길동만세홍길동만세홍길동만세.]", + "[major](은)는 length must be between 0 and 15 입력된 값: [금융데이터처리, 블록체인학과.]"); } - @DisplayName("교수 회원가입 도중 개인정보를 저장한다.") + @DisplayName("임시 저장했던 개인정보를 불러온다.") @Test - public void 교수_회원가입_도중_개인정보를_저장한다() throws Exception { + @WithMockJwtAuthenticationToken(memberId = 12L, memberRole = Role.ANONYMOUS) + public void 임시저장했던_개인정보를_불러온다() throws Exception { //given - SignUpDto signUpForm = SignUpDto.builder() - .name("유동현") - .major("컴퓨터공학과") - .phoneNumber("010-0000-1111") - .studentId("12121212") - .memberType(PROFESSOR) + OAuth2UserInfoAuthentication authentication = + (OAuth2UserInfoAuthentication) SecurityContextHolder.getContext().getAuthentication(); + StudentId loginStudentId = (StudentId) authentication.getPrincipal(); + SignUpDto expectedSavedForm = SignUpDto.builder() + .studentId(loginStudentId) + .name("홍길동") + .major("의예과") + .phoneNumber("010-1234-5678") + .email("my@email.com") + .memberType(MemberType.UNDERGRADUATE) .build(); - mvc.perform(post("/signUp") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content(jsonOf(signUpForm))) - .andExpect(status().isNoContent()) - .andReturn(); - } - - - @DisplayName("회원가입에 필요한 전공정보를 모두 가져온다.") - @Test - public void 회원가입에_필요한_전공정보를_모두_가져온다() throws Exception { - //given - MajorInfoDto majorInfo1 = new MajorInfoDto(1, "공과대학", "기계공학과"); - MajorInfoDto majorInfo2 = new MajorInfoDto(2, "자연과학대학", "수학과"); - MajorInfoDto majorInfo3 = new MajorInfoDto(3, "경영대학", "경영학과"); - List majorInfos = new ArrayList<>() {{ - add(majorInfo1); - add(majorInfo2); - add(majorInfo3); - }}; - given(signUpService.getMajorInfo()).willReturn(majorInfos); + given(signUpService.loadSignUpForm(loginStudentId, authentication)).willReturn(expectedSavedForm); //when - String response = mvc.perform(get("/signUp/majorInfo")) + String response = mvc.perform(get("/signUp")) .andExpect(status().isOk()) .andReturn() .getResponse() .getContentAsString(StandardCharsets.UTF_8); //then - assertThat(response).isEqualTo(jsonOf(majorInfos)); + assertThat(response).isEqualTo(jsonOf(expectedSavedForm)); } +// @DisplayName("교수 회원가입 도중 개인정보를 저장한다.") +// @Test +// @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) +// public void 교수_회원가입_도중_개인정보를_저장한다() throws Exception { +// //given +// ProfessorSignUpDto signUpForm = ProfessorSignUpDto.builder() +// .name("유동현") +// .email("my@email.com") +// .major("컴퓨터공학과") +// .phoneNumber("010-0000-1111") +// .memberId(11112222) +// .build(); +// +// mvc.perform(post("/signUp/professor") +// .with(csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content(jsonOf(signUpForm))) +// .andExpect(status().isNoContent()) +// .andReturn(); +// } +// +// @DisplayName("교수 개인정보를 빈칸으로 제출하면 안된다.") +// @Test +// @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) +// public void 교수_개인정보를_빈칸으로_제출하면_안된다() throws Exception { +// //given +// ProfessorSignUpDto signUpForm = ProfessorSignUpDto.builder() +// .name("") +// .email("") +// .major("") +// .phoneNumber("") +// .memberId(null) +// .build(); +// +// String response = mvc.perform(post("/signUp/professor") +// .with(csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content(jsonOf(signUpForm))) +// .andExpect(status().isBadRequest()) +// .andReturn() +// .getResponse().getContentAsString(StandardCharsets.UTF_8); +// +// assertThat(response).contains( +// "[memberId](은)는 must not be null", +// "[name](은)는 must not be blank", +// "[major](은)는 must not be blank", +// "[phoneNumber](은)는 must match \"\\d{3}-\\d{4}-\\d{4}\""); +// } +// +// @DisplayName("교수 개인정보 입력값이 정해진 범위를 초과하면 안된다.") +// @Test +// @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) +// public void 교수_개인정보_입력값이_정해진_범위를_초과하면_안된다() throws Exception { +// //given +// ProfessorSignUpDto signUpForm = ProfessorSignUpDto.builder() +// .name("홍길동만세".repeat(5) + ".") // 25자까지만 가능 +// .email("") // 상관없음. +// .major("금융데이터처리, 블록체인학과.") // 15자가지만 가능 +// .phoneNumber("8210-1111-1111") +// .memberId(-1) +// .build(); +// +// String response = mvc.perform(post("/signUp/student") +// .with(csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content(jsonOf(signUpForm))) +// .andExpect(status().isBadRequest()) +// .andDo(print()) // 지울것 +// .andReturn() +// .getResponse().getContentAsString(StandardCharsets.UTF_8); +// +// assertThat(response).contains( +// "[name](은)는 length must be between 0 and 25", +// "[phoneNumber](은)는 must match \"\\d{3}-\\d{4}-\\d{4}\"", +// "[major](은)는 length must be between 0 and 15"); +// } + @DisplayName("회원가입에 필요한 질문들을 가져온다.") @Test + @WithMockJwtAuthenticationToken(memberId = 12L, memberRole = Role.ANONYMOUS) public void 회원가입에_필요한_질문들을_가져온다() throws Exception { //given ArrayList questionnaireInDatabase = new ArrayList<>(){{ - add(new QuestionnaireDto(1L, "지원동기 및 목표를 기술해주세요.")); - add(new QuestionnaireDto(2L, "프로그래밍 관련 언어를 다루어 본 적이 있다면 적어주세요.")); - add(new QuestionnaireDto(3L, "빅데이터 관련 활동 혹은 공모전 관련 경험이 있다면 적어주세요.")); - add(new QuestionnaireDto(4L, "추후 희망하는 진로가 무엇이며, 동아리 활동이 진로에 어떠한 영향을 줄 것이라고 생각하나요?")); - add(new QuestionnaireDto(5L, "어떤 경로로 IBAS를 알게 되셨나요?")); + add(new QuestionnaireDto(1, "지원동기 및 목표를 기술해주세요.")); + add(new QuestionnaireDto(2, "프로그래밍 관련 언어를 다루어 본 적이 있다면 적어주세요.")); + add(new QuestionnaireDto(3, "빅데이터 관련 활동 혹은 공모전 관련 경험이 있다면 적어주세요.")); + add(new QuestionnaireDto(4, "추후 희망하는 진로가 무엇이며, 동아리 활동이 진로에 어떠한 영향을 줄 것이라고 생각하나요?")); + add(new QuestionnaireDto(5, "어떤 경로로 IBAS를 알게 되셨나요?")); }}; given(signUpService.getQuestionnaire()).willReturn(questionnaireInDatabase); @@ -222,13 +273,14 @@ private String jsonOf(Object response) throws JsonProcessingException { @DisplayName("임시저장했던 답변을 가져온다.") @Test + @WithMockJwtAuthenticationToken(memberId = 12L, memberRole = Role.ANONYMOUS) public void 임시저장했던_답변을_가져온다() throws Exception { //given ArrayList savedDTOs = new ArrayList<>() {{ - add(new AnswerDto(1L, "저는 꼭 이 동아리에 입부하고 싶습니다.")); - add(new AnswerDto(2L, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); - add(new AnswerDto(3L, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); - add(new AnswerDto(4L, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); + add(new AnswerDto(1, "저는 꼭 이 동아리에 입부하고 싶습니다.")); + add(new AnswerDto(2, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); + add(new AnswerDto(3, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); + add(new AnswerDto(4, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); }}; given(signUpService.getAnswers(any())).willReturn(savedDTOs); @@ -245,19 +297,15 @@ private String jsonOf(Object response) throws JsonProcessingException { @DisplayName("회원가입을 위한 답변을 저장한다.") @Test + @WithMockJwtAuthenticationToken(memberId = 12L, memberRole = Role.ANONYMOUS) public void 회원가입을_위한_답변을_저장한다() throws Exception { //given - Member member = MemberTest.signingUpMemberAfterProfile(); - ArrayList questionnaires = new ArrayList<>() {{ - add(new Questionnaire(1L, "질문 1")); - add(new Questionnaire(2L, "질문 2")); - add(new Questionnaire(3L, "질문 3")); - }}; - + Member member = basicMember1(); ArrayList submittedAnswers = new ArrayList<>() {{ - add(new Answer(member, questionnaires.get(0), "저는 꼭 이 동아리에 입부하고 싶습니다.")); - add(new Answer(member, questionnaires.get(1), "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); - add(new Answer(member, questionnaires.get(2), "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); + add(new Answer(member, 1, "저는 꼭 이 동아리에 입부하고 싶습니다.")); + add(new Answer(member, 2, "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); + add(new Answer(member, 3, "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); + add(new Answer(member, 4, "이 동아리에 입부한다면, 말하는 대로 코딩해주는 인공지능 모델을 개발하고 싶습니다.")); }}; //when then @@ -265,34 +313,143 @@ private String jsonOf(Object response) throws JsonProcessingException { .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(jsonOf(submittedAnswers))) - .andExpect(status().isOk()) + .andExpect(status().isNoContent()) .andReturn(); } @DisplayName("회원가입을 완료처리한다.") @Test + @WithMockJwtAuthenticationToken(memberId = 12L, memberRole = Role.ANONYMOUS) public void 회원가입을_완료처리한다() throws Exception { + //when + mvc.perform(put("/signUp").with(csrf())) + .andExpect(status().isNoContent()) + .andReturn(); + } + + @DisplayName("회원가입에 필요한 전공정보를 모두 가져온다.") + @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) + public void 회원가입에_필요한_전공정보를_모두_가져온다() throws Exception { //given - Member member = MemberTest.signingUpMemberAfterProfile(); - ArrayList questionnaires = new ArrayList<>() {{ - add(new Questionnaire(1L, "질문 1")); - add(new Questionnaire(2L, "질문 2")); - add(new Questionnaire(3L, "질문 3")); + MajorInfoDto majorInfo1 = new MajorInfoDto(1, "공과대학", "기계공학과"); + MajorInfoDto majorInfo2 = new MajorInfoDto(2, "자연과학대학", "수학과"); + MajorInfoDto majorInfo3 = new MajorInfoDto(3, "경영대학", "경영학과"); + List majorInfos = new ArrayList<>() {{ + add(majorInfo1); + add(majorInfo2); + add(majorInfo3); }}; + given(signUpService.getMajorInfo()).willReturn(majorInfos); - ArrayList submittedAnswers = new ArrayList<>() {{ - add(new Answer(member, questionnaires.get(0), "저는 꼭 이 동아리에 입부하고 싶습니다.")); - add(new Answer(member, questionnaires.get(1), "어렸을적부터 빅데이터를 발가락으로 전처리하며 놀았습니다.")); - add(new Answer(member, questionnaires.get(2), "외주를 받아 진행했던 적이 있는데, 아주 잘 되어 스타트업 창업을 진행했습니다.")); - }}; + //when + String response = mvc.perform(get("/signUp/majorInfo")) + .andExpect(status().isOk()) + .andReturn() + .getResponse() + .getContentAsString(StandardCharsets.UTF_8); + + //then + assertThat(response).isEqualTo(jsonOf(majorInfos)); + } + + @DisplayName("학번 중복 검사 결과, 중복된다") + @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) + public void ID_중복_검사_중복됨() throws Exception { + //given + given(signUpService.validateFieldsDuplication(any(MemberDuplicationQueryCondition.class))).willReturn(true); //when - mvc.perform(put("/signUp") - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content(jsonOf(submittedAnswers))) - .andExpect(status().isNoContent()) + mvc.perform(get("/signUp/isDuplicated") + .param("memberId", "12171652")) + .andExpect(status().isOk()) + .andExpect(content().string("true")) .andReturn(); } + @DisplayName("학번 중복 검사 결과, 중복되지 않는다.") + @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) + public void ID_중복_검사_중복되지_않는다() throws Exception { + //given + given(signUpService.validateFieldsDuplication(any(MemberDuplicationQueryCondition.class))).willReturn(false); + + //when + mvc.perform(get("/signUp/isDuplicated") + .param("memberId", "12171652")) + .andExpect(status().isOk()) + .andExpect(content().string("false")) + .andReturn(); + } + + @DisplayName("핸드폰 중복 검사 결과, 중복된다.") + @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) + public void 핸드폰_중복_검사_중복된다() throws Exception { + //given + given(signUpService.validateFieldsDuplication(any(MemberDuplicationQueryCondition.class))).willReturn(true); + + //when + mvc.perform(get("/signUp/isDuplicated") + .param("phoneNumber", "010-0000-0000")) + .andExpect(status().isOk()) + .andExpect(content().string("true")) + .andReturn(); + } + + @DisplayName("핸드폰 중복 검사 결과, 중복되지 않는다.") + @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) + public void 핸드폰_중복_검사_중복되지_않는다() throws Exception { + //given + given(signUpService.validateFieldsDuplication(any(MemberDuplicationQueryCondition.class))).willReturn(false); + + //when + mvc.perform(get("/signUp/isDuplicated") + .param("phoneNumber", "010-0000-0000")) + .andExpect(status().isOk()) + .andExpect(content().string("false")) + .andReturn(); + } + + + @DisplayName("핸드폰 중복 검사 결과, 번호 형식이 잘못되면 400 반환") + @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) + public void 핸드폰_양식이_잘못된_경우_400() throws Exception { + //given + given(signUpService.validateFieldsDuplication(any(MemberDuplicationQueryCondition.class))).willReturn(true); + + //when + mvc.perform(get("/signUp/isDuplicated") + .param("phoneNumber", "0101-0000-0000")) + .andExpect(status().isBadRequest()) + .andReturn(); + } + + @DisplayName("핸드폰과 학번이 동시에 중복검사") + @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) + public void 핸드폰과_학번이_동시에_중복검사() throws Exception { + given(signUpService.validateFieldsDuplication(any(MemberDuplicationQueryCondition.class))).willReturn(true); + + mvc.perform(get("/signUp/isDuplicated") + .param("phoneNumber", "010-0000-0000") + .param("memberId", "12171652")) + .andExpect(status().isOk()) + .andExpect(content().string("true")); + } + + @DisplayName("중복 검사 시 핸드폰과 학번 둘 다 안넘어오면 400 반환") + @Test + @WithMockJwtAuthenticationToken(memberRole = Role.ANONYMOUS) + public void 중복_검사_시_핸드폰과_학번_둘_다_안넘어오면_400_에러() throws Exception { + given(signUpService.validateFieldsDuplication(any(MemberDuplicationQueryCondition.class))) + .willThrow(NoQueryParameterException.class); + + mvc.perform(get("/signUp/isDuplicated")) + .andExpect(status().isBadRequest()) + .andReturn(); + } } diff --git a/resource-server/src/test/java/com/inhabas/api/web/SignUpScheduleControllerTest.java b/resource-server/src/test/java/com/inhabas/api/web/SignUpScheduleControllerTest.java index 09545bc4..93234579 100644 --- a/resource-server/src/test/java/com/inhabas/api/web/SignUpScheduleControllerTest.java +++ b/resource-server/src/test/java/com/inhabas/api/web/SignUpScheduleControllerTest.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.inhabas.api.domain.signUpSchedule.InvalidDateException; import com.inhabas.api.domain.signUpSchedule.dto.SignUpScheduleDto; -import com.inhabas.api.domain.signUpSchedule.domain.usecase.SignUpScheduler; +import com.inhabas.api.domain.signUpSchedule.domain.SignUpScheduler; import com.inhabas.testAnnotataion.NoSecureWebMvcTest; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -40,7 +40,7 @@ public class SignUpScheduleControllerTest { @Test public void getSignUpSchedule() throws Exception { //given - SignUpScheduleDto existingSchedule = new SignUpScheduleDto(999, + SignUpScheduleDto existingSchedule = new SignUpScheduleDto(1, 999, LocalDateTime.of(2022, 1, 1, 0, 0, 0), LocalDateTime.of(2022, 1, 2, 0, 0, 0), LocalDateTime.of(2022, 1, 3, 0, 0, 0), @@ -56,7 +56,7 @@ public void getSignUpSchedule() throws Exception { @DisplayName("회원가입 일정을 수정한다.") @Test public void updateSignUpSchedule() throws Exception { - String jsonRequest = objectMapper.writeValueAsString(new SignUpScheduleDto(999, + String jsonRequest = objectMapper.writeValueAsString(new SignUpScheduleDto(1, 999, LocalDateTime.of(2022, 1, 1, 0, 0, 0), LocalDateTime.of(2022, 1, 2, 0, 0, 0), LocalDateTime.of(2022, 1, 3, 0, 0, 0), @@ -72,7 +72,7 @@ public void updateSignUpSchedule() throws Exception { @DisplayName("회원 기수가 양의 정수가 아닌경우, 400") @Test public void invalidGenerationTest() throws Exception { - String jsonRequest = objectMapper.writeValueAsString(new SignUpScheduleDto(0, + String jsonRequest = objectMapper.writeValueAsString(new SignUpScheduleDto(1, 0, LocalDateTime.of(2022, 1, 1, 0, 0, 0), LocalDateTime.of(2022, 1, 2, 0, 0, 0), LocalDateTime.of(2022, 1, 3, 0, 0, 0), @@ -93,7 +93,7 @@ public void invalidGenerationTest() throws Exception { @Test public void invalidDateInfoTest() throws Exception { doThrow(InvalidDateException.class).when(signUpScheduler).updateSchedule(any()); - String jsonRequest = objectMapper.writeValueAsString(new SignUpScheduleDto(999, + String jsonRequest = objectMapper.writeValueAsString(new SignUpScheduleDto(1, 999, LocalDateTime.of(2022, 1, 5, 0, 0, 0), LocalDateTime.of(2022, 1, 4, 0, 0, 0), LocalDateTime.of(2022, 1, 3, 0, 0, 0), diff --git a/resource-server/src/test/java/com/inhabas/api/web/argumentResolver/ArgumentResolverTest.java b/resource-server/src/test/java/com/inhabas/api/web/argumentResolver/ArgumentResolverTest.java index d6bf097b..2099fe18 100644 --- a/resource-server/src/test/java/com/inhabas/api/web/argumentResolver/ArgumentResolverTest.java +++ b/resource-server/src/test/java/com/inhabas/api/web/argumentResolver/ArgumentResolverTest.java @@ -1,21 +1,24 @@ package com.inhabas.api.web.argumentResolver; -import com.inhabas.api.auth.domain.token.jwtUtils.JwtAuthenticationToken; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.auth.domain.oauth2.userInfo.OAuth2UserInfoAuthentication; +import com.inhabas.api.auth.domain.token.jwtUtils.JwtAuthenticationResult; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.MethodParameter; -import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.context.request.NativeWebRequest; -import java.util.List; +import java.util.Collections; import static org.assertj.core.api.Assertions.assertThat; @@ -47,26 +50,147 @@ public void returnNullIfNotAuthenticated() { assertThat(invalidUser).isNull(); } + @Disabled + @DisplayName("Jwt token 인증된 OAuth2UserInfoAuthentication 를 컨트롤러 파라미터로 주입한다.") + @Test + public void successToInjectJwtTokenAuthenticatedAuthUserIntoArguments() { + //given + //기존 회원 정보 + String uid = "12943275193"; + + // jwt 토큰 인증 결과 + JwtAuthenticationResult authentication = + new JwtAuthenticationResult(1L, uid, "google", "my@gmail.com", Collections.singleton(new SimpleGrantedAuthority("ROLE_MEMBER"))); + + //oauth2Info 객체를 컨텍스트에 설정. 최종 인증 끝 + SecurityContextHolder.getContext().setAuthentication(authentication); + + Mockito.doReturn(JwtAuthenticationResult.class).when(parameter).getParameterType(); + + //when + OAuth2UserInfoAuthentication oauth2Info = (OAuth2UserInfoAuthentication) loginMemberArgumentResolver.resolveArgument(parameter, null, request, null); + + //then + assertThat(oauth2Info).isNotNull(); + assertThat(oauth2Info.getAuthorities()) + .singleElement() + .extracting("role") + .isEqualTo("ROLE_MEMBER"); + } + + @Disabled + @DisplayName("OAuth2 인증된 ResolvedAuthenticationResult 를 컨트롤러 파라미터로 주입한다.") + @Test + public void successToInjectOAuth2AuthenticatedAuthUserIntoArguments() { + +// //given +// //기존 회원 정보 +// Integer authUserId = 1; +// HashMap attributes = new HashMap<>() {{ +// put("name", "김아무개"); +// put("email", "my@email.com"); +// put("picture", "https://my_photo.com"); +// }}; +// //OAuth2 인증 결과 +// CustomOAuth2User principal = new CustomOAuth2User( +// List.of(new SimpleGrantedAuthority("ROLE_USER")), +// attributes, +// "email", +// AuthUserDetail.builder() +// .id(authUserId) +// .email("my@email.com") +// .profileId(12171652) +// .provider("google") +// .hasJoined(true) +// .isActive(true) +// .build()); +// //OAuth2 인증결과를 authentication 객체에 담는다. +// OAuth2AuthenticationToken token = new OAuth2AuthenticationToken( +// principal, +// principal.getAuthorities(), +// "google"); +// //authentication 객체를 컨텍스트에 설정. 최종 인증 끝 +// SecurityContextHolder.getContext().setAuthentication(token); +// +// doReturn(AuthUserDetail.class).when(parameter).getParameterType(); +// +// //when +// AuthUserDetail authenticatedUser = (AuthUserDetail) loginMemberArgumentResolver.resolveArgument(parameter, null, request, null); +// +// //then +// assertThat(authenticatedUser).isNotNull(); +// assertThat(authenticatedUser.getId()).isEqualTo(authUserId); +// assertThat(authenticatedUser.getEmail()).isEqualTo("my@email.com"); +// assertThat(authenticatedUser.getProvider()).isEqualTo("google"); + } + + @DisplayName("Jwt 토큰 인증된 회원의 Member Id를 반환한다.") @Test public void successToInjectJwtTokenIntegerIdIntoArguments() { //given - Long memberId = 1L; + StudentId StudentId = new StudentId("12171652"); // jwt 토큰 인증 결과 - List grantedAuthorities = List.of(new SimpleGrantedAuthority("ROLE_TEST")); - JwtAuthenticationToken authentication = JwtAuthenticationToken.of(1L, "Nodata", grantedAuthorities); + JwtAuthenticationResult authentication = + new JwtAuthenticationResult(1L, "12943275193", "google", "my@gmail.com", Collections.singleton(new SimpleGrantedAuthority("ROLE_MEMBER"))); + authentication.setPrincipal(StudentId); //authentication 객체를 컨텍스트에 설정. 최종 인증 끝 SecurityContextHolder.getContext().setAuthentication(authentication); + Mockito.doReturn(StudentId.class).when(parameter).getParameterType(); + //when Object profileId = loginMemberArgumentResolver.resolveArgument(parameter, null, request, null); // then Assertions.assertThat(profileId).isNotNull(); - Assertions.assertThat(profileId).isEqualTo(memberId); - Assertions.assertThat(profileId).isInstanceOf(Long.class); + Assertions.assertThat(profileId).isEqualTo(StudentId); + Assertions.assertThat(profileId).isInstanceOf(StudentId.class); } + @Disabled + @DisplayName("OAuth2 인증된 authUser에 대한 Id를 받아온 경우 Profile Id를 반환한다.") + @Test + public void successToInjectIntegerIdIntoArgumentsAndReturnProfileId() { +// //given +// //기존 회원 정보 +// Integer authUserId = 1; +// HashMap attributes = new HashMap<>() {{ +// put("name", "김아무개"); +// put("email", "my@email.com"); +// put("picture", "https://my_photo.com"); +// }}; +// //OAuth2 인증 결과 +// CustomOAuth2User principal = new CustomOAuth2User( +// List.of(new SimpleGrantedAuthority("ROLE_USER")), +// attributes, +// "email", +// AuthUserDetail.builder() +// .id(authUserId) +// .email("my@email.com") +// .profileId(12171652) +// .provider("google") +// .hasJoined(true) +// .isActive(true) +// .build()); +// //OAuth2 인증결과를 authentication 객체에 담는다. +// OAuth2AuthenticationToken token = new OAuth2AuthenticationToken( +// principal, +// principal.getAuthorities(), +// "google"); +// //authentication 객체를 컨텍스트에 설정. 최종 인증 끝 +// SecurityContextHolder.getContext().setAuthentication(token); +// +// doReturn(Integer.class).when(parameter).getParameterType(); +// +// // when +// Object profileId = loginMemberArgumentResolver.resolveArgument(parameter, null, request, null); +// +// // then +// assertThat(profileId).isNotNull(); +// assertThat(profileId).isEqualTo(principal.getAuthUserDetail().getProfileId()); +// assertThat(profileId).isInstanceOf(Integer.class); + } } diff --git a/resource-server/src/test/java/com/inhabas/testAnnotataion/CustomSpringBootTest.java b/resource-server/src/test/java/com/inhabas/testAnnotataion/CustomSpringBootTest.java index 07aacc4b..44c1896b 100644 --- a/resource-server/src/test/java/com/inhabas/testAnnotataion/CustomSpringBootTest.java +++ b/resource-server/src/test/java/com/inhabas/testAnnotataion/CustomSpringBootTest.java @@ -13,7 +13,7 @@ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) -@ActiveProfiles({"test"}) +@ActiveProfiles({"production"}) @Transactional @AutoConfigureMockMvc @SpringBootTest diff --git a/resource-server/src/test/java/com/inhabas/testAnnotataion/DefaultWebMvcTest.java b/resource-server/src/test/java/com/inhabas/testAnnotataion/DefaultWebMvcTest.java index 1d4311b6..b2345ec6 100644 --- a/resource-server/src/test/java/com/inhabas/testAnnotataion/DefaultWebMvcTest.java +++ b/resource-server/src/test/java/com/inhabas/testAnnotataion/DefaultWebMvcTest.java @@ -1,8 +1,6 @@ package com.inhabas.testAnnotataion; -import com.inhabas.api.auth.AuthBeansConfig; import com.inhabas.api.auth.domain.oauth2.member.security.DefaultRoleHierarchy; -import com.inhabas.api.config.WebSecurityConfig; import com.inhabas.testConfig.TestConfigurationForSecurity; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -23,7 +21,7 @@ */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) -@ActiveProfiles("test") // for disable cloud config & security filter chain +@ActiveProfiles("default_mvc_test") // for disable cloud config & security filter chain @WebMvcTest(excludeAutoConfiguration = {OAuth2ClientAutoConfiguration.class}) // disable autoload OAuth2-Client-Components from test properties @Import({DefaultRoleHierarchy.class, TestConfigurationForSecurity.class}) public @interface DefaultWebMvcTest { diff --git a/resource-server/src/test/java/com/inhabas/testAnnotataion/WithMockJwtAuthenticationToken.java b/resource-server/src/test/java/com/inhabas/testAnnotataion/WithMockJwtAuthenticationToken.java index 2866c17d..0d58d36c 100644 --- a/resource-server/src/test/java/com/inhabas/testAnnotataion/WithMockJwtAuthenticationToken.java +++ b/resource-server/src/test/java/com/inhabas/testAnnotataion/WithMockJwtAuthenticationToken.java @@ -16,7 +16,13 @@ @WithSecurityContext(factory = WithMockJwtAuthenticationTokenSecurityContextFactory.class) public @interface WithMockJwtAuthenticationToken { - long memberId() default 1L; - Role memberRole() default Role.BASIC; + String uid() default "1234"; + + String email() default "my@email.com"; + + String provider() default "google"; + long memberId() default 1L; // 다른값으로 설정되지 않으면, authUser 의 member profile 을 null 로 간주. + + Role memberRole() default Role.BASIC; } diff --git a/resource-server/src/test/java/com/inhabas/testAnnotataion/WithMockJwtAuthenticationTokenSecurityContextFactory.java b/resource-server/src/test/java/com/inhabas/testAnnotataion/WithMockJwtAuthenticationTokenSecurityContextFactory.java index 7277f989..f36ebff5 100644 --- a/resource-server/src/test/java/com/inhabas/testAnnotataion/WithMockJwtAuthenticationTokenSecurityContextFactory.java +++ b/resource-server/src/test/java/com/inhabas/testAnnotataion/WithMockJwtAuthenticationTokenSecurityContextFactory.java @@ -1,13 +1,14 @@ package com.inhabas.testAnnotataion; -import com.inhabas.api.auth.domain.token.jwtUtils.JwtAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; +import com.inhabas.api.auth.domain.oauth2.member.domain.valueObject.StudentId; +import com.inhabas.api.auth.domain.token.TokenAuthenticationResult; +import com.inhabas.api.auth.domain.token.jwtUtils.JwtAuthenticationResult; 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.context.support.WithSecurityContextFactory; -import java.util.List; +import java.util.Collections; /** * WithMockJwtAuthenticationToken 어노테이션 정보를 기반으로 SecurityContext 를 설정한다.
@@ -19,17 +20,19 @@ public class WithMockJwtAuthenticationTokenSecurityContextFactory @Override public SecurityContext createSecurityContext(WithMockJwtAuthenticationToken principalInfo) { - SecurityContext context = SecurityContextHolder.createEmptyContext(); - Long memberId = principalInfo.memberId(); String role = principalInfo.memberRole().toString(); // 기본은 BASIC. - List grantedAuthorities = List.of(new SimpleGrantedAuthority(role)); + TokenAuthenticationResult token + = new JwtAuthenticationResult(1L, principalInfo.uid(), principalInfo.provider(), principalInfo.email(), Collections.singleton(new SimpleGrantedAuthority(role))); + token.setAuthenticated(true); - JwtAuthenticationToken authentication = JwtAuthenticationToken.of(memberId, "TEST", grantedAuthorities); + if (principalInfo.memberId() != 0) { // default 값이 아니면, 회원 프로필이 저장되어 있다고 간주. + Long memberId = principalInfo.memberId(); + token.setPrincipal(memberId); + } - context.setAuthentication(authentication); + context.setAuthentication(token); return context; - } } diff --git a/resource-server/src/test/java/com/inhabas/testConfig/TestConfigurationForSecurity.java b/resource-server/src/test/java/com/inhabas/testConfig/TestConfigurationForSecurity.java index 8f662b1d..229c169e 100644 --- a/resource-server/src/test/java/com/inhabas/testConfig/TestConfigurationForSecurity.java +++ b/resource-server/src/test/java/com/inhabas/testConfig/TestConfigurationForSecurity.java @@ -1,54 +1,25 @@ package com.inhabas.testConfig; -import com.inhabas.api.auth.AuthBeansConfig; -import com.inhabas.api.auth.domain.token.CustomRequestMatcher; -import com.inhabas.api.auth.domain.token.JwtAccessDeniedHandler; -import com.inhabas.api.auth.domain.token.jwtUtils.JwtAuthenticationProvider; -import com.inhabas.api.auth.domain.token.jwtUtils.JwtTokenUtil; -import com.inhabas.api.auth.domain.token.securityFilter.JwtAuthenticationEntryPoint; -import com.inhabas.api.auth.domain.token.securityFilter.JwtAuthenticationFilter; +import com.inhabas.api.auth.domain.token.TokenResolver; +import com.inhabas.api.auth.domain.token.securityFilter.TokenAuthenticationFailureHandler; +import com.inhabas.api.auth.domain.token.securityFilter.UserPrincipalService; import com.inhabas.api.web.interceptor.InterceptorConfig; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Bean; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.web.util.matcher.RequestMatcher; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; @TestConfiguration public class TestConfigurationForSecurity { @MockBean InterceptorConfig interceptorConfig; + @MockBean - JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; - @MockBean - JwtAccessDeniedHandler jwtAccessDeniedHandler; - @MockBean - JwtTokenUtil jwtTokenUtil; - @MockBean - JwtAuthenticationProvider jwtAuthenticationProvider; + TokenResolver tokenResolver; + @MockBean - AuthBeansConfig authBeansConfig; + TokenAuthenticationFailureHandler failureHandler; @MockBean - private AuthenticationManager authenticationManager; + UserPrincipalService userPrincipalService; - @Bean - public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception { - final List skipPaths = new ArrayList<>(); - skipPaths.add("/**"); - final RequestMatcher requestMatcher = new CustomRequestMatcher(skipPaths); - final JwtAuthenticationFilter filter = new JwtAuthenticationFilter( - requestMatcher, - jwtTokenUtil, - authBeansConfig.tokenResolver() - ); - filter.setAuthenticationManager(authenticationManager); - return filter; - } }