From 6ff31d3c4863ca8c3548bcdbe52d68196d0e925b Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 14:51:50 +0900 Subject: [PATCH 01/10] =?UTF-8?q?feat=20#78:=20member=EC=9D=98=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20DTO=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/member/dto/JuniorDetailInfo.java | 12 +++++++++++ .../modules/member/dto/MemberDetailInfo.java | 4 ++++ .../member/dto/MemberDetailProfile.java | 21 +++++++++++++++++++ .../modules/member/dto/SeniorDetailInfo.java | 14 +++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/JuniorDetailInfo.java create mode 100644 API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailInfo.java create mode 100644 API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailProfile.java create mode 100644 API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/SeniorDetailInfo.java diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/JuniorDetailInfo.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/JuniorDetailInfo.java new file mode 100644 index 00000000..f33d9640 --- /dev/null +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/JuniorDetailInfo.java @@ -0,0 +1,12 @@ +package swm.hkcc.LGTM.app.modules.member.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor +public class JuniorDetailInfo implements MemberDetailInfo { + private String educationalHistory; +} diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailInfo.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailInfo.java new file mode 100644 index 00000000..75f91f4c --- /dev/null +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailInfo.java @@ -0,0 +1,4 @@ +package swm.hkcc.LGTM.app.modules.member.dto; + +public interface MemberDetailInfo { +} diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailProfile.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailProfile.java new file mode 100644 index 00000000..3870c3c1 --- /dev/null +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailProfile.java @@ -0,0 +1,21 @@ +package swm.hkcc.LGTM.app.modules.member.dto; + +import lombok.*; +import swm.hkcc.LGTM.app.modules.mission.dto.MissionDto; +import swm.hkcc.LGTM.app.modules.tag.domain.TechTag; + +import java.util.List; + +@Builder +@Getter +@AllArgsConstructor +public class MemberDetailProfile { + private Long memberId; + private String githubId; + private String nickName; + private String profileImageUrl; + private List techTagList; + private boolean isAgreeWithEventInfo; + private MemberDetailInfo memberDetailInfo; + private List memberMissionHistory; +} diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/SeniorDetailInfo.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/SeniorDetailInfo.java new file mode 100644 index 00000000..63bd20d6 --- /dev/null +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/SeniorDetailInfo.java @@ -0,0 +1,14 @@ +package swm.hkcc.LGTM.app.modules.member.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor +public class SeniorDetailInfo implements MemberDetailInfo { + private String companyInfo; + private int careerPeriod; + private String position; +} From 9064d61217b25597863e5465ac39f54ff6d7cda2 Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 14:53:08 +0900 Subject: [PATCH 02/10] =?UTF-8?q?fix=20#78:=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=EB=AA=85=20general=ED=95=98=EA=B2=8C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/modules/mission/domain/mapper/MissionMapper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/mission/domain/mapper/MissionMapper.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/mission/domain/mapper/MissionMapper.java index c4a7b015..76a11c7e 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/mission/domain/mapper/MissionMapper.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/mission/domain/mapper/MissionMapper.java @@ -17,10 +17,10 @@ import static swm.hkcc.LGTM.app.modules.mission.domain.MissionStatus.MISSION_FINISHED; public class MissionMapper { - public static MissionDto missionToMissionDto(Mission ongoingMission, List techTags) { + public static MissionDto missionToMissionDto(Mission mission, List techTags) { return MissionDto.builder() - .missionId(ongoingMission.getMissionId()) - .missionTitle(ongoingMission.getTitle()) + .missionId(mission.getMissionId()) + .missionTitle(mission.getTitle()) .techTagList(techTags) .build(); } From ee92c24ddbf257115c8c01fe5f37ba3b771aff91 Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 14:53:52 +0900 Subject: [PATCH 03/10] =?UTF-8?q?feat=20#78:=20=EC=8B=9C=EB=8B=88=EC=96=B4?= =?UTF-8?q?=EC=9D=98=20=EC=A7=84=ED=96=89=ED=95=9C=20=EB=AF=B8=EC=85=98=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/modules/mission/repository/MissionRepository.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/mission/repository/MissionRepository.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/mission/repository/MissionRepository.java index 038d33f1..6448f700 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/mission/repository/MissionRepository.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/mission/repository/MissionRepository.java @@ -1,11 +1,12 @@ package swm.hkcc.LGTM.app.modules.mission.repository; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import swm.hkcc.LGTM.app.modules.mission.domain.Mission; +import java.util.List; + public interface MissionRepository extends JpaRepository, MissionCustomRepository { -// @Query("SELECT CASE WHEN COUNT(m) > 0 THEN true ELSE false END FROM Mission m WHERE m.missionId = :missionId AND m.writer.memberId = :memberId") -// boolean existsByMissionIdAndMemberId(Long missionId, Long memberId); boolean existsByMissionIdAndWriter_MemberId(Long missionId, Long memberId); + + List findAllByWriter_MemberId(Long memberId); } From 6364e6e305c90b9504203c169ee1a12a3f1aa55f Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 14:54:24 +0900 Subject: [PATCH 04/10] =?UTF-8?q?feat=20#78:=20=EC=A3=BC=EB=8B=88=EC=96=B4?= =?UTF-8?q?=EC=9D=98=20=EC=A7=84=ED=96=89=ED=95=9C=20=EB=AF=B8=EC=85=98=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C,=20N+1=20=EB=AC=B8=EC=A0=9C=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80=EB=A5=BC=20=EC=9C=84=ED=95=B4=20Fetch=20join=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/MissionRegistrationRepository.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/registration/repository/MissionRegistrationRepository.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/registration/repository/MissionRegistrationRepository.java index ea02edec..3e10e6b6 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/registration/repository/MissionRegistrationRepository.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/registration/repository/MissionRegistrationRepository.java @@ -3,6 +3,8 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import swm.hkcc.LGTM.app.modules.mission.domain.Mission; import swm.hkcc.LGTM.app.modules.registration.domain.MissionRegistration; import java.util.List; @@ -16,4 +18,7 @@ public interface MissionRegistrationRepository extends JpaRepository 0 THEN true ELSE false END FROM MissionRegistration m WHERE m.mission.missionId = :missionId AND m.junior.memberId = :memberId") boolean existsByMissionIdAndMemberId(Long missionId, Long memberId); + + @Query("SELECT mr FROM MissionRegistration mr JOIN FETCH mr.mission WHERE mr.junior.memberId = :memberId") + List findAllByJuniorMemberIdWithMission(@Param("memberId") Long memberId); } From 780ade28a0b3449b1b4faaeabe2beedbac7978df Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 14:55:01 +0900 Subject: [PATCH 05/10] =?UTF-8?q?feat=20#78:=20member=EC=9D=98=20=EA=B8=B0?= =?UTF-8?q?=EC=88=A0=ED=83=9C=EA=B7=B8=20=EC=A1=B0=ED=9A=8C,=20N+1=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EB=B0=A9=EC=A7=80=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20Fetch=20join=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/tag/repository/TechTagPerMemberRepository.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/tag/repository/TechTagPerMemberRepository.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/tag/repository/TechTagPerMemberRepository.java index 94f238f9..4f43d314 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/tag/repository/TechTagPerMemberRepository.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/tag/repository/TechTagPerMemberRepository.java @@ -1,8 +1,11 @@ package swm.hkcc.LGTM.app.modules.tag.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import swm.hkcc.LGTM.app.modules.member.domain.Member; +import swm.hkcc.LGTM.app.modules.tag.domain.TechTag; import swm.hkcc.LGTM.app.modules.tag.domain.TechTagPerMember; import java.util.List; @@ -10,4 +13,7 @@ @Repository public interface TechTagPerMemberRepository extends JpaRepository { List findByMember(Member member); + + @Query("SELECT t FROM TechTagPerMember t JOIN FETCH t.techTag WHERE t.member.memberId = :memberId") + List findWithTechTagByMemberId(@Param("memberId") Long memberId); } From 7682417dd9fa34ace47431674d4bdc75a4e44a95 Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 14:55:29 +0900 Subject: [PATCH 06/10] =?UTF-8?q?feat=20#78:=20=EC=B5=9C=EC=A2=85=20dto?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=ED=99=98=ED=95=98=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20dto=20mapper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/domain/mapper/MemberMapper.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/domain/mapper/MemberMapper.java diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/domain/mapper/MemberMapper.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/domain/mapper/MemberMapper.java new file mode 100644 index 00000000..e80d257c --- /dev/null +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/domain/mapper/MemberMapper.java @@ -0,0 +1,25 @@ +package swm.hkcc.LGTM.app.modules.member.domain.mapper; + +import swm.hkcc.LGTM.app.modules.member.domain.Member; +import swm.hkcc.LGTM.app.modules.member.dto.MemberDetailInfo; +import swm.hkcc.LGTM.app.modules.member.dto.MemberDetailProfile; +import swm.hkcc.LGTM.app.modules.mission.dto.MissionDto; +import swm.hkcc.LGTM.app.modules.tag.domain.TechTag; + +import java.util.List; + +public class MemberMapper { + + public static MemberDetailProfile toMemberDetailProfile(Member member, MemberDetailInfo memberDetailInfo, List techTagList, List missionDtos) { + return MemberDetailProfile.builder() + .memberId(member.getMemberId()) + .githubId(member.getGithubId()) + .nickName(member.getNickName()) + .profileImageUrl(member.getProfileImageUrl()) + .techTagList(techTagList) + .isAgreeWithEventInfo(member.isAgreeWithEventInfo()) + .memberDetailInfo(memberDetailInfo) + .memberMissionHistory(missionDtos) + .build(); + } +} From 58999133a339550eac5886f98f444c39abadcb12 Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 14:55:45 +0900 Subject: [PATCH 07/10] =?UTF-8?q?feat=20#78:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20=EB=B9=84?= =?UTF-8?q?=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/member/service/MemberService.java | 81 ++++++++++++++++++- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/service/MemberService.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/service/MemberService.java index 35378a47..50aac0e3 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/service/MemberService.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/service/MemberService.java @@ -1,23 +1,44 @@ package swm.hkcc.LGTM.app.modules.member.service; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import swm.hkcc.LGTM.app.modules.auth.constants.MemberType; +import swm.hkcc.LGTM.app.modules.member.domain.Junior; import swm.hkcc.LGTM.app.modules.member.domain.Member; +import swm.hkcc.LGTM.app.modules.member.domain.Senior; +import swm.hkcc.LGTM.app.modules.member.dto.JuniorDetailInfo; +import swm.hkcc.LGTM.app.modules.member.dto.MemberDetailProfile; +import swm.hkcc.LGTM.app.modules.member.dto.SeniorDetailInfo; import swm.hkcc.LGTM.app.modules.member.exception.NotExistMember; import swm.hkcc.LGTM.app.modules.member.repository.MemberRepository; +import swm.hkcc.LGTM.app.modules.mission.domain.Mission; +import swm.hkcc.LGTM.app.modules.mission.domain.mapper.MissionMapper; +import swm.hkcc.LGTM.app.modules.mission.dto.MissionDto; +import swm.hkcc.LGTM.app.modules.mission.repository.MissionRepository; +import swm.hkcc.LGTM.app.modules.registration.domain.MissionRegistration; +import swm.hkcc.LGTM.app.modules.registration.repository.MissionRegistrationRepository; +import swm.hkcc.LGTM.app.modules.tag.domain.TechTag; +import swm.hkcc.LGTM.app.modules.tag.domain.TechTagPerMember; +import swm.hkcc.LGTM.app.modules.tag.repository.TechTagPerMemberRepository; +import swm.hkcc.LGTM.app.modules.tag.repository.TechTagPerMissionRepository; +import java.util.List; import java.util.Optional; +import static swm.hkcc.LGTM.app.modules.member.domain.mapper.MemberMapper.toMemberDetailProfile; + @RequiredArgsConstructor @Service @Transactional +@Slf4j public class MemberService { - private static final String JUNIOR = "JUNIOR"; - private static final String SENIOR = "SENIOR"; - private final MemberRepository memberRepository; + private final TechTagPerMemberRepository techTagPerMemberRepository; + private final MissionRegistrationRepository missionRegistrationRepository; + private final MissionRepository missionRepository; + private final TechTagPerMissionRepository techTagPerMissionRepository; public Boolean updateDeviceToken(Long memberId, Optional deviceToken) { deviceToken.ifPresent(memberRepository::eraseDeviceToken); @@ -37,4 +58,58 @@ public MemberType getMemberType(Long memberId) { return MemberType.getType(member); } + + public MemberDetailProfile getJuniorProfile(Long memberId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(NotExistMember::new); + List techTagList = getTechTagList(memberId); + + Junior junior = member.getJunior(); + List juniorMissionHistory = missionRegistrationRepository.findAllByJuniorMemberIdWithMission(memberId); // N+1 문제 방지를 위해 fetch join 사용 + + JuniorDetailInfo juniorDetailInfo = JuniorDetailInfo.builder() + .educationalHistory(junior.getEducationalHistory()) + .build(); + + List missionDtos = juniorMissionHistory.stream() + .map(MissionRegistration::getMission) + .map(mission -> MissionMapper.missionToMissionDto( + mission, + techTagPerMissionRepository.findTechTagsByMissionId(mission.getMissionId()) + )) + .toList(); + + return toMemberDetailProfile(member, juniorDetailInfo, techTagList, missionDtos); + } + + public MemberDetailProfile getSeniorProfile(Long memberId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(NotExistMember::new); + List techTagList = getTechTagList(memberId); + + Senior senior = member.getSenior(); + List seniorMissionHistory = missionRepository.findAllByWriter_MemberId(memberId); + + SeniorDetailInfo seniorDetailInfo = SeniorDetailInfo.builder() + .companyInfo(senior.getCompanyInfo()) + .careerPeriod(senior.getCareerPeriod()) + .position(senior.getPosition()) + .build(); + + List missionDtos = seniorMissionHistory.stream() + .map(mission -> MissionMapper.missionToMissionDto( + mission, + techTagPerMissionRepository.findTechTagsByMissionId(mission.getMissionId()) + )) + .toList(); + + return toMemberDetailProfile(member, seniorDetailInfo, techTagList, missionDtos); + } + + private List getTechTagList(Long memberId) { + return techTagPerMemberRepository.findWithTechTagByMemberId(memberId) // N+1 문제 방지를 위해 fetch join 사용 + .stream() + .map(TechTagPerMember::getTechTag) + .toList(); + } } From ac2ef7cbcafc7603a465bce1bfac307969b3fdb2 Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 14:56:12 +0900 Subject: [PATCH 08/10] =?UTF-8?q?feat=20#78:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20api=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/controller/MemberController.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/controller/MemberController.java index 6e05f16e..714194f5 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/controller/MemberController.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/controller/MemberController.java @@ -1,16 +1,14 @@ package swm.hkcc.LGTM.app.modules.member.controller; -import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import swm.hkcc.LGTM.app.global.dto.ApiDataResponse; +import swm.hkcc.LGTM.app.modules.auth.constants.MemberType; import swm.hkcc.LGTM.app.modules.member.domain.custom.CustomUserDetails; +import swm.hkcc.LGTM.app.modules.member.dto.MemberDetailProfile; import swm.hkcc.LGTM.app.modules.member.service.MemberService; import java.util.Optional; @@ -31,4 +29,18 @@ public ApiDataResponse updateDeviceToken( Long memberId = customUserDetails.getMemberId(); return ApiDataResponse.of(memberService.updateDeviceToken(memberId, deviceToken)); } + + @GetMapping("/profile") + public ApiDataResponse getMemberProfile( + @AuthenticationPrincipal CustomUserDetails customUserDetails + ) { + Long memberId = customUserDetails.getMemberId(); + MemberType memberType = memberService.getMemberType(memberId); + + if (memberType == MemberType.JUNIOR) { + return ApiDataResponse.of(memberService.getJuniorProfile(memberId)); + } + + return ApiDataResponse.of(memberService.getSeniorProfile(memberId)); + } } From b1e3519f98b7b3cf463743ef8bca0a232ad4676e Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 16:40:37 +0900 Subject: [PATCH 09/10] =?UTF-8?q?test=20#78:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20api=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/repository/JuniorRepository.java | 4 + .../controller/GetMemberProfileTest.java | 455 ++++++++++++++++++ 2 files changed, 459 insertions(+) create mode 100644 API-Server/src/test/java/swm/hkcc/LGTM/app/modules/member/controller/GetMemberProfileTest.java diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/repository/JuniorRepository.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/repository/JuniorRepository.java index c3ebc179..a328012c 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/repository/JuniorRepository.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/repository/JuniorRepository.java @@ -3,8 +3,12 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import swm.hkcc.LGTM.app.modules.member.domain.Junior; +import swm.hkcc.LGTM.app.modules.member.domain.Senior; + +import java.util.Optional; @Repository public interface JuniorRepository extends JpaRepository { boolean existsByMember_MemberId(Long memberId); + Optional findByMember_MemberId(Long memberId); } diff --git a/API-Server/src/test/java/swm/hkcc/LGTM/app/modules/member/controller/GetMemberProfileTest.java b/API-Server/src/test/java/swm/hkcc/LGTM/app/modules/member/controller/GetMemberProfileTest.java new file mode 100644 index 00000000..11393091 --- /dev/null +++ b/API-Server/src/test/java/swm/hkcc/LGTM/app/modules/member/controller/GetMemberProfileTest.java @@ -0,0 +1,455 @@ +package swm.hkcc.LGTM.app.modules.member.controller; + +import com.epages.restdocs.apispec.ResourceDocumentation; +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; +import swm.hkcc.LGTM.app.global.constant.ResponseCode; +import swm.hkcc.LGTM.app.modules.auth.constants.MemberType; +import swm.hkcc.LGTM.app.modules.auth.constants.TokenType; +import swm.hkcc.LGTM.app.modules.auth.utils.jwt.TokenProvider; +import swm.hkcc.LGTM.app.modules.member.domain.*; +import swm.hkcc.LGTM.app.modules.member.domain.custom.CustomUserDetails; +import swm.hkcc.LGTM.app.modules.member.repository.JuniorRepository; +import swm.hkcc.LGTM.app.modules.member.repository.MemberRepository; +import swm.hkcc.LGTM.app.modules.member.repository.SeniorRepository; +import swm.hkcc.LGTM.app.modules.member.service.MemberService; +import swm.hkcc.LGTM.app.modules.mission.domain.Mission; +import swm.hkcc.LGTM.app.modules.mission.domain.MissionStatus; +import swm.hkcc.LGTM.app.modules.mission.repository.MissionRepository; +import swm.hkcc.LGTM.app.modules.registration.domain.MissionRegistration; +import swm.hkcc.LGTM.app.modules.registration.domain.ProcessStatus; +import swm.hkcc.LGTM.app.modules.registration.repository.MissionRegistrationRepository; +import swm.hkcc.LGTM.app.modules.tag.domain.TechTag; +import swm.hkcc.LGTM.app.modules.tag.domain.TechTagPerMember; +import swm.hkcc.LGTM.app.modules.tag.repository.TechTagPerMemberRepository; +import swm.hkcc.LGTM.app.modules.tag.repository.TechTagPerMissionRepository; +import swm.hkcc.LGTM.utils.CustomMDGenerator; + +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static com.epages.restdocs.apispec.ResourceDocumentation.headerWithName; +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static swm.hkcc.LGTM.utils.CustomMDGenerator.tableHead; +import static swm.hkcc.LGTM.utils.CustomMDGenerator.tableRow; + +@Slf4j +@SpringBootTest +@Transactional +@ActiveProfiles("test") +@ExtendWith({RestDocumentationExtension.class, SpringExtension.class}) +class GetMemberProfileTest { + + private MockMvc mockMvc; + + @Autowired + private TokenProvider tokenProvider; + + @Autowired + private MemberService memberService; + + @MockBean + private MemberRepository memberRepository; + + @MockBean + private TechTagPerMemberRepository techTagPerMemberRepository; + + @MockBean + private MissionRepository missionRepository; + + @MockBean + private MissionRegistrationRepository missionRegistrationRepository; + + @MockBean + private TechTagPerMissionRepository techTagPerMissionRepository; + + @MockBean + private SeniorRepository seniorRepository; + + @MockBean + private JuniorRepository juniorRepository; + + @BeforeEach + public void setUp(@Autowired WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentationContextProvider) { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .apply(springSecurity()) + .apply(documentationConfiguration(restDocumentationContextProvider)) + .addFilters(new CharacterEncodingFilter("UTF-8", true)) + .alwaysDo(print()) + .build(); + + // mock user authentication + Member member = (Member.builder() + .memberId(1L) + .build()); + member.setRoles(Collections.singletonList(Authority.builder().name("ROLE_USER").build())); + + CustomUserDetails customUserDetails = new CustomUserDetails(member); + + SecurityContextHolder + .getContext() + .setAuthentication( + new UsernamePasswordAuthenticationToken( + customUserDetails, "", customUserDetails.getAuthorities() + )); + } + + @Test + @DisplayName("시니어 회원 프로필 조회") + void getSeniorProfileTest() throws Exception { + // given + Senior mockSenior = createMockSenior(); + Member mockMember = createMockSeniorMember(mockSenior); + String memberAccessToken = getMockToken(mockMember); + List mockTechTags = createMockTechTags(); + Mission mockMission = createMockMission(mockMember); + List mockMemberTechTags = createMockMemberTechTags(mockMember); + + given(memberRepository.findById(anyLong())).willReturn(Optional.of(mockMember)); + given(techTagPerMemberRepository.findWithTechTagByMemberId(anyLong())).willReturn(mockMemberTechTags); + given(missionRepository.findAllByWriter_MemberId(anyLong())).willReturn(List.of(mockMission)); + given(seniorRepository.findByMember_MemberId(anyLong())).willReturn(Optional.of(mockSenior)); + given(techTagPerMissionRepository.findTechTagsByMissionId(anyLong())).willReturn(mockTechTags); + given(memberRepository.findOneByGithubId(anyString())).willReturn(Optional.of(mockMember)); + + // when + + // then + ResultActions actions = mockMvc.perform(get("/v1/member/profile") + .header("Authorization", "Bearer " + memberAccessToken) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.responseCode").value(0)) + .andExpect(jsonPath("$.message").value("Ok")) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.data.memberId").value(48)) + .andExpect(jsonPath("$.data.githubId").value("test-token-senior")) + .andExpect(jsonPath("$.data.nickName").value("test-token-senior")) + .andExpect(jsonPath("$.data.profileImageUrl").value("https://avatars.githubusercontent.com/u/899645?v=4")) + .andExpect(jsonPath("$.data.techTagList", hasSize(1))) + .andExpect(jsonPath("$.data.techTagList[0].techTagId").value(1)) + .andExpect(jsonPath("$.data.techTagList[0].name").value("Java")) + .andExpect(jsonPath("$.data.memberDetailInfo.companyInfo").value("(주)TestCompany")) + .andExpect(jsonPath("$.data.memberDetailInfo.careerPeriod").value("24")) + .andExpect(jsonPath("$.data.memberDetailInfo.position").value("안드로이드 엔지니어")) + .andExpect(jsonPath("$.data.memberMissionHistory", hasSize(1))) + .andExpect(jsonPath("$.data.memberMissionHistory.[0].missionId").value(27)) + .andExpect(jsonPath("$.data.memberMissionHistory.[0].missionTitle").value("당근마켓 리드가 직접 알려주는 당근마켓 인프라 찍먹하기")) + .andExpect(jsonPath("$.data.memberMissionHistory.[0].techTagList.[0].techTagId").value(7)) + .andExpect(jsonPath("$.data.memberMissionHistory.[0].techTagList.[0].name").value("Android")) + .andExpect(jsonPath("$.data.agreeWithEventInfo").value(true)); + + // document + actions + .andDo(document("get-senior-profile", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + resource(ResourceSnippetParameters.builder() + .summary("[멤버] 시니어 프로필 조회") + .description( + CustomMDGenerator.builder() + .h1("[Descriptions]") + .h3("시니어 프로필을 조회한다.") + .h1("[Request values]") + .table( + tableHead("Header", "Data Type", "Description"), + tableRow("Authorization", "String", "Bearer token for authentication") + ) + .line() + .h1("[Errors]") + .table( + tableHead("HTTP Status", "Response Code", "Message"), + tableRow( + ResponseCode.NOT_EXIST_MISSION.getHttpStatus().toString(), + ResponseCode.NOT_EXIST_MISSION.getCode().toString(), + ResponseCode.NOT_EXIST_MISSION.getMessage()), + tableRow( + ResponseCode.NOT_EXIST_MEMBER.getHttpStatus().toString(), + ResponseCode.NOT_EXIST_MEMBER.getCode().toString(), + ResponseCode.NOT_EXIST_MEMBER.getMessage()) + ) + .build() + ) + .tag("Member") + .requestHeaders( + headerWithName("Authorization").description("access token") + ) + .responseFields( + fieldWithPath("success").type(JsonFieldType.BOOLEAN).description("성공 여부"), + fieldWithPath("responseCode").type(JsonFieldType.NUMBER).description("응답 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("응답 메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).description("응답 데이터"), + fieldWithPath("data.memberId").type(JsonFieldType.NUMBER).description("회원 ID"), + fieldWithPath("data.githubId").type(JsonFieldType.STRING).description("회원의 Github ID"), + fieldWithPath("data.nickName").type(JsonFieldType.STRING).description("회원 닉네임"), + fieldWithPath("data.profileImageUrl").type(JsonFieldType.STRING).description("회원 프로필 이미지 URL"), + fieldWithPath("data.techTagList").type(JsonFieldType.ARRAY).description("기술 태그 리스트"), + fieldWithPath("data.techTagList[].techTagId").type(JsonFieldType.NUMBER).description("기술 태그 ID"), + fieldWithPath("data.techTagList[].name").type(JsonFieldType.STRING).description("기술 태그 이름"), + fieldWithPath("data.memberDetailInfo.companyInfo").type(JsonFieldType.STRING).description("회원의 회사 정보"), + fieldWithPath("data.memberDetailInfo.careerPeriod").type(JsonFieldType.NUMBER).description("회원의 경력 기간"), + fieldWithPath("data.memberDetailInfo.position").type(JsonFieldType.STRING).description("회원의 직책"), + fieldWithPath("data.memberMissionHistory").type(JsonFieldType.ARRAY).description("회원의 미션 히스토리"), + fieldWithPath("data.memberMissionHistory[].missionId").type(JsonFieldType.NUMBER).description("미션 ID"), + fieldWithPath("data.memberMissionHistory[].missionTitle").type(JsonFieldType.STRING).description("미션 제목"), + fieldWithPath("data.memberMissionHistory[].techTagList").type(JsonFieldType.ARRAY).description("미션에 사용된 기술 태그 리스트"), + fieldWithPath("data.memberMissionHistory[].techTagList[].techTagId").type(JsonFieldType.NUMBER).description("기술 태그 ID"), + fieldWithPath("data.memberMissionHistory[].techTagList[].name").type(JsonFieldType.STRING).description("기술 태그 이름"), + fieldWithPath("data.agreeWithEventInfo").type(JsonFieldType.BOOLEAN).description("이벤트 정보 동의 여부") + ) + .build()))); + + + } + + @Test + @DisplayName("주니어 회원 프로필 조회") + void getJuniorProfileTest() throws Exception{ + // given + Junior mockJunior = createMockJunior(); + Member mockMember = createMockJuniorMember(mockJunior); + String memberAccessToken = getMockToken(mockMember); + List mockTechTags = createMockTechTags(); + Mission mockMission = createMockMission(mockMember); + List mockMissionRegistrations = createMockMissionRegistrations(mockMission, mockMember); + List mockMemberTechTags = createMockMemberTechTags(mockMember); + + given(memberRepository.findById(anyLong())).willReturn(Optional.of(mockMember)); + given(techTagPerMemberRepository.findWithTechTagByMemberId(anyLong())).willReturn(mockMemberTechTags); + given(missionRegistrationRepository.findAllByJuniorMemberIdWithMission(anyLong())).willReturn(List.of()); + given(juniorRepository.findByMember_MemberId(anyLong())).willReturn(Optional.of(mockJunior)); + given(techTagPerMissionRepository.findTechTagsByMissionId(anyLong())).willReturn(mockTechTags); + given(memberRepository.findOneByGithubId(anyString())).willReturn(Optional.of(mockMember)); + given(missionRegistrationRepository.findAllByJuniorMemberIdWithMission(anyLong())).willReturn(mockMissionRegistrations); + + // when + + // then + ResultActions actions = mockMvc.perform(get("/v1/member/profile") + .header("Authorization", "Bearer " + memberAccessToken) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.responseCode").value(0)) + .andExpect(jsonPath("$.message").value("Ok")) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.data.memberId").value(48)) + .andExpect(jsonPath("$.data.githubId").value("test-token-junior")) + .andExpect(jsonPath("$.data.nickName").value("test-token-junior")) + .andExpect(jsonPath("$.data.profileImageUrl").value("https://avatars.githubusercontent.com/u/899645?v=4")) + .andExpect(jsonPath("$.data.techTagList", hasSize(1))) + .andExpect(jsonPath("$.data.techTagList[0].techTagId").value(1)) + .andExpect(jsonPath("$.data.techTagList[0].name").value("Java")) + .andExpect(jsonPath("$.data.memberDetailInfo.educationalHistory").value("대학생")) + .andExpect(jsonPath("$.data.memberMissionHistory", hasSize(1))) + .andExpect(jsonPath("$.data.memberMissionHistory.[0].missionId").value(27)) + .andExpect(jsonPath("$.data.memberMissionHistory.[0].missionTitle").value("당근마켓 리드가 직접 알려주는 당근마켓 인프라 찍먹하기")) + .andExpect(jsonPath("$.data.memberMissionHistory.[0].techTagList.[0].techTagId").value(7)) + .andExpect(jsonPath("$.data.memberMissionHistory.[0].techTagList.[0].name").value("Android")) + .andExpect(jsonPath("$.data.agreeWithEventInfo").value(true)); + + // document + actions + .andDo(document("get-junior-profile", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + resource(ResourceSnippetParameters.builder() + .summary("[멤버] 주니어 프로필 조회") + .description( + CustomMDGenerator.builder() + .h1("[Descriptions]") + .h3("주니어 프로필을 조회한다.") + .h1("[Request values]") + .table( + tableHead("Header", "Data Type", "Description"), + tableRow("Authorization", "String", "Bearer token for authentication") + ) + .line() + .h1("[Errors]") + .table( + tableHead("HTTP Status", "Response Code", "Message"), + tableRow( + ResponseCode.NOT_EXIST_MISSION.getHttpStatus().toString(), + ResponseCode.NOT_EXIST_MISSION.getCode().toString(), + ResponseCode.NOT_EXIST_MISSION.getMessage()), + tableRow( + ResponseCode.NOT_EXIST_MEMBER.getHttpStatus().toString(), + ResponseCode.NOT_EXIST_MEMBER.getCode().toString(), + ResponseCode.NOT_EXIST_MEMBER.getMessage()) + ) + .build() + ) + .tag("Member") + .requestHeaders( + headerWithName("Authorization").description("access token") + ) + .responseFields( + fieldWithPath("success").type(JsonFieldType.BOOLEAN).description("성공 여부"), + fieldWithPath("responseCode").type(JsonFieldType.NUMBER).description("응답 코드"), + fieldWithPath("message").type(JsonFieldType.STRING).description("응답 메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT).description("응답 데이터"), + fieldWithPath("data.memberId").type(JsonFieldType.NUMBER).description("회원 ID"), + fieldWithPath("data.githubId").type(JsonFieldType.STRING).description("회원의 Github ID"), + fieldWithPath("data.nickName").type(JsonFieldType.STRING).description("회원 닉네임"), + fieldWithPath("data.profileImageUrl").type(JsonFieldType.STRING).description("회원 프로필 이미지 URL"), + fieldWithPath("data.techTagList").type(JsonFieldType.ARRAY).description("기술 태그 리스트"), + fieldWithPath("data.techTagList[].techTagId").type(JsonFieldType.NUMBER).description("기술 태그 ID"), + fieldWithPath("data.techTagList[].name").type(JsonFieldType.STRING).description("기술 태그 이름"), + fieldWithPath("data.memberDetailInfo.educationalHistory").type(JsonFieldType.STRING).description("회원의 학력 정보"), + fieldWithPath("data.memberMissionHistory").type(JsonFieldType.ARRAY).description("회원의 미션 히스토리"), + fieldWithPath("data.memberMissionHistory[].missionId").type(JsonFieldType.NUMBER).description("미션 ID"), + fieldWithPath("data.memberMissionHistory[].missionTitle").type(JsonFieldType.STRING).description("미션 제목"), + fieldWithPath("data.memberMissionHistory[].techTagList").type(JsonFieldType.ARRAY).description("미션에 사용된 기술 태그 리스트"), + fieldWithPath("data.memberMissionHistory[].techTagList[].techTagId").type(JsonFieldType.NUMBER).description("기술 태그 ID"), + fieldWithPath("data.memberMissionHistory[].techTagList[].name").type(JsonFieldType.STRING).description("기술 태그 이름"), + fieldWithPath("data.agreeWithEventInfo").type(JsonFieldType.BOOLEAN).description("이벤트 정보 동의 여부") + ) + .build()))); + + + } + + private List createMockTechTags() { + return List.of( + TechTag.builder() + .techTagId(7L) + .name("Android") + .build() + ); + } + + private Senior createMockSenior() { + return Senior.builder() + .seniorId(5L) + .companyInfo("(주)TestCompany") + .careerPeriod(24) + .position("안드로이드 엔지니어") + .accountNumber("1234-5678-910") + .bank(Bank.K_BANK) + .build(); + } + + private Junior createMockJunior() { + return Junior.builder() + .juniorId(5L) + .educationalHistory("대학생") + .realName("홍길동") + .build(); + } + + private Member createMockSeniorMember(Senior senior) { + Member member = Member.builder() + .memberId(48L) + .githubId("test-token-senior") + .nickName("test-token-senior") + .profileImageUrl("https://avatars.githubusercontent.com/u/899645?v=4") + .introduction("Test Senior Developer") + .isAgreeWithEventInfo(true) + .senior(senior) + .build(); + + member.setRoles(Collections.singletonList(Authority.builder().name("ROLE_USER").build())); + return member; + } + + private Member createMockJuniorMember(Junior junior) { + Member member = Member.builder() + .memberId(48L) + .githubId("test-token-junior") + .nickName("test-token-junior") + .profileImageUrl("https://avatars.githubusercontent.com/u/899645?v=4") + .introduction("Test Junior Developer") + .isAgreeWithEventInfo(true) + .junior(junior) + .build(); + + member.setRoles(Collections.singletonList(Authority.builder().name("ROLE_USER").build())); + return member; + } + + private Mission createMockMission(Member mockWriter) { + return Mission.builder() + .missionId(27L) + .writer(mockWriter) + .missionRepositoryUrl("https://www.github.com/kxxhyorim") + .title("당근마켓 리드가 직접 알려주는 당근마켓 인프라 찍먹하기") + .missionStatus(MissionStatus.RECRUITING) + .description("content") + .recommendTo("ReomnnandTo") + .notRecommendTo("notReomnnandTo") + .registrationDueDate(LocalDate.now().plusDays(7)) + .price(10000) + .maxPeopleNumber(10) + .build(); + } + + private List createMockMemberTechTags(Member mockMember) { + return List.of( + TechTagPerMember.builder() + .techTagPerMemberId(1L) + .member(mockMember) + .techTag(TechTag.builder() + .techTagId(1L) + .name("Java") + .build()) + .build() + ); + } + + private List createMockMissionRegistrations(Mission mission, Member member) { + return List.of( + MissionRegistration.builder() + .registrationId(1L) + .status(ProcessStatus.MISSION_PROCEEDING) + .githubPullRequestUrl("test pr url") + .mission(mission) + .junior(member) + .build() + ); + } + + private String getMockToken(Member member) { + return tokenProvider.createToken(member.getGithubId(), TokenType.ACCESS_TOKEN); + } +} \ No newline at end of file From 424466c0497f79d1bd6e19cd18a36072dbb76877 Mon Sep 17 00:00:00 2001 From: great-park Date: Wed, 6 Sep 2023 17:07:24 +0900 Subject: [PATCH 10/10] =?UTF-8?q?fix=20#78:=20=EC=9E=90=EA=B8=B0=EC=86=8C?= =?UTF-8?q?=EA=B0=9C=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/modules/member/domain/mapper/MemberMapper.java | 1 + .../app/modules/member/dto/MemberDetailProfile.java | 1 + .../member/controller/GetMemberProfileTest.java | 10 +++++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/domain/mapper/MemberMapper.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/domain/mapper/MemberMapper.java index e80d257c..0f9abe1c 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/domain/mapper/MemberMapper.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/domain/mapper/MemberMapper.java @@ -16,6 +16,7 @@ public static MemberDetailProfile toMemberDetailProfile(Member member, MemberDet .githubId(member.getGithubId()) .nickName(member.getNickName()) .profileImageUrl(member.getProfileImageUrl()) + .introduction(member.getIntroduction()) .techTagList(techTagList) .isAgreeWithEventInfo(member.isAgreeWithEventInfo()) .memberDetailInfo(memberDetailInfo) diff --git a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailProfile.java b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailProfile.java index 3870c3c1..0399c970 100644 --- a/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailProfile.java +++ b/API-Server/src/main/java/swm/hkcc/LGTM/app/modules/member/dto/MemberDetailProfile.java @@ -14,6 +14,7 @@ public class MemberDetailProfile { private String githubId; private String nickName; private String profileImageUrl; + private String introduction; private List techTagList; private boolean isAgreeWithEventInfo; private MemberDetailInfo memberDetailInfo; diff --git a/API-Server/src/test/java/swm/hkcc/LGTM/app/modules/member/controller/GetMemberProfileTest.java b/API-Server/src/test/java/swm/hkcc/LGTM/app/modules/member/controller/GetMemberProfileTest.java index 11393091..2e4d6308 100644 --- a/API-Server/src/test/java/swm/hkcc/LGTM/app/modules/member/controller/GetMemberProfileTest.java +++ b/API-Server/src/test/java/swm/hkcc/LGTM/app/modules/member/controller/GetMemberProfileTest.java @@ -1,6 +1,5 @@ package swm.hkcc.LGTM.app.modules.member.controller; -import com.epages.restdocs.apispec.ResourceDocumentation; import com.epages.restdocs.apispec.ResourceSnippetParameters; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; @@ -25,7 +24,6 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; import swm.hkcc.LGTM.app.global.constant.ResponseCode; -import swm.hkcc.LGTM.app.modules.auth.constants.MemberType; import swm.hkcc.LGTM.app.modules.auth.constants.TokenType; import swm.hkcc.LGTM.app.modules.auth.utils.jwt.TokenProvider; import swm.hkcc.LGTM.app.modules.member.domain.*; @@ -60,10 +58,8 @@ import static org.mockito.BDDMockito.given; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -166,6 +162,7 @@ void getSeniorProfileTest() throws Exception { .andExpect(jsonPath("$.data.githubId").value("test-token-senior")) .andExpect(jsonPath("$.data.nickName").value("test-token-senior")) .andExpect(jsonPath("$.data.profileImageUrl").value("https://avatars.githubusercontent.com/u/899645?v=4")) + .andExpect(jsonPath("$.data.introduction").value("Test Senior Developer")) .andExpect(jsonPath("$.data.techTagList", hasSize(1))) .andExpect(jsonPath("$.data.techTagList[0].techTagId").value(1)) .andExpect(jsonPath("$.data.techTagList[0].name").value("Java")) @@ -223,6 +220,7 @@ void getSeniorProfileTest() throws Exception { fieldWithPath("data.githubId").type(JsonFieldType.STRING).description("회원의 Github ID"), fieldWithPath("data.nickName").type(JsonFieldType.STRING).description("회원 닉네임"), fieldWithPath("data.profileImageUrl").type(JsonFieldType.STRING).description("회원 프로필 이미지 URL"), + fieldWithPath("data.introduction").type(JsonFieldType.STRING).description("자기 소개"), fieldWithPath("data.techTagList").type(JsonFieldType.ARRAY).description("기술 태그 리스트"), fieldWithPath("data.techTagList[].techTagId").type(JsonFieldType.NUMBER).description("기술 태그 ID"), fieldWithPath("data.techTagList[].name").type(JsonFieldType.STRING).description("기술 태그 이름"), @@ -244,7 +242,7 @@ void getSeniorProfileTest() throws Exception { @Test @DisplayName("주니어 회원 프로필 조회") - void getJuniorProfileTest() throws Exception{ + void getJuniorProfileTest() throws Exception { // given Junior mockJunior = createMockJunior(); Member mockMember = createMockJuniorMember(mockJunior); @@ -278,6 +276,7 @@ void getJuniorProfileTest() throws Exception{ .andExpect(jsonPath("$.data.githubId").value("test-token-junior")) .andExpect(jsonPath("$.data.nickName").value("test-token-junior")) .andExpect(jsonPath("$.data.profileImageUrl").value("https://avatars.githubusercontent.com/u/899645?v=4")) + .andExpect(jsonPath("$.data.introduction").value("Test Junior Developer")) .andExpect(jsonPath("$.data.techTagList", hasSize(1))) .andExpect(jsonPath("$.data.techTagList[0].techTagId").value(1)) .andExpect(jsonPath("$.data.techTagList[0].name").value("Java")) @@ -333,6 +332,7 @@ void getJuniorProfileTest() throws Exception{ fieldWithPath("data.githubId").type(JsonFieldType.STRING).description("회원의 Github ID"), fieldWithPath("data.nickName").type(JsonFieldType.STRING).description("회원 닉네임"), fieldWithPath("data.profileImageUrl").type(JsonFieldType.STRING).description("회원 프로필 이미지 URL"), + fieldWithPath("data.introduction").type(JsonFieldType.STRING).description("자기 소개"), fieldWithPath("data.techTagList").type(JsonFieldType.ARRAY).description("기술 태그 리스트"), fieldWithPath("data.techTagList[].techTagId").type(JsonFieldType.NUMBER).description("기술 태그 ID"), fieldWithPath("data.techTagList[].name").type(JsonFieldType.STRING).description("기술 태그 이름"),