From 09907bc3c9e66187d39c9a406b3fa89c5bff2357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=9D=B8=EC=A4=80?= <54973090+dlswns2480@users.noreply.github.com> Date: Thu, 8 Aug 2024 10:03:47 +0900 Subject: [PATCH] =?UTF-8?q?[fix=20#74]=20=EC=95=A0=ED=94=8C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=20(#75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix : apple id_token 디코딩 버그 픽스 * feat : 회원 등록 여부 필드 추가 * feat : 회원 등록 여부 필드 추가에 따른 로직 수정 * edit : 로직 수정에 따른 테스트 코드 수정 * feat : UserEntity 생성자에 id 추가 * feat : 유저 등록, 닉네임 수정 메소드 분리 * feat : 유저 등록 시 미분류 카테고리 생성 --- .../out/persistence/user/impl/UserAdapter.kt | 7 ---- .../persistence/user/persist/UserEntity.kt | 16 ++++---- .../com/pokit/content/ContentFixture.kt | 4 +- .../auth/common/support/AppleTokenParser.kt | 2 +- .../pokit/auth/port/service/AuthService.kt | 2 +- .../com/pokit/user/port/out/UserPort.kt | 2 - .../pokit/user/port/service/UserService.kt | 38 +++++++++++++++---- .../auth/port/service/AuthServiceTest.kt | 4 +- .../port/service/ContentServiceTest.kt | 12 ++++-- .../user/port/service/UserServiceTest.kt | 12 +----- .../category/exception/CategoryErrorCode.kt | 7 ++-- .../kotlin/com/pokit/token/model/Token.kt | 1 + .../com/pokit/user/exception/UserErrorCode.kt | 3 +- .../main/kotlin/com/pokit/user/model/User.kt | 10 ++++- 14 files changed, 72 insertions(+), 48 deletions(-) diff --git a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/impl/UserAdapter.kt b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/impl/UserAdapter.kt index c8894af7..e72a9b00 100644 --- a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/impl/UserAdapter.kt +++ b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/impl/UserAdapter.kt @@ -2,7 +2,6 @@ package com.pokit.out.persistence.user.impl import com.pokit.out.persistence.user.persist.UserEntity import com.pokit.out.persistence.user.persist.UserRepository -import com.pokit.out.persistence.user.persist.registerInfo import com.pokit.out.persistence.user.persist.toDomain import com.pokit.user.model.User import com.pokit.user.port.out.UserPort @@ -25,12 +24,6 @@ class UserAdapter( override fun loadById(id: Long) = userRepository.findByIdAndDeleted(id, false) ?.run { toDomain() } - override fun register(user: User): User? { - val userEntity = userRepository.findByIdOrNull(user.id) - userEntity?.registerInfo(user) - return userEntity?.toDomain() - } - override fun checkByNickname(nickname: String) = userRepository.existsByNickname(nickname) override fun delete(user: User) { userRepository.findByIdOrNull(user.id) diff --git a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserEntity.kt b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserEntity.kt index 7e6ac978..4d578750 100644 --- a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserEntity.kt +++ b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserEntity.kt @@ -28,7 +28,10 @@ class UserEntity( val authPlatform: AuthPlatform, @Column(name = "deleted") - var deleted: Boolean = false + var deleted: Boolean = false, + + @Column(name = "is_registered") + var registered: Boolean ) { fun delete() { this.deleted = true @@ -37,10 +40,12 @@ class UserEntity( companion object { fun of(user: User) = UserEntity( + id = user.id, email = user.email, role = user.role, nickname = user.nickName, - authPlatform = user.authPlatform + authPlatform = user.authPlatform, + registered = user.registered ) } } @@ -50,9 +55,6 @@ fun UserEntity.toDomain() = User( email = this.email, role = this.role, nickName = this.nickname, - authPlatform = this.authPlatform + authPlatform = this.authPlatform, + registered = this.registered ) - -fun UserEntity.registerInfo(user: User) { - this.nickname = user.nickName -} diff --git a/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/content/ContentFixture.kt b/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/content/ContentFixture.kt index b1add855..9397fa12 100644 --- a/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/content/ContentFixture.kt +++ b/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/content/ContentFixture.kt @@ -10,7 +10,7 @@ class ContentFixture { fun getContent() = Content( categoryId = 1L, type = ContentType.LINK, - data = "blahblah.com", + data = "https://github.com/YAPP-Github/24th-App-Team-4-BE/pull/73", title = "어떤 제목", memo = "이러한 내용 요약", alertYn = "YES" @@ -35,7 +35,7 @@ class ContentFixture { ) fun getContentCommand(categoryId: Long) = ContentCommand( - data = "www.naver.com", + data = "https://github.com/YAPP-Github/24th-App-Team-4-BE/pull/73", title = "네이버", categoryId = categoryId, memo = "네이버우어", diff --git a/adapters/out-web/src/main/kotlin/com/pokit/auth/common/support/AppleTokenParser.kt b/adapters/out-web/src/main/kotlin/com/pokit/auth/common/support/AppleTokenParser.kt index 2db1b26e..b6c78e45 100644 --- a/adapters/out-web/src/main/kotlin/com/pokit/auth/common/support/AppleTokenParser.kt +++ b/adapters/out-web/src/main/kotlin/com/pokit/auth/common/support/AppleTokenParser.kt @@ -16,7 +16,7 @@ class AppleTokenParser( private val typeReference = object : TypeReference>() {} fun parseHeader(idToken: String): Map { - val header = idToken.split("\\.")[0] + val header = idToken.split(".")[0] val decodedHeader = String(Base64.getDecoder().decode(header), StandardCharsets.UTF_8) return objectMapper.readValue(decodedHeader, typeReference) } diff --git a/application/src/main/kotlin/com/pokit/auth/port/service/AuthService.kt b/application/src/main/kotlin/com/pokit/auth/port/service/AuthService.kt index 714bb079..039e2948 100644 --- a/application/src/main/kotlin/com/pokit/auth/port/service/AuthService.kt +++ b/application/src/main/kotlin/com/pokit/auth/port/service/AuthService.kt @@ -42,7 +42,7 @@ class AuthService( val token = tokenProvider.createToken(user.id) - return token + return token.copy(isRegistered = user.registered) } @Transactional diff --git a/application/src/main/kotlin/com/pokit/user/port/out/UserPort.kt b/application/src/main/kotlin/com/pokit/user/port/out/UserPort.kt index 75651625..5df32f3c 100644 --- a/application/src/main/kotlin/com/pokit/user/port/out/UserPort.kt +++ b/application/src/main/kotlin/com/pokit/user/port/out/UserPort.kt @@ -9,8 +9,6 @@ interface UserPort { fun loadById(id: Long): User? - fun register(user: User): User? - fun checkByNickname(nickname: String): Boolean fun delete(user: User) diff --git a/application/src/main/kotlin/com/pokit/user/port/service/UserService.kt b/application/src/main/kotlin/com/pokit/user/port/service/UserService.kt index 8edcbf32..bcdb6ce7 100644 --- a/application/src/main/kotlin/com/pokit/user/port/service/UserService.kt +++ b/application/src/main/kotlin/com/pokit/user/port/service/UserService.kt @@ -1,5 +1,10 @@ package com.pokit.user.port.service +import com.pokit.category.exception.CategoryErrorCode +import com.pokit.category.model.Category +import com.pokit.category.model.CategoryStatus.UNCATEGORIZED +import com.pokit.category.port.out.CategoryImagePort +import com.pokit.category.port.out.CategoryPort import com.pokit.common.exception.ClientValidationException import com.pokit.common.exception.NotFoundCustomException import com.pokit.user.dto.request.SignUpRequest @@ -14,17 +19,36 @@ import org.springframework.transaction.annotation.Transactional @Service @Transactional(readOnly = true) class UserService( - private val userPort: UserPort + private val userPort: UserPort, + private val categoryPort: CategoryPort, + private val categoryImagePort: CategoryImagePort ) : UserUseCase { + companion object { + private const val UNCATEGORIZED_IMAGE_ID = 1 + } + @Transactional override fun signUp(user: User, request: SignUpRequest): User { - user.modifyUser( - request.nickName, - ) - - val savedUser = userPort.register(user) + val findUser = userPort.loadById(user.id) ?: throw NotFoundCustomException(UserErrorCode.NOT_FOUND_USER) + if (findUser.registered) { + throw ClientValidationException(UserErrorCode.ALREADY_REGISTERED) + } + + findUser.register(request.nickName) + val savedUser = userPort.persist(findUser) + + val image = (categoryImagePort.loadById(UNCATEGORIZED_IMAGE_ID) + ?: throw NotFoundCustomException(CategoryErrorCode.NOT_FOUND_UNCATEGORIZED_IMAGE)) + + val category = Category( + userId = savedUser.id, + categoryName = UNCATEGORIZED.displayName, + categoryImage = image + ) + categoryPort.persist(category) + return savedUser } @@ -42,7 +66,7 @@ class UserService( throw ClientValidationException(UserErrorCode.ALREADY_EXISTS_NICKNAME) } - findUser.modifyUser(request.nickname) + findUser.modifyNickname(request.nickname) return userPort.persist(findUser) } } diff --git a/application/src/test/kotlin/com/pokit/auth/port/service/AuthServiceTest.kt b/application/src/test/kotlin/com/pokit/auth/port/service/AuthServiceTest.kt index 22466a07..0829c2ef 100644 --- a/application/src/test/kotlin/com/pokit/auth/port/service/AuthServiceTest.kt +++ b/application/src/test/kotlin/com/pokit/auth/port/service/AuthServiceTest.kt @@ -34,8 +34,10 @@ class AuthServiceTest : BehaviorSpec({ every { googleApiClient.getUserInfo(request.idToken) } returns userInfo every { userPort.loadByEmail(userInfo.email) } returns user + every { userPort.loadById(user.id) } returns user every { tokenProvider.createToken(user.id) } returns token - every { tokenProvider.reissueToken("refresh") } returns reissueResult + every { tokenProvider.getUserId("refresh") } returns user.id + every { tokenProvider.reissueToken(user.id, "refresh") } returns reissueResult When("로그인할 때 구글 플랫폼으로 올바른 인증코드로 요청하면") { val resultToken = authService.signIn(request) diff --git a/application/src/test/kotlin/com/pokit/content/port/service/ContentServiceTest.kt b/application/src/test/kotlin/com/pokit/content/port/service/ContentServiceTest.kt index 4184ac36..3c133047 100644 --- a/application/src/test/kotlin/com/pokit/content/port/service/ContentServiceTest.kt +++ b/application/src/test/kotlin/com/pokit/content/port/service/ContentServiceTest.kt @@ -7,6 +7,7 @@ import com.pokit.category.port.out.CategoryPort import com.pokit.common.exception.NotFoundCustomException import com.pokit.content.ContentFixture import com.pokit.content.dto.request.toDomain +import com.pokit.content.model.Content import com.pokit.content.port.out.ContentPort import com.pokit.log.port.out.UserLogPort import com.pokit.user.UserFixture @@ -55,6 +56,9 @@ class ContentServiceTest : BehaviorSpec({ val content = ContentFixture.getContent() val command = ContentFixture.getContentCommand(1L) + val createContent = command.toDomain() + createContent.parseDomain() + val invalidCommand = ContentFixture.getContentCommand(2L) val user = UserFixture.getUser() @@ -65,12 +69,12 @@ class ContentServiceTest : BehaviorSpec({ } returns category every { - contentPort.persist(command.toDomain()) - } returns command.toDomain() + contentPort.persist(any(Content::class)) + } returns createContent every { - contentPort.loadByUserIdAndId(user.id, content.id) - } returns content + contentPort.loadByUserIdAndId(user.id, createContent.id) + } returns createContent every { contentPort.loadByUserIdAndId(user.id, invalidContentId) diff --git a/application/src/test/kotlin/com/pokit/user/port/service/UserServiceTest.kt b/application/src/test/kotlin/com/pokit/user/port/service/UserServiceTest.kt index 005ed79c..c5d11e50 100644 --- a/application/src/test/kotlin/com/pokit/user/port/service/UserServiceTest.kt +++ b/application/src/test/kotlin/com/pokit/user/port/service/UserServiceTest.kt @@ -22,8 +22,8 @@ class UserServiceTest : BehaviorSpec({ val request = UserFixture.getSignUpRequest() val modifieUser = User(user.id, user.email, user.role, request.nickName, AuthPlatform.GOOGLE) - every { userPort.register(user) } returns modifieUser - every { userPort.register(invalidUser) } returns null + every { userPort.loadById(user.id) } returns user + every { userPort.persist(any(User::class)) } returns modifieUser When("수정하려는 정보를 받으면") { val response = userService.signUp(user, request) @@ -32,14 +32,6 @@ class UserServiceTest : BehaviorSpec({ response.nickName shouldBe modifieUser.nickName } } - - When("수정하려는 회원을 찾을 수 없으면") { - Then("예외가 발생한다.") { - shouldThrow { - userService.signUp(invalidUser, request) - } - } - } } Given("닉네임 중복 체크 시") { diff --git a/domain/src/main/kotlin/com/pokit/category/exception/CategoryErrorCode.kt b/domain/src/main/kotlin/com/pokit/category/exception/CategoryErrorCode.kt index eb1ab8e8..d201fc27 100644 --- a/domain/src/main/kotlin/com/pokit/category/exception/CategoryErrorCode.kt +++ b/domain/src/main/kotlin/com/pokit/category/exception/CategoryErrorCode.kt @@ -2,13 +2,14 @@ package com.pokit.category.exception import com.pokit.common.exception.ErrorCode -enum class CategoryErrorCode ( +enum class CategoryErrorCode( override val message: String, override val code: String, -): ErrorCode { +) : ErrorCode { ALREADY_EXISTS_CATEGORY("사용 중인 포킷명입니다.", "C_001"), NOT_FOUND_CATEGORY("포킷 정보를 찾을 수 없습니다.", "C_002"), UNAVAILABLE_CATEGORY_NAME("사용할 수 없는 포킷명입니다.", "C_003"), NOT_FOUND_CATEGORY_IMAGE("포킷 이미지 정보를 찾을 수 없습니다.", "C_004"), - MAX_CATEGORY_LIMIT_EXCEEDED("최대 30개의 포킷을 생성할 수 있습니다. 포킷을 삭제한 뒤에 추가해주세요.", "C_005") + MAX_CATEGORY_LIMIT_EXCEEDED("최대 30개의 포킷을 생성할 수 있습니다. 포킷을 삭제한 뒤에 추가해주세요.", "C_005"), + NOT_FOUND_UNCATEGORIZED_IMAGE("미분류 카테고리 이미지를 찾는데 실패했습니다.", "C_006") } diff --git a/domain/src/main/kotlin/com/pokit/token/model/Token.kt b/domain/src/main/kotlin/com/pokit/token/model/Token.kt index d619797c..d3adcb83 100644 --- a/domain/src/main/kotlin/com/pokit/token/model/Token.kt +++ b/domain/src/main/kotlin/com/pokit/token/model/Token.kt @@ -3,4 +3,5 @@ package com.pokit.token.model data class Token( val accessToken: String, val refreshToken: String, + val isRegistered: Boolean = false ) diff --git a/domain/src/main/kotlin/com/pokit/user/exception/UserErrorCode.kt b/domain/src/main/kotlin/com/pokit/user/exception/UserErrorCode.kt index 1293f25f..8693f114 100644 --- a/domain/src/main/kotlin/com/pokit/user/exception/UserErrorCode.kt +++ b/domain/src/main/kotlin/com/pokit/user/exception/UserErrorCode.kt @@ -9,5 +9,6 @@ enum class UserErrorCode( INVALID_EMAIL("올바르지 않은 이메일 형식의 유저입니다.", "U_001"), INVALID_INTEREST_TYPE("관심사가 잘못되었습니다.", "U_002"), NOT_FOUND_USER("존재하지 않는 회원입니다.", "U_003"), - ALREADY_EXISTS_NICKNAME("이미 존재하는 닉네임입니다.", "U_004") + ALREADY_EXISTS_NICKNAME("이미 존재하는 닉네임입니다.", "U_004"), + ALREADY_REGISTERED("이미 회원가입 한 유저입니다.", "U_005") } diff --git a/domain/src/main/kotlin/com/pokit/user/model/User.kt b/domain/src/main/kotlin/com/pokit/user/model/User.kt index b2ed32ca..27fe5fb4 100644 --- a/domain/src/main/kotlin/com/pokit/user/model/User.kt +++ b/domain/src/main/kotlin/com/pokit/user/model/User.kt @@ -10,9 +10,15 @@ data class User( val email: String, val role: Role, var nickName: String = email, - val authPlatform: AuthPlatform + val authPlatform: AuthPlatform, + var registered: Boolean = false ) { - fun modifyUser(nickName: String) { + fun register(nickName: String) { + this.nickName = nickName + this.registered = true + } + + fun modifyNickname(nickName: String) { this.nickName = nickName }