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

refactor(apply): refactor controller #570

Closed

Conversation

summerlunaa
Copy link
Contributor

@summerlunaa summerlunaa commented Jul 16, 2022

close: #561

  • create api reponse 수정 (create시에 Location header에 id 를 넣어준다.)
    • 추가로 응답 body에 생성된 객체를 담아주도록 수정
  • id로 조회하는 api 추가
    • cheater
    • mission
    • term
  • TermController에 @LoginUser 추가

@dongho108 dongho108 added 기능 New feature or request 리팩터링 Refactor code labels Jul 16, 2022
Copy link
Contributor

@kth990303 kth990303 left a comment

Choose a reason for hiding this comment

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

역시 코틀린 마스터들이 코드를 작성하니 뛰어난 결과물이 나오네요.
슬랙에서 얘기나왔던 부분들 관련해서 코멘트 남겼습니다!
해당 컨벤션 부분 외에는 모두 괜찮아서 approve 할게요~

Comment on lines 32 to 35
val assignmentId = assignmentService.create(missionId, user.id, request)
return ResponseEntity
.created(URI.create("/api/recruitments/$recruitmentId/missions/$missionId/assignments/$assignmentId"))
.build()
Copy link
Contributor

Choose a reason for hiding this comment

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

슬랙에서 스레드로 얘기했을 때 body로 id를 담아서 객체로 넘겨주는 것으로 결론이 난 것 같은데, 이슈는 반대로 돼있긴 하네요. 이 부분은 확정이 안난 거 맞을까요?

