Skip to content

Commit

Permalink
Merge pull request #32 from Route-Box/feature/#31
Browse files Browse the repository at this point in the history
유저 프로필 정보 조회 API 구현
  • Loading branch information
Wo-ogie authored Aug 8, 2024
2 parents a2bdf51 + f22f659 commit 195222e
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package com.routebox.routebox.application.user

import com.routebox.routebox.application.user.dto.GetMyProfileResult
import com.routebox.routebox.application.user.dto.GetUserProfileResult
import com.routebox.routebox.domain.user.UserService
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional

@Component
class GetMyProfileUseCase(private val userService: UserService) {
class GetUserProfileUseCase(private val userService: UserService) {

@Transactional(readOnly = true)
operator fun invoke(userId: Long): GetMyProfileResult {
operator fun invoke(userId: Long): GetUserProfileResult {
val user = userService.getUserById(userId)
return GetMyProfileResult.from(user)
return GetUserProfileResult.from(user)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.routebox.routebox.domain.user.constant.Gender
import io.swagger.v3.oas.annotations.media.Schema
import java.time.LocalDate

data class GetMyProfileResult(
data class GetUserProfileResult(
@Schema(description = "Id(PK) of user", example = "1")
val id: Long,

Expand All @@ -25,7 +25,7 @@ data class GetMyProfileResult(
val introduction: String,
) {
companion object {
fun from(user: User) = GetMyProfileResult(
fun from(user: User) = GetUserProfileResult(
id = user.id,
profileImageUrl = user.profileImageUrl,
nickname = user.nickname,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.routebox.routebox.controller.user

import com.routebox.routebox.application.user.CheckNicknameAvailabilityUseCase
import com.routebox.routebox.application.user.GetMyProfileUseCase
import com.routebox.routebox.application.user.GetUserProfileUseCase
import com.routebox.routebox.application.user.UpdateUserInfoUseCase
import com.routebox.routebox.application.user.dto.UpdateUserInfoCommand
import com.routebox.routebox.controller.user.dto.CheckNicknameAvailabilityResponse
Expand Down Expand Up @@ -32,18 +32,19 @@ import org.springframework.web.bind.annotation.RestController
@Validated
@RequestMapping("/api")
class UserController(
private val getMyProfileUseCase: GetMyProfileUseCase,
private val getUserProfileUseCase: GetUserProfileUseCase,
private val checkNicknameAvailabilityUseCase: CheckNicknameAvailabilityUseCase,
private val updateUserInfoUseCase: UpdateUserInfoUseCase,
) {
@Operation(
summary = "내 프로필 정보 조회",
description = "<p><strong>내 루트 개수, 취향 정보 등 추가 예정 (미구현)</strong>" +
"<p>내 프로필 정보를 조회합니다.",
security = [SecurityRequirement(name = "access-token")],
)
@GetMapping("/v1/users/me/profile")
fun getMyProfile(@AuthenticationPrincipal principal: UserPrincipal): UserProfileResponse {
val myProfile = getMyProfileUseCase(userId = principal.userId)
val myProfile = getUserProfileUseCase(userId = principal.userId)
return UserProfileResponse(
id = myProfile.id,
profileImageUrl = myProfile.profileImageUrl,
Expand All @@ -54,6 +55,27 @@ class UserController(
)
}

@Operation(
summary = "유저 프로필 정보 조회",
description = "<p><strong>유저가 작성한 루트 개수, 취향 정보 등 추가 예정 (미구현)</strong>" +
"<p>특정 유저의 프로필 정보를 조회합니다.",
security = [SecurityRequirement(name = "access-token")],
)
@GetMapping("/v1/users/{userId}/profile")
fun getUserProfile(
@Parameter(description = "프로필 정보를 조회할 유저의 id", example = "5") @PathVariable userId: Long,
): UserProfileResponse {
val userProfile = getUserProfileUseCase(userId)
return UserProfileResponse(
id = userProfile.id,
profileImageUrl = userProfile.profileImageUrl,
nickname = userProfile.nickname,
gender = userProfile.gender,
birthDay = userProfile.birthDay,
introduction = userProfile.introduction,
)
}

@Operation(
summary = "닉네임 이용 가능 여부 확인",
description = "닉네임의 이용 가능 여부를 확인합니다. 현재 사용중인 유저가 없다면 이용 가능한 닉네임입니다.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import kotlin.random.Random
import kotlin.test.Test

@ExtendWith(MockitoExtension::class)
class GetMyProfileUseCaseTest {
class GetUserProfileUseCaseTest {

@InjectMocks
lateinit var sut: GetMyProfileUseCase
lateinit var sut: GetUserProfileUseCase

@Mock
lateinit var userService: UserService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package com.routebox.routebox.controller.user

import com.fasterxml.jackson.databind.ObjectMapper
import com.routebox.routebox.application.user.CheckNicknameAvailabilityUseCase
import com.routebox.routebox.application.user.GetMyProfileUseCase
import com.routebox.routebox.application.user.GetUserProfileUseCase
import com.routebox.routebox.application.user.UpdateUserInfoUseCase
import com.routebox.routebox.application.user.dto.GetMyProfileResult
import com.routebox.routebox.application.user.dto.GetUserProfileResult
import com.routebox.routebox.application.user.dto.UpdateUserInfoCommand
import com.routebox.routebox.application.user.dto.UpdateUserInfoResult
import com.routebox.routebox.config.ControllerTestConfig
Expand Down Expand Up @@ -37,7 +37,7 @@ class UserControllerTest @Autowired constructor(
private val mapper: ObjectMapper,
) {
@MockBean
lateinit var getMyProfileUseCase: GetMyProfileUseCase
lateinit var getUserProfileUseCase: GetUserProfileUseCase

@MockBean
lateinit var updateUserInfoUseCase: UpdateUserInfoUseCase
Expand All @@ -49,15 +49,15 @@ class UserControllerTest @Autowired constructor(
fun `내 프로필 정보를 조회한다`() {
// given
val userId = Random.nextLong()
val expectedResult = GetMyProfileResult(
val expectedResult = GetUserProfileResult(
id = userId,
profileImageUrl = "https://user-profile-image",
nickname = RandomStringUtils.random(5),
gender = Gender.PRIVATE,
birthDay = LocalDate.of(2024, 1, 1),
introduction = "I am...",
)
given(getMyProfileUseCase.invoke(userId)).willReturn(expectedResult)
given(getUserProfileUseCase.invoke(userId)).willReturn(expectedResult)

// when & then
mvc.perform(
Expand All @@ -70,8 +70,37 @@ class UserControllerTest @Autowired constructor(
.andExpect(jsonPath("$.gender").value(expectedResult.gender.toString()))
.andExpect(jsonPath("$.birthDay").value(expectedResult.birthDay.toString()))
.andExpect(jsonPath("$.introduction").value(expectedResult.introduction))
then(getMyProfileUseCase).should().invoke(userId)
then(getMyProfileUseCase).shouldHaveNoMoreInteractions()
then(getUserProfileUseCase).should().invoke(userId)
then(getUserProfileUseCase).shouldHaveNoMoreInteractions()
}

@Test
fun `특정 유저의 id가 주어지고, 주어진 id에 해당하는 유저의 프로필 정보를 조회한다`() {
// given
val targetUserId = Random.nextLong()
val expectedResult = GetUserProfileResult(
id = targetUserId,
profileImageUrl = "https://user-profile-image",
nickname = RandomStringUtils.random(5),
gender = Gender.PRIVATE,
birthDay = LocalDate.of(2024, 1, 1),
introduction = "I am...",
)
given(getUserProfileUseCase.invoke(targetUserId)).willReturn(expectedResult)

// when & then
mvc.perform(
get("/api/v1/users/{userId}/profile", targetUserId)
.with(user(createUserPrincipal(Random.nextLong()))),
).andExpect(status().isOk)
.andExpect(jsonPath("$.id").value(expectedResult.id))
.andExpect(jsonPath("$.profileImageUrl").value(expectedResult.profileImageUrl))
.andExpect(jsonPath("$.nickname").value(expectedResult.nickname))
.andExpect(jsonPath("$.gender").value(expectedResult.gender.toString()))
.andExpect(jsonPath("$.birthDay").value(expectedResult.birthDay.toString()))
.andExpect(jsonPath("$.introduction").value(expectedResult.introduction))
then(getUserProfileUseCase).should().invoke(targetUserId)
then(getUserProfileUseCase).shouldHaveNoMoreInteractions()
}

@Test
Expand Down

0 comments on commit 195222e

Please sign in to comment.