diff --git a/src/main/java/com/ajou/hertz/common/properties/HertzProperties.java b/src/main/java/com/ajou/hertz/common/properties/HertzProperties.java new file mode 100644 index 0000000..d3ace40 --- /dev/null +++ b/src/main/java/com/ajou/hertz/common/properties/HertzProperties.java @@ -0,0 +1,7 @@ +package com.ajou.hertz.common.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties("hertz") +public record HertzProperties(String userDefaultProfileImageUrl) { +} diff --git a/src/main/java/com/ajou/hertz/domain/user/dto/UserDto.java b/src/main/java/com/ajou/hertz/domain/user/dto/UserDto.java index 370d37c..263799f 100644 --- a/src/main/java/com/ajou/hertz/domain/user/dto/UserDto.java +++ b/src/main/java/com/ajou/hertz/domain/user/dto/UserDto.java @@ -20,6 +20,7 @@ public class UserDto { private String email; private String password; private String kakaoUid; + private String profileImageUrl; private LocalDate birth; private Gender gender; private String phone; @@ -32,6 +33,7 @@ public static UserDto from(User user) { user.getEmail(), user.getPassword(), user.getKakaoUid(), + user.getProfileImageUrl(), user.getBirth(), user.getGender(), user.getPhone(), diff --git a/src/main/java/com/ajou/hertz/domain/user/dto/response/UserResponse.java b/src/main/java/com/ajou/hertz/domain/user/dto/response/UserResponse.java index 18cbea6..43ab75e 100644 --- a/src/main/java/com/ajou/hertz/domain/user/dto/response/UserResponse.java +++ b/src/main/java/com/ajou/hertz/domain/user/dto/response/UserResponse.java @@ -17,6 +17,7 @@ public class UserResponse { private Long id; private String email; + private String profileImageUrl; private LocalDate birth; private Gender gender; private String contactLink; @@ -25,6 +26,7 @@ public static UserResponse from(UserDto userDto) { return new UserResponse( userDto.getId(), userDto.getEmail(), + userDto.getProfileImageUrl(), userDto.getBirth(), userDto.getGender(), userDto.getContactLink() diff --git a/src/main/java/com/ajou/hertz/domain/user/entity/User.java b/src/main/java/com/ajou/hertz/domain/user/entity/User.java index 6d46a59..978d56f 100644 --- a/src/main/java/com/ajou/hertz/domain/user/entity/User.java +++ b/src/main/java/com/ajou/hertz/domain/user/entity/User.java @@ -57,6 +57,9 @@ public class User extends TimeTrackedBaseEntity { @Column(unique = true) private String kakaoUid; + @Column(nullable = false) + private String profileImageUrl; + private LocalDate birth; @Column(nullable = false) @@ -72,10 +75,14 @@ public class User extends TimeTrackedBaseEntity { public static User create( @NonNull String email, @NonNull String password, + @NonNull String profileImageUrl, LocalDate birth, @NonNull Gender gender, String phone ) { - return new User(null, Set.of(RoleType.USER), email, password, null, birth, gender, phone, null); + return new User( + null, Set.of(RoleType.USER), email, password, null, + profileImageUrl, birth, gender, phone, null + ); } } diff --git a/src/main/java/com/ajou/hertz/domain/user/entity/UserProfileImage.java b/src/main/java/com/ajou/hertz/domain/user/entity/UserProfileImage.java new file mode 100644 index 0000000..e899fa8 --- /dev/null +++ b/src/main/java/com/ajou/hertz/domain/user/entity/UserProfileImage.java @@ -0,0 +1,36 @@ +package com.ajou.hertz.domain.user.entity; + +import com.ajou.hertz.common.entity.FileEntity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@Entity +public class UserProfileImage extends FileEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_profile_image_id", nullable = false) + private Long id; + + @JoinColumn(name = "user_id", nullable = false) + @OneToOne(fetch = FetchType.LAZY) + private User user; + + private UserProfileImage(Long id, User user, String originalName, String storedName, String url) { + super(originalName, storedName, url); + this.id = id; + this.user = user; + } +} diff --git a/src/main/java/com/ajou/hertz/domain/user/service/UserCommandService.java b/src/main/java/com/ajou/hertz/domain/user/service/UserCommandService.java index ff7ff5d..f175ff6 100644 --- a/src/main/java/com/ajou/hertz/domain/user/service/UserCommandService.java +++ b/src/main/java/com/ajou/hertz/domain/user/service/UserCommandService.java @@ -4,6 +4,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.ajou.hertz.common.properties.HertzProperties; import com.ajou.hertz.domain.user.dto.UserDto; import com.ajou.hertz.domain.user.dto.request.SignUpRequest; import com.ajou.hertz.domain.user.entity.User; @@ -20,6 +21,7 @@ public class UserCommandService { private final UserQueryService userQueryService; private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; + private final HertzProperties hertzProperties; /** * 새로운 회원을 등록한다. @@ -38,6 +40,7 @@ public UserDto createNewUser(SignUpRequest signUpRequest) { User.create( email, passwordEncoder.encode(signUpRequest.getPassword()), + hertzProperties.userDefaultProfileImageUrl(), signUpRequest.getBirth(), signUpRequest.getGender(), signUpRequest.getPhone() diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5b4f7b5..c86d7f4 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,5 @@ hertz.app-version=0.0.1 +hertz.user-default-profile-image-url=${USER_DEFAULT_PROFILE_IMAGE} jwt.secret-key=${JWT_SECRET_KEY} diff --git a/src/test/java/com/ajou/hertz/config/TestSecurityConfig.java b/src/test/java/com/ajou/hertz/config/TestSecurityConfig.java index 8fed18a..c44d26d 100644 --- a/src/test/java/com/ajou/hertz/config/TestSecurityConfig.java +++ b/src/test/java/com/ajou/hertz/config/TestSecurityConfig.java @@ -46,7 +46,7 @@ public void securitySetUp() throws Exception { private UserDto createUserDto() throws Exception { Constructor userResponseConstructor = UserDto.class.getDeclaredConstructor( Long.class, Set.class, String.class, String.class, String.class, - LocalDate.class, Gender.class, String.class, String.class + String.class, LocalDate.class, Gender.class, String.class, String.class ); userResponseConstructor.setAccessible(true); return userResponseConstructor.newInstance( @@ -55,6 +55,7 @@ private UserDto createUserDto() throws Exception { "test@mail.com", "$2a$abc123", "kakao-user-id", + "https://user-default-profile-image", LocalDate.of(2024, 1, 1), Gender.ETC, "01012345678", diff --git a/src/test/java/com/ajou/hertz/unit/common/auth/service/AuthServiceTest.java b/src/test/java/com/ajou/hertz/unit/common/auth/service/AuthServiceTest.java index cc12f39..dec0b03 100644 --- a/src/test/java/com/ajou/hertz/unit/common/auth/service/AuthServiceTest.java +++ b/src/test/java/com/ajou/hertz/unit/common/auth/service/AuthServiceTest.java @@ -109,7 +109,7 @@ private JwtTokenInfoDto createJwtTokenInfoDto() { private UserDto createUserDto(long id) throws Exception { Constructor userResponseConstructor = UserDto.class.getDeclaredConstructor( Long.class, Set.class, String.class, String.class, String.class, - LocalDate.class, Gender.class, String.class, String.class + String.class, LocalDate.class, Gender.class, String.class, String.class ); userResponseConstructor.setAccessible(true); return userResponseConstructor.newInstance( @@ -118,6 +118,7 @@ private UserDto createUserDto(long id) throws Exception { "test@mail.com", "$2a$abc123", "kakao-user-id", + "https://user-default-profile-image", LocalDate.of(2024, 1, 1), Gender.ETC, "01012345678", diff --git a/src/test/java/com/ajou/hertz/unit/domain/user/controller/UserControllerV1Test.java b/src/test/java/com/ajou/hertz/unit/domain/user/controller/UserControllerV1Test.java index d9d6c9a..cf790df 100644 --- a/src/test/java/com/ajou/hertz/unit/domain/user/controller/UserControllerV1Test.java +++ b/src/test/java/com/ajou/hertz/unit/domain/user/controller/UserControllerV1Test.java @@ -185,7 +185,7 @@ private SignUpRequest createSignUpRequest() throws Exception { private UserDto createUserDto(long id) throws Exception { Constructor userResponseConstructor = UserDto.class.getDeclaredConstructor( Long.class, Set.class, String.class, String.class, String.class, - LocalDate.class, Gender.class, String.class, String.class + String.class, LocalDate.class, Gender.class, String.class, String.class ); userResponseConstructor.setAccessible(true); return userResponseConstructor.newInstance( @@ -194,6 +194,7 @@ private UserDto createUserDto(long id) throws Exception { "test@mail.com", "$2a$abc123", "kakao-user-id", + "https://user-default-profile-image", LocalDate.of(2024, 1, 1), Gender.ETC, "01012345678", diff --git a/src/test/java/com/ajou/hertz/unit/domain/user/service/UserCommandServiceTest.java b/src/test/java/com/ajou/hertz/unit/domain/user/service/UserCommandServiceTest.java index 8a5e772..f3d05df 100644 --- a/src/test/java/com/ajou/hertz/unit/domain/user/service/UserCommandServiceTest.java +++ b/src/test/java/com/ajou/hertz/unit/domain/user/service/UserCommandServiceTest.java @@ -14,7 +14,9 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.test.context.event.annotation.BeforeTestMethod; +import com.ajou.hertz.common.properties.HertzProperties; import com.ajou.hertz.domain.user.constant.Gender; import com.ajou.hertz.domain.user.constant.RoleType; import com.ajou.hertz.domain.user.dto.UserDto; @@ -41,6 +43,14 @@ class UserCommandServiceTest { @Mock private PasswordEncoder passwordEncoder; + @Mock + private HertzProperties hertzProperties; + + @BeforeTestMethod + public void setUp() { + given(hertzProperties.userDefaultProfileImageUrl()).willReturn("https://user-default-profile-image"); + } + @Test void 주어진_회원_정보로_신규_회원을_등록한다() throws Exception { // given @@ -88,7 +98,7 @@ private void verifyEveryMocksShouldHaveNoMoreInteractions() { private User createUser(Long id, String password) throws Exception { Constructor userConstructor = User.class.getDeclaredConstructor( Long.class, Set.class, String.class, String.class, String.class, - LocalDate.class, Gender.class, String.class, String.class + String.class, LocalDate.class, Gender.class, String.class, String.class ); userConstructor.setAccessible(true); return userConstructor.newInstance( @@ -97,6 +107,7 @@ private User createUser(Long id, String password) throws Exception { "test@test.com", password, "kakao-user-id", + "https://user-default-profile-image-url", LocalDate.of(2024, 1, 1), Gender.ETC, "010-1234-5678", diff --git a/src/test/java/com/ajou/hertz/unit/domain/user/service/UserQueryServiceTest.java b/src/test/java/com/ajou/hertz/unit/domain/user/service/UserQueryServiceTest.java index c0ab103..918408e 100644 --- a/src/test/java/com/ajou/hertz/unit/domain/user/service/UserQueryServiceTest.java +++ b/src/test/java/com/ajou/hertz/unit/domain/user/service/UserQueryServiceTest.java @@ -122,7 +122,7 @@ private void verifyEveryMocksShouldHaveNoMoreInteractions() { private User createUser(Long id, String email) throws Exception { Constructor userConstructor = User.class.getDeclaredConstructor( Long.class, Set.class, String.class, String.class, String.class, - LocalDate.class, Gender.class, String.class, String.class + String.class, LocalDate.class, Gender.class, String.class, String.class ); userConstructor.setAccessible(true); return userConstructor.newInstance( @@ -131,6 +131,7 @@ private User createUser(Long id, String email) throws Exception { email, "password", "kakao-user-id", + "https://user-default-profile-image-url", LocalDate.of(2024, 1, 1), Gender.ETC, "010-1234-5678",