Skip to content

Commit 037564f

Browse files
authored
온보딩 테스트 조회 API를 구현한다. (#74)
1 parent 231e848 commit 037564f

File tree

26 files changed

+196
-65
lines changed

26 files changed

+196
-65
lines changed

api/src/main/kotlin/com/gotchai/api/global/config/SecurityConfig.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,11 @@ class SecurityConfig {
3737
}
3838
authorizeHttpRequests {
3939
it
40-
.requestMatchers(HttpMethod.GET, "/ping")
41-
.permitAll()
40+
.requestMatchers(
41+
HttpMethod.GET,
42+
"/ping",
43+
"/api/v1/onboarding/**"
44+
).permitAll()
4245
.requestMatchers(
4346
HttpMethod.POST,
4447
"/api/v1/auth/login/**",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.gotchai.api.presentation.v1.onboarding
2+
3+
import com.gotchai.api.global.annotation.ApiV1Controller
4+
import com.gotchai.api.presentation.v1.exam.response.ExamResponse
5+
import com.gotchai.domain.onboarding.port.`in`.OnboardingQueryUseCase
6+
import org.springframework.web.bind.annotation.GetMapping
7+
8+
@ApiV1Controller
9+
class OnboardingController(
10+
private val onboardingQueryUseCase: OnboardingQueryUseCase
11+
) {
12+
@GetMapping("/onboarding/exams")
13+
fun getOnboardingExam(): ExamResponse =
14+
onboardingQueryUseCase
15+
.getOnboardingExam()
16+
.let { ExamResponse.from(it) }
17+
}

api/src/test/kotlin/com/gotchai/api/presentation/v1/exam/ExamControllerTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import com.gotchai.api.presentation.v1.exam.response.GetExamParticipantCountResp
1313
import com.gotchai.api.util.document
1414
import com.gotchai.api.util.expectError
1515
import com.gotchai.api.util.paramDesc
16+
import com.gotchai.domain.exam.exception.ExamNotFoundException
1617
import com.gotchai.domain.exam.port.`in`.ExamQueryUseCase
1718
import com.gotchai.domain.fixture.ID
1819
import com.gotchai.domain.fixture.createExam
1920
import com.gotchai.domain.fixture.createGetExamResult
20-
import com.gotchai.domain.global.exception.NotFoundDataException
2121
import com.ninjasquad.springmockk.MockkBean
2222
import io.mockk.every
2323
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
@@ -97,7 +97,7 @@ class ExamControllerTest : ControllerTest() {
9797
}
9898

9999
context("조회하려는 테스트가 존재하지 않는 경우") {
100-
every { examQueryUseCase.getExamById(any()) } throws NotFoundDataException()
100+
every { examQueryUseCase.getExamById(any()) } throws ExamNotFoundException()
101101

102102
it("상태 코드 404와 ErrorResponse를 반환한다.") {
103103
webClient
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.gotchai.api.presentation.v1.onboarding
2+
3+
import com.gotchai.api.common.ControllerTest
4+
import com.gotchai.api.docs.errorResponseFields
5+
import com.gotchai.api.docs.examResponseFields
6+
import com.gotchai.api.global.dto.ApiResponse
7+
import com.gotchai.api.presentation.v1.exam.response.ExamResponse
8+
import com.gotchai.api.util.document
9+
import com.gotchai.api.util.expectError
10+
import com.gotchai.domain.exam.entity.ExamType
11+
import com.gotchai.domain.exam.exception.ExamNotFoundException
12+
import com.gotchai.domain.fixture.createExam
13+
import com.gotchai.domain.onboarding.port.`in`.OnboardingQueryUseCase
14+
import com.ninjasquad.springmockk.MockkBean
15+
import io.mockk.every
16+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
17+
import org.springframework.test.web.reactive.server.expectBody
18+
19+
@WebMvcTest(OnboardingController::class)
20+
class OnboardingControllerTest : ControllerTest() {
21+
@MockkBean
22+
private lateinit var onboardingQueryUseCase: OnboardingQueryUseCase
23+
24+
init {
25+
describe("getOnboardingExam()은") {
26+
context("온보딩 테스트가 존재하는 경우") {
27+
every { onboardingQueryUseCase.getOnboardingExam() } returns createExam(type = ExamType.ONBOARDING)
28+
29+
it("상태 코드 200과 ExamResponse를 반환한다.") {
30+
webClient
31+
.get()
32+
.uri("/api/v1/onboarding/exams")
33+
.exchange()
34+
.expectStatus()
35+
.isOk
36+
.expectBody<ApiResponse<ExamResponse>>()
37+
.document("온보딩 테스트 조회 성공(200)") {
38+
responseBody(examResponseFields)
39+
}
40+
}
41+
}
42+
43+
context("온보딩 테스트가 존재하지 않는 경우") {
44+
every { onboardingQueryUseCase.getOnboardingExam() } throws ExamNotFoundException()
45+
46+
it("상태 코드 404와 ErrorResponse를 반환한다.") {
47+
webClient
48+
.get()
49+
.uri("/api/v1/onboarding/exams")
50+
.exchange()
51+
.expectStatus()
52+
.isNotFound
53+
.expectError()
54+
.document("온보딩 테스트 조회 실패(404)") {
55+
responseBody(errorResponseFields)
56+
}
57+
}
58+
}
59+
}
60+
}
61+
}

api/src/testFixtures/kotlin/com/gotchai/api/common/ControllerTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.gotchai.api.common
22

3-
import com.gotchai.api.config.SecurityTestConfig
43
import com.gotchai.domain.fixture.createUser
54
import com.gotchai.domain.global.security.GotchaiAuthentication
65
import io.kotest.core.extensions.Extension
@@ -12,13 +11,13 @@ import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDoc
1211
import org.springframework.restdocs.RestDocumentationContextProvider
1312
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation
1413
import org.springframework.security.core.context.SecurityContextHolder
14+
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf
1515
import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity
16-
import org.springframework.test.context.ContextConfiguration
1716
import org.springframework.test.web.servlet.client.MockMvcWebTestClient
17+
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
1818
import org.springframework.web.context.WebApplicationContext
1919

2020
@AutoConfigureRestDocs
21-
@ContextConfiguration(classes = [SecurityTestConfig::class])
2221
abstract class ControllerTest : DescribeSpec() {
2322
override fun extensions(): List<Extension> = listOf(SpringExtension)
2423

@@ -36,6 +35,7 @@ abstract class ControllerTest : DescribeSpec() {
3635
MockMvcWebTestClient
3736
.bindToApplicationContext(webApplicationContext)
3837
.apply(springSecurity())
38+
.defaultRequest(post("/**").with(csrf()))
3939
.configureClient()
4040
.filter(WebTestClientRestDocumentation.documentationConfiguration(restDocumentationContextProvider))
4141
.build()

api/src/testFixtures/kotlin/com/gotchai/api/config/SecurityTestConfig.kt

Lines changed: 0 additions & 16 deletions
This file was deleted.

api/src/testFixtures/kotlin/com/gotchai/api/docs/BadgeDocs.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ val badgeResponseFields =
1919

2020
val getMyBadgeListResponseFields =
2121
listFieldsOf(
22-
description = "뱃지 리스트",
22+
"list" bodyDesc "뱃지 리스트",
2323
GetMyBadgeResponse::id bodyDesc "식별자",
2424
GetMyBadgeResponse::examId bodyDesc "테스트 식별자",
2525
GetMyBadgeResponse::name bodyDesc "이름",

api/src/testFixtures/kotlin/com/gotchai/api/docs/ExamDocs.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ import com.gotchai.api.util.bodyDesc
77
import com.gotchai.api.util.fieldsOf
88
import com.gotchai.api.util.listFieldsOf
99

10-
val examListResponseFields =
11-
listFieldsOf(
12-
description = "테스트 리스트",
10+
val examResponseFields =
11+
fieldsOf(
1312
ExamResponse::id bodyDesc "식별자",
1413
ExamResponse::title bodyDesc "제목",
1514
ExamResponse::subTitle bodyDesc "부제목",
@@ -21,6 +20,12 @@ val examListResponseFields =
2120
ExamResponse::createdAt bodyDesc "생성 날짜"
2221
)
2322

23+
val examListResponseFields =
24+
listFieldsOf(
25+
"list" bodyDesc "테스트 리스트",
26+
*examResponseFields.toTypedArray()
27+
)
28+
2429
val examDetailResponseFields =
2530
fieldsOf(
2631
ExamDetailResponse::id bodyDesc "식별자",

api/src/testFixtures/kotlin/com/gotchai/api/docs/QuizDocs.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@ import com.gotchai.api.presentation.v1.quiz.request.GradeQuizRequest
44
import com.gotchai.api.presentation.v1.quiz.response.GradeQuizResponse
55
import com.gotchai.api.presentation.v1.quiz.response.QuizDetailResponse
66
import com.gotchai.api.presentation.v1.quiz.response.QuizPickResponse
7-
import com.gotchai.api.util.arrayFieldsOf
87
import com.gotchai.api.util.bodyDesc
98
import com.gotchai.api.util.fieldsOf
9+
import com.gotchai.api.util.listFieldsOf
1010

1111
val quizDetailResponseFields =
1212
fieldsOf(
1313
QuizDetailResponse::id bodyDesc "퀴즈 식별자",
1414
QuizDetailResponse::contents bodyDesc "퀴즈 내용",
1515
QuizDetailResponse::createdAt bodyDesc "생성 날짜"
1616
) +
17-
arrayFieldsOf(
18-
"quizPicks",
19-
"퀴즈 선택지 목록",
17+
listFieldsOf(
18+
"quizPicks" bodyDesc "퀴즈 선택지 목록",
2019
QuizPickResponse::id bodyDesc "선택지 식별자",
2120
QuizPickResponse::contents bodyDesc "선택지 내용"
2221
)

api/src/testFixtures/kotlin/com/gotchai/api/fixture/ExamFixture.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import com.gotchai.api.presentation.v1.exam.response.GetExamParticipantCountResp
44

55
const val PARTICIPANT_COUNT = 1
66

7-
fun createExamGetParticipantCount(participantCount: Int = PARTICIPANT_COUNT): GetExamParticipantCountResponse =
7+
fun createExamGetParticipantCountResponse(participantCount: Int = PARTICIPANT_COUNT): GetExamParticipantCountResponse =
88
GetExamParticipantCountResponse(participantCount = participantCount)

0 commit comments

Comments
 (0)