Update ktorm, clean repositories and drop mariadb support

This commit is contained in:
2021-04-12 18:35:21 +02:00
parent a4bf998c5b
commit 204ae7988e
40 changed files with 473 additions and 1018 deletions
-22
View File
@@ -1,22 +0,0 @@
package be.simplenotes.persistence
import be.simplenotes.config.DataSourceConfig
import org.testcontainers.containers.MariaDBContainer
class KMariadbContainer : MariaDBContainer<KMariadbContainer>("mariadb:10.5.5")
fun h2dataSourceConfig() = DataSourceConfig(
jdbcUrl = "jdbc:h2:mem:regular;DB_CLOSE_DELAY=-1;",
username = "h2",
password = "",
maximumPoolSize = 2,
connectionTimeout = 3000
)
fun mariadbDataSourceConfig(jdbcUrl: String) = DataSourceConfig(
jdbcUrl = jdbcUrl,
username = "test",
password = "test",
maximumPoolSize = 2,
connectionTimeout = 3000
)
-37
View File
@@ -1,37 +0,0 @@
package be.simplenotes.persistence
import be.simplenotes.config.DataSourceConfig
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.parallel.ResourceLock
@ResourceLock("h2")
class H2DbHealthCheckImplTest : DbTest() {
override fun dataSourceConfig() = h2dataSourceConfig()
@Test
fun healthCheck() {
assertThat(beanContext.getBean<DbHealthCheck>().isOk()).isTrue
}
}
@Tag("slow")
@ResourceLock("mariadb")
class MariaDbHealthCheckImplTest : DbTest() {
lateinit var mariaDB: KMariadbContainer
override fun dataSourceConfig(): DataSourceConfig {
mariaDB = KMariadbContainer()
mariaDB.start()
return mariadbDataSourceConfig(mariaDB.jdbcUrl)
}
@Test
fun healthCheck() {
val healthCheck = beanContext.getBean<DbHealthCheck>()
assertThat(healthCheck.isOk()).isTrue
mariaDB.stop()
assertThat(healthCheck.isOk()).isFalse
}
}
+12 -5
View File
@@ -6,21 +6,28 @@ import org.flywaydb.core.Flyway
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.parallel.ResourceLock
import javax.sql.DataSource
@ResourceLock("h2")
abstract class DbTest {
abstract fun dataSourceConfig(): DataSourceConfig
val beanContext = BeanContext
.build()
val beanContext = BeanContext.build()
inline fun <reified T> BeanContext.getBean(): T = getBean(T::class.java)
@BeforeAll
fun setComponent() {
beanContext
.registerSingleton(dataSourceConfig())
.registerSingleton(
DataSourceConfig(
jdbcUrl = "jdbc:h2:mem:regular;DB_CLOSE_DELAY=-1",
username = "h2",
password = "",
maximumPoolSize = 2,
connectionTimeout = 3000
)
)
.start()
}
@@ -1,24 +1,29 @@
package be.simplenotes.persistence.notes
package be.simplenotes.persistence
import be.simplenotes.persistence.DbTest
import be.simplenotes.persistence.converters.NoteConverter
import be.simplenotes.persistence.notes.*
import be.simplenotes.persistence.repositories.NoteRepository
import be.simplenotes.persistence.repositories.UserRepository
import be.simplenotes.persistence.users.createFakeUser
import be.simplenotes.types.ExportedNote
import be.simplenotes.types.PersistedNote
import be.simplenotes.types.PersistedUser
import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.dsl.eq
import me.liuwj.ktorm.entity.filter
import me.liuwj.ktorm.entity.find
import me.liuwj.ktorm.entity.mapColumns
import me.liuwj.ktorm.entity.toList
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.jupiter.api.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.parallel.ResourceLock
import org.ktorm.database.Database
import org.ktorm.dsl.eq
import org.ktorm.entity.filter
import org.ktorm.entity.find
import org.ktorm.entity.mapColumns
import org.ktorm.entity.toList
import java.sql.SQLIntegrityConstraintViolationException
internal abstract class BaseNoteRepositoryImplTest : DbTest() {
internal class NoteRepositoryImplTest : DbTest() {
private lateinit var noteRepo: NoteRepository
private lateinit var userRepo: UserRepository
@@ -94,27 +99,6 @@ internal abstract class BaseNoteRepositoryImplTest : DbTest() {
assertThat(noteRepo.findAll(1000)).isEmpty()
}
// TODO: datetime -> timestamp migration
@Disabled("Not working with mariadb, inserts are too fast so the updated_at is the same")
@Test
fun pagination() {
(50 downTo 1).forEach { i ->
noteRepo.insertFakeNote(user1, "$i")
}
assertThat(noteRepo.findAll(user1.id, limit = 20, offset = 0).onEach { println(it) })
.hasSize(20)
.allMatch { it.title.toInt() in 1..20 }
assertThat(noteRepo.findAll(user1.id, limit = 20, offset = 20))
.hasSize(20)
.allMatch { it.title.toInt() in 21..40 }
assertThat(noteRepo.findAll(user1.id, limit = 20, offset = 40))
.hasSize(10)
.allMatch { it.title.toInt() in 41..50 }
}
@Test
fun `find all notes with tag`() {
with(noteRepo) {
@@ -145,12 +129,18 @@ internal abstract class BaseNoteRepositoryImplTest : DbTest() {
fun `find an existing note`() {
val fakeNote = noteRepo.insertFakeNote(user1)
val converter = beanContext.getBean(NoteConverter::class.java)
val note = db.notes.find { it.title eq fakeNote.meta.title }!!
val note = db.notes.find { Notes.title eq fakeNote.title }!!
.let { entity ->
val tags = db.tags.filter { it.noteUuid eq entity.uuid }.mapColumns { it.name } as List<String>
converter.toPersistedNote(entity, tags)
val tags = db.tags.filter { be.simplenotes.persistence.Tags.noteUuid eq entity.uuid }.mapColumns { be.simplenotes.persistence.Tags.name } as List<String>
PersistedNote(
uuid = entity.uuid,
title = entity.title,
tags = tags,
markdown = entity.markdown,
html = entity.html,
updatedAt = entity.updatedAt,
public = entity.public,
)
}
assertThat(noteRepo.find(user1.id, note.uuid)).isEqualTo(note)
@@ -199,11 +189,11 @@ internal abstract class BaseNoteRepositoryImplTest : DbTest() {
val notes1 = noteRepo.insertFakeNotes(user1, count = 3)
val notes2 = noteRepo.insertFakeNotes(user2, count = 1)
val user1Tags = notes1.flatMap { it.meta.tags }.toSet()
val user1Tags = notes1.flatMap { it.tags }.toSet()
assertThat(noteRepo.getTags(user1.id))
.containsExactlyInAnyOrderElementsOf(user1Tags)
val user2Tags = notes2.flatMap { it.meta.tags }.toSet()
val user2Tags = notes2.flatMap { it.tags }.toSet()
assertThat(noteRepo.getTags(user2.id))
.containsExactlyInAnyOrderElementsOf(user2Tags)
@@ -229,9 +219,7 @@ internal abstract class BaseNoteRepositoryImplTest : DbTest() {
.isEqualTo(newNote1)
val note2 = noteRepo.insertFakeNote(user1)
val newNote2 = fakeNote().let {
it.copy(meta = it.meta.copy(tags = tagGenerator().take(3).toList()))
}
val newNote2 = fakeNote().copy(tags = tagGenerator().take(3).toList())
assertThat(noteRepo.update(user1.id, note2.uuid, newNote2))
.isNotNull
@@ -253,7 +241,7 @@ internal abstract class BaseNoteRepositoryImplTest : DbTest() {
.isTrue
val isDeleted = db.notes
.find { it.uuid eq note1.uuid }
.find { Notes.uuid eq note1.uuid }
?.deleted
assertThat(isDeleted).`as`("Check that Notes.deleted is true").isTrue
@@ -261,7 +249,7 @@ internal abstract class BaseNoteRepositoryImplTest : DbTest() {
assertThat(noteRepo.restore(user1.id, note1.uuid)).isTrue
val isDeleted2 = db.notes
.find { it.uuid eq note1.uuid }
.find { Notes.uuid eq note1.uuid }
?.deleted
assertThat(isDeleted2).`as`("Check that Notes.deleted is false after restore()").isFalse
@@ -302,8 +290,8 @@ internal abstract class BaseNoteRepositoryImplTest : DbTest() {
val expected = notes.mapIndexed { i, n ->
ExportedNote(
title = n.meta.title,
tags = n.meta.tags,
title = n.title,
tags = n.tags,
markdown = n.markdown,
html = n.html,
updatedAt = n.updatedAt,
@@ -1,17 +1,17 @@
package be.simplenotes.persistence.users
package be.simplenotes.persistence
import be.simplenotes.persistence.DbTest
import be.simplenotes.persistence.repositories.UserRepository
import me.liuwj.ktorm.database.Database
import me.liuwj.ktorm.dsl.eq
import me.liuwj.ktorm.entity.find
import me.liuwj.ktorm.entity.toList
import be.simplenotes.persistence.users.fakeUser
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.ktorm.database.Database
import org.ktorm.dsl.eq
import org.ktorm.entity.find
import org.ktorm.entity.toList
internal abstract class BaseUserRepositoryImplTest : DbTest() {
internal class UserRepositoryImplTest : DbTest() {
private lateinit var userRepo: UserRepository
private lateinit var db: Database
@@ -30,7 +30,7 @@ internal abstract class BaseUserRepositoryImplTest : DbTest() {
.extracting("username", "password")
.contains(user.username, user.password)
assertThat(db.users.find { it.username eq user.username }).isNotNull
assertThat(db.users.find { Users.username eq user.username }).isNotNull
assertThat(db.users.toList()).hasSize(1)
assertThat(userRepo.create(user)).isNull()
}
@@ -1,164 +0,0 @@
package be.simplenotes.persistence.converters
import be.simplenotes.persistence.notes.NoteEntity
import be.simplenotes.types.*
import io.micronaut.context.BeanContext
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import java.time.LocalDateTime
import java.util.*
internal class NoteConverterTest {
private val ctx = BeanContext.run()
val converter = ctx.getBean(NoteConverter::class.java)
@Nested
@DisplayName("Entity -> Models")
inner class EntityToModels {
@Test
fun `convert NoteEntity to Note`() {
val entity = NoteEntity {
title = "title"
markdown = "md"
html = "html"
}
val tags = listOf("a", "b")
val note = converter.toNote(entity, tags)
val expectedNote = Note(
NoteMetadata(
title = "title",
tags = tags,
),
markdown = "md",
html = "html"
)
assertThat(note).isEqualTo(expectedNote)
}
@Test
fun `convert NoteEntity to ExportedNote`() {
val entity = NoteEntity {
title = "title"
markdown = "md"
html = "html"
updatedAt = LocalDateTime.MIN
deleted = true
}
val tags = listOf("a", "b")
val note = converter.toExportedNote(entity, tags)
val expectedNote = ExportedNote(
title = "title",
tags = tags,
markdown = "md",
html = "html",
updatedAt = LocalDateTime.MIN,
trash = true
)
assertThat(note).isEqualTo(expectedNote)
}
@Test
fun `convert NoteEntity to PersistedNoteMetadata`() {
val entity = NoteEntity {
uuid = UUID.randomUUID()
title = "title"
markdown = "md"
html = "html"
updatedAt = LocalDateTime.MIN
deleted = true
}
val tags = listOf("a", "b")
val note = converter.toPersistedNoteMetadata(entity, tags)
val expectedNote = PersistedNoteMetadata(
title = "title",
tags = tags,
updatedAt = LocalDateTime.MIN,
uuid = entity.uuid
)
assertThat(note).isEqualTo(expectedNote)
}
}
@Nested
@DisplayName("Models -> Entity")
inner class ModelsToEntity {
@Test
fun `convert Note to NoteEntity`() {
val note = Note(NoteMetadata("title", emptyList()), "md", "html")
val entity = converter.toEntity(note, UUID.randomUUID(), 2, LocalDateTime.MIN)
assertThat(entity)
.hasFieldOrPropertyWithValue("markdown", "md")
.hasFieldOrPropertyWithValue("html", "html")
.hasFieldOrPropertyWithValue("title", "title")
.hasFieldOrPropertyWithValue("uuid", entity.uuid)
.hasFieldOrPropertyWithValue("updatedAt", LocalDateTime.MIN)
}
@Test
fun `convert PersistedNoteMetadata to NoteEntity`() {
val persistedNoteMetadata =
PersistedNoteMetadata("title", emptyList(), LocalDateTime.MIN, UUID.randomUUID())
val entity = converter.toEntity(persistedNoteMetadata)
assertThat(entity)
.hasFieldOrPropertyWithValue("uuid", persistedNoteMetadata.uuid)
.hasFieldOrPropertyWithValue("updatedAt", persistedNoteMetadata.updatedAt)
.hasFieldOrPropertyWithValue("title", "title")
}
@Test
fun `convert NoteMetadata to NoteEntity`() {
val noteMetadata = NoteMetadata("title", emptyList())
val entity = converter.toEntity(noteMetadata)
assertThat(entity)
.hasFieldOrPropertyWithValue("title", "title")
}
@Test
fun `convert PersistedNote to NoteEntity`() {
val persistedNote = PersistedNote(
NoteMetadata("title", emptyList()),
markdown = "md",
html = "html",
updatedAt = LocalDateTime.MIN,
uuid = UUID.randomUUID(),
public = true
)
val entity = converter.toEntity(persistedNote)
assertThat(entity)
.hasFieldOrPropertyWithValue("title", "title")
.hasFieldOrPropertyWithValue("markdown", "md")
.hasFieldOrPropertyWithValue("uuid", persistedNote.uuid)
.hasFieldOrPropertyWithValue("updatedAt", persistedNote.updatedAt)
.hasFieldOrPropertyWithValue("deleted", false)
.hasFieldOrPropertyWithValue("public", true)
}
@Test
fun `convert ExportedNote to NoteEntity`() {
val exportedNote = ExportedNote(
"title",
emptyList(),
markdown = "md",
html = "html",
updatedAt = LocalDateTime.MIN,
trash = true
)
val entity = converter.toEntity(exportedNote)
assertThat(entity)
.hasFieldOrPropertyWithValue("title", "title")
.hasFieldOrPropertyWithValue("markdown", "md")
.hasFieldOrPropertyWithValue("updatedAt", exportedNote.updatedAt)
.hasFieldOrPropertyWithValue("deleted", true)
}
}
}
@@ -1,48 +0,0 @@
package be.simplenotes.persistence.converters
import be.simplenotes.persistence.users.UserEntity
import be.simplenotes.types.PersistedUser
import be.simplenotes.types.User
import io.micronaut.context.BeanContext
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
internal class UserConverterTest {
private val ctx = BeanContext.run()
private val converter = ctx.getBean(UserConverter::class.java)
@Test
fun `convert UserEntity to User`() {
val entity = UserEntity {
username = "test"
password = "test2"
}.apply {
this["id"] = 2
}
val user = converter.toUser(entity)
assertThat(user).isEqualTo(User("test", "test2"))
}
@Test
fun `convert UserEntity to PersistedUser`() {
val entity = UserEntity {
username = "test"
password = "test2"
}.apply {
this["id"] = 2
}
val user = converter.toPersistedUser(entity)
assertThat(user).isEqualTo(PersistedUser("test", "test2", 2))
}
@Test
fun `convert User to UserEntity`() {
val user = User("test", "test2")
val entity = converter.toEntity(user)
assertThat(entity)
.hasFieldOrPropertyWithValue("username", "test")
.hasFieldOrPropertyWithValue("password", "test2")
}
}
@@ -1,31 +0,0 @@
package be.simplenotes.persistence.notes
import be.simplenotes.config.DataSourceConfig
import be.simplenotes.persistence.KMariadbContainer
import be.simplenotes.persistence.h2dataSourceConfig
import be.simplenotes.persistence.mariadbDataSourceConfig
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.parallel.ResourceLock
@ResourceLock("h2")
internal class H2NoteRepositoryImplTests : BaseNoteRepositoryImplTest() {
override fun dataSourceConfig() = h2dataSourceConfig()
}
@Tag("slow")
@ResourceLock("mariadb")
internal class MariaDbNoteRepositoryImplTests : BaseNoteRepositoryImplTest() {
lateinit var mariaDB: KMariadbContainer
@AfterAll
fun stopMariaDB() {
mariaDB.stop()
}
override fun dataSourceConfig(): DataSourceConfig {
mariaDB = KMariadbContainer()
mariaDB.start()
return mariadbDataSourceConfig(mariaDB.jdbcUrl)
}
}
@@ -1,31 +0,0 @@
package be.simplenotes.persistence.users
import be.simplenotes.config.DataSourceConfig
import be.simplenotes.persistence.KMariadbContainer
import be.simplenotes.persistence.h2dataSourceConfig
import be.simplenotes.persistence.mariadbDataSourceConfig
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.parallel.ResourceLock
@ResourceLock("h2")
internal class UserRepositoryImplTest : BaseUserRepositoryImplTest() {
override fun dataSourceConfig() = h2dataSourceConfig()
}
@Tag("slow")
@ResourceLock("mariadb")
internal class MariaDbUserRepositoryImplTest : BaseUserRepositoryImplTest() {
lateinit var mariaDB: KMariadbContainer
@AfterAll
fun stopMariaDB() {
mariaDB.stop()
}
override fun dataSourceConfig(): DataSourceConfig {
mariaDB = KMariadbContainer()
mariaDB.start()
return mariadbDataSourceConfig(mariaDB.jdbcUrl)
}
}