Skip to content

Commit e0dd5b7

Browse files
authored
feat: 마이페이지 응답 요소 추가 (#437)
* feat: 마이페이지 응답 요소 추가 - 멘티의 경우는 관심 국가 어디인지 - 멘토의 경우는 수학 대학교 어디인지 * test: 마이페이지 응답 요소 추가 관련 테스트 코드 작성 * refactor: null 반환 가능성 제거 * refactor: static import로 가독성 개선 * refactor: MyPageResponse 인스턴스에 대한 재할당 제거 * fix: 머지 충돌 해결
1 parent 1f8e455 commit e0dd5b7

File tree

4 files changed

+141
-94
lines changed

4 files changed

+141
-94
lines changed

src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,21 @@
33
import com.example.solidconnection.location.country.domain.Country;
44
import java.util.List;
55
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.data.jpa.repository.Query;
7+
import org.springframework.data.repository.query.Param;
68

79
public interface CountryRepository extends JpaRepository<Country, Long> {
810

911
List<Country> findAllByKoreanNameIn(List<String> koreanNames);
12+
13+
@Query("""
14+
SELECT DISTINCT c.koreanName
15+
FROM Country c
16+
WHERE c.code IN (
17+
SELECT ic.countryCode
18+
FROM InterestedCountry ic
19+
WHERE ic.siteUserId = :siteUserId
20+
)
21+
""")
22+
List<String> findKoreanNamesBySiteUserId(@Param("siteUserId") long siteUserId);
1023
}

src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.example.solidconnection.siteuser.dto;
22

3+
import static com.fasterxml.jackson.annotation.JsonInclude.Include.*;
4+
35
import com.example.solidconnection.siteuser.domain.AuthType;
46
import com.example.solidconnection.siteuser.domain.Role;
57
import com.example.solidconnection.siteuser.domain.SiteUser;
8+
import com.fasterxml.jackson.annotation.JsonInclude;
69
import com.fasterxml.jackson.annotation.JsonProperty;
10+
import java.util.List;
711

812
public record MyPageResponse(
913
String nickname,
@@ -15,9 +19,15 @@ public record MyPageResponse(
1519
int likedMentorCount,
1620

1721
@JsonProperty("likedUniversityCount")
18-
int likedUnivApplyInfoCount) {
22+
int likedUnivApplyInfoCount,
23+
24+
@JsonInclude(NON_NULL)
25+
List<String> interestedCountries,
26+
27+
@JsonInclude(NON_NULL)
28+
String attendedUniversity) {
1929

20-
public static MyPageResponse of(SiteUser siteUser, int likedUnivApplyInfoCount) {
30+
public static MyPageResponse of(SiteUser siteUser, int likedUnivApplyInfoCount, List<String> interestedCountries, String attendedUniversity) {
2131
return new MyPageResponse(
2232
siteUser.getNickname(),
2333
siteUser.getProfileImageUrl(),
@@ -26,7 +36,9 @@ public static MyPageResponse of(SiteUser siteUser, int likedUnivApplyInfoCount)
2636
siteUser.getEmail(),
2737
0, // TODO: 커뮤니티 기능 생기면 업데이트 필요
2838
0, // TODO: 멘토 기능 생기면 업데이트 필요
29-
likedUnivApplyInfoCount
39+
likedUnivApplyInfoCount,
40+
interestedCountries,
41+
attendedUniversity
3042
);
3143
}
3244
}

src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
11
package com.example.solidconnection.siteuser.service;
22

33
import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET;
4+
import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_NOT_FOUND;
45
import static com.example.solidconnection.common.exception.ErrorCode.NICKNAME_ALREADY_EXISTED;
56
import static com.example.solidconnection.common.exception.ErrorCode.PASSWORD_MISMATCH;
7+
import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_NOT_FOUND;
68
import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND;
79

810
import com.example.solidconnection.common.exception.CustomException;
11+
import com.example.solidconnection.location.country.repository.CountryRepository;
12+
import com.example.solidconnection.mentor.domain.Mentor;
13+
import com.example.solidconnection.mentor.repository.MentorRepository;
914
import com.example.solidconnection.s3.domain.ImgType;
1015
import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
1116
import com.example.solidconnection.s3.service.S3Service;
17+
import com.example.solidconnection.siteuser.domain.Role;
1218
import com.example.solidconnection.siteuser.domain.SiteUser;
1319
import com.example.solidconnection.siteuser.dto.MyPageResponse;
1420
import com.example.solidconnection.siteuser.dto.PasswordUpdateRequest;
1521
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
22+
import com.example.solidconnection.university.domain.University;
1623
import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository;
24+
import com.example.solidconnection.university.repository.UniversityRepository;
1725
import java.time.LocalDateTime;
1826
import java.time.format.DateTimeFormatter;
27+
import java.util.List;
1928
import lombok.RequiredArgsConstructor;
2029
import org.springframework.security.crypto.password.PasswordEncoder;
2130
import org.springframework.stereotype.Service;
@@ -32,6 +41,9 @@ public class MyPageService {
3241
private final PasswordEncoder passwordEncoder;
3342
private final SiteUserRepository siteUserRepository;
3443
private final LikedUnivApplyInfoRepository likedUnivApplyInfoRepository;
44+
private final CountryRepository countryRepository;
45+
private final MentorRepository mentorRepository;
46+
private final UniversityRepository universityRepository;
3547
private final S3Service s3Service;
3648

3749
/*
@@ -42,7 +54,19 @@ public MyPageResponse getMyPageInfo(long siteUserId) {
4254
SiteUser siteUser = siteUserRepository.findById(siteUserId)
4355
.orElseThrow(() -> new CustomException(USER_NOT_FOUND));
4456
int likedUnivApplyInfoCount = likedUnivApplyInfoRepository.countBySiteUserId(siteUser.getId());
45-
return MyPageResponse.of(siteUser, likedUnivApplyInfoCount);
57+
58+
List<String> interestedCountries = null;
59+
String universityKoreanName = null;
60+
if (siteUser.getRole() == Role.MENTEE) {
61+
interestedCountries = countryRepository.findKoreanNamesBySiteUserId(siteUser.getId());
62+
} else if (siteUser.getRole() == Role.MENTOR) {
63+
Mentor mentor = mentorRepository.findBySiteUserId(siteUser.getId())
64+
.orElseThrow(() -> new CustomException(MENTOR_NOT_FOUND));
65+
University university = universityRepository.findById(mentor.getUniversityId())
66+
.orElseThrow(() -> new CustomException(UNIVERSITY_NOT_FOUND));
67+
universityKoreanName = university.getKoreanName();
68+
}
69+
return MyPageResponse.of(siteUser, likedUnivApplyInfoCount, interestedCountries, universityKoreanName);
4670
}
4771

4872
/*

src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java

Lines changed: 88 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,39 @@
11
package com.example.solidconnection.siteuser.service;
22

33
import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET;
4-
import static com.example.solidconnection.common.exception.ErrorCode.PASSWORD_MISMATCH;
54
import static com.example.solidconnection.siteuser.service.MyPageService.MIN_DAYS_BETWEEN_NICKNAME_CHANGES;
65
import static com.example.solidconnection.siteuser.service.MyPageService.NICKNAME_LAST_CHANGE_DATE_FORMAT;
76
import static org.assertj.core.api.Assertions.assertThat;
8-
import static org.assertj.core.api.Assertions.assertThatThrownBy;
97
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
10-
import static org.junit.jupiter.api.Assertions.assertAll;
118
import static org.mockito.BDDMockito.any;
129
import static org.mockito.BDDMockito.eq;
1310
import static org.mockito.BDDMockito.given;
1411
import static org.mockito.BDDMockito.never;
1512
import static org.mockito.BDDMockito.then;
1613

1714
import com.example.solidconnection.common.exception.CustomException;
15+
import com.example.solidconnection.location.country.domain.Country;
16+
import com.example.solidconnection.location.country.domain.InterestedCountry;
17+
import com.example.solidconnection.location.country.fixture.CountryFixture;
18+
import com.example.solidconnection.location.country.repository.InterestedCountryRepository;
19+
import com.example.solidconnection.mentor.fixture.MentorFixture;
1820
import com.example.solidconnection.s3.domain.ImgType;
1921
import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
2022
import com.example.solidconnection.s3.service.S3Service;
2123
import com.example.solidconnection.siteuser.domain.AuthType;
2224
import com.example.solidconnection.siteuser.domain.Role;
2325
import com.example.solidconnection.siteuser.domain.SiteUser;
2426
import com.example.solidconnection.siteuser.dto.MyPageResponse;
25-
import com.example.solidconnection.siteuser.dto.PasswordUpdateRequest;
2627
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
2728
import com.example.solidconnection.siteuser.fixture.SiteUserFixtureBuilder;
2829
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
2930
import com.example.solidconnection.support.TestContainerSpringBootTest;
3031
import com.example.solidconnection.university.domain.LikedUnivApplyInfo;
32+
import com.example.solidconnection.university.domain.University;
3133
import com.example.solidconnection.university.fixture.UnivApplyInfoFixture;
3234
import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository;
3335
import java.time.LocalDateTime;
36+
import org.junit.jupiter.api.Assertions;
3437
import org.junit.jupiter.api.BeforeEach;
3538
import org.junit.jupiter.api.DisplayName;
3639
import org.junit.jupiter.api.Nested;
@@ -56,9 +59,18 @@ class MyPageServiceTest {
5659
@Autowired
5760
private LikedUnivApplyInfoRepository likedUnivApplyInfoRepository;
5861

62+
@Autowired
63+
private InterestedCountryRepository interestedCountryRepository;
64+
5965
@Autowired
6066
private SiteUserFixture siteUserFixture;
6167

68+
@Autowired
69+
private MentorFixture mentorFixture;
70+
71+
@Autowired
72+
private CountryFixture countryFixture;
73+
6274
@Autowired
6375
private UnivApplyInfoFixture univApplyInfoFixture;
6476

@@ -76,25 +88,94 @@ void setUp() {
7688
}
7789

7890
@Test
79-
void 마이페이지_정보를_조회한다() {
91+
void 멘티의_마이페이지_정보를_조회한다() {
8092
// given
8193
int likedUnivApplyInfoCount = createLikedUnivApplyInfos(user);
94+
Country country = countryFixture.미국();
95+
InterestedCountry interestedCountry = new InterestedCountry(user, country);
96+
interestedCountryRepository.save(interestedCountry);
8297

8398
// when
8499
MyPageResponse response = myPageService.getMyPageInfo(user.getId());
85100

86101
// then
87-
assertAll(
102+
Assertions.assertAll(
88103
() -> assertThat(response.nickname()).isEqualTo(user.getNickname()),
89104
() -> assertThat(response.profileImageUrl()).isEqualTo(user.getProfileImageUrl()),
90105
() -> assertThat(response.role()).isEqualTo(user.getRole()),
91106
() -> assertThat(response.email()).isEqualTo(user.getEmail()),
92107
// () -> assertThat(response.likedPostCount()).isEqualTo(user.getLikedPostList().size()),
93108
// todo : 좋아요한 게시물 수 반환 기능 추가와 함께 수정요망
94-
() -> assertThat(response.likedUnivApplyInfoCount()).isEqualTo(likedUnivApplyInfoCount)
109+
() -> assertThat(response.likedUnivApplyInfoCount()).isEqualTo(likedUnivApplyInfoCount),
110+
() -> assertThat(response.interestedCountries().get(0)).isEqualTo(country.getKoreanName()),
111+
() -> assertThat(response.attendedUniversity()).isNull()
95112
);
96113
}
97114

115+
@Test
116+
void 멘토의_마이페이지_정보를_조회한다() {
117+
// given
118+
SiteUser mentorUser = siteUserFixture.멘토(1, "mentor");
119+
University university = univApplyInfoFixture.괌대학_A_지원_정보().getUniversity();
120+
mentorFixture.멘토(mentorUser.getId(), university.getId());
121+
int likedUnivApplyInfoCount = createLikedUnivApplyInfos(mentorUser);
122+
123+
// when
124+
MyPageResponse response = myPageService.getMyPageInfo(mentorUser.getId());
125+
126+
// then
127+
Assertions.assertAll(
128+
() -> assertThat(response.nickname()).isEqualTo(mentorUser.getNickname()),
129+
() -> assertThat(response.profileImageUrl()).isEqualTo(mentorUser.getProfileImageUrl()),
130+
() -> assertThat(response.role()).isEqualTo(mentorUser.getRole()),
131+
() -> assertThat(response.email()).isEqualTo(mentorUser.getEmail()),
132+
// () -> assertThat(response.likedPostCount()).isEqualTo(user.getLikedPostList().size()),
133+
// todo : 좋아요한 게시물 수 반환 기능 추가와 함께 수정요망
134+
() -> assertThat(response.likedUnivApplyInfoCount()).isEqualTo(likedUnivApplyInfoCount),
135+
() -> assertThat(response.attendedUniversity()).isEqualTo(university.getKoreanName()),
136+
() -> assertThat(response.interestedCountries()).isNull()
137+
);
138+
}
139+
140+
private int createLikedUnivApplyInfos(SiteUser testUser) {
141+
LikedUnivApplyInfo likedUnivApplyInfo1 = new LikedUnivApplyInfo(null, univApplyInfoFixture.괌대학_A_지원_정보().getId(), testUser.getId());
142+
LikedUnivApplyInfo likedUnivApplyInfo2 = new LikedUnivApplyInfo(null, univApplyInfoFixture.메이지대학_지원_정보().getId(), testUser.getId());
143+
LikedUnivApplyInfo likedUnivApplyInfo3 = new LikedUnivApplyInfo(null, univApplyInfoFixture.코펜하겐IT대학_지원_정보().getId(), testUser.getId());
144+
145+
likedUnivApplyInfoRepository.save(likedUnivApplyInfo1);
146+
likedUnivApplyInfoRepository.save(likedUnivApplyInfo2);
147+
likedUnivApplyInfoRepository.save(likedUnivApplyInfo3);
148+
return likedUnivApplyInfoRepository.countBySiteUserId(testUser.getId());
149+
}
150+
151+
private MockMultipartFile createValidImageFile() {
152+
return new MockMultipartFile(
153+
"image",
154+
"test.jpg",
155+
"image/jpeg",
156+
"test image content".getBytes()
157+
);
158+
}
159+
160+
private String createExpectedErrorMessage(LocalDateTime modifiedAt) {
161+
String formatLastModifiedAt = String.format(
162+
"(마지막 수정 시간 : %s)",
163+
NICKNAME_LAST_CHANGE_DATE_FORMAT.format(modifiedAt)
164+
);
165+
return CAN_NOT_CHANGE_NICKNAME_YET.getMessage() + " : " + formatLastModifiedAt;
166+
}
167+
168+
private SiteUser createSiteUserWithCustomProfile() {
169+
return siteUserFixtureBuilder.siteUser()
170+
171+
.authType(AuthType.EMAIL)
172+
.nickname("커스텀프로필")
173+
.profileImageUrl("profile/profileImageUrl")
174+
.role(Role.MENTEE)
175+
.password("customPassword123")
176+
.create();
177+
}
178+
98179
@Nested
99180
class 프로필_이미지_수정_테스트 {
100181

@@ -182,87 +263,4 @@ void setUp() {
182263
.hasMessage(createExpectedErrorMessage(modifiedAt));
183264
}
184265
}
185-
186-
@Nested
187-
class 비밀번호_변경_테스트 {
188-
189-
private String currentPassword;
190-
private String newPassword;
191-
192-
@BeforeEach
193-
void setUp() {
194-
currentPassword = "currentPassword123";
195-
newPassword = "newPassword123";
196-
197-
user.updatePassword(passwordEncoder.encode(currentPassword));
198-
siteUserRepository.save(user);
199-
}
200-
201-
@Test
202-
void 비밀번호를_성공적으로_변경한다() {
203-
// given
204-
PasswordUpdateRequest request = new PasswordUpdateRequest(currentPassword, newPassword, newPassword);
205-
206-
// when
207-
myPageService.updatePassword(user.getId(), request);
208-
209-
// then
210-
SiteUser updatedUser = siteUserRepository.findById(user.getId()).get();
211-
assertAll(
212-
() -> assertThat(passwordEncoder.matches(newPassword, updatedUser.getPassword())).isTrue(),
213-
() -> assertThat(passwordEncoder.matches(currentPassword, updatedUser.getPassword())).isFalse()
214-
);
215-
}
216-
217-
@Test
218-
void 현재_비밀번호가_일치하지_않으면_예외가_발생한다() {
219-
// given
220-
String wrongPassword = "wrongPassword";
221-
PasswordUpdateRequest request = new PasswordUpdateRequest(wrongPassword, newPassword, newPassword);
222-
223-
// when & then
224-
assertThatThrownBy(() -> myPageService.updatePassword(user.getId(), request))
225-
.isInstanceOf(CustomException.class)
226-
.hasMessage(PASSWORD_MISMATCH.getMessage());
227-
}
228-
}
229-
230-
private int createLikedUnivApplyInfos(SiteUser testUser) {
231-
LikedUnivApplyInfo likedUnivApplyInfo1 = new LikedUnivApplyInfo(null, univApplyInfoFixture.괌대학_A_지원_정보().getId(), testUser.getId());
232-
LikedUnivApplyInfo likedUnivApplyInfo2 = new LikedUnivApplyInfo(null, univApplyInfoFixture.메이지대학_지원_정보().getId(), testUser.getId());
233-
LikedUnivApplyInfo likedUnivApplyInfo3 = new LikedUnivApplyInfo(null, univApplyInfoFixture.코펜하겐IT대학_지원_정보().getId(), testUser.getId());
234-
235-
likedUnivApplyInfoRepository.save(likedUnivApplyInfo1);
236-
likedUnivApplyInfoRepository.save(likedUnivApplyInfo2);
237-
likedUnivApplyInfoRepository.save(likedUnivApplyInfo3);
238-
return likedUnivApplyInfoRepository.countBySiteUserId(testUser.getId());
239-
}
240-
241-
private MockMultipartFile createValidImageFile() {
242-
return new MockMultipartFile(
243-
"image",
244-
"test.jpg",
245-
"image/jpeg",
246-
"test image content".getBytes()
247-
);
248-
}
249-
250-
private String createExpectedErrorMessage(LocalDateTime modifiedAt) {
251-
String formatLastModifiedAt = String.format(
252-
"(마지막 수정 시간 : %s)",
253-
NICKNAME_LAST_CHANGE_DATE_FORMAT.format(modifiedAt)
254-
);
255-
return CAN_NOT_CHANGE_NICKNAME_YET.getMessage() + " : " + formatLastModifiedAt;
256-
}
257-
258-
private SiteUser createSiteUserWithCustomProfile() {
259-
return siteUserFixtureBuilder.siteUser()
260-
261-
.authType(AuthType.EMAIL)
262-
.nickname("커스텀프로필")
263-
.profileImageUrl("profile/profileImageUrl")
264-
.role(Role.MENTEE)
265-
.password("customPassword123")
266-
.create();
267-
}
268266
}

0 commit comments

Comments
 (0)