SimpleNotes/api/test/integration/services/NoteServiceTest.kt

228 lines
7.5 KiB
Kotlin

package integration.services
import am.ik.yavi.builder.ValidatorBuilder
import am.ik.yavi.core.CustomConstraint
import am.ik.yavi.core.Validator
import be.vandewalleh.entities.Note
import be.vandewalleh.features.Migration
import be.vandewalleh.mainModule
import be.vandewalleh.services.NoteService
import be.vandewalleh.services.UserService
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.util.StdDateFormat
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.readValue
import com.github.javafaker.Faker
import kotlinx.coroutines.runBlocking
import me.liuwj.ktorm.jackson.*
import org.amshove.kluent.*
import org.junit.jupiter.api.*
import org.kodein.di.DI
import org.kodein.di.bind
import org.kodein.di.instance
import org.kodein.di.singleton
import utils.KMariadbContainer
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class NoteServiceTest {
@Nested
inner class DB {
private val mariadb = KMariadbContainer().apply { start() }
private val kodein = DI {
import(mainModule, allowOverride = true)
bind(overrides = true) from singleton { mariadb.datasource() }
}
init {
val migration by kodein.instance<Migration>()
migration.migrate()
}
@Test
fun run() {
val userService by kodein.instance<UserService>()
val user = runBlocking { userService.create("test", "test")!! }
val noteService by kodein.instance<NoteService>()
val note = runBlocking {
noteService.create(user.id, Note {
this.title = "a note"
this.content = """# Title
|
|😝😝😝😝
|another line
""".trimMargin()
this.tags = listOf("a", "tag")
})
}
println(note)
val objectMapper = ObjectMapper().apply {
registerModule(JavaTimeModule())
registerModule(KtormModule())
disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT)
dateFormat = StdDateFormat()
}
val json = objectMapper.writeValueAsString(note)
println(json)
}
@Test
fun `test tag list`() {
val userService by kodein.instance<UserService>()
val user = runBlocking { userService.create("test", "test")!! }
val user2 = runBlocking { userService.create("user2", "test")!! }
val noteService by kodein.instance<NoteService>()
runBlocking {
noteService.create(user.id, Note {
title = "test"
content = ""
tags = listOf("same")
})
noteService.create(user.id, Note {
title = "test2"
content = ""
tags = listOf("same")
})
noteService.create(user.id, Note {
title = "test3"
content = ""
tags = listOf("another")
})
noteService.create(user2.id, Note {
title = "test"
content = ""
tags = listOf("user2")
})
}
val user1Tags = runBlocking { noteService.getTags(user.id) }
user1Tags `should be equal to` listOf("same", "another")
val user2Tags = runBlocking { noteService.getTags(user2.id) }
user2Tags `should be equal to` listOf("user2")
}
@Test
fun `test patch note`() {
val noteService by kodein.instance<NoteService>()
val userService by kodein.instance<UserService>()
val user = runBlocking { userService.create(Faker().name().username(), "test") }!!
val note = runBlocking {
noteService.create(user.id, Note {
this.title = "title"
this.content = "old content"
this.tags = emptyList()
})
}
val get = runBlocking { noteService.find(user.id, note.uuid) }
runBlocking {
noteService.updateNote(user.id, Note {
uuid = note.uuid
title = "new title"
})
}
val updated = runBlocking { noteService.find(user.id, note.uuid) }
println("updated: $updated")
}
}
@Nested
inner class NoteValidation {
@Test
fun `test update constraints`() {
val fieldPresentConstraint = object : CustomConstraint<Note> {
override fun defaultMessageFormat() = "fmt {0} {1} {2}"
override fun messageKey() = "title|content|tags"
override fun test(note: Note): Boolean {
val hasTitle = note["title"] != null
val hasContent = note["content"] != null
val hasTags = note["tags"] != null && note.tags.isNotEmpty()
return hasTitle || hasContent || hasTags
}
}
val userValidator: Validator<Note> = ValidatorBuilder<Note>()
.constraintOnTarget(fieldPresentConstraint, "present")
.build()
userValidator.validate(Note {
title = "this is a title"
}).isValid `should be equal to` true
userValidator.validate(Note {
content = "this is a title"
}).isValid `should be equal to` true
userValidator.validate(Note {
tags = emptyList()
}).isValid `should be equal to` false
userValidator.validate(Note {
tags = listOf("tags")
}).isValid `should be equal to` true
userValidator.validate(Note {
tags = listOf("tags")
title = "This is a title"
}).isValid `should be equal to` true
userValidator.validate(Note {
tags = listOf("tags")
title = "This is a title"
content = """
# This is
some markdown content
""".trimIndent()
}).isValid `should be equal to` true
userValidator.validate(Note {
tags = listOf("tags")
title = "This is a title"
content = """
# This is
some markdown content
""".trimIndent()
}).isValid `should be equal to` true
userValidator.validate(Note()).isValid `should be equal to` false
}
}
@Nested
inner class NoteEntity {
@Test
fun `test entity`() {
val objectMapper = ObjectMapper().apply {
registerModule(JavaTimeModule())
registerModule(KtormModule())
disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT)
dateFormat = StdDateFormat()
}
val note: Note = objectMapper.readValue("""{"uuid": "2007e4d7-2986-4188-bde1-b99916d94bad"}""")
println(note.uuid)
println(note.uuid::class.qualifiedName)
println(note.uuid.leastSignificantBits)
println(note.uuid.mostSignificantBits)
}
}
}