Skip to content

Commit

Permalink
[Feat/#155] 아티클 아이디로 문제 조회하는 API 구현 (#157)
Browse files Browse the repository at this point in the history
* feat: BrowseProblemsUseCase 구현

* feat: browseProblemsUseCase 컨트롤러에 반영
  • Loading branch information
belljun3395 authored Jul 8, 2024
1 parent 17ee380 commit 72bda63
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.few.api.domain.problem.usecase

import com.few.api.domain.problem.usecase.`in`.BrowseProblemsUseCaseIn
import com.few.api.domain.problem.usecase.out.BrowseProblemsUseCaseOut
import com.few.api.repo.dao.problem.ProblemDao
import com.few.api.repo.dao.problem.query.SelectProblemsByArticleIdQuery
import org.springframework.stereotype.Component

@Component
class BrowseProblemsUseCase(
private val problemDao: ProblemDao
) {

fun execute(useCaseIn: BrowseProblemsUseCaseIn): BrowseProblemsUseCaseOut {
SelectProblemsByArticleIdQuery(useCaseIn.articleId).let { query: SelectProblemsByArticleIdQuery ->
problemDao.selectProblemsByArticleId(query) ?: throw IllegalArgumentException("cannot find problems by articleId: ${query.articleId}") // todo 에러 표준화
}.let {
return BrowseProblemsUseCaseOut(it.problemIds)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.few.api.domain.problem.usecase.`in`

data class BrowseProblemsUseCaseIn(
val articleId: Long
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.few.api.domain.problem.usecase.out

data class BrowseProblemsUseCaseOut(
val problemIds: List<Long>
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.few.api.web.controller.problem

import com.few.api.domain.problem.usecase.BrowseProblemsUseCase
import com.few.api.web.controller.problem.request.CheckProblemBody
import com.few.api.web.controller.problem.response.CheckProblemResponse
import com.few.api.web.controller.problem.response.ProblemContents
Expand All @@ -8,8 +9,10 @@ import com.few.api.web.support.ApiResponse
import com.few.api.web.support.ApiResponseGenerator
import com.few.api.domain.problem.usecase.CheckProblemUseCase
import com.few.api.domain.problem.usecase.ReadProblemUseCase
import com.few.api.domain.problem.usecase.`in`.BrowseProblemsUseCaseIn
import com.few.api.domain.problem.usecase.`in`.CheckProblemUseCaseIn
import com.few.api.domain.problem.usecase.`in`.ReadProblemUseCaseIn
import com.few.api.web.controller.problem.response.BrowseProblemsResponse
import jakarta.validation.Valid
import jakarta.validation.constraints.Min
import org.springframework.http.HttpStatus
Expand All @@ -22,10 +25,26 @@ import java.util.*
@RestController
@RequestMapping(value = ["/api/v1/problems"], produces = [MediaType.APPLICATION_JSON_VALUE])
class ProblemController(
private val browseProblemsUseCase: BrowseProblemsUseCase,
private val readProblemUseCase: ReadProblemUseCase,
private val checkProblemUseCase: CheckProblemUseCase
) {

@GetMapping
fun browseProblems(@RequestParam(value = "articleId", required = false) articleId: Long?): ApiResponse<ApiResponse.SuccessBody<BrowseProblemsResponse>> {
articleId?.let { id ->
val useCaseOut = BrowseProblemsUseCaseIn(id).let { useCaseIn ->
browseProblemsUseCase.execute(useCaseIn)
}

val response = BrowseProblemsResponse(useCaseOut.problemIds)

return ApiResponseGenerator.success(response, HttpStatus.OK)
}

throw IllegalArgumentException("Invalid parameter")
}

@GetMapping("/{problemId}")
fun readProblem(
@PathVariable(value = "problemId")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.few.api.web.controller.problem.response

data class BrowseProblemsResponse(
val problemIds: List<Long>
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import com.epages.restdocs.apispec.ResourceDocumentation.parameterWithName
import com.epages.restdocs.apispec.ResourceSnippetParameters
import com.epages.restdocs.apispec.Schema
import com.fasterxml.jackson.databind.ObjectMapper
import com.few.api.domain.problem.usecase.BrowseProblemsUseCase
import com.few.api.web.controller.ControllerTestSpec
import com.few.api.web.controller.description.Description
import com.few.api.web.controller.helper.*
import com.few.api.web.controller.problem.request.CheckProblemBody
import com.few.api.domain.problem.usecase.CheckProblemUseCase
import com.few.api.domain.problem.usecase.ReadProblemUseCase
import com.few.api.domain.problem.usecase.`in`.BrowseProblemsUseCaseIn
import com.few.api.domain.problem.usecase.`in`.CheckProblemUseCaseIn
import com.few.api.domain.problem.usecase.`in`.ReadProblemUseCaseIn
import com.few.api.domain.problem.usecase.out.BrowseProblemsUseCaseOut
import com.few.api.domain.problem.usecase.out.CheckProblemUseCaseOut
import com.few.api.domain.problem.usecase.out.ReadProblemContentsUseCaseOutDetail
import com.few.api.domain.problem.usecase.out.ReadProblemUseCaseOut
Expand Down Expand Up @@ -40,6 +43,9 @@ class ProblemControllerTest : ControllerTestSpec() {
@Autowired
private lateinit var problemController: ProblemController

@MockBean
private lateinit var browseProblemsUseCase: BrowseProblemsUseCase

@MockBean
private lateinit var readProblemUseCase: ReadProblemUseCase

Expand All @@ -61,6 +67,57 @@ class ProblemControllerTest : ControllerTestSpec() {
.build()
}

@Test
@DisplayName("[GET] /api/v1/problems?articleId=")
fun browseProblems() {
// given
val api = "BrowseProblems"
val articleId = 1L
val uri = UriComponentsBuilder.newInstance()
.path(BASE_URL)
.queryParam("articleId", articleId)
.build()
.toUriString()

val useCaseIn = BrowseProblemsUseCaseIn(articleId)
val useCaseOut = BrowseProblemsUseCaseOut(listOf(1L, 2L, 3L))
`when`(browseProblemsUseCase.execute(useCaseIn))
.thenReturn(useCaseOut)

// when
this.webTestClient.get()
.uri(uri)
.accept(MediaType.APPLICATION_JSON)
.exchange().expectStatus().isOk()
.expectBody().consumeWith(
WebTestClientRestDocumentation.document(
api.toIdentifier(),
ResourceDocumentation.resource(
ResourceSnippetParameters.builder()
.description("아티클 Id로 문제 목록 조회")
.summary(api.toIdentifier())
.privateResource(false)
.deprecated(false)
.tag(TAG)
.requestSchema(Schema.schema(api.toRequestSchema()))
.queryParameters(parameterWithName("articleId").description("아티클 Id").optional())
.responseSchema(Schema.schema(api.toResponseSchema()))
.responseFields(
*Description.describe(
arrayOf(
PayloadDocumentation.fieldWithPath("data")
.fieldWithObject("data"),
PayloadDocumentation.fieldWithPath("data.problemIds[]")
.fieldWithArray("문제 Id 목록")
)
)
)
.build()
)
)
)
}

@Test
@DisplayName("[GET] /api/v1/problems/{problemId}")
fun readProblem() {
Expand Down

0 comments on commit 72bda63

Please sign in to comment.