From 7ce7e3085af9c6e343a6a6cf9739c216c2c16d81 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:11:41 +0900 Subject: [PATCH] =?UTF-8?q?test:=20ExposedApplicationRepository=E3=81=A8Ex?= =?UTF-8?q?posedCustomEmojiRepository=E3=81=A8ExposedFilterRepository?= =?UTF-8?q?=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/domain/model/filter/FilterKeyword.kt | 15 +- .../core/domain/model/filter/FilterName.kt | 15 + .../exposed/FilterQueryMapper.kt | 2 +- .../ExposedCustomEmojiRepository.kt | 14 +- .../ExposedFilterRepository.kt | 8 +- .../ExposedApplicationRepositoryTest.kt | 70 ++++ .../ExposedCustomEmojiRepositoryTest.kt | 324 ++++++++++++++++++ .../ExposedFilterRepositoryTest.kt | 280 +++++++++++++++ 8 files changed, 718 insertions(+), 10 deletions(-) create mode 100644 hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedApplicationRepositoryTest.kt create mode 100644 hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedCustomEmojiRepositoryTest.kt create mode 100644 hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepositoryTest.kt diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterKeyword.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterKeyword.kt index 333eb8ae..6e5822fd 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterKeyword.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterKeyword.kt @@ -4,4 +4,17 @@ class FilterKeyword( val id: FilterKeywordId, var keyword: FilterKeywordKeyword, val mode: FilterMode -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as FilterKeyword + + return id == other.id + } + + override fun hashCode(): Int { + return id.hashCode() + } +} diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterName.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterName.kt index bd6596f3..c829c4ee 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterName.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/filter/FilterName.kt @@ -4,7 +4,22 @@ class FilterName(name: String) { val name = name.take(LENGTH) + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as FilterName + + return name == other.name + } + + override fun hashCode(): Int { + return name.hashCode() + } + companion object { const val LENGTH = 300 } + + } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/FilterQueryMapper.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/FilterQueryMapper.kt index 5b6039c4..f0c2814d 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/FilterQueryMapper.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/FilterQueryMapper.kt @@ -33,7 +33,7 @@ class FilterQueryMapper(private val filterResultRowMapper: ResultRowMapper FilterKeyword( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedCustomEmojiRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedCustomEmojiRepository.kt index d96f7a0c..7f1a0b50 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedCustomEmojiRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedCustomEmojiRepository.kt @@ -31,8 +31,7 @@ import org.springframework.stereotype.Repository import java.net.URI @Repository -class ExposedCustomEmojiRepository : CustomEmojiRepository, - AbstractRepository() { +class ExposedCustomEmojiRepository : CustomEmojiRepository, AbstractRepository() { override val logger: Logger get() = Companion.logger @@ -50,7 +49,12 @@ class ExposedCustomEmojiRepository : CustomEmojiRepository, } override suspend fun findById(id: Long): CustomEmoji? = query { - return@query CustomEmojis.selectAll().where { CustomEmojis.id eq id }.singleOrNull()?.toCustomEmoji() + CustomEmojis + .selectAll() + .where { CustomEmojis.id eq id } + .limit(1) + .singleOrNull() + ?.toCustomEmoji() } override suspend fun delete(customEmoji: CustomEmoji): Unit = query { @@ -58,7 +62,7 @@ class ExposedCustomEmojiRepository : CustomEmojiRepository, } override suspend fun findByNamesAndDomain(names: List, domain: String): List = query { - return@query CustomEmojis + CustomEmojis .selectAll() .where { CustomEmojis.name inList names and (CustomEmojis.domain eq domain) @@ -67,7 +71,7 @@ class ExposedCustomEmojiRepository : CustomEmojiRepository, } override suspend fun findByIds(ids: List): List = query { - return@query CustomEmojis + CustomEmojis .selectAll() .where { CustomEmojis.id inList ids diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt index 765641f1..837ccee9 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepository.kt @@ -63,18 +63,20 @@ class ExposedFilterRepository(private val filterQueryMapper: QueryMapper val filterId = FilterKeywords .selectAll() .where { FilterKeywords.id eq filterKeywordId.id } + .limit(1) .firstOrNull()?.get(FilterKeywords.filterId) ?: return@query null - val where = Filters.selectAll().where { Filters.id eq filterId } + val where = Filters.leftJoin(FilterKeywords).selectAll().where { Filters.id eq filterId } return@query filterQueryMapper.map(where).firstOrNull() } override suspend fun findByFilterId(filterId: FilterId): Filter? = query { - val where = Filters.selectAll().where { Filters.id eq filterId.id } + val where = Filters.leftJoin(FilterKeywords).selectAll().where { Filters.id eq filterId.id } return@query filterQueryMapper.map(where).firstOrNull() } override suspend fun findByUserDetailId(userDetailId: UserDetailId): List = query { - return@query Filters.selectAll().where { Filters.userId eq userDetailId.id }.let(filterQueryMapper::map) + return@query Filters.leftJoin(FilterKeywords).selectAll().where { Filters.userId eq userDetailId.id } + .let(filterQueryMapper::map) } companion object { diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedApplicationRepositoryTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedApplicationRepositoryTest.kt new file mode 100644 index 00000000..619db4fd --- /dev/null +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedApplicationRepositoryTest.kt @@ -0,0 +1,70 @@ +package dev.usbharu.hideout.core.infrastructure.exposedrepository + +import com.ninja_squad.dbsetup_kotlin.dbSetup +import dev.usbharu.hideout.core.domain.model.application.Application +import dev.usbharu.hideout.core.domain.model.application.ApplicationId +import dev.usbharu.hideout.core.domain.model.application.ApplicationName +import kotlinx.coroutines.test.runTest +import org.assertj.db.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import utils.AbstractRepositoryTest +import utils.columns +import utils.isEqualTo +import utils.withSuspend + +class ExposedApplicationRepositoryTest : AbstractRepositoryTest(Applications) { + @Test + fun save_idが同じレコードが存在しないとinsert() = runTest { + val application = Application(ApplicationId(1), ApplicationName("test-application")) + + ExposedApplicationRepository().save(application) + + assertThat(assertTable) + .row(0) + .isEqualTo(Applications.id, application.applicationId.id) + .isEqualTo(Applications.name, application.name.name) + } + + @Test + fun save_idが同じレコードが存在したらupdate() = runTest { + dbSetup(to = dataSource) { + insertInto(Applications.tableName) { + columns(Applications.columns) + values(1, "application-test") + } + }.launch() + + val application = Application(ApplicationId(1), ApplicationName("test-application")) + + ExposedApplicationRepository().save(application) + + assertThat(assertTable) + .row(0) + .isEqualTo(Applications.id, application.applicationId.id) + .isEqualTo(Applications.name, application.name.name) + } + + @Test + fun delete_削除される() = runTest { + dbSetup(to = dataSource) { + insertInto(Applications.tableName) { + columns(Applications.columns) + values(1, "test-application") + } + }.launch() + + val application = Application(ApplicationId(1), ApplicationName("test-application")) + + change.withSuspend { + ExposedApplicationRepository().delete(application) + } + + assertThat(change) + .changeOfDeletionOnTable(Applications.tableName) + .rowAtStartPoint() + .value(Applications.id.name).isEqualTo(application.applicationId.id) + .value(Applications.name.name).isEqualTo(application.name.name) + + + } +} \ No newline at end of file diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedCustomEmojiRepositoryTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedCustomEmojiRepositoryTest.kt new file mode 100644 index 00000000..e32171d3 --- /dev/null +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedCustomEmojiRepositoryTest.kt @@ -0,0 +1,324 @@ +package dev.usbharu.hideout.core.infrastructure.exposedrepository + +import com.ninja_squad.dbsetup_kotlin.dbSetup +import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji +import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId +import dev.usbharu.hideout.core.domain.model.instance.InstanceId +import dev.usbharu.hideout.core.domain.model.support.domain.Domain +import kotlinx.coroutines.test.runTest +import org.assertj.db.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import utils.* +import java.net.URI +import java.sql.Timestamp +import java.time.Instant +import kotlin.test.assertContentEquals +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull + +class ExposedCustomEmojiRepositoryTest : AbstractRepositoryTest(CustomEmojis) { + @Test + fun save_idが同じレコードが存在しないとinsert() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(Instance.tableName) { + columns(Instance.columns) + values( + 1, + "system", + "", + "https://example.com", + "", + null, + "", + "", + false, + false, + "", + "2024-09-10 16:59:50.160202" + ) + } + execute(enableReferenceIntegrityConstraints) + }.launch() + val customEmoji = CustomEmoji( + CustomEmojiId(1), + "name", + Domain("example.com"), + InstanceId(1), + URI.create("https://example.com"), + null, + Instant.parse("2020-01-01T00:00:00Z") + ) + + ExposedCustomEmojiRepository().save(customEmoji) + + assertThat(assertTable).row(0).isEqualTo(CustomEmojis.id, customEmoji.id.emojiId) + .isEqualTo(CustomEmojis.name, customEmoji.name).isEqualTo(CustomEmojis.domain, customEmoji.domain.domain) + .isEqualTo(CustomEmojis.instanceId, customEmoji.instanceId.instanceId) + .isEqualTo(CustomEmojis.url, customEmoji.url.toString()) + .isEqualTo(CustomEmojis.category, customEmoji.category).value(CustomEmojis.createdAt.name) + .isEqualTo(Timestamp.from(customEmoji.createdAt)) + } + + @Test + fun save_idが同じレコードが存在したらupdate() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(Instance.tableName) { + columns(Instance.columns) + values( + 1, + "system", + "", + "https://example.com", + "", + null, + "", + "", + false, + false, + "", + "2024-09-10 16:59:50.160202" + ) + } + insertInto(CustomEmojis.tableName) { + columns(CustomEmojis.columns) + values( + 1, + "emoji", + "example.com", + 1, + "https://example.com", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + } + execute(enableReferenceIntegrityConstraints) + }.launch() + val customEmoji = CustomEmoji( + CustomEmojiId(1), + "name", + Domain("example.com"), + InstanceId(1), + URI.create("https://example.com"), + null, + Instant.parse("2020-01-01T00:00:00Z") + ) + + ExposedCustomEmojiRepository().save(customEmoji) + + assertThat(assertTable).row(0).isEqualTo(CustomEmojis.id, customEmoji.id.emojiId) + .isEqualTo(CustomEmojis.name, customEmoji.name).isEqualTo(CustomEmojis.domain, customEmoji.domain.domain) + .isEqualTo(CustomEmojis.instanceId, customEmoji.instanceId.instanceId) + .isEqualTo(CustomEmojis.url, customEmoji.url.toString()) + .isEqualTo(CustomEmojis.category, customEmoji.category).value(CustomEmojis.createdAt.name) + .isEqualTo(Timestamp.from(customEmoji.createdAt)) + } + + @Test + fun delete_削除される() = runTest { + + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(CustomEmojis.tableName) { + columns(CustomEmojis.columns) + values( + 1, + "emoji", + "example.com", + 1, + "https://example.com", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + } + }.launch() + + val customEmoji = CustomEmoji( + CustomEmojiId(1), + "name", + Domain("example.com"), + InstanceId(1), + URI.create("https://example.com"), + null, + Instant.parse("2020-01-01T00:00:00Z") + ) + + + change.withSuspend { + ExposedCustomEmojiRepository().delete(customEmoji) + } + + assertThat(change).changeOfDeletionOnTable(CustomEmojis.tableName).rowAtStartPoint().value(CustomEmojis.id.name) + .isEqualTo(customEmoji.id.emojiId) + } + + @Test + fun findById_指定したIdで存在したら返す() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(CustomEmojis.tableName) { + columns(CustomEmojis.columns) + values( + 1, + "emoji", + "example.com", + 1, + "https://example.com", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + } + }.launch() + + val customEmoji = CustomEmoji( + CustomEmojiId(1), + "emoji", + Domain("example.com"), + InstanceId(1), + URI.create("https://example.com"), + null, + Instant.parse("2020-01-01T00:00:00Z") + ) + + val actual = ExposedCustomEmojiRepository().findById(1) + + assertEquals(customEmoji, actual) + assertNotNull(actual) + assertEquals(customEmoji.id, actual.id) + assertEquals(customEmoji.createdAt, actual.createdAt) + assertEquals(customEmoji.url, actual.url) + assertEquals(customEmoji.category, actual.category) + assertEquals(customEmoji.instanceId, actual.instanceId) + assertEquals(customEmoji.domain, actual.domain) + assertEquals(customEmoji.name, actual.name) + } + + @Test + fun findById_指定したIdで存在しないとnull() = runTest { + assertNull(ExposedCustomEmojiRepository().findById(1)) + } + + @Test + fun findByNamesAndDomain_指定した条件全部返す() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(CustomEmojis.tableName) { + columns(CustomEmojis.columns) + values( + 1, + "emoji", + "example.com", + 1, + "https://example.com/1", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + values( + 2, + "emoji2", + "example.com", + 1, + "https://example.com/2", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + values( + 3, + "emoji3", + "example.com", + 1, + "https://example.com/3", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + } + }.launch() + + val expected = listOf( + CustomEmoji( + CustomEmojiId(1), + "emoji", + Domain("example.com"), + InstanceId(1), + URI.create("https://example.com/1"), + null, + Instant.parse("2020-01-01T00:00:00Z") + ), CustomEmoji( + CustomEmojiId(2), + "emoji2", + Domain("example.com"), + InstanceId(1), + URI.create("https://example.com/2"), + null, + Instant.parse("2020-01-01T00:00:00Z") + ) + ) + + val actual = ExposedCustomEmojiRepository().findByNamesAndDomain(listOf("emoji", "emoji2"), "example.com") + + assertContentEquals(expected, actual) + } + + @Test + fun findByIds_指定された条件全部返す() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(CustomEmojis.tableName) { + columns(CustomEmojis.columns) + values( + 1, + "emoji", + "example.com", + 1, + "https://example.com/1", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + values( + 2, + "emoji2", + "example.com", + 1, + "https://example.com/2", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + values( + 3, + "emoji3", + "example.com", + 1, + "https://example.com/3", + null, + Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")) + ) + } + }.launch() + + val expected = listOf( + CustomEmoji( + CustomEmojiId(1), + "emoji", + Domain("example.com"), + InstanceId(1), + URI.create("https://example.com/1"), + null, + Instant.parse("2020-01-01T00:00:00Z") + ), CustomEmoji( + CustomEmojiId(3), + "emoji3", + Domain("example.com"), + InstanceId(1), + URI.create("https://example.com/3"), + null, + Instant.parse("2020-01-01T00:00:00Z") + ) + ) + + val actual = ExposedCustomEmojiRepository().findByIds(listOf(1, 3)) + + assertContentEquals(expected, actual) + } +} \ No newline at end of file diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepositoryTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepositoryTest.kt new file mode 100644 index 00000000..952eb316 --- /dev/null +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedFilterRepositoryTest.kt @@ -0,0 +1,280 @@ +package dev.usbharu.hideout.core.infrastructure.exposedrepository + +import com.ninja_squad.dbsetup_kotlin.dbSetup +import dev.usbharu.hideout.core.domain.model.filter.* +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId +import dev.usbharu.hideout.core.infrastructure.exposed.FilterQueryMapper +import dev.usbharu.hideout.core.infrastructure.exposed.FilterResultRowMapper +import kotlinx.coroutines.test.runTest +import org.assertj.db.api.Assertions.assertThat +import org.assertj.db.type.Changes +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.InjectMocks +import org.mockito.Spy +import org.mockito.junit.jupiter.MockitoExtension +import utils.* +import kotlin.test.assertContentEquals +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull + +@ExtendWith(MockitoExtension::class) +class ExposedFilterRepositoryTest : AbstractRepositoryTest(Filters) { + + @InjectMocks + lateinit var repository: ExposedFilterRepository + + @Spy + val filterQueryMapper: FilterQueryMapper = FilterQueryMapper(FilterResultRowMapper()) + + @Test + fun save_idが同じレコードが存在しないとinsert() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(UserDetails.tableName) { + columns(UserDetails.columns) + values(1, 2, "VeeeeeeeeeeeeeeeeryStrongPassword", false, null, null) + } + execute(enableReferenceIntegrityConstraints) + }.launch() + + val filter = Filter( + FilterId(1), + UserDetailId(1), + FilterName("filter"), + setOf(), + FilterAction.HIDE, + setOf(FilterKeyword(FilterKeywordId(1), FilterKeywordKeyword("keyword"), FilterMode.NONE)) + ) + repository.save(filter) + + assertThat(assertTable).row(0).isEqualTo(Filters.id, filter.id.id) + .isEqualTo(Filters.userId, filter.userDetailId.id).isEqualTo(Filters.name, filter.name.name) + .isEqualTo(Filters.filterAction, filter.filterAction.name) + .isEqualTo(Filters.context, filter.filterContext.joinToString(",") { it.name }) + + assertThat(getTable(FilterKeywords.tableName)).row(0) + .isEqualTo(FilterKeywords.id, filter.filterKeywords.first().id.id) + .isEqualTo(FilterKeywords.filterId, filter.id.id) + .isEqualTo(FilterKeywords.keyword, filter.filterKeywords.first().keyword.keyword) + .isEqualTo(FilterKeywords.mode, filter.filterKeywords.first().mode.name) + } + + @Test + fun save_idが同じレコードが存在したらupdate() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(UserDetails.tableName) { + columns(UserDetails.columns) + values(1, 2, "VeeeeeeeeeeeeeeeeryStrongPassword", false, null, null) + } + insertInto(Filters.tableName) { + columns(Filters.columns) + values(1, 1, "name", "", "WARN") + } + insertInto(FilterKeywords.tableName) { + columns(FilterKeywords.columns) + values(1, 1, "aaaaaaaaaaaaaaaaa", "REGEX") + } + execute(enableReferenceIntegrityConstraints) + }.launch() + + val filter = Filter( + FilterId(1), + UserDetailId(1), + FilterName("filter"), + setOf(), + FilterAction.HIDE, + setOf(FilterKeyword(FilterKeywordId(1), FilterKeywordKeyword("keyword"), FilterMode.NONE)) + ) + repository.save(filter) + + assertThat(assertTable).row(0).isEqualTo(Filters.id, filter.id.id) + .isEqualTo(Filters.userId, filter.userDetailId.id).isEqualTo(Filters.name, filter.name.name) + .isEqualTo(Filters.filterAction, filter.filterAction.name) + .isEqualTo(Filters.context, filter.filterContext.joinToString(",") { it.name }) + + assertThat(getTable(FilterKeywords.tableName)).row(0) + .isEqualTo(FilterKeywords.id, filter.filterKeywords.first().id.id) + .isEqualTo(FilterKeywords.filterId, filter.id.id) + .isEqualTo(FilterKeywords.keyword, filter.filterKeywords.first().keyword.keyword) + .isEqualTo(FilterKeywords.mode, filter.filterKeywords.first().mode.name) + } + + @Test + fun delete_削除される() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + insertInto(UserDetails.tableName) { + columns(UserDetails.columns) + values(1, 2, "VeeeeeeeeeeeeeeeeryStrongPassword", false, null, null) + } + insertInto(Filters.tableName) { + columns(Filters.columns) + values(1, 1, "name", "", "WARN") + } + insertInto(FilterKeywords.tableName) { + columns(FilterKeywords.columns) + values(1, 1, "aaaaaaaaaaaaaaaaa", "REGEX") + } + execute(enableReferenceIntegrityConstraints) + }.launch() + + val filter = Filter( + FilterId(1), + UserDetailId(1), + FilterName("filter"), + setOf(), + FilterAction.HIDE, + setOf(FilterKeyword(FilterKeywordId(1), FilterKeywordKeyword("keyword"), FilterMode.NONE)) + ) + + val changes = Changes(dataSource) + changes.withSuspend { + repository.delete(filter) + } + + assertThat(changes).changeOfDeletionOnTable(Filters.tableName).rowAtStartPoint().value(Filters.id.name) + .isEqualTo(filter.id.id).changeOfDeletionOnTable(FilterKeywords.tableName).rowAtStartPoint() + .value(FilterKeywords.id.name).isEqualTo(filter.filterKeywords.first().id.id) + } + + @Test + fun findByFilterKeywordId_指定された条件で存在したら返す() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + + insertInto(Filters.tableName) { + columns(Filters.columns) + values(1, 1, "name", "PUBLIC", "WARN") + } + insertInto(FilterKeywords.tableName) { + columns(FilterKeywords.columns) + values(1, 1, "keyword", "REGEX") + } + + execute(enableReferenceIntegrityConstraints) + }.launch() + + val expected = Filter( + FilterId(1), + UserDetailId(1), + FilterName("name"), + setOf(FilterContext.PUBLIC), + FilterAction.WARN, + setOf(FilterKeyword(FilterKeywordId(1), FilterKeywordKeyword("keyword"), FilterMode.REGEX)) + ) + + val actual = repository.findByFilterKeywordId(FilterKeywordId(1)) + + assertEquals(expected, actual) + } + + private fun assertEquals( + expected: Filter, actual: Filter? + ) { + kotlin.test.assertEquals(expected, actual) + assertNotNull(actual) + assertEquals(expected.id, actual.id) + assertEquals(expected.name, actual.name) + assertContentEquals(expected.filterContext, actual.filterContext.asIterable()) + assertEquals(expected.userDetailId, actual.userDetailId) + assertEquals(expected.filterKeywords.size, actual.filterKeywords.size) + assertContentEquals(expected.filterKeywords, actual.filterKeywords.asIterable()) + } + + + @Test + fun findByFilterKeywordId_指定された条件で存在しないとnull() = runTest { + assertNull(repository.findByFilterKeywordId(FilterKeywordId(1))) + } + + @Test + fun findByFilterId_指定された条件で存在したら返す() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + + insertInto(Filters.tableName) { + columns(Filters.columns) + values(1, 1, "name", "PUBLIC", "WARN") + } + insertInto(FilterKeywords.tableName) { + columns(FilterKeywords.columns) + values(1, 1, "keyword", "REGEX") + } + + execute(enableReferenceIntegrityConstraints) + }.launch() + + val expected = Filter( + FilterId(1), + UserDetailId(1), + FilterName("name"), + setOf(FilterContext.PUBLIC), + FilterAction.WARN, + setOf(FilterKeyword(FilterKeywordId(1), FilterKeywordKeyword("keyword"), FilterMode.REGEX)) + ) + + val actual = repository.findByFilterId(FilterId(1)) + + assertEquals(expected, actual) + } + + @Test + fun findByFilterId_指定された条件で存在しないとnull() = runTest { + assertNull(repository.findByFilterId(FilterId(1))) + } + + @Test + fun findByUserDetailId_指定された条件全部返す() = runTest { + dbSetup(to = dataSource) { + execute(disableReferenceIntegrityConstraints) + + insertInto(Filters.tableName) { + columns(Filters.columns) + values(1, 1, "name", "PUBLIC", "WARN") + values(2, 1, "name2", "PUBLIC", "WARN") + values(3, 1, "name3", "PUBLIC", "HIDE") + } + insertInto(FilterKeywords.tableName) { + columns(FilterKeywords.columns) + values(1, 1, "keyword", "REGEX") + values(2, 2, "keyword2", "REGEX") + values(3, 1, "keyword3", "REGEX") + } + + execute(enableReferenceIntegrityConstraints) + }.launch() + + val expected = listOf( + Filter( + FilterId(1), UserDetailId(1), FilterName("name"), setOf(FilterContext.PUBLIC), FilterAction.WARN, setOf( + FilterKeyword(FilterKeywordId(1), FilterKeywordKeyword("keyword"), FilterMode.REGEX), + FilterKeyword(FilterKeywordId(3), FilterKeywordKeyword("keyword3"), FilterMode.REGEX) + ) + ), Filter( + FilterId(2), + UserDetailId(1), + FilterName("name2"), + setOf(FilterContext.PUBLIC), + FilterAction.WARN, + setOf( + FilterKeyword(FilterKeywordId(2), FilterKeywordKeyword("keyword2"), FilterMode.REGEX) + ) + ), Filter( + FilterId(3), + UserDetailId(1), + FilterName("name3"), + setOf(FilterContext.PUBLIC), + FilterAction.HIDE, + setOf( + ) + ) + ) + + val actual = repository.findByUserDetailId(UserDetailId(1)) + + assertContentEquals(expected, actual) + } +} \ No newline at end of file