@@ -17,14 +17,15 @@ class AssignmentService(
private val missionRepository: MissionRepository,
private val evaluationTargetRepository: EvaluationTargetRepository
) {
fun create(missionId: Long, userId: Long, request: AssignmentRequest) {
fun create(missionId: Long, userId: Long, request: AssignmentRequest): Long {
Copy link
Contributor

Choose a reason for hiding this comment

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

다른 서비스에선 save라는 메서드명으로 돼있는데, 이 서비스 클래스에서만 생성 쪽 메서드명이 create로 돼있긴 해요. 크게 상관없을 듯하지만, 혹시나 해서 남겨봅니다!

@@ -24,8 +25,8 @@ class MailHistoryRestController(
@LoginUser(administrator = true) user: User
): ResponseEntity<Unit> {
Copy link
Contributor

Choose a reason for hiding this comment

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

이 부분도 아직 확정안된 것 같긴 한데 코멘트는 남겨볼게요! 슬랙에서 controller 생성 api에 savecreate 중에 create로 결론이 난 것 같아요. 이슈엔 별도의 언급이 없긴 하지만 혹시나 해서 남겨봅니다!

@@ -40,7 +39,13 @@ internal class AssignmentRestControllerTest : RestControllerTest() {
content = objectMapper.writeValueAsString(createAssignmentRequest())
header(HttpHeaders.AUTHORIZATION, "Bearer valid_token")
}.andExpect {
status { isOk }
status { isCreated }
Copy link
Contributor

Choose a reason for hiding this comment

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

status code를 좀 더 올바르게 바꿔주셨군요 👍

Comment on lines +61 to +67
val cheater = Cheater(email = cheatedUser.email, id = cheatedUser.id)
every { cheaterService.getById(cheater.id) } answers { cheater }

mockMvc.perform(
RestDocumentationRequestBuilders.get(
"/api/cheaters/{cheaterId}", cheater.id
)
Copy link
Contributor

Choose a reason for hiding this comment

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

id를 반환하는 로직, 조회 로직을 추가해줌으로써 테스트가 용이해지네요! 😄
덕분에 코드 짜기에도 편할 것 같아요.

summerlunaa and others added 20 commits July 19, 2022 22:16
@summerlunaa summerlunaa force-pushed the refactor/controller branch from 9a863f3 to f171257 Compare July 19, 2022 13:16
Copy link
Contributor

@asebn1 asebn1 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다! id와 객체를 같이 전달받으니 controller테스트에서 값을 검증하기 더 용이해진 것 같네요 👍

@@ -31,6 +33,7 @@ internal class CheaterServiceTest {
val cheaterData = createCheaterData()
every { cheaterRepository.existsByEmail(any()) } returns false
every { cheaterRepository.save(any()) } returns Cheater(cheaterData.email, cheaterData.description)
every { userRepository.findByEmail(any()) } returns createUser()
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 👍

Comment on lines +47 to +51
status { isCreated }
header {
string(
HttpHeaders.LOCATION,
"/api/recruitments/$recruitmentId/missions/$missionId/assignments/${assignmentData.id}"
Copy link
Contributor

Choose a reason for hiding this comment

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

잘 바꿔주셨네요 😀

Comment on lines 80 to 94
fun `부정행위자를 추가한다`() {
val cheaterData = createCheaterData()
every { cheaterService.save(cheaterData) } just Runs
val cheaterResponse = CheaterResponse(Cheater(cheaterData.email, cheaterData.description), createUser())

every { cheaterService.save(cheaterData) } returns cheaterResponse

mockMvc.post("/api/cheaters") {
header(HttpHeaders.AUTHORIZATION, "Bearer valid_token")
contentType = MediaType.APPLICATION_JSON
content = objectMapper.writeValueAsString(cheaterData)
content = objectMapper.writeValueAsString(cheaterResponse)
}.andExpect {
status { isOk }
status { isCreated }
header { string(HttpHeaders.LOCATION, "/api/cheaters/${cheaterResponse.id}") }
content { json(objectMapper.writeValueAsString(ApiResponse.success(cheaterResponse))) }
}
Copy link
Contributor

Choose a reason for hiding this comment

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

추가적인 검증이 적용돼서 테스트가 더 명확해진 것 같아요!

Copy link
Contributor

@jojogreen91 jojogreen91 left a comment

Choose a reason for hiding this comment

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

고생한게 보이네요 파랑, 애쉬!
간단하게 리뷰 남겨봤습니다 수고하셧습니다! :)

@@ -34,6 +34,8 @@ class EvaluationService(
EvaluationItem(it.title, it.description, it.maximumScore, it.position, evaluation.id, it.id)
}
)
request.id = evaluation.id
return request
Copy link
Contributor

Choose a reason for hiding this comment

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

매개변수로 받은 request 에 저장하면서 생긴 evaluation.id 를 set 해주고 반환하는데 혹시 헷갈릴 수도 있지않을까요?

다른 서비스 클래스에서 save 메서드를 고쳤을 때는 새로운 data 객체를 생성했는데 이것만 안그런거 같아서 다시한번 보게 되네요!

import org.springframework.data.repository.findByIdOrNull

fun CheaterRepository.getById(id: Long): Cheater = findByIdOrNull(id)
?: throw NoSuchElementException("부정행위자가 존재하지 않습니다. id: $id")
Copy link
Contributor

Choose a reason for hiding this comment

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

리소스가 존재하지 않는 예외를 repository 에서 발생시키도록 구현했네요!
저도 이렇게 하는게 좋은것 같습니다! :)

}

@GetMapping
fun findAll(): ResponseEntity<ApiResponse<List<TermResponse>>> {
fun findAll(
@LoginUser(administrator = true) user: User
Copy link
Contributor

Choose a reason for hiding this comment

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

@LoginUser Argument Resolver 에 관리자인지 아닌지를 판단하는 로직이 아직 구현되어 있지 않네요!

그냥 일반 유저가 접근하는걸 방지하는 용도로 사용되고 있는거죠?!

Copy link
Contributor

Choose a reason for hiding this comment

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

저도 확인해보니 아직은 LoginFailedException() 만 터뜨리는 것 같네요 👀

@woowahan-pjs woowahan-pjs removed 기능 New feature or request 리팩터링 Refactor code labels Jul 25, 2022
Copy link
Contributor

@kbsat kbsat left a comment

Choose a reason for hiding this comment

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

애쉬, 파랑 고생하셨어요! 👍

}

@GetMapping
fun findAll(): ResponseEntity<ApiResponse<List<TermResponse>>> {
fun findAll(
@LoginUser(administrator = true) user: User
Copy link
Contributor

Choose a reason for hiding this comment

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

저도 확인해보니 아직은 LoginFailedException() 만 터뜨리는 것 같네요 👀

@Test
fun `부정행위자 id로 부정행위자를 조회한다`() {
val cheater = Cheater(email = cheatedUser.email, id = cheatedUser.id)
every { cheaterService.getById(cheater.id) } answers { cheater }
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
every { cheaterService.getById(cheater.id) } answers { cheater }
every { cheaterService.getById(cheater.id) } returns cheater

굳이 answers로 람다를 리턴하지 않아도 될 것 같아요! 👍
https://notwoods.github.io/mockk-guidebook/docs/mocking/answers/

@Test
fun `기수 id로 기수를 조회한다`() {
val term = Term("1기", 1L)
every { termService.getById(term.id) } answers { term }
Copy link
Contributor

Choose a reason for hiding this comment

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

여기도 마찬가지로 answers 보다는 returns가 맞아보여요~!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants