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

fix: solve user update error #208

Merged
merged 22 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
47ab695
chore: TripleMeetingServiceTest commented
SangMinLeeAI Nov 22, 2024
2357180
fix: change update user information to upsert user information
SangMinLeeAI Nov 25, 2024
db8bfc5
chore: commented broken test
SangMinLeeAI Nov 25, 2024
4cd380e
feat: initialize repository test
SangMinLeeAI Nov 25, 2024
de6efa1
fix: remove gender update
SangMinLeeAI Nov 25, 2024
996d501
chore: format
SangMinLeeAI Nov 25, 2024
c601964
fix: change findUserProfile due to misfunction
SangMinLeeAI Nov 25, 2024
65580a1
fix: change update user information logic
SangMinLeeAI Nov 25, 2024
d7b405c
test: add user integration test
SangMinLeeAI Nov 25, 2024
afa3286
feat: move update user profile logic to user service
SangMinLeeAI Nov 25, 2024
34e81ad
test: add user domain test
SangMinLeeAI Nov 25, 2024
b24984e
Merge branch 'main' into fix/user-update
SangMinLeeAI Nov 25, 2024
ae8a8e9
chore: fix some missing value due to solving conflict
SangMinLeeAI Nov 25, 2024
fd7ba18
chore: add service injection
SangMinLeeAI Nov 25, 2024
e1141a0
chore: delete comment
SangMinLeeAI Nov 25, 2024
fc5293e
fix: delete h2 mode
SangMinLeeAI Nov 25, 2024
1dd7ef1
fix: add h2 option to avoid keyword
SangMinLeeAI Nov 25, 2024
07bc2d4
fix: change url in user api
SangMinLeeAI Nov 25, 2024
e2d903a
chore: move private function to end
SangMinLeeAI Nov 25, 2024
7415103
fix: delete making test-aplication.yml
SangMinLeeAI Nov 25, 2024
85ebdd5
feat: add swagger for UserApi
SangMinLeeAI Nov 25, 2024
7c18771
feat: change user creation logic
SangMinLeeAI Nov 25, 2024
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 @@ -2,7 +2,6 @@ package uoslife.servermeeting.user.command

import uoslife.servermeeting.user.entity.enums.AppearanceType
import uoslife.servermeeting.user.entity.enums.EyelidType
import uoslife.servermeeting.user.entity.enums.GenderType
import uoslife.servermeeting.user.entity.enums.SmokingType

class UserCommand {
Expand All @@ -24,7 +23,6 @@ class UserCommand {
val userId: Long,
val name: String?,
val phoneNumber: String?,
val gender: GenderType?,
val kakaoTalkId: String?,
)
}
32 changes: 2 additions & 30 deletions src/main/kotlin/uoslife/servermeeting/user/dao/UserDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import org.springframework.stereotype.Repository
import uoslife.servermeeting.payment.entity.Payment
import uoslife.servermeeting.payment.entity.QPayment.payment
import uoslife.servermeeting.payment.entity.enums.PaymentStatus
import uoslife.servermeeting.user.command.UserCommand
import uoslife.servermeeting.user.entity.QUser.user
import uoslife.servermeeting.user.entity.QUserInformation.userInformation
import uoslife.servermeeting.user.entity.User
Expand All @@ -27,36 +26,9 @@ class UserDao(
fun findUserProfile(userId: Long): User? {
return queryFactory
.selectFrom(user)
.join(userInformation)
.on(userInformation.user.eq(user))
.where(user.id.eq(userId))
.leftJoin(user.userInformation, userInformation)
.fetchJoin()
.where(user.id.eq(userId))
.fetchOne()
}

fun updateUserInformation(command: UserCommand.UpdateUserInformation): Long {

val jpaClause =
queryFactory.update(userInformation).where(userInformation.user.id.eq(command.userId))

command.smoking?.let { jpaClause.set(userInformation.smoking, it) }
command.mbti?.let { jpaClause.set(userInformation.mbti, it) }
command.interest?.let { jpaClause.set(userInformation.interest, it) }
command.height?.let { jpaClause.set(userInformation.height, it) }
command.age?.let { jpaClause.set(userInformation.age, it) }
command.studentNumber?.let { jpaClause.set(userInformation.studentNumber, it) }
command.department?.let { jpaClause.set(userInformation.department, it) }
command.eyelidType?.let { jpaClause.set(userInformation.eyelidType, it) }
command.appearanceType?.let { jpaClause.set(userInformation.appearanceType, it) }
return jpaClause.execute()
}

fun updateUserPersonalInformation(command: UserCommand.UpdateUserPersonalInformation): Long {
val jpaClause = queryFactory.update(user).where(user.id.eq(command.userId))
command.name?.let { jpaClause.set(user.name, it) }
command.phoneNumber?.let { jpaClause.set(user.phoneNumber, it) }
command.gender?.let { jpaClause.set(user.gender, it) }
command.kakaoTalkId?.let { jpaClause.set(user.kakaoTalkId, it) }
return jpaClause.execute()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ data class UserPersonalInformationUpdateRequest(
name = this.name,
phoneNumber = this.phoneNumber,
kakaoTalkId = this.kakaoTalkId,
gender = this.genderType,
)
}
}
46 changes: 42 additions & 4 deletions src/main/kotlin/uoslife/servermeeting/user/service/UserService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import uoslife.servermeeting.user.command.UserCommand
import uoslife.servermeeting.user.dao.UserDao
import uoslife.servermeeting.user.dto.response.UserBranchResponse
import uoslife.servermeeting.user.entity.User
import uoslife.servermeeting.user.entity.UserInformation
import uoslife.servermeeting.user.exception.KakaoTalkIdDuplicationException
import uoslife.servermeeting.user.exception.UserNotFoundException
import uoslife.servermeeting.user.repository.UserInformationRepository
import uoslife.servermeeting.user.repository.UserRepository

