-
Notifications
You must be signed in to change notification settings - Fork 1
[hoony-lab-issue44] 사용자 업데이트 #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: hoony-lab
Are you sure you want to change the base?
Changes from all commits
e62bf5e
de002a3
29f820e
ab73728
02f7f73
6bdaa5d
202b634
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package com.study.realworld.user.dto; | ||
|
|
||
|
|
||
| import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
| import com.fasterxml.jackson.annotation.JsonTypeName; | ||
| import com.study.realworld.user.domain.User; | ||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| import static com.fasterxml.jackson.annotation.JsonTypeInfo.As.WRAPPER_OBJECT; | ||
| import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME; | ||
|
|
||
| @JsonTypeName("user") | ||
| @JsonTypeInfo(include = WRAPPER_OBJECT, use = NAME) | ||
| @Getter | ||
| @NoArgsConstructor | ||
| public class UserUpdateRequest { | ||
| private String email; | ||
| private String username; | ||
| private String password; | ||
| private String bio; | ||
| private String image; | ||
|
|
||
| @Builder | ||
| public UserUpdateRequest(String email, String username, String password, String bio, String image) { | ||
| this.email = email; | ||
| this.username = username; | ||
| this.password = password; | ||
| this.bio = bio; | ||
| this.image = image; | ||
| } | ||
|
|
||
| public static User toUser(UserUpdateRequest request) { | ||
| return User.builder() | ||
| .email(request.getEmail()) | ||
| .username(request.getUsername()) | ||
| .password(request.getPassword()) | ||
| .bio(request.getBio()) | ||
| .image(request.getImage()) | ||
| .build(); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -4,16 +4,18 @@ | |||
| import com.study.realworld.user.domain.UserRepository; | ||||
| import com.study.realworld.user.dto.UserJoinRequest; | ||||
| import com.study.realworld.user.dto.UserLoginRequest; | ||||
| import com.study.realworld.user.dto.UserUpdateRequest; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.springframework.dao.DuplicateKeyException; | ||||
| import org.springframework.security.crypto.password.PasswordEncoder; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Propagation; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|
|
||||
| import java.util.List; | ||||
| import java.util.NoSuchElementException; | ||||
|
|
||||
| import static java.util.Objects.nonNull; | ||||
|
|
||||
| @RequiredArgsConstructor | ||||
| @Transactional(readOnly = true) | ||||
| @Service | ||||
|
|
@@ -36,7 +38,7 @@ public User findByEmail(String email) { | |||
| .orElseThrow(() -> new NoSuchElementException(email + " not found")); | ||||
| } | ||||
|
|
||||
| @Transactional(propagation = Propagation.NEVER) | ||||
| @Transactional | ||||
| public User save(UserJoinRequest request) { | ||||
| User user = UserJoinRequest.toUser(request); | ||||
| user.encodePassword(passwordEncoder); | ||||
|
|
@@ -45,7 +47,7 @@ public User save(UserJoinRequest request) { | |||
|
|
||||
| return userRepository.save(user); | ||||
| } | ||||
|
|
||||
| public User login(UserLoginRequest request) { | ||||
| User user = this.findByEmail(request.getEmail()); | ||||
|
|
||||
|
|
@@ -54,6 +56,17 @@ public User login(UserLoginRequest request) { | |||
| return user; | ||||
| } | ||||
|
|
||||
| @Transactional | ||||
| public User update(UserUpdateRequest request, String principal) { | ||||
| validateExistUser(request.getEmail()); | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. validation 👍 |
||||
|
|
||||
| User requestUser = UserUpdateRequest.toUser(request); | ||||
| if(nonNull(requestUser.getPassword())) requestUser.encodePassword(passwordEncoder); | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
password를 service에서 encoding하셨는데 그냥 이 작업 자체를 user에서 할 수는 없을까요? 그리고 그렇게 넘기게 된다면 nonNull checking을
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런 생각이
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 완전히 물론 null체크를 service에서도 할 수 있지만 지금은 저희가 User객체를 새로 생성했고 User도메인의 로직을 잘 사용하고 있잖아요? 그렇게 된다면 지금 Service는 입력된 값에 대한 null체크를 해야한다는 무거운 비즈니스 로직에 대한 책임을 지지 않고 User를 호출할 수 있게 되겠죠.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 첫 리뷰를 제가 조금 잘못한 것 같은데 null checking에 대한 이야기를 하려고했던 거 였어요 🙇♂️ |
||||
|
|
||||
| User user = this.findByEmail(principal); | ||||
| return user.updateUser(requestUser); | ||||
| } | ||||
|
|
||||
| private void validateDuplicateUser(String email) { | ||||
| if(userRepository.findByEmail(email).isPresent()) { | ||||
| throw new DuplicateKeyException(email + " duplicated email"); | ||||
|
|
@@ -66,4 +79,10 @@ private void validateMatchesPassword(User user, String rawPassword) { | |||
| } | ||||
| } | ||||
|
|
||||
| private void validateExistUser(String email) { | ||||
| if(userRepository.existsByEmail(email)) { | ||||
| throw new DuplicateKeyException(email); | ||||
| } | ||||
| } | ||||
|
Comment on lines
+82
to
+86
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
굳이
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 흠 뭐가 정답이라고 하기는 뭐하지만 @Transactional
public User save(UserJoinRequest request) {
if (userRepository.findByEmail(email).isPresent()) {
throw new DuplicateKeyException(email + " duplicated email");
}
// do someting
}
@Transactional
public User update(UserUpdateRequest request, String principal) {
if (userRepository.existsByEmail(email)) {
throw new DuplicateKeyException(email);
}
// do something
}뭐 이런식으로요... |
||||
|
|
||||
| } | ||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,23 @@ | ||
| package com.study.realworld.config.auth; | ||
|
|
||
| import com.study.realworld.user.domain.User; | ||
| import io.jsonwebtoken.JwtException; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.api.extension.ExtendWith; | ||
| import org.mockito.junit.jupiter.MockitoExtension; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.junit.jupiter.api.Assertions.assertAll; | ||
| import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
|
||
| @ExtendWith(MockitoExtension.class) | ||
| class JwtProviderTest { | ||
|
|
||
| private static final Long ID = 1L; | ||
| private static final String EMAIL = "email"; | ||
| private static final String TOKEN = "token"; | ||
| private static final String WRONG_TOKEN = "wrong-token"; | ||
| private static final String USERNAME = "username"; | ||
| private static final String PASSWORD = "password"; | ||
| private static final String BIO = "bio"; | ||
|
|
@@ -52,4 +55,14 @@ void JwtProviderTest() { | |
| ); | ||
| } | ||
|
|
||
| @Test | ||
| void getClaimsFromToken_exception() { | ||
| // given | ||
|
|
||
| // when | ||
|
|
||
| // then | ||
| assertThrows(JwtException.class, () -> jwtProvider.getClaimsFromToken(WRONG_TOKEN)); | ||
| } | ||
|
Comment on lines
+59
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메서드가 비어있군요...! 😥 |
||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
각각 5개의 메소드로 분리할 수 있지 않을까요?
하나의 updateUser 메소드가 담당하는 역할이 많아보여요 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 동감합니다!. 각각의 메서드를 분리하고 호출하는 형태도 좋을 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
한방에 한방에는 용납하기 힘든가보네요 !
각각 분리해서 한번에 콜 해보도록 하겠습니다 ~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오우 이건 후에 저도 해야할 고민이겠네요