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.mainModule import be.vandewalleh.migrations.Migration 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.Kodein import org.kodein.di.generic.bind import org.kodein.di.generic.instance import org.kodein.di.generic.singleton import utils.KMariadbContainer import javax.sql.DataSource @TestInstance(TestInstance.Lifecycle.PER_CLASS) class NoteServiceTest { @Nested inner class DB { private val mariadb = KMariadbContainer().apply { start() } private val kodein = Kodein { import(mainModule, allowOverride = true) bind(overrides = true) with singleton { mariadb.datasource() } } init { val migration by kodein.instance() migration.migrate() } @Test fun run() { val userService by kodein.instance() val user = runBlocking { userService.create("test", "test")!! } val noteService by kodein.instance() 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() val user = runBlocking { userService.create("test", "test")!! } val user2 = runBlocking { userService.create("user2", "test")!! } val noteService by kodein.instance() 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() val userService by kodein.instance() 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 { 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 = ValidatorBuilder() .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": "c6d80-5fe6-4a30-b034-da63f6663c2c"}""") println(note.uuid) println(note.uuid::class.qualifiedName) println(note.uuid.leastSignificantBits) println(note.uuid.mostSignificantBits) } } }