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

test: create recruitment fixture #588

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ dependencies {
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.2")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.2")
runtimeOnly("mysql:mysql-connector-java")
runtimeOnly("com.h2database:h2")
runtimeOnly("com.h2database:h2:2.1.214")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
exclude(group = "org.mockito")
}
testImplementation("com.ninja-squad:springmockk:2.0.3")
asciidoctorExt("org.springframework.restdocs:spring-restdocs-asciidoctor")
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
asciidoctorExt("org.springframework.restdocs:spring-restdocs-asciidoctor")
testImplementation("com.ninja-squad:springmockk:2.0.3")
testImplementation("io.kotest:kotest-runner-junit5:5.4.2")
testImplementation("io.kotest.extensions:kotest-extensions-spring:1.1.2")
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/apply/config/Databases.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class H2(
entityManager: EntityManager,
properties: DatabaseInitializationProperties
) : AbstractDatabase(entityManager, properties) {
override val metaTablesSql: String = "show tables"
override val metaTablesSql: String =
"select table_name from information_schema.tables where table_schema = 'PUBLIC'"
override val constraintsOffSql: String = "set referential_integrity false"
override val constraintsOnSql: String = "set referential_integrity true"
override fun createTruncateTableSql(tableName: String): String = "truncate table $tableName restart identity"
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/apply/domain/user/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import javax.persistence.AttributeOverride
import javax.persistence.Column
import javax.persistence.Embedded
import javax.persistence.Entity
import javax.persistence.Table

@Table(name = "users")
@Entity
class User(
@Embedded
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/application-test.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
spring.datasource.url=jdbc:h2:~/test;MODE=MYSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.autoconfigure.exclude=com.vaadin.flow.spring.SpringBootAutoConfiguration

spring.datasource.url=jdbc:h2:~/apply;MODE=MYSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.format_sql=true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alter table user rename users;
72 changes: 72 additions & 0 deletions src/test/kotlin/apply/acceptance/AcceptanceDsl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package apply.acceptance

import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.test.web.reactive.server.WebTestClient
import java.time.LocalDateTime

private val now: LocalDateTime = LocalDateTime.now()

data class Recruitment(
var title: String = "웹 백엔드 4기",
var term: Term? = null,
var termId: Long = 0L,
var startDateTime: LocalDateTime = now.minusYears(1),
var endDateTime: LocalDateTime = now.plusYears(1),
var recruitable: Boolean = false,
var hidden: Boolean = true,
var recruitmentItems: List<RecruitmentItem> = emptyList(),
var id: Long = 0L
)

data class RecruitmentItem(
var title: String = "프로그래밍 학습 과정과 현재 자신이 생각하는 역량은?",
var position: Int = 1,
var maximumLength: Int = 1000,
var description: String = "현재 어느 정도의 역량을 보유한 상태인지를 구체적으로 작성해 주세요.",
var id: Long = 0L
)

class RecruitmentItems {
val items: MutableList<RecruitmentItem> = mutableListOf()

fun recruitmentItem(block: RecruitmentItem.() -> Unit = {}) {
items.add(RecruitmentItem().apply(block))
}
}

fun recruitmentItems(block: RecruitmentItems.() -> Unit): List<RecruitmentItem> {
return RecruitmentItems().apply(block).items
}

fun WebTestClient.recruitment(block: Recruitment.() -> Unit = {}): Recruitment {
val recruitment = Recruitment().apply(block)
if (recruitment.term == null) {
recruitment.term = Term(id = recruitment.termId)
}
post().uri("/api/recruitments")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(recruitment)
.exchange()
.expectStatus().isCreated
.expectHeader().value(HttpHeaders.LOCATION) { recruitment.id = it.extractId() }
return recruitment
}

data class Term(
var name: String = "4기",
var id: Long = 0L
)

fun WebTestClient.term(block: Term.() -> Unit = {}): Term {
val term = Term().apply(block)
post().uri("/api/terms")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(term)
.exchange()
.expectStatus().isCreated
.expectHeader().value(HttpHeaders.LOCATION) { term.id = it.extractId() }
return term
}

private fun String.extractId(): Long = substringAfterLast("/").toLong()
55 changes: 55 additions & 0 deletions src/test/kotlin/apply/acceptance/AcceptanceDslTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package apply.acceptance

import io.kotest.matchers.collections.shouldNotContainDuplicates
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import support.createLocalDateTime

class AcceptanceDslTest : AcceptanceTest() {
init {
Given("기수 생성 예시") {
When("기수를 생성하면") {
val term1 = term()
val term2 = term {
name = "5기"
}

Then("기수가 생성된다") {
term1.id shouldNotBe term2.id
term2.name shouldBe "5기"
}
}
}

Given("모집 생성 예시") {
When("모집을 생성하면") {
val recruitment1 = recruitment()
val recruitment2 = recruitment {
termId = 0L
}
val recruitment3 = recruitment {
title = "웹 백엔드 5기"
term = term {
name = "5기"
}
startDateTime = createLocalDateTime(2022, 10, 17)
endDateTime = createLocalDateTime(2022, 10, 24)
recruitmentItems = recruitmentItems {
recruitmentItem {
title = "프로그래밍 학습 과정과 현재 자신이 생각하는 역량은?"
position = 1
}
recruitmentItem {
title = "프로그래머가 되려는 이유는 무엇인가요?"
position = 2
}
}
}

Then("모집이 생성된다") {
listOf(recruitment1.id, recruitment2.id, recruitment3.id).shouldNotContainDuplicates()
}
}
}
}
}
50 changes: 50 additions & 0 deletions src/test/kotlin/apply/acceptance/AcceptanceTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package apply.acceptance

import apply.config.Database
import apply.createUser
import apply.security.LoginUserResolver
import com.ninjasquad.springmockk.SpykBean
import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.extensions.spring.SpringTestExtension
import io.kotest.extensions.spring.SpringTestLifecycleMode
import io.mockk.every
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.reactive.server.WebTestClient
import support.test.TestEnvironment
import support.test.spec.afterRootTest
import support.test.spec.beforeRootTest

@SpykBean(LoginUserResolver::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestEnvironment
abstract class AcceptanceTest : BehaviorSpec() {
@Autowired
lateinit var client: WebTestClient

@Autowired
private lateinit var database: Database

@Autowired
private lateinit var loginUserResolver: LoginUserResolver

init {
extensions(SpringTestExtension(SpringTestLifecycleMode.Root))

beforeRootTest {
every { loginUserResolver.resolveArgument(any(), any(), any(), any()) } returns createUser()
}

afterRootTest {
database.clear(database.retrieveTables())
}
}

fun recruitment(block: Recruitment.() -> Unit = {}): Recruitment {
return client.recruitment(block)
}

fun term(block: Term.() -> Unit = {}): Term {
return client.term(block)
}
}
2 changes: 2 additions & 0 deletions src/test/kotlin/support/test/BaseTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package support.test

import io.mockk.junit5.MockKExtension
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ActiveProfiles
Expand All @@ -20,6 +21,7 @@ annotation class UnitTest

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@DataJpaTest
@TestEnvironment
annotation class RepositoryTest
Expand Down