From ff2312fef15a8aa05f79dfa72e9f927513d83c56 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 Date: Sun, 10 Aug 2025 02:02:11 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=9D=91=EB=8B=B5=20=EC=9A=94=EC=86=8C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 멘티의 경우는 관심 국가 어디인지 - 멘토의 경우는 수학 대학교 어디인지 --- .../country/repository/CountryRepository.java | 11 ++++++++ .../siteuser/dto/MyPageResponse.java | 16 ++++++++--- .../siteuser/service/MyPageService.java | 27 ++++++++++++++++++- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java b/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java index 70477f1f4..976bbf12f 100644 --- a/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java +++ b/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java @@ -10,4 +10,15 @@ public interface CountryRepository extends JpaRepository { @Query("SELECT c FROM Country c WHERE c.koreanName IN :names") List findByKoreanNames(@Param(value = "names") List names); + + @Query(""" + SELECT DISTINCT c.koreanName + FROM Country c + WHERE c.code IN ( + SELECT ic.countryCode + FROM InterestedCountry ic + WHERE ic.siteUserId = :siteUserId + ) + """) + List findKoreanNamesBySiteUserId(@Param("siteUserId") long siteUserId); } diff --git a/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java b/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java index d84ed61ec..f6ee0e45a 100644 --- a/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java +++ b/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java @@ -3,7 +3,9 @@ import com.example.solidconnection.siteuser.domain.AuthType; import com.example.solidconnection.siteuser.domain.Role; import com.example.solidconnection.siteuser.domain.SiteUser; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; public record MyPageResponse( String nickname, @@ -15,9 +17,15 @@ public record MyPageResponse( int likedMentorCount, @JsonProperty("likedUniversityCount") - int likedUnivApplyInfoCount) { + int likedUnivApplyInfoCount, - public static MyPageResponse of(SiteUser siteUser, int likedUnivApplyInfoCount) { + @JsonInclude(JsonInclude.Include.NON_NULL) + List interestedCountries, + + @JsonInclude(JsonInclude.Include.NON_NULL) + String attendedUniversity) { + + public static MyPageResponse of(SiteUser siteUser, int likedUnivApplyInfoCount, List interestedCountries, String attendedUniversity) { return new MyPageResponse( siteUser.getNickname(), siteUser.getProfileImageUrl(), @@ -26,7 +34,9 @@ public static MyPageResponse of(SiteUser siteUser, int likedUnivApplyInfoCount) siteUser.getEmail(), 0, // TODO: 커뮤니티 기능 생기면 업데이트 필요 0, // TODO: 멘토 기능 생기면 업데이트 필요 - likedUnivApplyInfoCount + likedUnivApplyInfoCount, + interestedCountries, + attendedUniversity ); } } diff --git a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java index 7b85bd411..2f5a3cf40 100644 --- a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java +++ b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java @@ -1,19 +1,28 @@ package com.example.solidconnection.siteuser.service; import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET; +import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.NICKNAME_ALREADY_EXISTED; +import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND; import com.example.solidconnection.common.exception.CustomException; +import com.example.solidconnection.location.country.repository.CountryRepository; +import com.example.solidconnection.mentor.domain.Mentor; +import com.example.solidconnection.mentor.repository.MentorRepository; import com.example.solidconnection.s3.domain.ImgType; import com.example.solidconnection.s3.dto.UploadedFileUrlResponse; import com.example.solidconnection.s3.service.S3Service; +import com.example.solidconnection.siteuser.domain.Role; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.dto.MyPageResponse; import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository; +import com.example.solidconnection.university.repository.UniversityRepository; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,6 +37,9 @@ public class MyPageService { private final SiteUserRepository siteUserRepository; private final LikedUnivApplyInfoRepository likedUnivApplyInfoRepository; + private final CountryRepository countryRepository; + private final MentorRepository mentorRepository; + private final UniversityRepository universityRepository; private final S3Service s3Service; /* @@ -38,7 +50,20 @@ public MyPageResponse getMyPageInfo(long siteUserId) { SiteUser siteUser = siteUserRepository.findById(siteUserId) .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); int likedUnivApplyInfoCount = likedUnivApplyInfoRepository.countBySiteUserId(siteUser.getId()); - return MyPageResponse.of(siteUser, likedUnivApplyInfoCount); + + MyPageResponse myPageResponse = null; + if (siteUser.getRole() == Role.MENTEE) { + List interestedCountries = countryRepository.findKoreanNamesBySiteUserId(siteUser.getId()); + myPageResponse = MyPageResponse.of(siteUser, likedUnivApplyInfoCount, interestedCountries, null); + } + else if (siteUser.getRole() == Role.MENTOR) { + Mentor mentor = mentorRepository.findBySiteUserId(siteUser.getId()) + .orElseThrow(() -> new CustomException(MENTOR_NOT_FOUND)); + University university = universityRepository.findById(mentor.getUniversityId()) + .orElseThrow(() -> new CustomException(UNIVERSITY_NOT_FOUND)); + myPageResponse = MyPageResponse.of(siteUser, likedUnivApplyInfoCount, null, university.getKoreanName()); + } + return myPageResponse; } /* From d77308b01805af0ff35c7d81d8c226e08270d23d Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 Date: Sun, 10 Aug 2025 02:20:49 +0900 Subject: [PATCH 2/6] =?UTF-8?q?test:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=9D=91=EB=8B=B5=20=EC=9A=94=EC=86=8C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EA=B4=80=EB=A0=A8=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../siteuser/service/MyPageServiceTest.java | 127 ++++++++++++------ 1 file changed, 86 insertions(+), 41 deletions(-) diff --git a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java index 0358f8024..86c971dd1 100644 --- a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java +++ b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java @@ -12,6 +12,11 @@ import static org.mockito.BDDMockito.then; import com.example.solidconnection.common.exception.CustomException; +import com.example.solidconnection.location.country.domain.Country; +import com.example.solidconnection.location.country.domain.InterestedCountry; +import com.example.solidconnection.location.country.fixture.CountryFixture; +import com.example.solidconnection.location.country.repository.InterestedCountryRepository; +import com.example.solidconnection.mentor.fixture.MentorFixture; import com.example.solidconnection.s3.domain.ImgType; import com.example.solidconnection.s3.dto.UploadedFileUrlResponse; import com.example.solidconnection.s3.service.S3Service; @@ -24,6 +29,7 @@ import com.example.solidconnection.siteuser.repository.SiteUserRepository; import com.example.solidconnection.support.TestContainerSpringBootTest; import com.example.solidconnection.university.domain.LikedUnivApplyInfo; +import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository; import java.time.LocalDateTime; @@ -52,9 +58,18 @@ class MyPageServiceTest { @Autowired private LikedUnivApplyInfoRepository likedUnivApplyInfoRepository; + @Autowired + private InterestedCountryRepository interestedCountryRepository; + @Autowired private SiteUserFixture siteUserFixture; + @Autowired + private MentorFixture mentorFixture; + + @Autowired + private CountryFixture countryFixture; + @Autowired private UnivApplyInfoFixture univApplyInfoFixture; @@ -69,9 +84,12 @@ void setUp() { } @Test - void 마이페이지_정보를_조회한다() { + void 멘티의_마이페이지_정보를_조회한다() { // given int likedUnivApplyInfoCount = createLikedUnivApplyInfos(user); + Country country = countryFixture.미국(); + InterestedCountry interestedCountry = new InterestedCountry(user, country); + interestedCountryRepository.save(interestedCountry); // when MyPageResponse response = myPageService.getMyPageInfo(user.getId()); @@ -84,8 +102,74 @@ void setUp() { () -> assertThat(response.email()).isEqualTo(user.getEmail()), // () -> assertThat(response.likedPostCount()).isEqualTo(user.getLikedPostList().size()), // todo : 좋아요한 게시물 수 반환 기능 추가와 함께 수정요망 - () -> assertThat(response.likedUnivApplyInfoCount()).isEqualTo(likedUnivApplyInfoCount) + () -> assertThat(response.likedUnivApplyInfoCount()).isEqualTo(likedUnivApplyInfoCount), + () -> assertThat(response.interestedCountries().get(0)).isEqualTo(country.getKoreanName()), + () -> assertThat(response.attendedUniversity()).isNull() + ); + } + + @Test + void 멘토의_마이페이지_정보를_조회한다() { + // given + SiteUser mentorUser = siteUserFixture.멘토(1, "mentor"); + University university = univApplyInfoFixture.괌대학_A_지원_정보().getUniversity(); + mentorFixture.멘토(mentorUser.getId(), university.getId()); + int likedUnivApplyInfoCount = createLikedUnivApplyInfos(mentorUser); + + // when + MyPageResponse response = myPageService.getMyPageInfo(mentorUser.getId()); + + // then + Assertions.assertAll( + () -> assertThat(response.nickname()).isEqualTo(mentorUser.getNickname()), + () -> assertThat(response.profileImageUrl()).isEqualTo(mentorUser.getProfileImageUrl()), + () -> assertThat(response.role()).isEqualTo(mentorUser.getRole()), + () -> assertThat(response.email()).isEqualTo(mentorUser.getEmail()), + // () -> assertThat(response.likedPostCount()).isEqualTo(user.getLikedPostList().size()), + // todo : 좋아요한 게시물 수 반환 기능 추가와 함께 수정요망 + () -> assertThat(response.likedUnivApplyInfoCount()).isEqualTo(likedUnivApplyInfoCount), + () -> assertThat(response.attendedUniversity()).isEqualTo(university.getKoreanName()), + () -> assertThat(response.interestedCountries()).isNull() + ); + } + + private int createLikedUnivApplyInfos(SiteUser testUser) { + LikedUnivApplyInfo likedUnivApplyInfo1 = new LikedUnivApplyInfo(null, univApplyInfoFixture.괌대학_A_지원_정보().getId(), testUser.getId()); + LikedUnivApplyInfo likedUnivApplyInfo2 = new LikedUnivApplyInfo(null, univApplyInfoFixture.메이지대학_지원_정보().getId(), testUser.getId()); + LikedUnivApplyInfo likedUnivApplyInfo3 = new LikedUnivApplyInfo(null, univApplyInfoFixture.코펜하겐IT대학_지원_정보().getId(), testUser.getId()); + + likedUnivApplyInfoRepository.save(likedUnivApplyInfo1); + likedUnivApplyInfoRepository.save(likedUnivApplyInfo2); + likedUnivApplyInfoRepository.save(likedUnivApplyInfo3); + return likedUnivApplyInfoRepository.countBySiteUserId(testUser.getId()); + } + + private MockMultipartFile createValidImageFile() { + return new MockMultipartFile( + "image", + "test.jpg", + "image/jpeg", + "test image content".getBytes() + ); + } + + private String createExpectedErrorMessage(LocalDateTime modifiedAt) { + String formatLastModifiedAt = String.format( + "(마지막 수정 시간 : %s)", + NICKNAME_LAST_CHANGE_DATE_FORMAT.format(modifiedAt) ); + return CAN_NOT_CHANGE_NICKNAME_YET.getMessage() + " : " + formatLastModifiedAt; + } + + private SiteUser createSiteUserWithCustomProfile() { + return siteUserFixtureBuilder.siteUser() + .email("customProfile@example.com") + .authType(AuthType.EMAIL) + .nickname("커스텀프로필") + .profileImageUrl("profile/profileImageUrl") + .role(Role.MENTEE) + .password("customPassword123") + .create(); } @Nested @@ -175,43 +259,4 @@ void setUp() { .hasMessage(createExpectedErrorMessage(modifiedAt)); } } - - private int createLikedUnivApplyInfos(SiteUser testUser) { - LikedUnivApplyInfo likedUnivApplyInfo1 = new LikedUnivApplyInfo(null, univApplyInfoFixture.괌대학_A_지원_정보().getId(), testUser.getId()); - LikedUnivApplyInfo likedUnivApplyInfo2 = new LikedUnivApplyInfo(null, univApplyInfoFixture.메이지대학_지원_정보().getId(), testUser.getId()); - LikedUnivApplyInfo likedUnivApplyInfo3 = new LikedUnivApplyInfo(null, univApplyInfoFixture.코펜하겐IT대학_지원_정보().getId(), testUser.getId()); - - likedUnivApplyInfoRepository.save(likedUnivApplyInfo1); - likedUnivApplyInfoRepository.save(likedUnivApplyInfo2); - likedUnivApplyInfoRepository.save(likedUnivApplyInfo3); - return likedUnivApplyInfoRepository.countBySiteUserId(testUser.getId()); - } - - private MockMultipartFile createValidImageFile() { - return new MockMultipartFile( - "image", - "test.jpg", - "image/jpeg", - "test image content".getBytes() - ); - } - - private String createExpectedErrorMessage(LocalDateTime modifiedAt) { - String formatLastModifiedAt = String.format( - "(마지막 수정 시간 : %s)", - NICKNAME_LAST_CHANGE_DATE_FORMAT.format(modifiedAt) - ); - return CAN_NOT_CHANGE_NICKNAME_YET.getMessage() + " : " + formatLastModifiedAt; - } - - private SiteUser createSiteUserWithCustomProfile() { - return siteUserFixtureBuilder.siteUser() - .email("customProfile@example.com") - .authType(AuthType.EMAIL) - .nickname("커스텀프로필") - .profileImageUrl("profile/profileImageUrl") - .role(Role.MENTEE) - .password("customPassword123") - .create(); - } } From cd4919566818c787790ac2eed031f41bbf19a311 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 Date: Sun, 10 Aug 2025 02:30:23 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20null=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5=EC=84=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/solidconnection/siteuser/service/MyPageService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java index 2f5a3cf40..f6738def9 100644 --- a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java +++ b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java @@ -51,7 +51,7 @@ public MyPageResponse getMyPageInfo(long siteUserId) { .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); int likedUnivApplyInfoCount = likedUnivApplyInfoRepository.countBySiteUserId(siteUser.getId()); - MyPageResponse myPageResponse = null; + MyPageResponse myPageResponse = MyPageResponse.of(siteUser, likedUnivApplyInfoCount, null, null); if (siteUser.getRole() == Role.MENTEE) { List interestedCountries = countryRepository.findKoreanNamesBySiteUserId(siteUser.getId()); myPageResponse = MyPageResponse.of(siteUser, likedUnivApplyInfoCount, interestedCountries, null); From 00bb9871c08d3a800515a4f385683d0e3f9bc30c Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 Date: Mon, 11 Aug 2025 23:01:19 +0900 Subject: [PATCH 4/6] =?UTF-8?q?refactor:=20static=20import=EB=A1=9C=20?= =?UTF-8?q?=EA=B0=80=EB=8F=85=EC=84=B1=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solidconnection/siteuser/dto/MyPageResponse.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java b/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java index f6ee0e45a..10b8b8953 100644 --- a/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java +++ b/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java @@ -1,5 +1,7 @@ package com.example.solidconnection.siteuser.dto; +import static com.fasterxml.jackson.annotation.JsonInclude.Include.*; + import com.example.solidconnection.siteuser.domain.AuthType; import com.example.solidconnection.siteuser.domain.Role; import com.example.solidconnection.siteuser.domain.SiteUser; @@ -19,10 +21,10 @@ public record MyPageResponse( @JsonProperty("likedUniversityCount") int likedUnivApplyInfoCount, - @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonInclude(NON_NULL) List interestedCountries, - @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonInclude(NON_NULL) String attendedUniversity) { public static MyPageResponse of(SiteUser siteUser, int likedUnivApplyInfoCount, List interestedCountries, String attendedUniversity) { From 0dbd02041f7437784d90493a84cccedca3c6ab28 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 Date: Mon, 11 Aug 2025 23:02:35 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20MyPageResponse=20=EC=9D=B8?= =?UTF-8?q?=EC=8A=A4=ED=84=B4=EC=8A=A4=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=9E=AC=ED=95=A0=EB=8B=B9=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../siteuser/service/MyPageService.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java index f6738def9..9997e67f7 100644 --- a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java +++ b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java @@ -51,19 +51,18 @@ public MyPageResponse getMyPageInfo(long siteUserId) { .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); int likedUnivApplyInfoCount = likedUnivApplyInfoRepository.countBySiteUserId(siteUser.getId()); - MyPageResponse myPageResponse = MyPageResponse.of(siteUser, likedUnivApplyInfoCount, null, null); + List interestedCountries = null; + String universityKoreanName = null; if (siteUser.getRole() == Role.MENTEE) { - List interestedCountries = countryRepository.findKoreanNamesBySiteUserId(siteUser.getId()); - myPageResponse = MyPageResponse.of(siteUser, likedUnivApplyInfoCount, interestedCountries, null); - } - else if (siteUser.getRole() == Role.MENTOR) { + interestedCountries = countryRepository.findKoreanNamesBySiteUserId(siteUser.getId()); + } else if (siteUser.getRole() == Role.MENTOR) { Mentor mentor = mentorRepository.findBySiteUserId(siteUser.getId()) .orElseThrow(() -> new CustomException(MENTOR_NOT_FOUND)); University university = universityRepository.findById(mentor.getUniversityId()) .orElseThrow(() -> new CustomException(UNIVERSITY_NOT_FOUND)); - myPageResponse = MyPageResponse.of(siteUser, likedUnivApplyInfoCount, null, university.getKoreanName()); + universityKoreanName = university.getKoreanName(); } - return myPageResponse; + return MyPageResponse.of(siteUser, likedUnivApplyInfoCount, interestedCountries, universityKoreanName); } /* From 5734a2f26636e6ef51a8f53a1c2152bba11436ed Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 Date: Thu, 14 Aug 2025 20:47:05 +0900 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=EB=A8=B8=EC=A7=80=20=EC=B6=A9?= =?UTF-8?q?=EB=8F=8C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../country/repository/CountryRepository.java | 2 + .../siteuser/service/MyPageService.java | 25 +++++- .../siteuser/service/MyPageServiceTest.java | 83 ++++++++++--------- 3 files changed, 69 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java b/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java index 783f57706..8b997a2de 100644 --- a/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java +++ b/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java @@ -3,6 +3,8 @@ import com.example.solidconnection.location.country.domain.Country; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface CountryRepository extends JpaRepository { diff --git a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java index 969408eea..d1d6e340c 100644 --- a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java +++ b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java @@ -3,19 +3,21 @@ import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET; import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.NICKNAME_ALREADY_EXISTED; +import static com.example.solidconnection.common.exception.ErrorCode.PASSWORD_MISMATCH; import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND; import com.example.solidconnection.common.exception.CustomException; +import com.example.solidconnection.location.country.repository.CountryRepository; import com.example.solidconnection.mentor.domain.Mentor; +import com.example.solidconnection.mentor.repository.MentorRepository; import com.example.solidconnection.s3.domain.ImgType; import com.example.solidconnection.s3.dto.UploadedFileUrlResponse; import com.example.solidconnection.s3.service.S3Service; import com.example.solidconnection.siteuser.domain.Role; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.dto.MyPageResponse; -import com.example.solidconnection.mentor.repository.MentorRepository; -import com.example.solidconnection.location.country.repository.CountryRepository; +import com.example.solidconnection.siteuser.dto.PasswordUpdateRequest; import com.example.solidconnection.siteuser.repository.SiteUserRepository; import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository; @@ -24,6 +26,7 @@ import java.time.format.DateTimeFormatter; import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -35,6 +38,7 @@ public class MyPageService { public static final int MIN_DAYS_BETWEEN_NICKNAME_CHANGES = 7; public static final DateTimeFormatter NICKNAME_LAST_CHANGE_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + private final PasswordEncoder passwordEncoder; private final SiteUserRepository siteUserRepository; private final LikedUnivApplyInfoRepository likedUnivApplyInfoRepository; private final CountryRepository countryRepository; @@ -111,4 +115,21 @@ private boolean isDefaultProfileImage(String profileImageUrl) { String prefix = "profile/"; return profileImageUrl == null || !profileImageUrl.startsWith(prefix); } + + @Transactional + public void updatePassword(long siteUserId, PasswordUpdateRequest request) { + SiteUser user = siteUserRepository.findById(siteUserId) + .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); + + // 사용자의 비밀번호와 request의 currentPassword가 동일한지 검증 + validatePasswordMatch(request.currentPassword(), user.getPassword()); + + user.updatePassword(passwordEncoder.encode(request.newPassword())); + } + + private void validatePasswordMatch(String currentPassword, String userPassword) { + if (!passwordEncoder.matches(currentPassword, userPassword)) { + throw new CustomException(PASSWORD_MISMATCH); + } + } } diff --git a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java index e46b1dc7f..f852909c6 100644 --- a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java +++ b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java @@ -29,6 +29,7 @@ import com.example.solidconnection.siteuser.repository.SiteUserRepository; import com.example.solidconnection.support.TestContainerSpringBootTest; import com.example.solidconnection.university.domain.LikedUnivApplyInfo; +import com.example.solidconnection.university.domain.University; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository; import java.time.LocalDateTime; @@ -40,6 +41,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.mock.web.MockMultipartFile; +import org.springframework.security.crypto.password.PasswordEncoder; @TestContainerSpringBootTest @DisplayName("마이페이지 서비스 테스트") @@ -75,6 +77,9 @@ class MyPageServiceTest { @Autowired private SiteUserFixtureBuilder siteUserFixtureBuilder; + @Autowired + private PasswordEncoder passwordEncoder; + private SiteUser user; @BeforeEach @@ -132,6 +137,45 @@ void setUp() { ); } + private int createLikedUnivApplyInfos(SiteUser testUser) { + LikedUnivApplyInfo likedUnivApplyInfo1 = new LikedUnivApplyInfo(null, univApplyInfoFixture.괌대학_A_지원_정보().getId(), testUser.getId()); + LikedUnivApplyInfo likedUnivApplyInfo2 = new LikedUnivApplyInfo(null, univApplyInfoFixture.메이지대학_지원_정보().getId(), testUser.getId()); + LikedUnivApplyInfo likedUnivApplyInfo3 = new LikedUnivApplyInfo(null, univApplyInfoFixture.코펜하겐IT대학_지원_정보().getId(), testUser.getId()); + + likedUnivApplyInfoRepository.save(likedUnivApplyInfo1); + likedUnivApplyInfoRepository.save(likedUnivApplyInfo2); + likedUnivApplyInfoRepository.save(likedUnivApplyInfo3); + return likedUnivApplyInfoRepository.countBySiteUserId(testUser.getId()); + } + + private MockMultipartFile createValidImageFile() { + return new MockMultipartFile( + "image", + "test.jpg", + "image/jpeg", + "test image content".getBytes() + ); + } + + private String createExpectedErrorMessage(LocalDateTime modifiedAt) { + String formatLastModifiedAt = String.format( + "(마지막 수정 시간 : %s)", + NICKNAME_LAST_CHANGE_DATE_FORMAT.format(modifiedAt) + ); + return CAN_NOT_CHANGE_NICKNAME_YET.getMessage() + " : " + formatLastModifiedAt; + } + + private SiteUser createSiteUserWithCustomProfile() { + return siteUserFixtureBuilder.siteUser() + .email("customProfile@example.com") + .authType(AuthType.EMAIL) + .nickname("커스텀프로필") + .profileImageUrl("profile/profileImageUrl") + .role(Role.MENTEE) + .password("customPassword123") + .create(); + } + @Nested class 프로필_이미지_수정_테스트 { @@ -219,43 +263,4 @@ void setUp() { .hasMessage(createExpectedErrorMessage(modifiedAt)); } } - - private int createLikedUnivApplyInfos(SiteUser testUser) { - LikedUnivApplyInfo likedUnivApplyInfo1 = new LikedUnivApplyInfo(null, univApplyInfoFixture.괌대학_A_지원_정보().getId(), testUser.getId()); - LikedUnivApplyInfo likedUnivApplyInfo2 = new LikedUnivApplyInfo(null, univApplyInfoFixture.메이지대학_지원_정보().getId(), testUser.getId()); - LikedUnivApplyInfo likedUnivApplyInfo3 = new LikedUnivApplyInfo(null, univApplyInfoFixture.코펜하겐IT대학_지원_정보().getId(), testUser.getId()); - - likedUnivApplyInfoRepository.save(likedUnivApplyInfo1); - likedUnivApplyInfoRepository.save(likedUnivApplyInfo2); - likedUnivApplyInfoRepository.save(likedUnivApplyInfo3); - return likedUnivApplyInfoRepository.countBySiteUserId(testUser.getId()); - } - - private MockMultipartFile createValidImageFile() { - return new MockMultipartFile( - "image", - "test.jpg", - "image/jpeg", - "test image content".getBytes() - ); - } - - private String createExpectedErrorMessage(LocalDateTime modifiedAt) { - String formatLastModifiedAt = String.format( - "(마지막 수정 시간 : %s)", - NICKNAME_LAST_CHANGE_DATE_FORMAT.format(modifiedAt) - ); - return CAN_NOT_CHANGE_NICKNAME_YET.getMessage() + " : " + formatLastModifiedAt; - } - - private SiteUser createSiteUserWithCustomProfile() { - return siteUserFixtureBuilder.siteUser() - .email("customProfile@example.com") - .authType(AuthType.EMAIL) - .nickname("커스텀프로필") - .profileImageUrl("profile/profileImageUrl") - .role(Role.MENTEE) - .password("customPassword123") - .create(); - } }