diff --git a/src/main/java/jungle/HandTris/application/impl/MemberProfileServiceImpl.java b/src/main/java/jungle/HandTris/application/impl/MemberProfileServiceImpl.java index 33df3b8..76545a4 100644 --- a/src/main/java/jungle/HandTris/application/impl/MemberProfileServiceImpl.java +++ b/src/main/java/jungle/HandTris/application/impl/MemberProfileServiceImpl.java @@ -1,6 +1,5 @@ package jungle.HandTris.application.impl; -import jakarta.servlet.http.HttpServletRequest; import jakarta.transaction.Transactional; import jungle.HandTris.application.service.MemberProfileService; import jungle.HandTris.application.service.MemberRecordService; @@ -10,8 +9,8 @@ import jungle.HandTris.domain.repo.MemberRepository; import jungle.HandTris.global.jwt.JWTUtil; import jungle.HandTris.presentation.dto.request.MemberUpdateReq; -import jungle.HandTris.presentation.dto.response.MemberProfileUpdateDetailsRes; import jungle.HandTris.presentation.dto.response.MemberRecordDetailRes; +import jungle.HandTris.presentation.dto.response.ReissueTokenRes; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.util.Pair; @@ -44,42 +43,51 @@ public Pair getMemberProfileWithStatsByNickname(S } @Override - public MemberProfileUpdateDetailsRes updateMemberProfile(HttpServletRequest request, MemberUpdateReq memberUpdateReq, MultipartFile profileImage, Boolean deleteProfileImage) { + public ReissueTokenRes changeMemberNickname(String nickname, MemberUpdateReq memberUpdateReq) { + + // 현재 닉네임과 동일한지 검증 + if (memberUpdateReq.changeNickname().equals(nickname)) { + throw new NicknameNotChangedException(); + } + + boolean nicknameExists = memberRepository.existsByNickname(memberUpdateReq.changeNickname()); + // 이미 존재하는 닉네임인지 검증 + if (nicknameExists) { + throw new DuplicateNicknameException(); + } - Boolean nicknameChanged = false; - String token = jwtUtil.resolveAccessToken(request); - String nickname = jwtUtil.getNickname(token); Member member = memberRepository.findByNickname(nickname) .orElseThrow(MemberNotFoundException::new); + member.updateNickname(memberUpdateReq.changeNickname()); - // 변경할 닉네임이 있을 경우에만 업데이트 - if (memberUpdateReq.nickname() != null && !memberUpdateReq.nickname().isEmpty()) { - // 현재 닉네임과 동일한지 검증 - if (memberUpdateReq.nickname().equals(member.getNickname())) { - throw new NicknameNotChangedException(); - } - - boolean nicknameExists = memberRepository.existsByNickname(memberUpdateReq.nickname()); - // 이미 존재하는 닉네임인지 검증 - if (nicknameExists) { - throw new DuplicateNicknameException(); - } - member.updateNickname(memberUpdateReq.nickname()); - nicknameChanged = true; - } + String accessToken = jwtUtil.createAccessToken(memberUpdateReq.changeNickname()); + String refreshToken = jwtUtil.createRefreshToken(memberUpdateReq.changeNickname()); + + member.updateRefreshToken(refreshToken); + + return new ReissueTokenRes(accessToken, refreshToken); + } - if (deleteProfileImage) { - member.updateProfileImageUrl(defaultImage); - } else if (profileImage != null && profileImage.getSize() > 0) { + @Override + public void changeMemberProfileImage(String nickname, MultipartFile profileImage) { + if (profileImage != null && profileImage.getSize() > 0){ // 이미지가 존재하는 경우에만 업데이트 validateImage(profileImage); + + Member member = memberRepository.findByNickname(nickname) + .orElseThrow(MemberNotFoundException::new); + uploadImage(profileImage, member); } + } - String accessToken = nicknameChanged ? jwtUtil.createAccessToken(member.getNickname()) : null; + @Override + public void deleteMemberProfileImage(String nickname) { + Member member = memberRepository.findByNickname(nickname) + .orElseThrow(MemberNotFoundException::new); - return new MemberProfileUpdateDetailsRes(member.getNickname(), member.getProfileImageUrl(), accessToken); + member.updateProfileImageUrl(defaultImage); } private void validateImage(MultipartFile profileImage) { diff --git a/src/main/java/jungle/HandTris/application/service/MemberProfileService.java b/src/main/java/jungle/HandTris/application/service/MemberProfileService.java index 51e59a0..0692041 100644 --- a/src/main/java/jungle/HandTris/application/service/MemberProfileService.java +++ b/src/main/java/jungle/HandTris/application/service/MemberProfileService.java @@ -1,14 +1,14 @@ package jungle.HandTris.application.service; -import jakarta.servlet.http.HttpServletRequest; import jungle.HandTris.presentation.dto.request.MemberUpdateReq; -import jungle.HandTris.presentation.dto.response.MemberProfileUpdateDetailsRes; import jungle.HandTris.presentation.dto.response.MemberRecordDetailRes; +import jungle.HandTris.presentation.dto.response.ReissueTokenRes; import org.springframework.data.util.Pair; import org.springframework.web.multipart.MultipartFile; public interface MemberProfileService { Pair getMemberProfileWithStatsByNickname(String nickname); - - MemberProfileUpdateDetailsRes updateMemberProfile(HttpServletRequest request, MemberUpdateReq memberUpdateReq, MultipartFile profileImage, Boolean deleteProfileImage); + ReissueTokenRes changeMemberNickname(String nickname, MemberUpdateReq memberUpdateReq); + void changeMemberProfileImage(String nickname, MultipartFile profileImage); + void deleteMemberProfileImage(String nickname); } diff --git a/src/main/java/jungle/HandTris/global/dto/WhiteListURI.java b/src/main/java/jungle/HandTris/global/dto/WhiteListURI.java index 88e0d83..13c6756 100644 --- a/src/main/java/jungle/HandTris/global/dto/WhiteListURI.java +++ b/src/main/java/jungle/HandTris/global/dto/WhiteListURI.java @@ -6,5 +6,5 @@ @Getter public class WhiteListURI { - public static final List WhiteListURI = List.of("mypage", "favicon", "actuator", "ws", "app", "topic"); + public static final List WhiteListURI = List.of("change", "favicon", "actuator", "ws", "app", "topic"); } diff --git a/src/main/java/jungle/HandTris/presentation/MemberProfileController.java b/src/main/java/jungle/HandTris/presentation/MemberProfileController.java index 77b1792..306b489 100644 --- a/src/main/java/jungle/HandTris/presentation/MemberProfileController.java +++ b/src/main/java/jungle/HandTris/presentation/MemberProfileController.java @@ -1,43 +1,43 @@ package jungle.HandTris.presentation; -import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import jungle.HandTris.application.service.MemberProfileService; -import jungle.HandTris.application.service.MemberRecordService; -import jungle.HandTris.domain.MemberRecord; import jungle.HandTris.global.dto.ResponseEnvelope; import jungle.HandTris.global.validation.UserNicknameFromJwt; import jungle.HandTris.presentation.dto.request.MemberUpdateReq; -import jungle.HandTris.presentation.dto.response.MemberProfileRes; -import jungle.HandTris.presentation.dto.response.MemberProfileUpdateDetailsRes; +import jungle.HandTris.presentation.dto.response.ReissueTokenRes; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @RestController @RequiredArgsConstructor -@RequestMapping("/member") +@RequestMapping("/change") public class MemberProfileController { private final MemberProfileService memberProfileService; - private final MemberRecordService memberRecordService; - @GetMapping("/mypage") - public ResponseEnvelope myPage(@UserNicknameFromJwt String nickname) { - MemberRecord memberRecord = memberRecordService.getMemberRecord(nickname); - MemberProfileRes memberProfileRes = new MemberProfileRes(memberRecord); - return ResponseEnvelope.of(memberProfileRes); + @PutMapping("/profileNickname") // 닉네임 변경 + public ResponseEnvelope changeNickname (@UserNicknameFromJwt String nickname, @Valid @RequestBody MemberUpdateReq memberUpdateReq) { + + ReissueTokenRes token = memberProfileService.changeMemberNickname(nickname, memberUpdateReq); + + return ResponseEnvelope.of(token); } - @PatchMapping("/mypage") - public ResponseEnvelope updateInfo( - HttpServletRequest request, - @Valid MemberUpdateReq memberUpdateReq, - @RequestPart(value = "profileImage", required = false) MultipartFile profileImage, - @RequestParam(value = "deleteProfileImage", required = false, defaultValue = "false") boolean deleteProfileImage - ) { + @PatchMapping("/profileImage") // 프로필 이미지 변경 + public ResponseEnvelope changeProfileImage (@UserNicknameFromJwt String nickname, @RequestPart(value = "profileImage") MultipartFile profileImage) { - MemberProfileUpdateDetailsRes updateMemberDetails = memberProfileService.updateMemberProfile(request, memberUpdateReq, profileImage, deleteProfileImage); + memberProfileService.changeMemberProfileImage(nickname, profileImage); - return ResponseEnvelope.of(updateMemberDetails); + return ResponseEnvelope.of("Profile Image Change Successful"); } + + @DeleteMapping("/profileImage") // 프로필 이미지 제거 + public ResponseEnvelope deleteProfileImage (@UserNicknameFromJwt String nickname) { + + memberProfileService.deleteMemberProfileImage(nickname); + + return ResponseEnvelope.of("Profile Image Delete Successful"); + } + } diff --git a/src/main/java/jungle/HandTris/presentation/dto/request/MemberUpdateReq.java b/src/main/java/jungle/HandTris/presentation/dto/request/MemberUpdateReq.java index b692235..886cd52 100644 --- a/src/main/java/jungle/HandTris/presentation/dto/request/MemberUpdateReq.java +++ b/src/main/java/jungle/HandTris/presentation/dto/request/MemberUpdateReq.java @@ -6,5 +6,5 @@ public record MemberUpdateReq (@Size(min = 4, max = 20, message = "닉네임은 최소 4자 이상, 20자 이하여야 합니다") @Pattern(regexp = "^[a-zA-Z0-9가-힣]+$", message = "닉네임은 알파벳 대소문자, 숫자, 한글만 사용 가능합니다.") @Pattern(regexp = "^((?!admin).)*$", message = "admin은 사용할 수 없습니다.") - String nickname) { + String changeNickname) { } diff --git a/src/test/java/jungle/HandTris/Member/AuthServiceTest.java b/src/test/java/jungle/HandTris/Member/AuthServiceTest.java index 0db6cb3..5f03597 100644 --- a/src/test/java/jungle/HandTris/Member/AuthServiceTest.java +++ b/src/test/java/jungle/HandTris/Member/AuthServiceTest.java @@ -12,8 +12,8 @@ import jungle.HandTris.domain.repo.MemberRepository; import jungle.HandTris.presentation.dto.request.MemberRequest; import jungle.HandTris.presentation.dto.request.MemberUpdateReq; -import jungle.HandTris.presentation.dto.response.MemberProfileUpdateDetailsRes; import jungle.HandTris.presentation.dto.response.MemberRecordDetailRes; +import jungle.HandTris.presentation.dto.response.ReissueTokenRes; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -339,7 +339,7 @@ public void testMyPageConnectWrongUser() { @Nested @DisplayName("회원 정보 요청") - class GetMemberProfile { + class GetMemberProfile { } @@ -365,12 +365,11 @@ public void testChangeMemberNicknameSuccess() { MemberUpdateReq changeNickname = new MemberUpdateReq("user2"); // when - MemberProfileUpdateDetailsRes changeMemberProfile = memberProfileService.updateMemberProfile( - request, changeNickname, null, false); + ReissueTokenRes changeMemberProfile = memberProfileService.changeMemberNickname( + requestMember.nickname(), changeNickname); // then - Assertions.assertThat(changeMemberProfile.nickname()).isEqualTo(member.getNickname()); - Assertions.assertThat(changeMemberProfile.token()).isNotEqualTo(token); + Assertions.assertThat(changeMemberProfile.access()).isNotEqualTo(token); } @Test @@ -390,8 +389,8 @@ public void testChangeMemberNicknameWithSameNickname() { // when & then Assertions.assertThatThrownBy(() -> { - memberProfileService.updateMemberProfile( - request, changeNickname, null, null); + memberProfileService.changeMemberNickname( + requestMember.nickname(), changeNickname); }).isInstanceOf(NicknameNotChangedException.class); } @@ -414,8 +413,8 @@ public void testChangeMemberNicknameWithDuplicateNickname() { // when & then Assertions.assertThatThrownBy(() -> { - memberProfileService.updateMemberProfile( - request, changeNickname, null, null); + memberProfileService.changeMemberNickname( + requestMember1.nickname(), changeNickname); }).isInstanceOf(DuplicateNicknameException.class); } } @@ -440,7 +439,7 @@ public void testChangeMemberProfileImageSuccess() { MockHttpServletRequest request = new MockHttpServletRequest(); request.addHeader("Authorization", "Bearer " + token); - MemberUpdateReq changeNickname = new MemberUpdateReq(null); + String originImageUrl = member.getProfileImageUrl(); // 변경하려는 프로필 사진 MockMultipartFile changeProfileImage = new MockMultipartFile( @@ -452,11 +451,10 @@ public void testChangeMemberProfileImageSuccess() { ); // when - MemberProfileUpdateDetailsRes changeMemberProfile = memberProfileService.updateMemberProfile( - request, changeNickname, changeProfileImage, false); + memberProfileService.changeMemberProfileImage(requestMember.nickname(), changeProfileImage); // then - Assertions.assertThat(changeMemberProfile.profileImageUrl()).isEqualTo(member.getProfileImageUrl()); + Assertions.assertThat(originImageUrl).isEqualTo(member.getProfileImageUrl()); } @Test @@ -472,7 +470,8 @@ public void testChangeMemberDefaultProfileImageSuccess() { MockHttpServletRequest request = new MockHttpServletRequest(); request.addHeader("Authorization", "Bearer " + token); - MemberUpdateReq changeNickname = new MemberUpdateReq(null); + String originImageUrl = member.getProfileImageUrl(); + // 변경하려는 프로필 사진 MockMultipartFile changeProfileImage = new MockMultipartFile( "image", // 파라미터 이름 @@ -481,14 +480,12 @@ public void testChangeMemberDefaultProfileImageSuccess() { "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=".getBytes() // PNG 이미지 데이터 (Base64) ); - MemberProfileUpdateDetailsRes changeMemberProfile = memberProfileService.updateMemberProfile( - request, changeNickname, changeProfileImage, false); + memberProfileService.changeMemberProfileImage(requestMember.nickname(), changeProfileImage); - Assertions.assertThat(changeMemberProfile.profileImageUrl()).isEqualTo(member.getProfileImageUrl()); + Assertions.assertThat(originImageUrl).isEqualTo(member.getProfileImageUrl()); // when - memberProfileService.updateMemberProfile( - request, changeNickname, null, true); + memberProfileService.deleteMemberProfileImage(requestMember.nickname()); // then Assertions.assertThat(defaultImage).isEqualTo(member.getProfileImageUrl()); } @@ -499,14 +496,7 @@ public void testChangeMemberNicknameWithSameNickname() { // given MemberRequest requestMember = new MemberRequest("user1", "1q2w3e4r!", "user1"); authService.signup(requestMember); - Pair SigninResult = authService.signin(requestMember); - Member member = SigninResult.getFirst(); - String token = SigninResult.getSecond(); - - MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Authorization", "Bearer " + token); - MemberUpdateReq changeNickname = new MemberUpdateReq(null); // 변경하려는 프로필 사진 MockMultipartFile changeProfileImage = new MockMultipartFile( "image", // 파라미터 이름 @@ -517,8 +507,7 @@ public void testChangeMemberNicknameWithSameNickname() { // when & then Assertions.assertThatThrownBy(() -> { - memberProfileService.updateMemberProfile( - request, changeNickname, changeProfileImage, false); + memberProfileService.changeMemberProfileImage(requestMember.nickname(), changeProfileImage); }).isInstanceOf(InvalidImageTypeException.class); } @@ -532,10 +521,6 @@ public void testChangeMemberNicknameWithDuplicateNickname() { Member member = SigninResult.getFirst(); String token = SigninResult.getSecond(); - MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Authorization", "Bearer " + token); - - MemberUpdateReq changeNickname = new MemberUpdateReq(null); // 변경하려는 프로필 사진 MockMultipartFile changeProfileImage = new MockMultipartFile( "image", // 파라미터 이름 @@ -550,8 +535,7 @@ public void testChangeMemberNicknameWithDuplicateNickname() { // when & then Assertions.assertThatThrownBy(() -> { - memberProfileService.updateMemberProfile( - request, changeNickname, changeProfileImage, false); + memberProfileService.changeMemberProfileImage(requestMember.nickname(), changeProfileImage); }).isInstanceOf(InvalidImageTypeException.class); } }