Skip to content

Commit 980be9b

Browse files
authored
test : 문제 통합테스트 추가 (#124)
test : 문제 통합테스트 추가
1 parent e887d6d commit 980be9b

11 files changed

+380
-76
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ src/main/resources/static/
4949

5050
## test ##
5151
spy.log
52+
src/test/resources/*.sql

src/main/kotlin/io/csbroker/apiserver/service/problem/LongProblemServiceImpl.kt

+9
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ class LongProblemServiceImpl(
159159
val tags = problem.problemTags.map {
160160
it.tag.name
161161
}
162+
163+
val gradingHistory = GradingHistory(
164+
problem = problem,
165+
user = user,
166+
userAnswer = answer,
167+
score = 0.0,
168+
)
169+
gradingHistoryRepository.save(gradingHistory)
170+
162171
val gradingHistories = problem.gradingHistory
163172
val totalSubmissionCount = gradingHistories.size
164173
val userSubmissionCount = gradingHistories.count { it.user.id == user.id }

src/test/kotlin/io/csbroker/apiserver/controller/IntegrationTest.kt

+31-15
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import io.csbroker.apiserver.auth.ProviderType
77
import io.csbroker.apiserver.common.enums.Role
88
import io.csbroker.apiserver.model.User
99
import org.intellij.lang.annotations.Language
10+
import org.junit.jupiter.api.BeforeEach
1011
import org.springframework.beans.factory.annotation.Autowired
1112
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
1213
import org.springframework.boot.test.context.SpringBootTest
@@ -39,6 +40,35 @@ class IntegrationTest {
3940
@Autowired
4041
private lateinit var authTokenProvider: AuthTokenProvider
4142

43+
protected lateinit var defaultUser: User
44+
protected lateinit var adminUser: User
45+
private val userEmail = "[email protected]"
46+
private val adminEmail = "[email protected]"
47+
48+
@BeforeEach
49+
fun setUp() {
50+
defaultUser = getOrCreateUser(userEmail)
51+
adminUser = getOrCreateUser(adminEmail)
52+
}
53+
54+
fun getOrCreateUser(email: String): User =
55+
try {
56+
findOne("SELECT u FROM User u where u.email = '$email'")
57+
} catch (e: Exception) {
58+
saveUser(email, email == adminEmail)
59+
}
60+
61+
fun saveUser(email: String, isAdmin: Boolean): User =
62+
save(
63+
User(
64+
email = email,
65+
username = email.split("@")[0],
66+
password = "test",
67+
role = if (isAdmin) Role.ROLE_ADMIN else Role.ROLE_USER,
68+
providerType = ProviderType.LOCAL,
69+
),
70+
)
71+
4272
fun request(
4373
method: HttpMethod,
4474
url: String,
@@ -117,21 +147,7 @@ class IntegrationTest {
117147
}
118148

119149
private fun createToken(isAdmin: Boolean): String {
120-
val email = if (isAdmin) "[email protected]" else "[email protected]"
121-
val users = findAll<User>("SELECT u FROM User u where u.email = '$email'")
122-
val user = if (users.isNotEmpty()) {
123-
users.first()
124-
} else {
125-
save(
126-
User(
127-
email = email,
128-
username = "test",
129-
password = "test",
130-
role = if (isAdmin) Role.ROLE_ADMIN else Role.ROLE_USER,
131-
providerType = ProviderType.LOCAL,
132-
),
133-
)
134-
}
150+
val user = getOrCreateUser(if (isAdmin) adminEmail else userEmail)
135151

136152
return authTokenProvider.createAuthToken(
137153
user.email,

src/test/kotlin/io/csbroker/apiserver/controller/v1/admin/AdminControllerIntegrationTest.kt

+5-15
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,13 @@ class AdminControllerIntegrationTest : IntegrationTest() {
3535

3636
@Test
3737
fun `단일 알림 생성`() {
38-
// given
39-
val user = save(
40-
User(
41-
email = "[email protected]",
42-
username = "test-noti",
43-
password = "test-noti",
44-
providerType = ProviderType.LOCAL,
45-
),
46-
)
47-
4838
// when
4939
val response = request(
5040
method = HttpMethod.POST,
5141
url = "/api/admin/notification",
5242
body = NotificationRequestDto(
5343
content = "test",
54-
userId = user.id!!,
44+
userId = defaultUser.id!!,
5545
link = "https://test.com",
5646
),
5747
isAdmin = true,
@@ -67,7 +57,7 @@ class AdminControllerIntegrationTest : IntegrationTest() {
6757
)
6858
notification.content shouldBe "test"
6959
notification.link shouldBe "https://test.com"
70-
notification.user.id shouldBe user.id
60+
notification.user.id shouldBe defaultUser.id
7161
}
7262
}
7363

@@ -76,9 +66,9 @@ class AdminControllerIntegrationTest : IntegrationTest() {
7666
// given
7767
val user = save(
7868
User(
79-
email = "test-noti2@test.com",
80-
username = "test-noti2",
81-
password = "test-noti2",
69+
email = "manyNotiCreator@test.com",
70+
username = "manyNotiCreator",
71+
password = "test",
8272
providerType = ProviderType.LOCAL,
8373
),
8474
)

src/test/kotlin/io/csbroker/apiserver/controller/v1/admin/problem/AdminProblemControllerIntegrationTest.kt

+3-21
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package io.csbroker.apiserver.controller.v1.admin.problem
22

3-
import io.csbroker.apiserver.auth.ProviderType
43
import io.csbroker.apiserver.controller.IntegrationTest
54
import io.csbroker.apiserver.dto.problem.ProblemDeleteRequestDto
65
import io.csbroker.apiserver.model.LongProblem
76
import io.csbroker.apiserver.model.Problem
8-
import io.csbroker.apiserver.model.User
97
import io.kotest.matchers.shouldBe
108
import org.junit.jupiter.api.Test
119
import org.springframework.http.HttpMethod
@@ -15,19 +13,11 @@ class AdminProblemControllerIntegrationTest : IntegrationTest() {
1513
@Test
1614
fun `문제 단일 삭제`() {
1715
// given
18-
val user = save(
19-
User(
20-
email = "[email protected]",
21-
username = "test-problem1",
22-
password = "test-problem1",
23-
providerType = ProviderType.LOCAL,
24-
),
25-
)
2616
val problem = save(
2717
LongProblem(
2818
title = "문제 제목",
2919
description = "문제 설명",
30-
creator = user,
20+
creator = adminUser,
3121
),
3222
)
3323

@@ -49,26 +39,18 @@ class AdminProblemControllerIntegrationTest : IntegrationTest() {
4939
@Test
5040
fun `문제 여러개 삭제`() {
5141
// given
52-
val user = save(
53-
User(
54-
email = "[email protected]",
55-
username = "test-problem2",
56-
password = "test-problem2",
57-
providerType = ProviderType.LOCAL,
58-
),
59-
)
6042
val problem1 = save(
6143
LongProblem(
6244
title = "문제 제목",
6345
description = "문제 설명",
64-
creator = user,
46+
creator = adminUser,
6547
),
6648
)
6749
val problem2 = save(
6850
LongProblem(
6951
title = "문제 제목",
7052
description = "문제 설명",
71-
creator = user,
53+
creator = adminUser,
7254
),
7355
)
7456

src/test/kotlin/io/csbroker/apiserver/controller/v1/admin/problem/AdminProblemSetControllerIntegrationTest.kt

+6-24
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package io.csbroker.apiserver.controller.v1.admin.problem
22

33
import com.jayway.jsonpath.JsonPath
4-
import io.csbroker.apiserver.auth.ProviderType
5-
import io.csbroker.apiserver.common.enums.Role
64
import io.csbroker.apiserver.controller.IntegrationTest
75
import io.csbroker.apiserver.dto.problem.problemset.ProblemSetUpsertRequestDto
86
import io.csbroker.apiserver.model.LongProblem
97
import io.csbroker.apiserver.model.MultipleChoiceProblem
108
import io.csbroker.apiserver.model.ProblemSet
119
import io.csbroker.apiserver.model.ProblemSetMapping
1210
import io.csbroker.apiserver.model.ShortProblem
13-
import io.csbroker.apiserver.model.User
1411
import io.kotest.matchers.shouldBe
1512
import org.junit.jupiter.api.Test
1613
import org.springframework.http.HttpMethod
@@ -20,26 +17,18 @@ class AdminProblemSetControllerIntegrationTest : IntegrationTest() {
2017
@Test
2118
fun `문제 세트 생성`() {
2219
// given
23-
val user = save(
24-
User(
25-
email = "[email protected]",
26-
username = "problemCreator",
27-
role = Role.ROLE_ADMIN,
28-
providerType = ProviderType.LOCAL,
29-
),
30-
)
3120
val longProblem = save(
3221
LongProblem(
3322
title = "long problem",
3423
description = "long problem description",
35-
creator = user,
24+
creator = adminUser,
3625
),
3726
)
3827
val shortProblem = save(
3928
ShortProblem(
4029
title = "short problem",
4130
description = "short problem description",
42-
creator = user,
31+
creator = adminUser,
4332
score = 10.0,
4433
answer = "answer",
4534
),
@@ -69,26 +58,19 @@ class AdminProblemSetControllerIntegrationTest : IntegrationTest() {
6958
@Test
7059
fun `문제 세트 수정`() {
7160
// given
72-
val user = save(
73-
User(
74-
email = "[email protected]",
75-
username = "problemCreator2",
76-
role = Role.ROLE_ADMIN,
77-
providerType = ProviderType.LOCAL,
78-
),
79-
)
61+
8062
val longProblem = save(
8163
LongProblem(
8264
title = "long problem",
8365
description = "long problem description",
84-
creator = user,
66+
creator = adminUser,
8567
),
8668
)
8769
val shortProblem = save(
8870
ShortProblem(
8971
title = "short problem",
9072
description = "short problem description",
91-
creator = user,
73+
creator = adminUser,
9274
score = 10.0,
9375
answer = "answer",
9476
),
@@ -97,7 +79,7 @@ class AdminProblemSetControllerIntegrationTest : IntegrationTest() {
9779
MultipleChoiceProblem(
9880
title = "multiple choice problem",
9981
description = "multiple choice problem description",
100-
creator = user,
82+
creator = adminUser,
10183
score = 10.0,
10284
isMultiple = false,
10385
),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package io.csbroker.apiserver.controller.v1.problem
2+
3+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
4+
import com.fasterxml.jackson.module.kotlin.readValue
5+
import com.jayway.jsonpath.JsonPath
6+
import io.csbroker.apiserver.controller.IntegrationTest
7+
import io.csbroker.apiserver.controller.v2.problem.response.SubmitLongProblemResponseDto
8+
import io.csbroker.apiserver.dto.problem.longproblem.LongProblemAnswerDto
9+
import io.csbroker.apiserver.model.GradingHistory
10+
import io.csbroker.apiserver.model.LongProblem
11+
import io.csbroker.apiserver.model.StandardAnswer
12+
import io.kotest.matchers.collections.shouldContain
13+
import io.kotest.matchers.shouldBe
14+
import org.junit.jupiter.api.Test
15+
import org.springframework.http.HttpMethod
16+
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
17+
18+
class LongProblemIntegrationTest : IntegrationTest() {
19+
20+
private val baseUrl = "/api/v1/problems/long"
21+
private val objectMapper = jacksonObjectMapper()
22+
23+
@Test
24+
fun `서술형 문제 조회`() {
25+
// given & when
26+
27+
val problem = getProblem()
28+
val response = request(
29+
method = HttpMethod.GET,
30+
url = "$baseUrl/${problem.id}",
31+
)
32+
33+
// then
34+
response.andExpect(status().isOk)
35+
.andDo {
36+
val title = JsonPath.read(it.response.contentAsString, "$.data.title") as String
37+
val description = JsonPath.read(it.response.contentAsString, "$.data.description") as String
38+
title shouldBe problem.title
39+
description shouldBe problem.description
40+
}
41+
}
42+
43+
@Test
44+
fun `서술형 문제 제출`() {
45+
val problem = getProblem()
46+
47+
// given & when
48+
val preSubmissionCount = findAll<GradingHistory>(
49+
"SELECT gh From GradingHistory gh where gh.problem.id = :id",
50+
mapOf("id" to problem.id!!),
51+
).size
52+
53+
val preUserSubmissionCount = findAll<GradingHistory>(
54+
"SELECT gh From GradingHistory gh where gh.problem.id = :problemId AND gh.user.id = :userId",
55+
mapOf("problemId" to problem.id!!, "userId" to defaultUser.id!!),
56+
).size
57+
58+
val standardAnswers = findAll<StandardAnswer>(
59+
"SELECT sa From StandardAnswer sa where sa.longProblem.id = :id",
60+
mapOf("id" to problem.id!!),
61+
)
62+
63+
val userAnswer = "answer"
64+
val response = request(
65+
method = HttpMethod.POST,
66+
url = "$baseUrl/${problem.id}/submit",
67+
body = LongProblemAnswerDto(userAnswer),
68+
)
69+
70+
// userAnswer 생성 확인
71+
72+
response.andExpect(status().isOk)
73+
.andDo {
74+
val jsonNode = objectMapper.readTree(it.response.contentAsString)
75+
val dataNode = jsonNode.get("data")
76+
val dataAsString = dataNode.toString()
77+
val responseDto = objectMapper.readValue<SubmitLongProblemResponseDto>(dataAsString)
78+
responseDto.title shouldBe problem.title
79+
responseDto.description shouldBe problem.description
80+
responseDto.totalSubmissionCount shouldBe preSubmissionCount + 1 // 제출 수가 증가하는지 확인
81+
responseDto.userSubmissionCount shouldBe preUserSubmissionCount + 1 // 제출 수가 증가하는지 확인
82+
responseDto.userAnswer shouldBe userAnswer
83+
standardAnswers.map { sa -> sa.content } shouldContain responseDto.standardAnswer // 모법답안중 하나가 반환되는지 확인
84+
}
85+
}
86+
87+
fun getProblem(): LongProblem {
88+
val problem = save(
89+
LongProblem(
90+
title = "title",
91+
description = "description",
92+
creator = defaultUser,
93+
),
94+
)
95+
save(StandardAnswer(content = "standard answer1", longProblem = problem))
96+
save(StandardAnswer(content = "standard answer2", longProblem = problem))
97+
98+
return problem
99+
}
100+
}

0 commit comments

Comments
 (0)