Skip to content

Commit

Permalink
feat: GET /users/me (#91)
Browse files Browse the repository at this point in the history
* feat: get user me

* feat: get user me via jwt

* refactor: coding style
  • Loading branch information
lohas1107 authored Jun 25, 2023
1 parent 33a4006 commit 2bb0fa5
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ import javax.inject.Named
class GetUserUseCase(
private val userRepository: UserRepository,
) {
fun execute(id: User.Id): User =
userRepository.findById(id) ?: throw notFound(User::class).id(id)
fun execute(request: Request, presenter: Presenter) {
with(request) {
val user = userRepository.findByEmail(email)
?: throw notFound(User::class).identifyBy("email", email)
presenter.present(user)
}
}

class Request(val email: String)

interface Presenter {
fun present(user: User)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class OAuth2Controller(
}
}

fun Jwt.toRequest(): CreateUserUseCase.Request =
private fun Jwt.toRequest(): CreateUserUseCase.Request =
CreateUserUseCase.Request(
email = claims["email"] as String? ?: throw PlatformException("JWT email should exist."),
identityProviderId = subject ?: throw PlatformException("JWT subject should exist.")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
package tw.waterballsa.gaas.spring.controllers

import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.security.oauth2.jwt.Jwt
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import tw.waterballsa.gaas.application.usecases.GetUserUseCase
import tw.waterballsa.gaas.domain.User
import tw.waterballsa.gaas.spring.controllers.presenter.GetUserPresenter
import tw.waterballsa.gaas.spring.controllers.viewmodel.GetUserViewModel

@RestController
@RequestMapping("/users")
class UserController(
private val getUserUseCase: GetUserUseCase
) {
@GetMapping("/users/{id}")
fun getUser(@PathVariable id: String): User = getUserUseCase.execute(User.Id(id))
@GetMapping("/me")
fun getUser(@AuthenticationPrincipal principal: Jwt): GetUserViewModel {
val request = principal.toRequest()
val presenter = GetUserPresenter()
getUserUseCase.execute(request, presenter)
return presenter.viewModel
}
}

private fun Jwt.toRequest(): GetUserUseCase.Request =
GetUserUseCase.Request(claims["email"] as String)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package tw.waterballsa.gaas.spring.controllers.presenter

import tw.waterballsa.gaas.application.usecases.GetUserUseCase
import tw.waterballsa.gaas.domain.User
import tw.waterballsa.gaas.spring.controllers.viewmodel.GetUserViewModel

class GetUserPresenter : GetUserUseCase.Presenter {
lateinit var viewModel: GetUserViewModel

override fun present(user: User) {
viewModel = user.toViewModel()
}

private fun User.toViewModel(): GetUserViewModel =
GetUserViewModel(
id = id!!.value,
email = email,
nickname = nickname,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tw.waterballsa.gaas.spring.controllers.viewmodel

data class GetUserViewModel(
val id: String,
val email: String,
val nickname: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package tw.waterballsa.gaas.spring.it.controllers
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.test.web.servlet.ResultActions
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
Expand All @@ -12,8 +11,6 @@ import tw.waterballsa.gaas.application.repositories.UserRepository
import tw.waterballsa.gaas.domain.User
import tw.waterballsa.gaas.spring.it.AbstractSpringBootTest


@AutoConfigureMockMvc(addFilters = false)
class UserControllerTest @Autowired constructor(
val userRepository: UserRepository,
) : AbstractSpringBootTest() {
Expand All @@ -24,28 +21,35 @@ class UserControllerTest @Autowired constructor(
}

@Test
fun givenUserCreated_whenGetUser_thenGetUserSuccessfully() {
val user = User(User.Id("1"), "[email protected]", "winner5566")
givenUserCreated(user)
findUserById("1").thenGetUserSuccessfully(user)
fun givenUserHasLoggedIn_whenGetUserSelf_thenGetUserSuccessfully() {
givenUserHasLoggedIn()
.whenGetUserSelf()
.thenGetUserSuccessfully()
}

@Test
fun givenUserNotCreated_whenGetUser_thenUserNotFound() {
findUserById("0").thenUserNotFound()
fun givenUserDoesNotLogIn_whenGetUserSelf_thenUserNotFound() {
givenUserDoesNotLogIn()
.whenGetUserSelf()
.thenUserNotFound()
}

private fun givenUserCreated(user: User) {
userRepository.createUser(user)
private fun givenUserDoesNotLogIn(): User = this.mockUser

private fun givenUserHasLoggedIn(): User {
return userRepository.createUser(mockUser)
}

private fun findUserById(id: String): ResultActions = mockMvc.perform(get("/users/$id"))
private fun User.whenGetUserSelf(): ResultActions {
val jwt = identities.first().toJwt()
return mockMvc.perform(get("/users/me").withJwt(jwt))
}

private fun ResultActions.thenGetUserSuccessfully(user: User) {
private fun ResultActions.thenGetUserSuccessfully() {
this.andExpect(status().isOk)
.andExpect(jsonPath("$.id").value(user.id!!.value))
.andExpect(jsonPath("$.email").value(user.email))
.andExpect(jsonPath("$.nickname").value(user.nickname))
.andExpect(jsonPath("$.id").value(mockUser.id!!.value))
.andExpect(jsonPath("$.email").value(mockUser.email))
.andExpect(jsonPath("$.nickname").value(mockUser.nickname))
}

private fun ResultActions.thenUserNotFound() {
Expand Down

0 comments on commit 2bb0fa5

Please sign in to comment.