diff --git a/simplenotes-persistance/build.gradle.kts b/simplenotes-persistance/build.gradle.kts index 89fe6de..12a9d1d 100644 --- a/simplenotes-persistance/build.gradle.kts +++ b/simplenotes-persistance/build.gradle.kts @@ -3,6 +3,7 @@ import be.simplenotes.Libs plugins { id("be.simplenotes.base") kotlin("kapt") + `java-test-fixtures` } dependencies { @@ -22,4 +23,15 @@ dependencies { testImplementation(Libs.junit) testImplementation(Libs.assertJ) + testImplementation(Libs.logbackClassic) + testImplementation("org.testcontainers:mariadb:1.15.0-rc2") + + testFixturesImplementation(project(":simplenotes-types")) + testFixturesImplementation(project(":simplenotes-config")) + testFixturesImplementation("com.github.javafaker:javafaker:1.0.2") + testFixturesImplementation("org.testcontainers:mariadb:1.15.0-rc2") + testFixturesImplementation(Libs.koinCore) + testFixturesImplementation(Libs.flywayCore) + testFixturesImplementation(Libs.junit) + } diff --git a/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/DbHealthCheckImplTest.kt b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/DbHealthCheckImplTest.kt new file mode 100644 index 0000000..a1d29aa --- /dev/null +++ b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/DbHealthCheckImplTest.kt @@ -0,0 +1,38 @@ +package be.simplenotes.persistance + +import be.simplenotes.config.DataSourceConfig +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.parallel.ResourceLock + +@ResourceLock("h2") +class H2DbHealthCheckImplTest : DbTest() { + private val healthCheck = koin.get() + override fun dataSourceConfig() = h2dataSourceConfig() + + @Test + fun healthCheck() { + assertThat(healthCheck.isOk()).isTrue + } + +} + +@ResourceLock("mariadb") +class MariaDbHealthCheckImplTest : DbTest() { + private val healthCheck = koin.get() + lateinit var mariaDB: KMariadbContainer + + override fun dataSourceConfig(): DataSourceConfig { + mariaDB = KMariadbContainer() + mariaDB.start() + return mariadbDataSourceConfig(mariaDB.jdbcUrl) + } + + @Test + fun healthCheck() { + assertThat(healthCheck.isOk()).isTrue + mariaDB.stop() + assertThat(healthCheck.isOk()).isFalse + } + +} diff --git a/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/NoteRepositoryImplTest.kt b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/BaseNoteRepositoryImplTest.kt similarity index 59% rename from simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/NoteRepositoryImplTest.kt rename to simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/BaseNoteRepositoryImplTest.kt index acb178a..051d3c6 100644 --- a/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/NoteRepositoryImplTest.kt +++ b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/BaseNoteRepositoryImplTest.kt @@ -1,13 +1,12 @@ package be.simplenotes.persistance.notes -import be.simplenotes.config.DataSourceConfig -import be.simplenotes.persistance.DbMigrations +import be.simplenotes.persistance.DbTest import be.simplenotes.persistance.converters.NoteConverter -import be.simplenotes.persistance.migrationModule -import be.simplenotes.persistance.persistanceModule import be.simplenotes.persistance.repositories.NoteRepository import be.simplenotes.persistance.repositories.UserRepository -import be.simplenotes.types.* +import be.simplenotes.persistance.users.createFakeUser +import be.simplenotes.types.ExportedNote +import be.simplenotes.types.PersistedUser import me.liuwj.ktorm.database.Database import me.liuwj.ktorm.dsl.eq import me.liuwj.ktorm.entity.filter @@ -16,42 +15,12 @@ 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.flywaydb.core.Flyway import org.junit.jupiter.api.* -import org.junit.jupiter.api.parallel.ResourceLock -import org.koin.dsl.koinApplication -import org.koin.dsl.module import org.mapstruct.factory.Mappers import java.sql.SQLIntegrityConstraintViolationException -import java.util.* -import javax.sql.DataSource -@ResourceLock("h2") -internal class NoteRepositoryImplTest { - private val testModule = module { - single { dataSourceConfig() } - } +internal abstract class BaseNoteRepositoryImplTest : DbTest() { - private val koinApp = koinApplication { - modules(persistanceModule, migrationModule, testModule) - } - - private fun dataSourceConfig() = DataSourceConfig( - jdbcUrl = "jdbc:h2:mem:regular;DB_CLOSE_DELAY=-1;", - driverClassName = "org.h2.Driver", - username = "h2", - password = "", - maximumPoolSize = 2, - connectionTimeout = 3000 - ) - - private val koin = koinApp.koin - - @AfterAll - fun afterAll() = koinApp.close() - - private val migration = koin.get() - private val dataSource = koin.get() private val noteRepo = koin.get() private val userRepo = koin.get() private val db = koin.get() @@ -60,35 +29,18 @@ internal class NoteRepositoryImplTest { private lateinit var user2: PersistedUser @BeforeEach - fun beforeEach() { - Flyway.configure() - .dataSource(dataSource) - .load() - .clean() - - migration.migrate() - - user1 = userRepo.create(User("1", "1"))!! - user2 = userRepo.create(User("2", "2"))!! + fun insertUsers() { + user1 = userRepo.createFakeUser()!! + user2 = userRepo.createFakeUser()!! } - private fun createNote( - userId: Int, - title: String, - tags: List = emptyList(), - md: String = "md", - html: String = "html", - ): PersistedNote = noteRepo.create(userId, Note(NoteMetadata(title, tags), md, html)) - - private fun PersistedNote.toPersistedMeta() = PersistedNoteMetadata(meta.title, meta.tags, updatedAt, uuid) - @Nested @DisplayName("create()") inner class Create { @Test fun `create note for non existing user`() { - val note = Note(NoteMetadata("title", emptyList()), "md", "html") + val note = fakeNote() assertThatThrownBy { noteRepo.create(1000, note) @@ -97,7 +49,7 @@ internal class NoteRepositoryImplTest { @Test fun `create note for existing user`() { - val note = Note(NoteMetadata("title", emptyList()), "md", "html") + val note = fakeNote() assertThat(noteRepo.create(user1.id, note)) .isEqualToIgnoringGivenFields(note, "uuid", "updatedAt", "public") @@ -116,15 +68,8 @@ internal class NoteRepositoryImplTest { @Test fun `find all notes`() { - val notes1 = listOf( - createNote(user1.id, "1", listOf("a", "b")), - createNote(user1.id, "2"), - createNote(user1.id, "3", listOf("c")) - ) - - val notes2 = listOf( - createNote(user2.id, "4") - ) + val notes1 = noteRepo.insertFakeNotes(user1, count = 3) + val notes2 = listOf(noteRepo.insertFakeNote(user2)) assertThat(noteRepo.findAll(user1.id)) .hasSize(3) @@ -143,13 +88,15 @@ internal class NoteRepositoryImplTest { 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 { - createNote(user1.id, "$it") + (50 downTo 1).forEach { i -> + noteRepo.insertFakeNote(user1, "$i") } - assertThat(noteRepo.findAll(user1.id, limit = 20, offset = 0)) + assertThat(noteRepo.findAll(user1.id, limit = 20, offset = 0).onEach { println(it) }) .hasSize(20) .allMatch { it.title.toInt() in 1..20 } @@ -164,12 +111,13 @@ internal class NoteRepositoryImplTest { @Test fun `find all notes with tag`() { - createNote(user1.id, "1", listOf("a", "b")) - createNote(user1.id, "2") - createNote(user1.id, "3", listOf("c")) - createNote(user1.id, "4", listOf("c")) - createNote(user2.id, "5", listOf("c")) - + with(noteRepo) { + insertFakeNote(user1, "1", listOf("a", "b")) + insertFakeNote(user1, "2", tags = emptyList()) + insertFakeNote(user1, "3", listOf("c")) + insertFakeNote(user1, "4", listOf("c")) + insertFakeNote(user2, "5", listOf("c")) + } assertThat(noteRepo.findAll(user1.id, tag = "a")) .hasSize(1) .first() @@ -189,34 +137,31 @@ internal class NoteRepositoryImplTest { @Test @Suppress("UNCHECKED_CAST") fun `find an existing note`() { - createNote(user1.id, "1", listOf("a", "b")) + val fakeNote = noteRepo.insertFakeNote(user1) val converter = Mappers.getMapper(NoteConverter::class.java) - val note = db.notes.find { it.title eq "1" }!! + val note = db.notes.find { it.title eq fakeNote.meta.title }!! .let { entity -> val tags = db.tags.filter { it.noteUuid eq entity.uuid }.mapColumns { it.name } as List converter.toPersistedNote(entity, tags) } - assertThat(noteRepo.find(user1.id, note.uuid)) - .isEqualTo(note) - - assertThat(noteRepo.exists(user1.id, note.uuid)) - .isTrue + assertThat(noteRepo.find(user1.id, note.uuid)).isEqualTo(note) + assertThat(noteRepo.exists(user1.id, note.uuid)).isTrue } @Test fun `find an existing note from the wrong user`() { - val note = createNote(user1.id, "1", listOf("a", "b")) + val note = noteRepo.insertFakeNote(user1) assertThat(noteRepo.find(user2.id, note.uuid)).isNull() assertThat(noteRepo.exists(user2.id, note.uuid)).isFalse } @Test fun `find a non existing note`() { - createNote(user1.id, "1", listOf("a", "b")) - val uuid = UUID.randomUUID() + noteRepo.insertFakeNote(user1) + val uuid = fakeUuid() assertThat(noteRepo.find(user1.id, uuid)).isNull() assertThat(noteRepo.exists(user2.id, uuid)).isFalse } @@ -228,16 +173,14 @@ internal class NoteRepositoryImplTest { @Test fun `delete an existing note for a user should succeed and then fail`() { - val note = createNote(user1.id, "1", listOf("a", "b")) - assertThat(noteRepo.delete(user1.id, note.uuid)) - .isTrue + val note = noteRepo.insertFakeNote(user1) + assertThat(noteRepo.delete(user1.id, note.uuid)).isTrue } @Test fun `delete an existing note for the wrong user`() { - val note = createNote(user1.id, "1", listOf("a", "b")) - assertThat(noteRepo.delete(1000, note.uuid)) - .isFalse + val note = noteRepo.insertFakeNote(user1) + assertThat(noteRepo.delete(1000, note.uuid)).isFalse } } @@ -247,15 +190,8 @@ internal class NoteRepositoryImplTest { @Test fun getTags() { - val notes1 = listOf( - createNote(user1.id, "1", listOf("a", "b")), - createNote(user1.id, "2"), - createNote(user1.id, "3", listOf("c", "a")) - ) - - val notes2 = listOf( - createNote(user2.id, "4", listOf("a")) - ) + val notes1 = noteRepo.insertFakeNotes(user1, count = 3) + val notes2 = noteRepo.insertFakeNotes(user2, count = 1) val user1Tags = notes1.flatMap { it.meta.tags }.toSet() assertThat(noteRepo.getTags(user1.id)) @@ -276,16 +212,18 @@ internal class NoteRepositoryImplTest { @Test fun getTags() { - val note1 = createNote(user1.id, "1", listOf("a", "b")) - val newNote1 = Note(meta = note1.meta, markdown = "new", "new") - assertThat(noteRepo.update(user1.id, note1.uuid, newNote1)) - .isNotNull + val note1 = noteRepo.insertFakeNote(user1) + val newNote1 = fakeNote() + + assertThat(noteRepo.update(user1.id, note1.uuid, newNote1)).isNotNull assertThat(noteRepo.find(user1.id, note1.uuid)) .isEqualToComparingOnlyGivenFields(newNote1, "meta", "markdown", "html") - val note2 = createNote(user1.id, "2") - val newNote2 = Note(meta = note1.meta.copy(tags = listOf("a")), markdown = "new", "new") + val note2 = noteRepo.insertFakeNote(user1) + val newNote2 = fakeNote().let { + it.copy(meta = it.meta.copy(tags = tagGenerator().take(3).toList())) + } assertThat(noteRepo.update(user1.id, note2.uuid, newNote2)) .isNotNull @@ -299,7 +237,7 @@ internal class NoteRepositoryImplTest { @Test fun `trashed noted should be restored`() { - val note1 = createNote(user1.id, "1", listOf("a", "b")) + val note1 = noteRepo.insertFakeNote(user1, "1", listOf("a", "b")) assertThat(noteRepo.delete(user1.id, note1.uuid, permanent = false)) .isTrue @@ -321,11 +259,69 @@ internal class NoteRepositoryImplTest { @Test fun `permanent delete`() { - val note1 = createNote(user1.id, "1", listOf("a", "b")) - assertThat(noteRepo.delete(user1.id, note1.uuid, permanent = true)) - .isTrue - - assertThat(noteRepo.restore(user1.id, note1.uuid)).isFalse + val note = noteRepo.insertFakeNote(user1) + assertThat(noteRepo.delete(user1.id, note.uuid, permanent = true)).isTrue + assertThat(noteRepo.restore(user1.id, note.uuid)).isFalse } } + + @Test + fun count() { + assertThat(noteRepo.count(user1.id)).isEqualTo(0) + + noteRepo.insertFakeNotes(user1, count = 10) + assertThat(noteRepo.count(user1.id)).isEqualTo(10) + } + + @Test + fun countWithTag() { + noteRepo.insertFakeNote(user1, tags = listOf("a", "b")) + noteRepo.insertFakeNote(user1, tags = emptyList()) + noteRepo.insertFakeNote(user1, tags = listOf("a")) + noteRepo.insertFakeNote(user1, tags = emptyList()) + + assertThat(noteRepo.count(user1.id, tag = "a")).isEqualTo(2) + } + + @Test + fun export() { + val notes = noteRepo.insertFakeNotes(user1, count = 4) + noteRepo.delete(user1.id, notes.first().uuid, permanent = false) + + val export = noteRepo.export(user1.id) + + val expected = notes.mapIndexed { i, n -> + ExportedNote( + title = n.meta.title, + tags = n.meta.tags, + markdown = n.markdown, + html = n.html, + updatedAt = n.updatedAt, + trash = i == 0, + ) + } + assertThat(export) + .usingElementComparatorIgnoringFields("updatedAt") + .containsExactlyInAnyOrderElementsOf(expected) + } + + @Test + fun findAllDetails() { + val notes = noteRepo.insertFakeNotes(user1, count = 10) + val res = noteRepo.findAllDetails(user1.id) + assertThat(res) + .usingElementComparatorIgnoringFields("updatedAt") + .containsExactlyInAnyOrderElementsOf(notes) + } + + @Test + fun access() { + val n = noteRepo.insertFakeNote(user1) + noteRepo.makePublic(user1.id, n.uuid) + assertThat(noteRepo.findPublic(n.uuid)) + .isEqualToIgnoringGivenFields(n.copy(public = true), "updatedAt") + + noteRepo.makePrivate(user1.id, n.uuid) + assertThat(noteRepo.findPublic(n.uuid)).isNull() + } } diff --git a/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/H2NoteRepositoryImplTests.kt b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/H2NoteRepositoryImplTests.kt new file mode 100644 index 0000000..9b311f1 --- /dev/null +++ b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/notes/H2NoteRepositoryImplTests.kt @@ -0,0 +1,29 @@ +package be.simplenotes.persistance.notes + +import be.simplenotes.config.DataSourceConfig +import be.simplenotes.persistance.KMariadbContainer +import be.simplenotes.persistance.h2dataSourceConfig +import be.simplenotes.persistance.mariadbDataSourceConfig +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.parallel.ResourceLock + +@ResourceLock("h2") +internal class H2NoteRepositoryImplTests : BaseNoteRepositoryImplTest() { + override fun dataSourceConfig() = h2dataSourceConfig() +} + +@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) + } +} diff --git a/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/UserRepositoryImplTest.kt b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/BaseUserRepositoryImplTest.kt similarity index 51% rename from simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/UserRepositoryImplTest.kt rename to simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/BaseUserRepositoryImplTest.kt index f35e169..0103c6f 100644 --- a/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/UserRepositoryImplTest.kt +++ b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/BaseUserRepositoryImplTest.kt @@ -1,73 +1,27 @@ package be.simplenotes.persistance.users -import be.simplenotes.config.DataSourceConfig -import be.simplenotes.persistance.DbMigrations -import be.simplenotes.persistance.migrationModule -import be.simplenotes.persistance.persistanceModule +import be.simplenotes.persistance.DbTest import be.simplenotes.persistance.repositories.UserRepository -import be.simplenotes.types.User -import me.liuwj.ktorm.database.* -import me.liuwj.ktorm.dsl.* -import me.liuwj.ktorm.entity.* +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 org.assertj.core.api.Assertions.assertThat -import org.flywaydb.core.Flyway -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test -import org.junit.jupiter.api.parallel.ResourceLock -import org.koin.dsl.koinApplication -import org.koin.dsl.module -import javax.sql.DataSource -@ResourceLock("h2") -internal class UserRepositoryImplTest { +internal abstract class BaseUserRepositoryImplTest : DbTest() { - // region setup - private val testModule = module { - single { dataSourceConfig() } - } - - private val koinApp = koinApplication { - modules(persistanceModule, migrationModule, testModule) - } - - private fun dataSourceConfig() = DataSourceConfig( - jdbcUrl = "jdbc:h2:mem:regular;DB_CLOSE_DELAY=-1;", - driverClassName = "org.h2.Driver", - username = "h2", - password = "", - maximumPoolSize = 2, - connectionTimeout = 3000 - ) - - private val koin = koinApp.koin - - @AfterAll - fun afterAll() = koinApp.close() - - private val migration = koin.get() - private val dataSource = koin.get() private val userRepo = koin.get() private val db = koin.get() - @BeforeEach - fun beforeEach() { - Flyway.configure() - .dataSource(dataSource) - .load() - .clean() - migration.migrate() - } - // endregion setup - @Test fun `insert user`() { - val user = User("username", "test") + val user = fakeUser() assertThat(userRepo.create(user)) .isNotNull - .hasFieldOrPropertyWithValue("username", user.username) - .hasFieldOrPropertyWithValue("password", user.password) + .extracting("username", "password") + .contains(user.username, user.password) assertThat(db.users.find { it.username eq user.username }).isNotNull assertThat(db.users.toList()).hasSize(1) @@ -79,7 +33,7 @@ internal class UserRepositoryImplTest { @Test fun `query existing user`() { - val user = User("username", "test") + val user = fakeUser() userRepo.create(user) val foundUserMaybe = userRepo.find(user.username) @@ -105,7 +59,7 @@ internal class UserRepositoryImplTest { @Test fun `delete existing user`() { - val user = User("username", "test") + val user = fakeUser() userRepo.create(user) val foundUser = userRepo.find(user.username)!! diff --git a/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/UserRepositoryImplTests.kt b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/UserRepositoryImplTests.kt new file mode 100644 index 0000000..38dcf71 --- /dev/null +++ b/simplenotes-persistance/src/test/kotlin/be/simplenotes/persistance/users/UserRepositoryImplTests.kt @@ -0,0 +1,29 @@ +package be.simplenotes.persistance.users + +import be.simplenotes.config.DataSourceConfig +import be.simplenotes.persistance.KMariadbContainer +import be.simplenotes.persistance.h2dataSourceConfig +import be.simplenotes.persistance.mariadbDataSourceConfig +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.parallel.ResourceLock + +@ResourceLock("h2") +internal class UserRepositoryImplTest : BaseUserRepositoryImplTest() { + override fun dataSourceConfig() = h2dataSourceConfig() +} + +@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) + } +} diff --git a/simplenotes-persistance/src/test/resources/logback.xml b/simplenotes-persistance/src/test/resources/logback.xml new file mode 100644 index 0000000..380db36 --- /dev/null +++ b/simplenotes-persistance/src/test/resources/logback.xml @@ -0,0 +1,15 @@ + + + true + + %cyan(%d{YYYY-MM-dd HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %green(%logger{36}) - %msg%n + + + + + + + + + + diff --git a/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/DataSources.kt b/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/DataSources.kt new file mode 100644 index 0000000..a7fe074 --- /dev/null +++ b/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/DataSources.kt @@ -0,0 +1,24 @@ +package be.simplenotes.persistance + +import be.simplenotes.config.DataSourceConfig +import org.testcontainers.containers.MariaDBContainer + +class KMariadbContainer : MariaDBContainer("mariadb:10.5.5") + +fun h2dataSourceConfig() = DataSourceConfig( + jdbcUrl = "jdbc:h2:mem:regular;DB_CLOSE_DELAY=-1;", + driverClassName = "org.h2.Driver", + username = "h2", + password = "", + maximumPoolSize = 2, + connectionTimeout = 3000 +) + +fun mariadbDataSourceConfig(jdbcUrl: String) = DataSourceConfig( + jdbcUrl = jdbcUrl, + driverClassName = "org.mariadb.jdbc.Driver", + username = "test", + password = "test", + maximumPoolSize = 2, + connectionTimeout = 3000 +) diff --git a/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/DbTest.kt b/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/DbTest.kt new file mode 100644 index 0000000..6ba9d22 --- /dev/null +++ b/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/DbTest.kt @@ -0,0 +1,40 @@ +package be.simplenotes.persistance + +import be.simplenotes.config.DataSourceConfig +import org.flywaydb.core.Flyway.* +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.BeforeEach +import org.koin.dsl.koinApplication +import org.koin.dsl.module +import javax.sql.DataSource + +abstract class DbTest { + + abstract fun dataSourceConfig(): DataSourceConfig + + private val testModule = module { + single { dataSourceConfig() } + } + + private val koinApp = koinApplication { + modules(persistanceModule, migrationModule, testModule) + } + + val koin = koinApp.koin + + @AfterAll + fun afterAll() = koinApp.close() + + @BeforeEach + fun beforeEach() { + val migration = koin.get() + val dataSource = koin.get() + configure() + .dataSource(dataSource) + .load() + .clean() + + migration.migrate() + } + +} diff --git a/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/notes/NotesFixtures.kt b/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/notes/NotesFixtures.kt new file mode 100644 index 0000000..a546dd3 --- /dev/null +++ b/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/notes/NotesFixtures.kt @@ -0,0 +1,37 @@ +package be.simplenotes.persistance.notes + +import be.simplenotes.persistance.repositories.NoteRepository +import be.simplenotes.types.* +import com.github.javafaker.Faker +import java.util.* + +private val faker = Faker() + +fun fakeUuid() = UUID.randomUUID()!! +fun fakeTitle() = faker.lorem().characters(3, 50)!! +fun tagGenerator() = generateSequence { faker.lorem().word() } +fun fakeTags() = tagGenerator().take(faker.random().nextInt(0, 3)).toList() +fun fakeContent() = faker.lorem().paragraph(faker.random().nextInt(0, 3))!! +fun fakeNote() = Note(NoteMetadata(fakeTitle(), fakeTags()), fakeContent(), fakeContent()) + +fun PersistedNote.toPersistedMeta() = + PersistedNoteMetadata(meta.title, meta.tags, updatedAt, uuid) + +fun NoteRepository.insertFakeNote( + userId: Int, + title: String, + tags: List = emptyList(), + md: String = "md", + html: String = "html", +): PersistedNote = create(userId, Note(NoteMetadata(title, tags), md, html)) + +fun NoteRepository.insertFakeNote( + user: PersistedUser, + title: String = fakeTitle(), + tags: List = fakeTags(), + md: String = fakeContent(), + html: String = fakeContent(), +): PersistedNote = insertFakeNote(user.id, title, tags, md, html) + +fun NoteRepository.insertFakeNotes(user: PersistedUser, count: Int): List = + generateSequence { insertFakeNote(user) }.take(count).toList() diff --git a/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/users/UserFixtures.kt b/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/users/UserFixtures.kt new file mode 100644 index 0000000..179eb56 --- /dev/null +++ b/simplenotes-persistance/src/testFixtures/kotlin/be/simplenotes/persistance/users/UserFixtures.kt @@ -0,0 +1,14 @@ +package be.simplenotes.persistance.users + +import be.simplenotes.persistance.repositories.UserRepository +import be.simplenotes.types.PersistedUser +import be.simplenotes.types.User +import com.github.javafaker.Faker + +private val faker = Faker() + +fun fakeUser() = User(faker.name().username(), faker.internet().password()) + +fun UserRepository.createFakeUser(): PersistedUser? { + return create(fakeUser()) +}