From 2df37cd5021708ee3aa383a089c84115b409d331 Mon Sep 17 00:00:00 2001 From: Seokjin Jeon Date: Sat, 18 May 2024 15:39:09 +0900 Subject: [PATCH] =?UTF-8?q?[BE]=20feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=EB=8B=89=EB=84=A4=EC=9E=84=20=EC=A0=95?= =?UTF-8?q?=EC=B1=85=20=EC=B6=94=EA=B0=80=20(#972)=20(#974)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 기본 닉네임 정책 추가 --- .../command/MemberAuthCommandService.java | 5 +++- .../com/festago/auth/domain/UserInfo.java | 9 ------ .../auth/domain/UserInfoMemberMapper.java | 24 +++++++++++++++ .../config/DefaultNicknamePolicyConfig.java | 27 +++++++++++++++++ .../member/domain/DefaultNicknamePolicy.java | 6 ++++ .../com/festago/member/domain/Member.java | 4 +-- .../DefaultNicknamePolicyImpl.java | 22 ++++++++++++++ .../command/MemberAuthCommandServiceTest.java | 4 +++ .../com/festago/member/domain/MemberTest.java | 10 +++---- .../DefaultNicknamePolicyImplTest.java | 29 +++++++++++++++++++ 10 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 backend/src/main/java/com/festago/auth/domain/UserInfoMemberMapper.java create mode 100644 backend/src/main/java/com/festago/member/config/DefaultNicknamePolicyConfig.java create mode 100644 backend/src/main/java/com/festago/member/domain/DefaultNicknamePolicy.java create mode 100644 backend/src/main/java/com/festago/member/infrastructure/DefaultNicknamePolicyImpl.java create mode 100644 backend/src/test/java/com/festago/member/infrastructure/DefaultNicknamePolicyImplTest.java diff --git a/backend/src/main/java/com/festago/auth/application/command/MemberAuthCommandService.java b/backend/src/main/java/com/festago/auth/application/command/MemberAuthCommandService.java index 607b3a802..4b2b73a9a 100644 --- a/backend/src/main/java/com/festago/auth/application/command/MemberAuthCommandService.java +++ b/backend/src/main/java/com/festago/auth/application/command/MemberAuthCommandService.java @@ -2,6 +2,7 @@ import com.festago.auth.domain.RefreshToken; import com.festago.auth.domain.UserInfo; +import com.festago.auth.domain.UserInfoMemberMapper; import com.festago.auth.dto.event.MemberDeletedEvent; import com.festago.auth.dto.v1.LoginResult; import com.festago.auth.dto.v1.TokenRefreshResult; @@ -28,6 +29,7 @@ public class MemberAuthCommandService { private final MemberRepository memberRepository; private final RefreshTokenRepository refreshTokenRepository; private final ApplicationEventPublisher eventPublisher; + private final UserInfoMemberMapper userInfoMemberMapper; private final Clock clock; public LoginResult oAuth2Login(UserInfo userInfo) { @@ -44,7 +46,8 @@ public LoginResult oAuth2Login(UserInfo userInfo) { } private Member signUp(UserInfo userInfo) { - return memberRepository.save(userInfo.toMember()); + Member member = userInfoMemberMapper.toMember(userInfo); + return memberRepository.save(member); } private RefreshToken saveRefreshToken(Long memberId) { diff --git a/backend/src/main/java/com/festago/auth/domain/UserInfo.java b/backend/src/main/java/com/festago/auth/domain/UserInfo.java index a8c0afe16..232b81e4f 100644 --- a/backend/src/main/java/com/festago/auth/domain/UserInfo.java +++ b/backend/src/main/java/com/festago/auth/domain/UserInfo.java @@ -1,6 +1,5 @@ package com.festago.auth.domain; -import com.festago.member.domain.Member; import lombok.Builder; @Builder @@ -11,12 +10,4 @@ public record UserInfo( String profileImage ) { - public Member toMember() { - return new Member( - socialId, - socialType, - nickname, - profileImage - ); - } } diff --git a/backend/src/main/java/com/festago/auth/domain/UserInfoMemberMapper.java b/backend/src/main/java/com/festago/auth/domain/UserInfoMemberMapper.java new file mode 100644 index 000000000..dbebb691d --- /dev/null +++ b/backend/src/main/java/com/festago/auth/domain/UserInfoMemberMapper.java @@ -0,0 +1,24 @@ +package com.festago.auth.domain; + +import com.festago.member.domain.DefaultNicknamePolicy; +import com.festago.member.domain.Member; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +@Component +@RequiredArgsConstructor +public class UserInfoMemberMapper { + + private final DefaultNicknamePolicy defaultNicknamePolicy; + + public Member toMember(UserInfo userInfo) { + String nickname = userInfo.nickname(); + return new Member( + userInfo.socialId(), + userInfo.socialType(), + StringUtils.hasText(nickname) ? nickname : defaultNicknamePolicy.generate(), + userInfo.profileImage() + ); + } +} diff --git a/backend/src/main/java/com/festago/member/config/DefaultNicknamePolicyConfig.java b/backend/src/main/java/com/festago/member/config/DefaultNicknamePolicyConfig.java new file mode 100644 index 000000000..f4565eb5e --- /dev/null +++ b/backend/src/main/java/com/festago/member/config/DefaultNicknamePolicyConfig.java @@ -0,0 +1,27 @@ +package com.festago.member.config; + +import com.festago.member.domain.DefaultNicknamePolicy; +import com.festago.member.infrastructure.DefaultNicknamePolicyImpl; +import java.util.List; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class DefaultNicknamePolicyConfig { + + @Bean + public DefaultNicknamePolicy defaultNicknamePolicy() { + List adjectives = List.of( + "츄러스를 먹는", "노래 부르는", "때창하는", "응원하는", + "응원봉을 든", "타코야끼를 먹는", "공연에 심취한", "신나는", + "춤추는", "행복한", "즐거운", "신나는", "흥겨운" + ); + List nouns = List.of( + "다람쥐", "토끼", "고양이", "펭귄", + "캥거루", "사슴", "미어캣", "호랑이", + "여우", "판다", "고슴도치", "토끼", + "햄스터", "얼룩말", "너구리", "치타" + ); + return new DefaultNicknamePolicyImpl(adjectives, nouns); + } +} diff --git a/backend/src/main/java/com/festago/member/domain/DefaultNicknamePolicy.java b/backend/src/main/java/com/festago/member/domain/DefaultNicknamePolicy.java new file mode 100644 index 000000000..042b3392c --- /dev/null +++ b/backend/src/main/java/com/festago/member/domain/DefaultNicknamePolicy.java @@ -0,0 +1,6 @@ +package com.festago.member.domain; + +public interface DefaultNicknamePolicy { + + String generate(); +} diff --git a/backend/src/main/java/com/festago/member/domain/Member.java b/backend/src/main/java/com/festago/member/domain/Member.java index 1ed93648f..6e3907892 100644 --- a/backend/src/main/java/com/festago/member/domain/Member.java +++ b/backend/src/main/java/com/festago/member/domain/Member.java @@ -38,7 +38,6 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Member extends BaseTimeEntity { - private static final String DEFAULT_NICKNAME = "FestivalLover"; private static final int MAX_SOCIAL_ID_LENGTH = 255; private static final int MAX_NICKNAME_LENGTH = 30; private static final int MAX_PROFILE_IMAGE_LENGTH = 255; @@ -76,7 +75,7 @@ public Member(Long id, String socialId, SocialType socialType, String nickname, this.id = id; this.socialId = socialId; this.socialType = socialType; - this.nickname = (StringUtils.hasText(nickname)) ? nickname : DEFAULT_NICKNAME; + this.nickname = nickname; this.profileImage = ImageUrlHelper.getBlankStringIfBlank(profileImage); } @@ -100,6 +99,7 @@ private void validateSocialType(SocialType socialType) { private void validateNickname(String nickname) { String fieldName = "nickname"; Validator.maxLength(nickname, MAX_NICKNAME_LENGTH, fieldName); + Validator.notBlank(nickname, fieldName); } private void validateProfileImage(String profileImage) { diff --git a/backend/src/main/java/com/festago/member/infrastructure/DefaultNicknamePolicyImpl.java b/backend/src/main/java/com/festago/member/infrastructure/DefaultNicknamePolicyImpl.java new file mode 100644 index 000000000..e3fa4273d --- /dev/null +++ b/backend/src/main/java/com/festago/member/infrastructure/DefaultNicknamePolicyImpl.java @@ -0,0 +1,22 @@ +package com.festago.member.infrastructure; + +import com.festago.member.domain.DefaultNicknamePolicy; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class DefaultNicknamePolicyImpl implements DefaultNicknamePolicy { + + private final List adjectives; + private final List nouns; + + @Override + public String generate() { + Random random = ThreadLocalRandom.current(); + String adjective = adjectives.get(random.nextInt(adjectives.size())); + String noun = nouns.get(random.nextInt(nouns.size())); + return adjective + " " + noun; + } +} diff --git a/backend/src/test/java/com/festago/auth/application/command/MemberAuthCommandServiceTest.java b/backend/src/test/java/com/festago/auth/application/command/MemberAuthCommandServiceTest.java index 847a5a56e..bac29d949 100644 --- a/backend/src/test/java/com/festago/auth/application/command/MemberAuthCommandServiceTest.java +++ b/backend/src/test/java/com/festago/auth/application/command/MemberAuthCommandServiceTest.java @@ -9,11 +9,13 @@ import com.festago.auth.domain.RefreshToken; import com.festago.auth.domain.SocialType; import com.festago.auth.domain.UserInfo; +import com.festago.auth.domain.UserInfoMemberMapper; import com.festago.auth.repository.MemoryRefreshTokenRepository; import com.festago.auth.repository.RefreshTokenRepository; import com.festago.common.exception.ErrorCode; import com.festago.common.exception.NotFoundException; import com.festago.common.exception.UnauthorizedException; +import com.festago.member.domain.DefaultNicknamePolicy; import com.festago.member.domain.Member; import com.festago.member.repository.MemberRepository; import com.festago.member.repository.MemoryMemberRepository; @@ -46,10 +48,12 @@ void setUp() { clock = spy(Clock.systemDefaultZone()); memberRepository = new MemoryMemberRepository(); refreshTokenRepository = new MemoryRefreshTokenRepository(); + DefaultNicknamePolicy defaultNicknamePolicy = () -> "nickname"; memberAuthCommandService = new MemberAuthCommandService( memberRepository, refreshTokenRepository, mock(ApplicationEventPublisher.class), + new UserInfoMemberMapper(defaultNicknamePolicy), clock ); } diff --git a/backend/src/test/java/com/festago/member/domain/MemberTest.java b/backend/src/test/java/com/festago/member/domain/MemberTest.java index a9b0fc582..8c55e45a9 100644 --- a/backend/src/test/java/com/festago/member/domain/MemberTest.java +++ b/backend/src/test/java/com/festago/member/domain/MemberTest.java @@ -55,12 +55,10 @@ class MemberTest { @ParameterizedTest @NullSource @ValueSource(strings = {"", " ", "\t", "\n"}) - void nickname이_null_또는_공백이면_기본_닉네임_생성(String nickname) { - // given && when - Member member = new Member(1L, "12345", SocialType.FESTAGO, nickname, "profileImage.png"); - - // then - assertThat(member.getNickname()).isEqualTo("FestivalLover"); + void nickname이_null_또는_공백이면_예외(String nickname) { + // when & then + assertThatThrownBy(() -> new Member(1L, "12345", SocialType.FESTAGO, nickname, "profileImage.png")) + .isInstanceOf(ValidException.class); } @Test diff --git a/backend/src/test/java/com/festago/member/infrastructure/DefaultNicknamePolicyImplTest.java b/backend/src/test/java/com/festago/member/infrastructure/DefaultNicknamePolicyImplTest.java new file mode 100644 index 000000000..166f7710b --- /dev/null +++ b/backend/src/test/java/com/festago/member/infrastructure/DefaultNicknamePolicyImplTest.java @@ -0,0 +1,29 @@ +package com.festago.member.infrastructure; + +import static org.assertj.core.api.Assertions.*; + +import com.festago.member.domain.DefaultNicknamePolicy; +import java.util.List; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +class DefaultNicknamePolicyImplTest { + + @Test + void 형용사와_명사가_합쳐진_닉네임이_반환된다() { + // given + DefaultNicknamePolicy defaultNicknamePolicy = new DefaultNicknamePolicyImpl( + List.of("춤추는"), + List.of("다람쥐") + ); + + // when + String nickname = defaultNicknamePolicy.generate(); + + // then + assertThat(nickname).isEqualTo("춤추는 다람쥐"); + } +}