Skip to content
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

기본 이름이 중복되어 생성되는 문제 해결 #30

Merged
merged 5 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.backend.blooming.authentication.infrastructure.oauth.OAuthType;
import com.backend.blooming.authentication.infrastructure.oauth.dto.UserInformationDto;
import com.backend.blooming.user.domain.Email;
import com.backend.blooming.user.domain.Name;
import com.backend.blooming.user.domain.User;
import com.backend.blooming.user.infrastructure.repository.UserRepository;
import lombok.RequiredArgsConstructor;
Expand All @@ -25,6 +26,8 @@
@RequiredArgsConstructor
public class AuthenticationService {

private static final int NAME_MAX_LENGTH = 50;
private static final int BEGIN_INDEX = 0;
private final OAuthClientComposite oAuthClientComposite;
private final TokenProvider tokenProvider;
private final UserRepository userRepository;
Expand Down Expand Up @@ -56,12 +59,21 @@ private User persistUser(final UserInformationDto userInformationDto, final OAut
final User savedUser = User.builder()
.oAuthId(userInformationDto.oAuthId())
.oAuthType(oAuthType)
.name(convertToNameAndTruncateLength(userInformationDto.oAuthId()))
.email(new Email(userInformationDto.email()))
.build();

return userRepository.save(savedUser);
}

private Name convertToNameAndTruncateLength(final String oAuthId) {
if (oAuthId.length() > NAME_MAX_LENGTH) {
return new Name(oAuthId.substring(BEGIN_INDEX, NAME_MAX_LENGTH));
}

return new Name(oAuthId);
}

private TokenDto convertToTokenDto(final User user) {
final Long userId = user.getId();
final String accessToken = tokenProvider.createToken(TokenType.ACCESS, userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public enum ExceptionMessage {
NULL_OR_EMPTY_EMAIL("이메일은 비어있을 수 없습니다."),
LONGER_THAN_MAXIMUM_EMAIL("이메일의 최대 길이를 초과했습니다."),
INVALID_EMAIL_FORMAT("이메일 형식에 어긋났습니다."),

NULL_OR_EMPTY_NAME("이름은 비어있을 수 없습니다."),
LONGER_THAN_MAXIMUM_NAME("이름의 최대 길이를 초과했습니다."),

// 테마 색상
UNSUPPORTED_THEME_COLOR("지원하지 않는 테마 색상입니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.backend.blooming.user.application.dto.UpdateUserDto;
import com.backend.blooming.user.application.dto.ReadUsersWithFriendsStatusDto;
import com.backend.blooming.user.application.exception.NotFoundUserException;
import com.backend.blooming.user.domain.Name;
import com.backend.blooming.user.domain.User;
import com.backend.blooming.user.infrastructure.repository.UserRepository;
import com.backend.blooming.user.infrastructure.repository.UserWithFriendsStatusRepository;
Expand Down Expand Up @@ -52,7 +53,8 @@ public ReadUserDto updateById(final Long userId, final UpdateUserDto updateUserD

private void updateUserByRequest(final User user, final UpdateUserDto updateUserDto) {
if (updateUserDto.name() != null) {
user.updateName(updateUserDto.name());
final Name updateName = new Name(updateUserDto.name());
user.updateName(updateName);
}
if (updateUserDto.color() != null) {
final ThemeColor themeColor = ThemeColor.from(updateUserDto.color());
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/backend/blooming/user/domain/Name.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.backend.blooming.user.domain;

import com.backend.blooming.user.domain.exception.MemberException;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Embeddable
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@EqualsAndHashCode
@ToString
public class Name {

private static final int MAX_LENGTH = 50;

@Column(name = "name", unique = true, length = MAX_LENGTH, nullable = false)
private String value;

public Name(final String value) {
validateValue(value);
this.value = value;
}

private void validateValue(final String value) {
if (value == null || value.isEmpty()) {
throw new MemberException.NullOrEmptyNameException();
}
if (value.length() > MAX_LENGTH) {
throw new MemberException.LongerThanMaximumNameLengthException();
}
}
}
23 changes: 9 additions & 14 deletions src/main/java/com/backend/blooming/user/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
@Table(name = "users")
public class User extends BaseTimeEntity {

private static final String DEFAULT_NAME = "";
private static final String DEFAULT_STATUS_MESSAGE = "";
private static final ThemeColor DEFAULT_THEME_COLOR = ThemeColor.INDIGO;

Expand All @@ -45,8 +44,8 @@ public class User extends BaseTimeEntity {
@Embedded
private Email email;

@Column(unique = true, length = 50, nullable = false)
private String name;
@Embedded
private Name name;

@Enumerated(EnumType.STRING)
@Column(name = "theme_color", nullable = false)
Expand All @@ -63,26 +62,18 @@ private User(
final String oAuthId,
final OAuthType oAuthType,
final Email email,
final String name,
final Name name,
final ThemeColor color,
final String statusMessage
) {
this.oAuthId = oAuthId;
this.oAuthType = oAuthType;
this.email = email;
this.name = processName(name);
this.name = name;
this.color = processColor(color);
this.statusMessage = processStatusMessage(statusMessage);
}

private String processName(final String name) {
if (name == null) {
return DEFAULT_NAME;
}

return name;
}

private ThemeColor processColor(final ThemeColor color) {
if (color == null) {
return DEFAULT_THEME_COLOR;
Expand All @@ -103,7 +94,7 @@ public void delete() {
this.deleted = true;
}

public void updateName(final String name) {
public void updateName(final Name name) {
this.name = name;
}

Expand All @@ -119,6 +110,10 @@ public String getEmail() {
return email.getValue();
}

public String getName() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vo 값을 가져오는 경우 해당 vo에서 get 해오도록 했는데 정수님 코드 보고 도메인 엔티티에 직접 get 메서드 정의해 사용하면 좋을 것 같아서 이 부분도 수정하도록 하겠습니다!

return name.getValue();
}

public String getColorName() {
return color.name();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,18 @@ public InvalidEmailFormatException() {
super(ExceptionMessage.INVALID_EMAIL_FORMAT);
}
}

public static class NullOrEmptyNameException extends MemberException {

public NullOrEmptyNameException() {
super(ExceptionMessage.NULL_OR_EMPTY_NAME);
}
}

public static class LongerThanMaximumNameLengthException extends MemberException {

public LongerThanMaximumNameLengthException() {
super(ExceptionMessage.LONGER_THAN_MAXIMUM_NAME);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public List<UserWithFriendsStatusDto> findAllByNameContainsAndDeletedIsFalse(
.leftJoin(friend)
.on(buildFriendsConditions(currentUser.getId()))
.fetchJoin()
.where(user.deleted.isFalse().and(user.name.contains(keyword)))
.where(user.deleted.isFalse().and(user.name.value.contains(keyword)))
.fetch();

return userWithFriendDtos.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import com.backend.blooming.authentication.infrastructure.exception.UnsupportedOAuthTypeException;
import com.backend.blooming.authentication.infrastructure.oauth.OAuthClient;
import com.backend.blooming.configuration.IsolateDatabase;
import com.backend.blooming.user.domain.User;
import com.backend.blooming.user.infrastructure.repository.UserRepository;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
Expand All @@ -29,6 +31,9 @@ class AuthenticationServiceTest extends AuthenticationServiceTestFixture {
@Autowired
private AuthenticationService authenticationService;

@Autowired
private UserRepository userRepository;

@Test
void 로그인시_존재하지_않는_사용자인_경우_해당_사용자를_저장후_토큰_정보를_반환한다() {
// given
Expand All @@ -45,6 +50,30 @@ class AuthenticationServiceTest extends AuthenticationServiceTestFixture {
});
}

@Test
void 로그인시_존재하지_않는_사용자이며_oauthid가_50자를_초과하는_경우_이름을_50자까지만_저장한_후_토큰_정보를_반환한다() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

실제로 이름이 50자까지 저장되었는지 비교검증은 필요없을까요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 부분에 대한 검증에 대해서 고민 중에 있었습니다.
일단 현재 방식으로 한 이유는 50자를 초과하면 오류가 발생해 반환 자체가 안 될 것이기 때문에 정상처리 되었을 것이라 이해했습니다.
그리고 반환된 토큰에서 id를 도출하고 userRepository를 통해 사용자 정보를 가져오는 게 조금 귀찮아서 일단, when 절에서 호출한 메서드를 통해 도출된 값으로 검증을 진행했습니다.

그런데, 효선님께서 말씀하신 방식이 좀 더 이해가 쉬울 것 같다는 생각을 하기도 했습니다.
그래서 그 편이 더 이해가 쉽다면 해당 방식으로 진행하도록 하겠습니다!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 테스트에 비교 검증하는 부분이 있다면 이해가 더 쉬울 것 같아 이 부분만 추가해주시면 좋을 것 같습니다!

Copy link
Member Author

@JJ503 JJ503 Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 테스트하길 잘했어요..!
제가 substring을 아무 생각 없이 했더니 잘못 걸어뒀더라고요..!🥲
역시 귀찮다고 테스트를 허투루 하면 안 되겠군요...
좋은 의견 감사합니다!

// given
willReturn(oauthid가_50자를_초과하는_사용자_소셜_정보).given(oAuthClient).findUserInformation(소셜_액세스_토큰);

// when
final LoginInformationDto actual = authenticationService.login(oauth_타입, 소셜_액세스_토큰);

// then
final User savedUser = userRepository.findByOAuthIdAndOAuthType(
oauthid가_50자를_초과하는_사용자_소셜_정보.oAuthId(),
oauth_타입
)
.get();
System.out.println(savedUser);

assertSoftly(softAssertions -> {
softAssertions.assertThat(actual.token().accessToken()).isNotEmpty();
softAssertions.assertThat(actual.token().refreshToken()).isNotEmpty();
softAssertions.assertThat(actual.isSignUp()).isTrue();
softAssertions.assertThat(savedUser.getName().length()).isEqualTo(50);
});
}

@Test
void 로그인시_존재하는_사용자인_경우_사용자_정보를_반환시_회원가입_여부는_거짓이다() {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.backend.blooming.authentication.infrastructure.oauth.dto.UserInformationDto;
import com.backend.blooming.authentication.infrastructure.oauth.kakao.dto.KakaoUserInformationDto;
import com.backend.blooming.user.domain.Email;
import com.backend.blooming.user.domain.Name;
import com.backend.blooming.user.domain.User;
import com.backend.blooming.user.infrastructure.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -24,8 +25,13 @@ public class AuthenticationServiceTestFixture {
protected String 소셜_액세스_토큰 = "social_access_token";
protected UserInformationDto 첫_로그인_사용자_소셜_정보 =
new KakaoUserInformationDto("12345", new KakaoUserInformationDto.KakaoAccount("[email protected]"));
protected UserInformationDto oauthid가_50자를_초과하는_사용자_소셜_정보 =
new KakaoUserInformationDto(
"1234567890123456789012345678901234567890123456789012345",
new KakaoUserInformationDto.KakaoAccount("[email protected]")
);
protected UserInformationDto 기존_사용자_소셜_정보 =
new KakaoUserInformationDto("12346", new KakaoUserInformationDto.KakaoAccount("test2@email.com"));
new KakaoUserInformationDto("12346", new KakaoUserInformationDto.KakaoAccount("test3@email.com"));
protected String 유효한_refresh_token;
protected String 존재하지_않는_사용자의_refresh_token;
protected String 유효하지_않는_refresh_token = "Bearer invalid_refresh_token";
Expand All @@ -36,7 +42,7 @@ void setUpFixture() {
final User 기존_사용자 = User.builder()
.oAuthType(oauth_타입)
.oAuthId(기존_사용자_소셜_정보.oAuthId())
.name("기존 사용자")
.name(new Name("기존 사용자"))
.email(new Email(기존_사용자_소셜_정보.email()))
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.backend.blooming.friend.domain.Friend;
import com.backend.blooming.friend.infrastructure.repository.FriendRepository;
import com.backend.blooming.user.domain.Email;
import com.backend.blooming.user.domain.Name;
import com.backend.blooming.user.domain.User;
import com.backend.blooming.user.infrastructure.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -45,55 +46,55 @@ void setUpFixture() {
final User 사용자 = User.builder()
.oAuthId("12345")
.oAuthType(OAuthType.KAKAO)
.name("사용자1")
.name(new Name("사용자1"))
.email(new Email("[email protected]"))
.build();
final User 친구_요청할_사용자 = User.builder()
.oAuthId("12346")
.oAuthType(OAuthType.KAKAO)
.name("사용자2")
.name(new Name("사용자2"))
.email(new Email("[email protected]"))
.build();
final User 친구_요청을_보낸_사용자 = User.builder()
.oAuthId("12347")
.oAuthType(OAuthType.KAKAO)
.name("사용자3")
.name(new Name("사용자3"))
.email(new Email("[email protected]"))
.build();
final User 이미_친구_요청을_받은_사용자 = User.builder()
.oAuthId("12348")
.oAuthType(OAuthType.KAKAO)
.name("사용자4")
.name(new Name("사용자4"))
.email(new Email("[email protected]"))
.build();
final User 친구_요청을_받은_사용자2 = User.builder()
.oAuthId("12349")
.oAuthType(OAuthType.KAKAO)
.name("사용자5")
.name(new Name("사용자5"))
.email(new Email("[email protected]"))
.build();
final User 친구_요청을_받은_사용자3 = User.builder()
.oAuthId("12350")
.oAuthType(OAuthType.KAKAO)
.name("사용자6")
.name(new Name("사용자6"))
.email(new Email("[email protected]"))
.build();
final User 친구인_사용자1 = User.builder()
.oAuthId("23456")
.oAuthType(OAuthType.KAKAO)
.name("친구1")
.name(new Name("친구1"))
.email(new Email("[email protected]"))
.build();
final User 친구인_사용자2 = User.builder()
.oAuthId("23457")
.oAuthType(OAuthType.KAKAO)
.name("친구2")
.name(new Name("친구2"))
.email(new Email("[email protected]"))
.build();
final User 친구인_사용자3 = User.builder()
.oAuthId("23458")
.oAuthType(OAuthType.KAKAO)
.name("친구3")
.name(new Name("친구3"))
.email(new Email("[email protected]"))
.build();
userRepository.saveAll(List.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.backend.blooming.authentication.infrastructure.oauth.OAuthType;
import com.backend.blooming.user.domain.Email;
import com.backend.blooming.user.domain.Name;
import com.backend.blooming.user.domain.User;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.test.util.ReflectionTestUtils;
Expand All @@ -12,19 +13,19 @@ public class FriendTestFixture {
protected static User 친구_요청을_한_사용자 = User.builder()
.oAuthId("12345")
.oAuthType(OAuthType.KAKAO)
.name("사용자1")
.name(new Name("사용자1"))
.email(new Email("[email protected]"))
.build();
protected static User 친구_요청을_받은_사용자 = User.builder()
.oAuthId("12346")
.oAuthType(OAuthType.KAKAO)
.name("사용자2")
.name(new Name("사용자2"))
.email(new Email("[email protected]"))
.build();
protected static User 친구_요청과_상관없는_사용자 = User.builder()
.oAuthId("12347")
.oAuthType(OAuthType.KAKAO)
.name("사용자3")
.name(new Name("사용자3"))
.email(new Email("[email protected]"))
.build();

Expand Down
Loading