Skip to content

Commit 12692da

Browse files
committed
fix: 회원정보 수정기능 fix
- 람다로 변경 - test 코드 추가
1 parent a935fc8 commit 12692da

File tree

5 files changed

+120
-36
lines changed

5 files changed

+120
-36
lines changed

build.gradle.kts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,12 @@ dependencies {
6060
annotationProcessor("org.projectlombok:lombok:1.18.30")
6161

6262
// Test (Junit5)
63-
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
64-
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
63+
testImplementation("org.springframework.boot:spring-boot-starter-test")
64+
testImplementation("org.mockito:mockito-core:4.0.0")
65+
testImplementation("org.mockito:mockito-junit-jupiter:4.0.0")
66+
testImplementation("org.mockito:mockito-inline:4.7.0")
67+
testImplementation("org.junit.jupiter:junit-jupiter-api")
68+
testImplementation("org.junit.jupiter:junit-jupiter-engine")
6569

6670
// Json (Jackson)
6771
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")

src/main/java/org/dfbf/soundlink/domain/emotionRecord/entity/SpotifyMusic.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.Builder;
66
import lombok.Getter;
77
import lombok.NoArgsConstructor;
8+
import org.dfbf.soundlink.domain.user.dto.request.UserUpdateDto;
89
import org.hibernate.annotations.CreationTimestamp;
910
import org.hibernate.annotations.UpdateTimestamp;
1011

@@ -15,7 +16,6 @@
1516
@NoArgsConstructor(access = AccessLevel.PROTECTED)
1617
public class SpotifyMusic {
1718
@Id
18-
@GeneratedValue(strategy = GenerationType.IDENTITY)
1919
private Long spotifyId;
2020

2121
@Column(name = "title")
@@ -42,4 +42,11 @@ public SpotifyMusic (Long spotifyId, String title, String artist, String albumIm
4242
this.artist = artist;
4343
this.albumImage = albumImage;
4444
}
45+
46+
public SpotifyMusic (UserUpdateDto userUpdateDto) {
47+
this.spotifyId = userUpdateDto.spotifyId();
48+
this.title = userUpdateDto.title();
49+
this.artist = userUpdateDto.artist();
50+
this.albumImage = userUpdateDto.albumImage();
51+
}
4552
}

src/main/java/org/dfbf/soundlink/domain/user/repository/UserRepository.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,4 @@ public interface UserRepository extends JpaRepository<User, Long> {
3434

3535
@Query("Select u.password from User u where u.loginId =:loginId ")
3636
String findByPassword(@Param("loginId")String loginId);
37-
38-
39-
40-
4137
}

src/main/java/org/dfbf/soundlink/domain/user/service/UserService.java

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import jakarta.mail.MessagingException;
44
import jakarta.servlet.http.HttpServletResponse;
55
import jakarta.transaction.Transactional;
6-
import lombok.AllArgsConstructor;
6+
import lombok.RequiredArgsConstructor;
77
import lombok.extern.slf4j.Slf4j;
88
import org.dfbf.soundlink.domain.emotionRecord.entity.SpotifyMusic;
99
import org.dfbf.soundlink.domain.emotionRecord.repository.EmotionRecordRepository;
@@ -33,7 +33,7 @@
3333

3434
@Slf4j
3535
@Service
36-
@AllArgsConstructor
36+
@RequiredArgsConstructor
3737
public class UserService {
3838

3939
private final UserRepository userRepository;
@@ -45,8 +45,19 @@ public class UserService {
4545
private final RedisService redisService;
4646
private final JwtProvider jwtProvider;
4747
private final TokenProperties tokenProperties;
48+
4849
private RedisTemplate<String, String> redisTemplate;
4950

51+
//refreshToken을 쿠키로 설정
52+
private ResponseCookie getRefreshToken(String refreshToken) {
53+
return ResponseCookie
54+
.from("REFRESHTOKEN", refreshToken)
55+
.domain("localhost")
56+
.path("/")
57+
.httpOnly(true)
58+
.maxAge(tokenProperties.getRefreshTokenExpirationTime()) //만료시간 설정
59+
.build();
60+
}
5061

5162
// 회원가입
5263
public ResponseResult signUp(UserSignUpDto userSignUpDto) {
@@ -72,26 +83,31 @@ public ResponseResult getUser(Long userId) {
7283
}
7384

7485
// 회원정보 수정
75-
@Transactional
7686
public ResponseResult updateUser(Long userId, UserUpdateDto userUpdateDto) {
7787
try {
78-
User user = userRepository.findById(userId).orElseThrow(() -> new NoUserDataException());
88+
User user = userRepository.findById(userId).orElseThrow(NoUserDataException::new);
7989
user.update(userUpdateDto, passwordEncoder);
8090

81-
// SpotifyMusic 객체 찾고 없으면 새로 생성
91+
// SpotifyMusic 객체 찾기 (없으면 새로 생성 & 저장)
8292
SpotifyMusic spotifyMusic = spotifyMusicRepository.findById(userUpdateDto.spotifyId())
83-
.orElse(new SpotifyMusic(userUpdateDto.spotifyId(), userUpdateDto.title(), userUpdateDto.artist(), userUpdateDto.albumImage()));
84-
85-
// SpotifyMusic 저장
86-
spotifyMusicRepository.save(spotifyMusic);
93+
.orElseGet(() -> {
94+
SpotifyMusic sm = new SpotifyMusic(userUpdateDto);
95+
spotifyMusicRepository.save(sm);
96+
return sm;
97+
});
8798

88-
// ProfileMusic 객체 찾고 없으면 새로 생성
99+
// ProfileMusic 객체 찾기 (없으면 새로 생성 & 저장)
89100
ProfileMusic profileMusic = profileMusicRepository.findByUserId(userId)
90-
.orElse(new ProfileMusic(user, spotifyMusic));
101+
.map(pm -> {
102+
pm.update(spotifyMusic);
103+
return pm;
104+
})
105+
.orElseGet(() -> profileMusicRepository.save(new ProfileMusic(user, spotifyMusic)));
91106

92-
// ProfileMusic이 업데이트
93-
profileMusic.update(spotifyMusic);
94-
profileMusicRepository.save(profileMusic);
107+
/**
108+
* orElse -> 일단 함수는 실행, 그러나 값이 null이면 orElse의 값으로 대체 (함수O, 람다x)
109+
* orElseGet -> null일때만 실행 (함수O, 람다O)
110+
*/
95111

96112
return new ResponseResult(ErrorCode.SUCCESS);
97113
} catch (NoUserDataException e) {
@@ -104,6 +120,9 @@ public ResponseResult updateUser(Long userId, UserUpdateDto userUpdateDto) {
104120
public ResponseResult deleteUser(Long userId) {
105121
try {
106122
User user = userRepository.findById(userId).orElseThrow(() -> new NoUserDataException());
123+
124+
profileMusicRepository.deleteByUser(user); // 유저 프로필 음악 삭제
125+
emotionRecordRepository.deleteByUser(user); // 유저 감정 기록 삭제
107126
userRepository.deleteById(userId); // 유저 삭제
108127

109128
return new ResponseResult(ErrorCode.SUCCESS);
@@ -169,24 +188,13 @@ public ResponseResult checkEmail(String email){
169188

170189
//닉네임 중복 확인
171190
public ResponseResult checkNickName(String nickName){
172-
boolean exists =userRepository.existsByNickname(nickName);
191+
boolean exists = userRepository.existsByNickname(nickName);
173192
if(exists){
174193
return new ResponseResult(ErrorCode.DUPLICATE_NICKNAME);
175194
}
176195
return new ResponseResult(ErrorCode.NOT_DUPLICATE_NICKNAME);
177196
}
178197

179-
//refreshToken을 쿠키로 설정
180-
private ResponseCookie getRefreshToken(String refreshToken) {
181-
return ResponseCookie
182-
.from("REFRESHTOKEN", refreshToken)
183-
.domain("localhost")
184-
.path("/")
185-
.httpOnly(true)
186-
.maxAge(tokenProperties.getRefreshTokenExpirationTime()) //만료시간 설정
187-
.build();
188-
}
189-
190198
//로그인
191199
public ResponseResult login(LoginReqDto loginReqDto, HttpServletResponse response) {
192200
try {
@@ -238,7 +246,4 @@ public ResponseResult logout(HttpServletResponse response) {
238246
return new ResponseResult(ErrorCode. INTERNAL_SERVER_ERROR,"로그아웃 중 오류가 발생했습니다.");
239247
}
240248
}
241-
242-
243-
244249
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package org.dfbf.soundlink.domain.user;
2+
3+
import org.dfbf.soundlink.domain.emotionRecord.entity.SpotifyMusic;
4+
import org.dfbf.soundlink.domain.emotionRecord.repository.SpotifyMusicRepository;
5+
import org.dfbf.soundlink.domain.user.dto.request.UserUpdateDto;
6+
import org.dfbf.soundlink.domain.user.entity.ProfileMusic;
7+
import org.dfbf.soundlink.domain.user.entity.User;
8+
import org.dfbf.soundlink.domain.user.repository.ProfileMusicRepository;
9+
import org.dfbf.soundlink.domain.user.repository.UserRepository;
10+
import org.dfbf.soundlink.domain.user.service.UserService;
11+
import org.dfbf.soundlink.global.exception.ResponseResult;
12+
import org.junit.jupiter.api.Test;
13+
import org.junit.jupiter.api.extension.ExtendWith;
14+
import org.mockito.InjectMocks;
15+
import org.mockito.Mock;
16+
import org.mockito.junit.jupiter.MockitoExtension;
17+
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
18+
19+
import java.util.Optional;
20+
21+
import static org.mockito.Mockito.*;
22+
import static org.junit.jupiter.api.Assertions.*;
23+
24+
@ExtendWith(MockitoExtension.class)
25+
public class UserServiceTest {
26+
@InjectMocks
27+
private UserService userService;
28+
29+
@Mock
30+
private UserRepository userRepository;
31+
32+
@Mock
33+
private SpotifyMusicRepository spotifyMusicRepository;
34+
35+
@Mock
36+
private ProfileMusicRepository profileMusicRepository;
37+
38+
@Mock
39+
private BCryptPasswordEncoder passwordEncoder; // @MockBean으로 빈을 주입
40+
41+
42+
// 회원 정보 수정
43+
@Test
44+
public void testUpdateUser() {
45+
// Given
46+
Long userId = 1L;
47+
UserUpdateDto userUpdateDto = mock(UserUpdateDto.class);
48+
User existingUser = mock(User.class);
49+
SpotifyMusic spotifyMusic = mock(SpotifyMusic.class);
50+
ProfileMusic profileMusic = mock(ProfileMusic.class);
51+
52+
53+
// When
54+
when(userRepository.findById(userId)).thenReturn(Optional.of(existingUser));
55+
when(userUpdateDto.spotifyId()).thenReturn(123L);
56+
when(spotifyMusicRepository.findById(123L)).thenReturn(Optional.empty()); // Will be created
57+
when(profileMusicRepository.findByUserId(userId)).thenReturn(Optional.empty()); // Will be created
58+
59+
ResponseResult result = userService.updateUser(userId, userUpdateDto);
60+
61+
62+
// Then
63+
assertEquals(200, result.getCode());
64+
assertEquals("성공", result.getMessage());
65+
66+
verify(spotifyMusicRepository).save(any(SpotifyMusic.class));
67+
verify(profileMusicRepository).save(any(ProfileMusic.class));
68+
69+
verify(existingUser).update(eq(userUpdateDto), any(BCryptPasswordEncoder.class));
70+
}
71+
72+
}

0 commit comments

Comments
 (0)