@Service
Expand All @@ -28,6 +30,7 @@ class UserService(
private val userRepository: UserRepository,
@Qualifier("portOneService") private val paymentService: PaymentService,
private val userTeamRepository: UserTeamRepository,
private val userInformationRepository: UserInformationRepository,
private val userDao: UserDao,
private val userTeamDao: UserTeamDao,
private val validator: Validator,
Expand Down Expand Up @@ -58,17 +61,17 @@ class UserService(
@Transactional
fun updateUserInformation(command: UserCommand.UpdateUserInformation): User {
command.mbti = validator.setValidMBTI(command.mbti)
val updated: Long = userDao.updateUserInformation(command)
return userDao.findUserProfile(command.userId) ?: throw UserNotFoundException()
val user = userRepository.findByIdOrNull(command.userId) ?: throw UserNotFoundException()
return upsertUserInformation(user, command)
}

@Transactional
fun updateUserPersonalInformation(command: UserCommand.UpdateUserPersonalInformation): User {
if (command.kakaoTalkId != null) {
isDuplicatedKakaoTalkId(command.kakaoTalkId)
}
val updateUserPersonalInformation = userDao.updateUserPersonalInformation(command)
return userRepository.findByIdOrNull(command.userId) ?: throw UserNotFoundException()
val user = userRepository.findByIdOrNull(command.userId) ?: throw UserNotFoundException()
return updateUserProfile(user, command)
}

/**
Expand Down Expand Up @@ -113,6 +116,41 @@ class UserService(
return true
}

private fun upsertUserInformation(
user: User,
command: UserCommand.UpdateUserInformation
): User {
val existingUserInfo =
Copy link
Contributor

Choose a reason for hiding this comment

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

์ด๊ฑฐ ๋งค๋ฒˆ ์ฒดํฌํ•˜๊ธฐ๋ณด๋‹ค, ์ด๋ฉ”์ผ๋กœ ์œ ์ € ์ƒ์„ฑํ• ๋•Œ, ๋นˆ ๊ฐ’์œผ๋กœ ๋™์‹œ์— ๋งŒ๋“ค๊ณ 
๋‚˜์ค‘์— user.userinformation ?: throw exception ์ด์šฉํ•˜๋Š” ๊ฒŒ ์–ด๋–ค๊ฐ€์š”?
๋” ํšจ์œจ์ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค

Copy link
Contributor Author

Choose a reason for hiding this comment

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

์ˆ˜์ •ํ–ˆ์Šด๋‹ค

if (user.userInformation == null) {
user.userInformation = userInformationRepository.save(UserInformation(user = user))
user.userInformation
} else {
user.userInformation
}

existingUserInfo?.smoking = command.smoking ?: existingUserInfo?.smoking
existingUserInfo?.mbti = command.mbti ?: existingUserInfo?.mbti
existingUserInfo?.interest = command.interest ?: existingUserInfo?.interest
existingUserInfo?.height = command.height ?: existingUserInfo?.height
existingUserInfo?.age = command.age ?: existingUserInfo?.age
existingUserInfo?.studentNumber = command.studentNumber ?: existingUserInfo?.studentNumber
existingUserInfo?.department = command.department ?: existingUserInfo?.department
existingUserInfo?.eyelidType = command.eyelidType ?: existingUserInfo?.eyelidType
existingUserInfo?.appearanceType =
command.appearanceType ?: existingUserInfo?.appearanceType
return user
}

private fun updateUserProfile(
user: User,
command: UserCommand.UpdateUserPersonalInformation
): User {
user.name = command.name ?: user.name
user.phoneNumber = command.phoneNumber ?: user.phoneNumber
user.kakaoTalkId = command.kakaoTalkId ?: user.kakaoTalkId
return user
}

fun getUserMeetingTeamBranch(userId: Long): UserBranchResponse {
val user = userRepository.findByIdOrNull(userId) ?: throw UserNotFoundException()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package uoslife.servermeeting.domain.user.service

import com.querydsl.jpa.impl.JPAQueryFactory
import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.extensions.spring.SpringExtension
import io.kotest.matchers.shouldBe
import io.mockk.mockk
import jakarta.persistence.EntityManager
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.test.annotation.Rollback
import uoslife.servermeeting.meetingteam.dao.UserTeamDao
import uoslife.servermeeting.meetingteam.repository.UserTeamRepository
import uoslife.servermeeting.meetingteam.service.BaseMeetingService
import uoslife.servermeeting.meetingteam.util.Validator
import uoslife.servermeeting.payment.service.PaymentService
import uoslife.servermeeting.user.command.UserCommand
import uoslife.servermeeting.user.dao.UserDao
import uoslife.servermeeting.user.entity.User
import uoslife.servermeeting.user.entity.enums.AppearanceType
import uoslife.servermeeting.user.entity.enums.EyelidType
import uoslife.servermeeting.user.entity.enums.SmokingType
import uoslife.servermeeting.user.repository.UserInformationRepository
import uoslife.servermeeting.user.repository.UserRepository
import uoslife.servermeeting.user.service.UserService

@DataJpaTest(showSql = true)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Rollback(true)
internal class UserIntegrationTest
@Autowired
constructor(
private val userRepository: UserRepository,
private val userTeamRepository: UserTeamRepository,
private val userInformationRepository: UserInformationRepository,
private val entityManager: EntityManager
) : BehaviorSpec() {

override fun extensions() = listOf(SpringExtension)
init {
val jpaQueryFactory = JPAQueryFactory(entityManager)
val userDao = UserDao(jpaQueryFactory)
val paymentService = mockk<PaymentService>()
val userTeamDao = mockk<UserTeamDao>()
val meetingService = mockk<BaseMeetingService>()
val userService =
UserService(
userRepository = userRepository,
userInformationRepository = userInformationRepository,
paymentService = paymentService,
userTeamRepository = userTeamRepository,
userDao = userDao,
validator = Validator(),
userTeamDao = userTeamDao,
singleMeetingService = meetingService,
tripleMeetingService = meetingService
)

given("์œ ์ €๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์„๋•Œ") {
val savedUser = userRepository.saveAllAndFlush(users)

`when`("์œ ์ € info ์—…๋ฐ์ดํŠธ ์ •๋ณด ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด") {
then("์—…๋ฐ์ดํŠธ๋ฅผ ํ•œ๋‹ค") {
val firstUser = userService.updateUserInformation(initUserInformationCommand)
entityManager.flush()

firstUser.userInformation?.mbti shouldBe "INTJ"
firstUser.userInformation?.interest shouldBe listOf("์šด๋™", "๋…์„œ")
firstUser.userInformation?.height shouldBe 180
firstUser.userInformation?.age shouldBe 25
firstUser.userInformation?.studentNumber shouldBe 2020830018
firstUser.userInformation?.department shouldBe "์ปดํ“จํ„ฐ๊ณตํ•™๊ณผ"
firstUser.userInformation?.eyelidType shouldBe EyelidType.DOUBLE
firstUser.userInformation?.appearanceType shouldBe AppearanceType.ARAB
}
}
`when`("์œ ์ € ํ”„๋กœํŒŒ์ผ ์—…๋ฐ์ดํŠธ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด") {
then("์—…๋ฐ์ดํŠธ๋ฅผ ํ•œ๋‹ค") {
val firstUser =
userService.updateUserPersonalInformation(initUserProfileCommand)
entityManager.flush()

firstUser.name shouldBe "์„์šฐ์ง„"
firstUser.phoneNumber shouldBe "010-1234-5678"
firstUser.kakaoTalkId shouldBe "seok"
}
}
`when`("์œ ์ € ์ •๋ณด๊ฐ€ ์ด๋ฏธ ์žˆ์„๋•Œ") {
userService.updateUserPersonalInformation(initUserProfileCommand)
userService.updateUserInformation(initUserInformationCommand)

then("userInformation์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค") {
val firstUser =
userService.updateUserInformation(updateUserPersonalInformationCommand)
entityManager.flush()

firstUser.userInformation?.smoking shouldBe SmokingType.E_CIGARETTE
firstUser.userInformation?.mbti shouldBe "ENTP"
firstUser.userInformation?.interest shouldBe listOf("์ˆ˜์˜", "์ฝ”๋”ฉ")
firstUser.userInformation?.height shouldBe 185
firstUser.userInformation?.age shouldBe 23
firstUser.userInformation?.studentNumber shouldBe 2023830018
firstUser.userInformation?.department shouldBe "์ „์ž์ „๊ธฐ์ปดํ“จํ„ฐ๊ณตํ•™๋ถ€"
firstUser.userInformation?.eyelidType shouldBe EyelidType.SINGLE
firstUser.userInformation?.appearanceType shouldBe AppearanceType.TOFU
}
then("userProfile์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค") {
val firstUser =
userService.updateUserPersonalInformation(initUserProfileCommand)
entityManager.flush()

firstUser.name shouldBe "์„์šฐ์ง„"
firstUser.phoneNumber shouldBe "010-1234-5678"
firstUser.kakaoTalkId shouldBe "seok"
}
}
}
}

companion object {
private val users =
listOf(
User(name = "์„์šฐ์ง„", email = "[email protected]"),
User(name = "์ตœ๋™์ค€", email = "[email protected]"),
)
private val initUserInformationCommand =
UserCommand.UpdateUserInformation(
userId = 1L,
smoking = SmokingType.FALSE,
mbti = "INTJ",
interest = listOf("์šด๋™", "๋…์„œ"),
height = 180,
age = 25,
studentNumber = 2020830018,
department = "์ปดํ“จํ„ฐ๊ณตํ•™๊ณผ",
eyelidType = EyelidType.DOUBLE,
appearanceType = AppearanceType.ARAB,
)
private val initUserProfileCommand =
UserCommand.UpdateUserPersonalInformation(
userId = 1L,
name = "์„์šฐ์ง„",
phoneNumber = "010-1234-5678",
kakaoTalkId = "seok"
)
private val updateUserPersonalInformationCommand =
UserCommand.UpdateUserInformation(
userId = 1L,
smoking = SmokingType.E_CIGARETTE,
mbti = "ENTP",
interest = listOf("์ˆ˜์˜", "์ฝ”๋”ฉ"),
height = 185,
age = 23,
studentNumber = 2023830018,
department = "์ „์ž์ „๊ธฐ์ปดํ“จํ„ฐ๊ณตํ•™๋ถ€",
eyelidType = EyelidType.SINGLE,
appearanceType = AppearanceType.TOFU,
)
private val updateUserProfileCommand =
UserCommand.UpdateUserPersonalInformation(
userId = 1L,
name = "์„์šฐ์ง„",
phoneNumber = "010-9006-8420",
kakaoTalkId = "seok"
)
}
}
Loading
Loading