mirror of https://github.com/usbharu/Hideout.git
commit
5f97c45906
|
@ -1,4 +1,5 @@
|
|||
org.gradle.parallel=true
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED
|
||||
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED
|
||||
kotlin.compiler.preciseCompilationResultsBackup=true
|
|
@ -132,6 +132,8 @@ dependencies {
|
|||
testImplementation(libs.ktor.client.mock)
|
||||
testImplementation(libs.h2db)
|
||||
testImplementation(libs.mockito.kotlin)
|
||||
testImplementation("org.assertj:assertj-db:2.0.2")
|
||||
testImplementation("com.ninja-squad:DbSetup-kotlin:2.1.0")
|
||||
}
|
||||
|
||||
detekt {
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
kotlin.code.style=official
|
||||
org.gradle.parallel=true
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC
|
||||
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED
|
||||
kotlin.compiler.preciseCompilationResultsBackup=true
|
|
@ -56,7 +56,7 @@ class MigrationLocalActorApplicationService(
|
|||
val canAccountMigration =
|
||||
localActorMigrationCheckDomainService.canAccountMigration(userDetail, fromActor, toActor)
|
||||
if (canAccountMigration.canMigration) {
|
||||
fromActor.moveTo = toActorId
|
||||
fromActor.setMoveTo(toActorId)
|
||||
actorRepository.save(fromActor)
|
||||
} else {
|
||||
when (canAccountMigration) {
|
||||
|
|
|
@ -40,7 +40,7 @@ class GetPostDetailApplicationService(
|
|||
|
||||
val iconMedia = actor.icon?.let { mediaRepository.findById(it) }
|
||||
|
||||
val mediaList = mediaRepository.findByIds(post.mediaIds)
|
||||
val mediaList = mediaRepository.findByIdIn(post.mediaIds)
|
||||
|
||||
val reactions = reactionsQueryService.findAllByPostId(post.id)
|
||||
|
||||
|
@ -82,7 +82,7 @@ class GetPostDetailApplicationService(
|
|||
actor to iconMedia
|
||||
}
|
||||
|
||||
val mediaList = mediaRepository.findByIds(post.mediaIds)
|
||||
val mediaList = mediaRepository.findByIdIn(post.mediaIds)
|
||||
return PostDetail.of(
|
||||
post = post,
|
||||
actor = first,
|
||||
|
|
|
@ -85,31 +85,40 @@ class Actor(
|
|||
}
|
||||
|
||||
var alsoKnownAs = alsoKnownAs
|
||||
set(value) {
|
||||
require(value.none { it == id })
|
||||
field = value
|
||||
}
|
||||
private set
|
||||
|
||||
fun setAlsoKnownAs(alsoKnownAs: Set<ActorId>) {
|
||||
require(alsoKnownAs.none { it == id })
|
||||
this.alsoKnownAs = alsoKnownAs
|
||||
}
|
||||
|
||||
var moveTo = moveTo
|
||||
set(value) {
|
||||
require(value != id)
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(MOVE))
|
||||
field = value
|
||||
}
|
||||
private set
|
||||
|
||||
fun setMoveTo(moveTo: ActorId?) {
|
||||
require(moveTo != id)
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(MOVE))
|
||||
this.moveTo = moveTo
|
||||
}
|
||||
|
||||
var emojis = emojiIds
|
||||
private set
|
||||
|
||||
var description = description
|
||||
set(value) {
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(UPDATE))
|
||||
field = value
|
||||
}
|
||||
private set
|
||||
|
||||
fun setDescription(description: ActorDescription) {
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(UPDATE))
|
||||
this.description = description
|
||||
}
|
||||
|
||||
var screenName = screenName
|
||||
set(value) {
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(UPDATE))
|
||||
field = value
|
||||
}
|
||||
private set
|
||||
|
||||
fun setScreenName(screenName: ActorScreenName) {
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(UPDATE))
|
||||
this.screenName = screenName
|
||||
}
|
||||
|
||||
var deleted = deleted
|
||||
private set
|
||||
|
@ -135,4 +144,48 @@ class Actor(
|
|||
fun checkUpdate() {
|
||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(CHECK_UPDATE))
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Actor
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
|
||||
override fun toString(): String {
|
||||
return "Actor(" +
|
||||
"id=$id, " +
|
||||
"name=$name, " +
|
||||
"domain=$domain, " +
|
||||
"inbox=$inbox, " +
|
||||
"outbox=$outbox, " +
|
||||
"url=$url, " +
|
||||
"publicKey=$publicKey, " +
|
||||
"privateKey=$privateKey, " +
|
||||
"createdAt=$createdAt, " +
|
||||
"keyId=$keyId, " +
|
||||
"followersEndpoint=$followersEndpoint, " +
|
||||
"followingEndpoint=$followingEndpoint, " +
|
||||
"instance=$instance, " +
|
||||
"locked=$locked, " +
|
||||
"followersCount=$followersCount, " +
|
||||
"followingCount=$followingCount, " +
|
||||
"postsCount=$postsCount, " +
|
||||
"lastPostAt=$lastPostAt, " +
|
||||
"lastUpdateAt=$lastUpdateAt, " +
|
||||
"banner=$banner, " +
|
||||
"icon=$icon, " +
|
||||
"suspend=$suspend, " +
|
||||
"alsoKnownAs=$alsoKnownAs, " +
|
||||
"moveTo=$moveTo, " +
|
||||
"emojis=$emojis, " +
|
||||
"description=$description, " +
|
||||
"screenName=$screenName, " +
|
||||
"deleted=$deleted" +
|
||||
")"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,17 @@ package dev.usbharu.hideout.core.domain.model.actor
|
|||
class ActorDescription(description: String) {
|
||||
val description: String = description.take(LENGTH)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as ActorDescription
|
||||
|
||||
return description == other.description
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = description.hashCode()
|
||||
|
||||
companion object {
|
||||
const val LENGTH = 10000
|
||||
val empty = ActorDescription("")
|
||||
|
|
|
@ -20,6 +20,17 @@ class ActorScreenName(screenName: String) {
|
|||
|
||||
val screenName: String = screenName.take(LENGTH)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as ActorScreenName
|
||||
|
||||
return screenName == other.screenName
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = screenName.hashCode()
|
||||
|
||||
companion object {
|
||||
const val LENGTH = 300
|
||||
val empty = ActorScreenName("")
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,19 @@ 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
|
||||
}
|
||||
|
|
|
@ -19,6 +19,6 @@ package dev.usbharu.hideout.core.domain.model.media
|
|||
interface MediaRepository {
|
||||
suspend fun save(media: Media): Media
|
||||
suspend fun findById(id: MediaId): Media?
|
||||
suspend fun findByIds(ids: List<MediaId>): List<Media>
|
||||
suspend fun findByIdIn(ids: List<MediaId>): List<Media>
|
||||
suspend fun delete(media: Media)
|
||||
}
|
||||
|
|
|
@ -34,18 +34,4 @@ interface RelationshipRepository {
|
|||
targetIds: List<ActorId>,
|
||||
following: Boolean
|
||||
): List<Relationship>
|
||||
|
||||
suspend fun findByTargetId(
|
||||
targetId: ActorId,
|
||||
option: FindRelationshipOption? = null,
|
||||
inverseOption: FindRelationshipOption? = null
|
||||
): List<Relationship>
|
||||
}
|
||||
|
||||
data class FindRelationshipOption(
|
||||
val follow: Boolean? = null,
|
||||
val block: Boolean? = null,
|
||||
val mute: Boolean? = null,
|
||||
val followRequest: Boolean? = null,
|
||||
val muteFollowRequest: Boolean? = null
|
||||
)
|
||||
|
|
|
@ -26,6 +26,17 @@ class Timeline(
|
|||
addDomainEvent(TimelineEventFactory(this).createEvent(TimelineEvent.CHANGE_VISIBILITY))
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Timeline
|
||||
|
||||
return id == other.id
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = id.hashCode()
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
id: TimelineId,
|
||||
|
|
|
@ -35,7 +35,7 @@ class ActorQueryMapper(private val actorResultRowMapper: ResultRowMapper<Actor>)
|
|||
.first()
|
||||
.let(actorResultRowMapper::map)
|
||||
.apply {
|
||||
alsoKnownAs = buildAlsoKnownAs(it)
|
||||
setAlsoKnownAs(buildAlsoKnownAs(it))
|
||||
clearDomainEvents()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import dev.usbharu.hideout.core.domain.model.support.domain.Domain
|
|||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.springframework.stereotype.Component
|
||||
import java.net.URI
|
||||
|
||||
@Component
|
||||
class ActorResultRowMapper : ResultRowMapper<Actor> {
|
||||
|
@ -35,15 +34,15 @@ class ActorResultRowMapper : ResultRowMapper<Actor> {
|
|||
domain = Domain(resultRow[Actors.domain]),
|
||||
screenName = ActorScreenName(resultRow[Actors.screenName]),
|
||||
description = ActorDescription(resultRow[Actors.description]),
|
||||
inbox = URI.create(resultRow[Actors.inbox]),
|
||||
outbox = URI.create(resultRow[Actors.outbox]),
|
||||
url = URI.create(resultRow[Actors.url]),
|
||||
inbox = resultRow[Actors.inbox],
|
||||
outbox = resultRow[Actors.outbox],
|
||||
url = resultRow[Actors.url],
|
||||
publicKey = ActorPublicKey(resultRow[Actors.publicKey]),
|
||||
privateKey = resultRow[Actors.privateKey]?.let { ActorPrivateKey(it) },
|
||||
createdAt = resultRow[Actors.createdAt],
|
||||
keyId = ActorKeyId(resultRow[Actors.keyId]),
|
||||
followersEndpoint = resultRow[Actors.followers]?.let { URI.create(it) },
|
||||
followingEndpoint = resultRow[Actors.following]?.let { URI.create(it) },
|
||||
followersEndpoint = resultRow[Actors.followers],
|
||||
followingEndpoint = resultRow[Actors.following],
|
||||
instance = InstanceId(resultRow[Actors.instance]),
|
||||
locked = resultRow[Actors.locked],
|
||||
followersCount = resultRow[Actors.followersCount]?.let { ActorRelationshipCount(it) },
|
||||
|
|
|
@ -33,7 +33,7 @@ class FilterQueryMapper(private val filterResultRowMapper: ResultRowMapper<Filte
|
|||
it
|
||||
.first()
|
||||
.let(filterResultRowMapper::map)
|
||||
.apply {
|
||||
.run {
|
||||
reconstructWith(
|
||||
it.mapNotNull { resultRow: ResultRow ->
|
||||
FilterKeyword(
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposed
|
||||
|
||||
import org.jetbrains.exposed.sql.Column
|
||||
import org.jetbrains.exposed.sql.ColumnType
|
||||
import org.jetbrains.exposed.sql.Table
|
||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||
import java.net.URI
|
||||
|
||||
class UriColumnType(val colLength: Int) : ColumnType<URI>() {
|
||||
override fun sqlType(): String = currentDialect.dataTypeProvider.varcharType(colLength)
|
||||
|
||||
override fun valueFromDB(value: Any): URI? = when (value) {
|
||||
is URI -> value
|
||||
is String -> URI(value)
|
||||
is CharSequence -> URI(value.toString())
|
||||
else -> error("Unexpected value of type String: $value of ${value::class.qualifiedName}")
|
||||
}
|
||||
|
||||
override fun notNullValueToDB(value: URI): Any = value.toString()
|
||||
}
|
||||
|
||||
fun Table.uri(name: String, colLength: Int): Column<URI> = registerColumn(name, UriColumnType(colLength))
|
|
@ -90,9 +90,9 @@ class ExposedUserTimelineQueryService : UserTimelineQueryService, AbstractReposi
|
|||
name = it[Actors.name],
|
||||
domain = it[Actors.domain],
|
||||
screenName = it[Actors.screenName],
|
||||
url = URI.create(it[Actors.url]),
|
||||
url = it[Actors.url],
|
||||
locked = it[Actors.locked],
|
||||
icon = it.getOrNull(iconMedia[Media.url])?.let { URI.create(it) }
|
||||
icon = it.getOrNull(iconMedia[Media.url])
|
||||
),
|
||||
overview = it[authorizedQuery[Posts.overview]],
|
||||
text = it[authorizedQuery[Posts.text]],
|
||||
|
|
|
@ -75,6 +75,7 @@ class ExposedActorInstanceRelationshipRepository(override val domainEventPublish
|
|||
ActorInstanceRelationships.actorId eq actorId.id and
|
||||
(ActorInstanceRelationships.instanceId eq instanceId.instanceId)
|
||||
}
|
||||
.limit(1)
|
||||
.singleOrNull()
|
||||
?.toActorInstanceRelationship()
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.usbharu.hideout.core.domain.model.support.domain.Domain
|
|||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository
|
||||
import dev.usbharu.hideout.core.infrastructure.exposed.QueryMapper
|
||||
import dev.usbharu.hideout.core.infrastructure.exposed.uri
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||
|
@ -30,15 +31,15 @@ class ExposedActorRepository(
|
|||
it[domain] = actor.domain.domain
|
||||
it[screenName] = actor.screenName.screenName
|
||||
it[description] = actor.description.description
|
||||
it[inbox] = actor.inbox.toString()
|
||||
it[outbox] = actor.outbox.toString()
|
||||
it[url] = actor.url.toString()
|
||||
it[inbox] = actor.inbox
|
||||
it[outbox] = actor.outbox
|
||||
it[url] = actor.url
|
||||
it[publicKey] = actor.publicKey.publicKey
|
||||
it[privateKey] = actor.privateKey?.privateKey
|
||||
it[createdAt] = actor.createdAt
|
||||
it[keyId] = actor.keyId.keyId
|
||||
it[following] = actor.followingEndpoint?.toString()
|
||||
it[followers] = actor.followersEndpoint?.toString()
|
||||
it[following] = actor.followingEndpoint
|
||||
it[followers] = actor.followersEndpoint
|
||||
it[instance] = actor.instance.instanceId
|
||||
it[locked] = actor.locked
|
||||
it[followingCount] = actor.followingCount?.relationshipCount
|
||||
|
@ -69,8 +70,8 @@ class ExposedActorRepository(
|
|||
|
||||
override suspend fun delete(actor: Actor) {
|
||||
query {
|
||||
Actors.deleteWhere { id eq actor.id.id }
|
||||
ActorsAlsoKnownAs.deleteWhere { actorId eq actor.id.id }
|
||||
Actors.deleteWhere { id eq actor.id.id }
|
||||
onComplete {
|
||||
update(actor)
|
||||
}
|
||||
|
@ -126,15 +127,15 @@ object Actors : Table("actors") {
|
|||
val domain = varchar("domain", Domain.LENGTH)
|
||||
val screenName = varchar("screen_name", ActorScreenName.LENGTH)
|
||||
val description = varchar("description", ActorDescription.LENGTH)
|
||||
val inbox = varchar("inbox", 1000).uniqueIndex()
|
||||
val outbox = varchar("outbox", 1000).uniqueIndex()
|
||||
val url = varchar("url", 1000).uniqueIndex()
|
||||
val inbox = uri("inbox", 1000).uniqueIndex()
|
||||
val outbox = uri("outbox", 1000).uniqueIndex()
|
||||
val url = uri("url", 1000).uniqueIndex()
|
||||
val publicKey = varchar("public_key", 10000)
|
||||
val privateKey = varchar("private_key", 100000).nullable()
|
||||
val createdAt = timestamp("created_at")
|
||||
val keyId = varchar("key_id", 1000)
|
||||
val following = varchar("following", 1000).nullable()
|
||||
val followers = varchar("followers", 1000).nullable()
|
||||
val following = uri("following", 1000).nullable()
|
||||
val followers = uri("followers", 1000).nullable()
|
||||
val instance = long("instance").references(Instance.id)
|
||||
val locked = bool("locked")
|
||||
val followingCount = integer("following_count").nullable()
|
||||
|
|
|
@ -31,8 +31,7 @@ import org.springframework.stereotype.Repository
|
|||
import java.net.URI
|
||||
|
||||
@Repository
|
||||
class CustomEmojiRepositoryImpl : CustomEmojiRepository,
|
||||
AbstractRepository() {
|
||||
class ExposedCustomEmojiRepository : CustomEmojiRepository, AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
|
@ -50,7 +49,12 @@ class CustomEmojiRepositoryImpl : 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 CustomEmojiRepositoryImpl : CustomEmojiRepository,
|
|||
}
|
||||
|
||||
override suspend fun findByNamesAndDomain(names: List<String>, domain: String): List<CustomEmoji> = query {
|
||||
return@query CustomEmojis
|
||||
CustomEmojis
|
||||
.selectAll()
|
||||
.where {
|
||||
CustomEmojis.name inList names and (CustomEmojis.domain eq domain)
|
||||
|
@ -67,7 +71,7 @@ class CustomEmojiRepositoryImpl : CustomEmojiRepository,
|
|||
}
|
||||
|
||||
override suspend fun findByIds(ids: List<Long>): List<CustomEmoji> = query {
|
||||
return@query CustomEmojis
|
||||
CustomEmojis
|
||||
.selectAll()
|
||||
.where {
|
||||
CustomEmojis.id inList ids
|
||||
|
@ -76,7 +80,7 @@ class CustomEmojiRepositoryImpl : CustomEmojiRepository,
|
|||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(CustomEmojiRepositoryImpl::class.java)
|
||||
private val logger = LoggerFactory.getLogger(ExposedCustomEmojiRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
|
@ -63,18 +63,20 @@ class ExposedFilterRepository(private val filterQueryMapper: QueryMapper<Filter>
|
|||
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<Filter> = 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 {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.instance.*
|
||||
import dev.usbharu.hideout.core.infrastructure.exposed.uri
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||
|
@ -27,7 +28,7 @@ import java.net.URI
|
|||
import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity
|
||||
|
||||
@Repository
|
||||
class InstanceRepositoryImpl : InstanceRepository,
|
||||
class ExposedInstanceRepository : InstanceRepository,
|
||||
AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
@ -37,9 +38,9 @@ class InstanceRepositoryImpl : InstanceRepository,
|
|||
it[id] = instance.id.instanceId
|
||||
it[name] = instance.name.name
|
||||
it[description] = instance.description.description
|
||||
it[url] = instance.url.toString()
|
||||
it[iconUrl] = instance.iconUrl.toString()
|
||||
it[sharedInbox] = instance.sharedInbox?.toString()
|
||||
it[url] = instance.url
|
||||
it[iconUrl] = instance.iconUrl
|
||||
it[sharedInbox] = instance.sharedInbox
|
||||
it[software] = instance.software.software
|
||||
it[version] = instance.version.version
|
||||
it[isBlocked] = instance.isBlocked
|
||||
|
@ -52,7 +53,7 @@ class InstanceRepositoryImpl : InstanceRepository,
|
|||
}
|
||||
|
||||
override suspend fun findById(id: InstanceId): InstanceEntity? = query {
|
||||
return@query Instance.selectAll().where { Instance.id eq id.instanceId }
|
||||
return@query Instance.selectAll().where { Instance.id eq id.instanceId }.limit(1)
|
||||
.singleOrNull()?.toInstance()
|
||||
}
|
||||
|
||||
|
@ -61,11 +62,11 @@ class InstanceRepositoryImpl : InstanceRepository,
|
|||
}
|
||||
|
||||
override suspend fun findByUrl(url: URI): dev.usbharu.hideout.core.domain.model.instance.Instance? = query {
|
||||
return@query Instance.selectAll().where { Instance.url eq url.toString() }.singleOrNull()?.toInstance()
|
||||
return@query Instance.selectAll().where { Instance.url eq url }.limit(1).singleOrNull()?.toInstance()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(InstanceRepositoryImpl::class.java)
|
||||
private val logger = LoggerFactory.getLogger(ExposedInstanceRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,9 +75,9 @@ fun ResultRow.toInstance(): InstanceEntity {
|
|||
id = InstanceId(this[Instance.id]),
|
||||
name = InstanceName(this[Instance.name]),
|
||||
description = InstanceDescription(this[Instance.description]),
|
||||
url = URI.create(this[Instance.url]),
|
||||
iconUrl = URI.create(this[Instance.iconUrl]),
|
||||
sharedInbox = this[Instance.sharedInbox]?.let { URI.create(it) },
|
||||
url = this[Instance.url],
|
||||
iconUrl = this[Instance.iconUrl],
|
||||
sharedInbox = this[Instance.sharedInbox],
|
||||
software = InstanceSoftware(this[Instance.software]),
|
||||
version = InstanceVersion(this[Instance.version]),
|
||||
isBlocked = this[Instance.isBlocked],
|
||||
|
@ -90,9 +91,9 @@ object Instance : Table("instance") {
|
|||
val id = long("id")
|
||||
val name = varchar("name", 1000)
|
||||
val description = varchar("description", 5000)
|
||||
val url = varchar("url", 255).uniqueIndex()
|
||||
val iconUrl = varchar("icon_url", 255)
|
||||
val sharedInbox = varchar("shared_inbox", 255).nullable().uniqueIndex()
|
||||
val url = uri("url", 255).uniqueIndex()
|
||||
val iconUrl = uri("icon_url", 255)
|
||||
val sharedInbox = uri("shared_inbox", 255).nullable().uniqueIndex()
|
||||
val software = varchar("software", 255)
|
||||
val version = varchar("version", 255)
|
||||
val isBlocked = bool("is_blocked")
|
|
@ -18,16 +18,16 @@ package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
|||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.media.*
|
||||
import dev.usbharu.hideout.core.infrastructure.exposed.uri
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.net.URI
|
||||
import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia
|
||||
|
||||
@Repository
|
||||
class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
||||
class ExposedMediaRepository : MediaRepository, AbstractRepository() {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
|
@ -35,9 +35,9 @@ class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
|||
Media.upsert {
|
||||
it[id] = media.id.id
|
||||
it[name] = media.name.name
|
||||
it[url] = media.url.toString()
|
||||
it[remoteUrl] = media.remoteUrl?.toString()
|
||||
it[thumbnailUrl] = media.thumbnailUrl?.toString()
|
||||
it[url] = media.url
|
||||
it[remoteUrl] = media.remoteUrl
|
||||
it[thumbnailUrl] = media.thumbnailUrl
|
||||
it[type] = media.type.name
|
||||
it[blurhash] = media.blurHash?.hash
|
||||
it[mimeType] = media.mimeType.type + "/" + media.mimeType.subtype
|
||||
|
@ -51,12 +51,13 @@ class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
|||
return query {
|
||||
return@query Media
|
||||
.selectAll().where { Media.id eq id.id }
|
||||
.limit(1)
|
||||
.singleOrNull()
|
||||
?.toMedia()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun findByIds(ids: List<MediaId>): List<dev.usbharu.hideout.core.domain.model.media.Media> {
|
||||
override suspend fun findByIdIn(ids: List<MediaId>): List<dev.usbharu.hideout.core.domain.model.media.Media> {
|
||||
return query {
|
||||
return@query Media
|
||||
.selectAll()
|
||||
|
@ -72,7 +73,7 @@ class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(MediaRepositoryImpl::class.java)
|
||||
private val logger = LoggerFactory.getLogger(ExposedMediaRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,9 +83,9 @@ fun ResultRow.toMedia(): EntityMedia {
|
|||
return EntityMedia(
|
||||
id = MediaId(this[Media.id]),
|
||||
name = MediaName(this[Media.name]),
|
||||
url = URI.create(this[Media.url]),
|
||||
remoteUrl = this[Media.remoteUrl]?.let { URI.create(it) },
|
||||
thumbnailUrl = this[Media.thumbnailUrl]?.let { URI.create(it) },
|
||||
url = this[Media.url],
|
||||
remoteUrl = this[Media.remoteUrl],
|
||||
thumbnailUrl = this[Media.thumbnailUrl],
|
||||
type = fileType,
|
||||
blurHash = this[Media.blurhash]?.let { MediaBlurHash(it) },
|
||||
mimeType = MimeType(mimeType.substringBefore("/"), mimeType.substringAfter("/"), fileType),
|
||||
|
@ -99,9 +100,9 @@ fun ResultRow.toMediaOrNull(): EntityMedia? {
|
|||
return EntityMedia(
|
||||
id = MediaId(this.getOrNull(Media.id) ?: return null),
|
||||
name = MediaName(this.getOrNull(Media.name) ?: return null),
|
||||
url = URI.create(this.getOrNull(Media.url) ?: return null),
|
||||
remoteUrl = this[Media.remoteUrl]?.let { URI.create(it) },
|
||||
thumbnailUrl = this[Media.thumbnailUrl]?.let { URI.create(it) },
|
||||
url = this.getOrNull(Media.url) ?: return null,
|
||||
remoteUrl = this[Media.remoteUrl],
|
||||
thumbnailUrl = this[Media.thumbnailUrl],
|
||||
type = FileType.valueOf(this[Media.type]),
|
||||
blurHash = this[Media.blurhash]?.let { MediaBlurHash(it) },
|
||||
mimeType = MimeType(mimeType.substringBefore("/"), mimeType.substringAfter("/"), fileType),
|
||||
|
@ -113,9 +114,9 @@ fun ResultRow.toMediaOrNull(): EntityMedia? {
|
|||
object Media : Table("media") {
|
||||
val id = long("id")
|
||||
val name = varchar("name", 255)
|
||||
val url = varchar("url", 255).uniqueIndex()
|
||||
val remoteUrl = varchar("remote_url", 255).uniqueIndex().nullable()
|
||||
val thumbnailUrl = varchar("thumbnail_url", 255).uniqueIndex().nullable()
|
||||
val url = uri("url", 255).uniqueIndex()
|
||||
val remoteUrl = uri("remote_url", 255).uniqueIndex().nullable()
|
||||
val thumbnailUrl = uri("thumbnail_url", 255).uniqueIndex().nullable()
|
||||
val type = varchar("type", 100)
|
||||
val blurhash = varchar("blurhash", 255).nullable()
|
||||
val mimeType = varchar("mime_type", 255)
|
|
@ -163,6 +163,8 @@ class ExposedPostRepository(
|
|||
override suspend fun findById(id: PostId): Post? = query {
|
||||
Posts
|
||||
.leftJoin(PostsMedia)
|
||||
.leftJoin(PostsEmojis)
|
||||
.leftJoin(PostsVisibleActors)
|
||||
.selectAll()
|
||||
.where {
|
||||
Posts.id eq id.id
|
||||
|
@ -174,6 +176,9 @@ class ExposedPostRepository(
|
|||
override suspend fun findAllById(ids: List<PostId>): List<Post> {
|
||||
return query {
|
||||
Posts
|
||||
.leftJoin(PostsMedia)
|
||||
.leftJoin(PostsEmojis)
|
||||
.leftJoin(PostsVisibleActors)
|
||||
.selectAll()
|
||||
.where {
|
||||
Posts.id inList ids.map { it.id }
|
||||
|
@ -182,21 +187,43 @@ class ExposedPostRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun findByActorId(id: ActorId, page: Page?): PaginationList<Post, PostId> = PaginationList(
|
||||
query {
|
||||
Posts
|
||||
override suspend fun findByActorId(id: ActorId, page: Page?): PaginationList<Post, PostId> {
|
||||
val postList = query {
|
||||
val query = Posts
|
||||
.selectAll()
|
||||
.where {
|
||||
actorId eq actorId
|
||||
actorId eq id.id
|
||||
}
|
||||
.let(postQueryMapper::map)
|
||||
},
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
||||
page(page, query)
|
||||
|
||||
query.let(postQueryMapper::map)
|
||||
}
|
||||
|
||||
val posts = if (page?.minId != null) {
|
||||
postList.reversed()
|
||||
} else {
|
||||
postList
|
||||
}
|
||||
|
||||
return PaginationList(
|
||||
posts,
|
||||
posts.lastOrNull()?.id,
|
||||
posts.firstOrNull()?.id
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun delete(post: Post) {
|
||||
query {
|
||||
PostsMedia.deleteWhere {
|
||||
postId eq post.id.id
|
||||
}
|
||||
PostsEmojis.deleteWhere {
|
||||
postId eq post.id.id
|
||||
}
|
||||
PostsVisibleActors.deleteWhere {
|
||||
postId eq post.id.id
|
||||
}
|
||||
Posts.deleteWhere {
|
||||
id eq post.id.id
|
||||
}
|
||||
|
@ -218,17 +245,7 @@ class ExposedPostRepository(
|
|||
Posts.actorId eq actorId.id and (visibility inList visibilityList.map { it.name })
|
||||
}
|
||||
|
||||
if (of?.minId != null) {
|
||||
query.orderBy(Posts.createdAt, SortOrder.ASC)
|
||||
of.minId?.let { query.andWhere { Posts.id greater it } }
|
||||
of.maxId?.let { query.andWhere { Posts.id less it } }
|
||||
} else {
|
||||
query.orderBy(Posts.createdAt, SortOrder.DESC)
|
||||
of?.sinceId?.let { query.andWhere { Posts.id greater it } }
|
||||
of?.maxId?.let { query.andWhere { Posts.id less it } }
|
||||
}
|
||||
|
||||
of?.limit?.let { query.limit(it) }
|
||||
page(of, query)
|
||||
|
||||
query.let(postQueryMapper::map)
|
||||
}
|
||||
|
@ -246,6 +263,23 @@ class ExposedPostRepository(
|
|||
)
|
||||
}
|
||||
|
||||
private fun page(
|
||||
page: Page?,
|
||||
query: Query
|
||||
) {
|
||||
if (page?.minId != null) {
|
||||
query.orderBy(createdAt, SortOrder.ASC)
|
||||
page.minId!!.let { query.andWhere { id greater it } }
|
||||
page.maxId?.let { query.andWhere { id less it } }
|
||||
} else {
|
||||
query.orderBy(createdAt, SortOrder.DESC)
|
||||
page?.sinceId?.let { query.andWhere { id greater it } }
|
||||
page?.maxId?.let { query.andWhere { id less it } }
|
||||
}
|
||||
|
||||
page?.limit?.let { query.limit(it) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedPostRepository::class.java)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.FindRelationshipOption
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
|
@ -69,7 +68,7 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve
|
|||
override suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship? = query {
|
||||
Relationships.selectAll().where {
|
||||
Relationships.actorId eq actorId.id and (Relationships.targetActorId eq targetId.id)
|
||||
}.singleOrNull()?.toRelationships()
|
||||
}.limit(1).singleOrNull()?.toRelationships()
|
||||
}
|
||||
|
||||
override suspend fun findByActorIdsAndTargetIdAndBlocking(
|
||||
|
@ -78,7 +77,9 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve
|
|||
blocking: Boolean
|
||||
): List<Relationship> = query {
|
||||
Relationships.selectAll().where {
|
||||
Relationships.actorId inList actorIds.map { it.id } and (Relationships.targetActorId eq targetId.id)
|
||||
Relationships.actorId inList actorIds.map {
|
||||
it.id
|
||||
} and (Relationships.targetActorId eq targetId.id) and (Relationships.blocking eq blocking)
|
||||
}.map { it.toRelationships() }
|
||||
}
|
||||
|
||||
|
@ -88,49 +89,19 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve
|
|||
following: Boolean
|
||||
): List<Relationship> = query {
|
||||
Relationships.selectAll().where {
|
||||
Relationships.actorId eq actorId.id and (Relationships.targetActorId inList targetIds.map { it.id })
|
||||
Relationships.actorId eq actorId.id and (
|
||||
Relationships.targetActorId inList targetIds.map {
|
||||
it.id
|
||||
}
|
||||
) and (Relationships.following eq following)
|
||||
}.map { it.toRelationships() }
|
||||
}
|
||||
|
||||
override suspend fun findByTargetId(
|
||||
targetId: ActorId,
|
||||
option: FindRelationshipOption?,
|
||||
inverseOption: FindRelationshipOption?
|
||||
): List<Relationship> {
|
||||
val query1 = Relationships.selectAll().where { Relationships.actorId eq targetId.id }
|
||||
inverseOption.apply(query1)
|
||||
// todo 逆のほうがいいかも
|
||||
val query = query1.alias("INV").selectAll().where {
|
||||
Relationships.targetActorId eq targetId.id
|
||||
}
|
||||
option.apply(query)
|
||||
|
||||
return query.map(ResultRow::toRelationships)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(ExposedRelationshipRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
fun FindRelationshipOption?.apply(query: Query) {
|
||||
if (this?.follow != null) {
|
||||
query.andWhere { Relationships.following eq this@apply.follow }
|
||||
}
|
||||
if (this?.mute != null) {
|
||||
query.andWhere { Relationships.muting eq this@apply.mute }
|
||||
}
|
||||
if (this?.block != null) {
|
||||
query.andWhere { Relationships.blocking eq this@apply.block }
|
||||
}
|
||||
if (this?.followRequest != null) {
|
||||
query.andWhere { Relationships.followRequesting eq this@apply.followRequest }
|
||||
}
|
||||
if (this?.muteFollowRequest != null) {
|
||||
query.andWhere { Relationships.mutingFollowRequest eq this@apply.muteFollowRequest }
|
||||
}
|
||||
}
|
||||
|
||||
fun ResultRow.toRelationships(): Relationship = Relationship(
|
||||
actorId = ActorId(this[Relationships.actorId]),
|
||||
targetActorId = ActorId(this[Relationships.targetActorId]),
|
||||
|
|
|
@ -54,7 +54,7 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu
|
|||
|
||||
override suspend fun findById(id: TimelineId): Timeline? {
|
||||
return query {
|
||||
Timelines.selectAll().where { Timelines.id eq id.value }.firstOrNull()?.toTimeline()
|
||||
Timelines.selectAll().where { Timelines.id eq id.value }.limit(1).firstOrNull()?.toTimeline()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,31 +32,27 @@ import org.slf4j.LoggerFactory
|
|||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPublisher) :
|
||||
class ExposedUserDetailRepository(override val domainEventPublisher: DomainEventPublisher) :
|
||||
UserDetailRepository,
|
||||
AbstractRepository(),
|
||||
DomainEventPublishableRepository<UserDetail> {
|
||||
override val logger: Logger
|
||||
get() = Companion.logger
|
||||
|
||||
override suspend fun save(userDetail: UserDetail): UserDetail {
|
||||
val userDetail1 = query {
|
||||
UserDetails.upsert {
|
||||
it[id] = userDetail.id.id
|
||||
it[actorId] = userDetail.actorId.id
|
||||
it[password] = userDetail.password.password
|
||||
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
|
||||
it[lastMigration] = userDetail.lastMigration
|
||||
it[homeTimelineId] = userDetail.homeTimelineId?.value
|
||||
}
|
||||
|
||||
onComplete {
|
||||
update(userDetail)
|
||||
}
|
||||
userDetail
|
||||
override suspend fun save(userDetail: UserDetail): UserDetail = query {
|
||||
UserDetails.upsert {
|
||||
it[id] = userDetail.id.id
|
||||
it[actorId] = userDetail.actorId.id
|
||||
it[password] = userDetail.password.password
|
||||
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
|
||||
it[lastMigration] = userDetail.lastMigration
|
||||
it[homeTimelineId] = userDetail.homeTimelineId?.value
|
||||
}
|
||||
|
||||
return userDetail1
|
||||
onComplete {
|
||||
update(userDetail)
|
||||
}
|
||||
userDetail
|
||||
}
|
||||
|
||||
override suspend fun delete(userDetail: UserDetail) {
|
||||
|
@ -71,6 +67,7 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub
|
|||
override suspend fun findByActorId(actorId: Long): UserDetail? = query {
|
||||
return@query UserDetails
|
||||
.selectAll().where { UserDetails.actorId eq actorId }
|
||||
.limit(1)
|
||||
.singleOrNull()
|
||||
?.let {
|
||||
userDetail(it)
|
||||
|
@ -80,6 +77,7 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub
|
|||
override suspend fun findById(id: UserDetailId): UserDetail? = query {
|
||||
UserDetails
|
||||
.selectAll().where { UserDetails.id eq id.id }
|
||||
.limit(1)
|
||||
.singleOrNull()
|
||||
?.let {
|
||||
userDetail(it)
|
||||
|
@ -107,7 +105,7 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub
|
|||
)
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UserDetailRepositoryImpl::class.java)
|
||||
private val logger = LoggerFactory.getLogger(ExposedUserDetailRepository::class.java)
|
||||
}
|
||||
}
|
||||
|
|
@ -158,7 +158,7 @@ open class DefaultTimelineStore(
|
|||
actorRepository.findAllById(actorIds).associateBy { it.id }
|
||||
|
||||
override suspend fun getMedias(mediaIds: List<MediaId>): Map<MediaId, Media> =
|
||||
mediaRepository.findByIds(mediaIds).associateBy { it.id }
|
||||
mediaRepository.findByIdIn(mediaIds).associateBy { it.id }
|
||||
|
||||
override suspend fun getReactions(postIds: List<PostId>): Map<PostId, List<Reactions>> =
|
||||
reactionsQueryService.findAllByPostIdIn(postIds).groupBy { PostId(it.postId) }
|
||||
|
|
|
@ -34,7 +34,7 @@ class ActorsTest {
|
|||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||
|
||||
val actorIds = setOf(ActorId(100), ActorId(200))
|
||||
actor.alsoKnownAs = actorIds
|
||||
actor.setAlsoKnownAs(actorIds)
|
||||
|
||||
assertEquals(actorIds, actor.alsoKnownAs)
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class ActorsTest {
|
|||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||
|
||||
|
||||
actor.moveTo = ActorId(100)
|
||||
actor.setMoveTo(ActorId(100))
|
||||
|
||||
assertContainsEvent(actor, ActorEvent.MOVE.eventName)
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class ActorsTest {
|
|||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
actor.alsoKnownAs = setOf(actor.id)
|
||||
actor.setAlsoKnownAs(setOf(actor.id))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ class ActorsTest {
|
|||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
actor.moveTo = actor.id
|
||||
actor.setMoveTo(actor.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ class ActorsTest {
|
|||
fun descriptionが更新されたときupdateイベントが発生する() {
|
||||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||
|
||||
actor.description = ActorDescription("hoge fuga")
|
||||
actor.setDescription(ActorDescription("hoge fuga"))
|
||||
|
||||
assertContainsEvent(actor, ActorEvent.UPDATE.eventName)
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class ActorsTest {
|
|||
fun screenNameが更新されたときupdateイベントが発生する() {
|
||||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||
|
||||
actor.screenName = ActorScreenName("fuga hoge")
|
||||
actor.setScreenName(ActorScreenName("fuga hoge"))
|
||||
|
||||
assertContainsEvent(actor, ActorEvent.UPDATE.eventName)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package dev.usbharu.hideout.core.domain.model.actor
|
|||
|
||||
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.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.support.domain.Domain
|
||||
import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
@ -32,12 +33,14 @@ object TestActorFactory {
|
|||
followingCount: Int = 0,
|
||||
postCount: Int = 0,
|
||||
lastPostDate: Instant? = null,
|
||||
lastUpdateAt: Instant = createdAt,
|
||||
suspend: Boolean = false,
|
||||
alsoKnownAs: Set<ActorId> = emptySet(),
|
||||
moveTo: Long? = null,
|
||||
emojiIds: Set<CustomEmojiId> = emptySet(),
|
||||
deleted: Boolean = false,
|
||||
roles: Set<Role> = emptySet(),
|
||||
icon: Long? = null,
|
||||
banner: Long? = null,
|
||||
): Actor {
|
||||
return runBlocking {
|
||||
Actor(
|
||||
|
@ -61,13 +64,14 @@ object TestActorFactory {
|
|||
followingCount = ActorRelationshipCount(followingCount),
|
||||
postsCount = ActorPostsCount(postCount),
|
||||
lastPostAt = lastPostDate,
|
||||
lastUpdateAt = lastUpdateAt,
|
||||
suspend = suspend,
|
||||
alsoKnownAs = alsoKnownAs,
|
||||
moveTo = moveTo?.let { ActorId(it) },
|
||||
emojiIds = emojiIds,
|
||||
deleted = deleted,
|
||||
icon = null,
|
||||
banner = null,
|
||||
icon = icon?.let { MediaId(it) },
|
||||
banner = banner?.let { MediaId(it) },
|
||||
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package dev.usbharu.hideout.core.domain.model.post
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
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.media.MediaId
|
||||
import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService
|
||||
|
@ -29,13 +30,14 @@ object TestPostFactory {
|
|||
visibleActors: List<Long> = emptyList(),
|
||||
hide: Boolean = false,
|
||||
moveTo: Long? = null,
|
||||
emojiIds: List<Long> = emptyList(),
|
||||
): Post {
|
||||
return Post(
|
||||
PostId(id),
|
||||
ActorId(actorId),
|
||||
instanceId = InstanceId(instanceId),
|
||||
overview = overview?.let { PostOverview(it) },
|
||||
content = PostContent(content, content, emptyList()),
|
||||
content = PostContent(content, content, emojiIds.map { CustomEmojiId(it) }),
|
||||
createdAt = createdAt,
|
||||
visibility = visibility,
|
||||
url = url,
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup.Operations
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationship
|
||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceId
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.jupiter.MockitoExtension
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import utils.AbstractRepositoryTest
|
||||
import utils.columns
|
||||
import utils.disableReferenceIntegrityConstraints
|
||||
import utils.isEqualTo
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
@ExtendWith(MockitoExtension::class)
|
||||
class ExposedActorInstanceRelationshipRepositoryTest : AbstractRepositoryTest(ActorInstanceRelationships) {
|
||||
|
||||
@InjectMocks
|
||||
lateinit var repository: ExposedActorInstanceRelationshipRepository
|
||||
|
||||
@Mock
|
||||
lateinit var domainEventPublisher: DomainEventPublisher
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがない場合はinsert() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(Operations.sql("SET REFERENTIAL_INTEGRITY FALSE"))
|
||||
insertInto(Instance.tableName) {
|
||||
columns(
|
||||
Instance.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"system",
|
||||
"",
|
||||
"https://example.com",
|
||||
"",
|
||||
null,
|
||||
"",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"2024-09-10 16:59:50.160202"
|
||||
)
|
||||
}
|
||||
insertInto("public.actors") {
|
||||
columns(
|
||||
Actors.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
|
||||
val actorInstanceRelationship = ActorInstanceRelationship(
|
||||
actorId = ActorId(1), instanceId = InstanceId(1), blocking = false, muting = false, doNotSendPrivate = false
|
||||
)
|
||||
|
||||
repository.save(actorInstanceRelationship)
|
||||
|
||||
dbSetup(to = dataSource) {
|
||||
execute(Operations.sql("SET REFERENTIAL_INTEGRITY TRUE"))
|
||||
}
|
||||
|
||||
assertThat(assertTable).row(0).isEqualTo(ActorInstanceRelationships.actorId, 1)
|
||||
.isEqualTo(ActorInstanceRelationships.actorId, 1).isEqualTo(ActorInstanceRelationships.blocking, false)
|
||||
.isEqualTo(ActorInstanceRelationships.muting, false)
|
||||
.isEqualTo(ActorInstanceRelationships.doNotSendPrivate, false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがある場合はupdate() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(Operations.sql("SET REFERENTIAL_INTEGRITY FALSE"))
|
||||
insertInto(Instance.tableName) {
|
||||
columns(
|
||||
Instance.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"system",
|
||||
"",
|
||||
"https://example.com",
|
||||
"",
|
||||
null,
|
||||
"",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"2024-09-10 16:59:50.160202"
|
||||
)
|
||||
}
|
||||
insertInto("public.actors") {
|
||||
columns(
|
||||
Actors.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto(ActorInstanceRelationships.tableName) {
|
||||
columns(ActorInstanceRelationships.columns)
|
||||
values(1, 1, true, true, true)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
|
||||
val actorInstanceRelationship = ActorInstanceRelationship(
|
||||
actorId = ActorId(1), instanceId = InstanceId(1), blocking = false, muting = false, doNotSendPrivate = false
|
||||
)
|
||||
|
||||
repository.save(actorInstanceRelationship)
|
||||
|
||||
dbSetup(to = dataSource) {
|
||||
execute(Operations.sql("SET REFERENTIAL_INTEGRITY TRUE"))
|
||||
}
|
||||
|
||||
assertThat(assertTable).row(0).isEqualTo(ActorInstanceRelationships.actorId, 1)
|
||||
.isEqualTo(ActorInstanceRelationships.actorId, 1).isEqualTo(ActorInstanceRelationships.blocking, false)
|
||||
.isEqualTo(ActorInstanceRelationships.muting, false)
|
||||
.isEqualTo(ActorInstanceRelationships.doNotSendPrivate, false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除される() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(Operations.sql("SET REFERENTIAL_INTEGRITY FALSE"))
|
||||
insertInto(ActorInstanceRelationships.tableName) {
|
||||
columns(ActorInstanceRelationships.columns)
|
||||
values(1, 1, true, true, true)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actorInstanceRelationship = ActorInstanceRelationship(
|
||||
actorId = ActorId(1), instanceId = InstanceId(1), blocking = false, muting = false, doNotSendPrivate = false
|
||||
)
|
||||
|
||||
change.setStartPointNow()
|
||||
|
||||
repository.delete(actorInstanceRelationship)
|
||||
|
||||
change.setEndPointNow()
|
||||
|
||||
assertThat(change)
|
||||
.changeOfDeletionOnTable(ActorInstanceRelationships.tableName)
|
||||
.rowAtStartPoint()
|
||||
.value(ActorInstanceRelationships.instanceId.name).isEqualTo(1)
|
||||
.value(ActorInstanceRelationships.actorId.name).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorIdAndInstanceId_指定したActorIdとInstanceIdで存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(ActorInstanceRelationships.tableName) {
|
||||
columns(ActorInstanceRelationships.columns)
|
||||
values(1, 1, true, true, true)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val expected = ActorInstanceRelationship(
|
||||
actorId = ActorId(1), instanceId = InstanceId(1), blocking = true, muting = true, doNotSendPrivate = true
|
||||
)
|
||||
|
||||
val actual = repository.findByActorIdAndInstanceId(ActorId(1), InstanceId(1))
|
||||
|
||||
assertNotNull(actual)
|
||||
assertEquals(expected, actual)
|
||||
assertEquals(expected.actorId, actual.actorId)
|
||||
assertEquals(expected.instanceId, actual.instanceId)
|
||||
assertEquals(expected.blocking, actual.blocking)
|
||||
assertEquals(expected.muting, actual.muting)
|
||||
assertEquals(expected.doNotSendPrivate, actual.doNotSendPrivate)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorIdAndInstanceId_指定したActorIdとInstanceIdで存在しないとnull() = runTest {
|
||||
assertNull(repository.findByActorIdAndInstanceId(ActorId(1), InstanceId(1)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_ドメインイベントがパブリッシュされる() = runTest {
|
||||
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val actorInstanceRelationship = ActorInstanceRelationship(
|
||||
actorId = ActorId(1), instanceId = InstanceId(1), blocking = false, muting = false, doNotSendPrivate = false
|
||||
)
|
||||
actorInstanceRelationship.block()
|
||||
repository.save(actorInstanceRelationship)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_ドメインイベントがパブリッシュされる() = runTest {
|
||||
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(ActorInstanceRelationships.tableName) {
|
||||
columns(ActorInstanceRelationships.columns)
|
||||
values(1, 1, true, true, true)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actorInstanceRelationship = ActorInstanceRelationship(
|
||||
actorId = ActorId(1), instanceId = InstanceId(1), blocking = false, muting = false, doNotSendPrivate = false
|
||||
)
|
||||
actorInstanceRelationship.block()
|
||||
repository.delete(actorInstanceRelationship)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,558 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.actor.*
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import dev.usbharu.hideout.core.infrastructure.exposed.ActorQueryMapper
|
||||
import dev.usbharu.hideout.core.infrastructure.exposed.ActorResultRowMapper
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.assertj.db.type.Changes
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Spy
|
||||
import org.mockito.junit.jupiter.MockitoExtension
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import utils.*
|
||||
import java.net.URI
|
||||
import java.sql.Timestamp
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
@ExtendWith(MockitoExtension::class)
|
||||
class ExposedActorRepositoryTest : AbstractRepositoryTest(Actors) {
|
||||
|
||||
@InjectMocks
|
||||
lateinit var repository: ExposedActorRepository
|
||||
|
||||
@Mock
|
||||
lateinit var domainEventPublisher: DomainEventPublisher
|
||||
|
||||
@Spy
|
||||
val actorQueryMapper = ActorQueryMapper(ActorResultRowMapper())
|
||||
|
||||
@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 actor = TestActorFactory.create()
|
||||
|
||||
repository.save(actor)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(1)
|
||||
.isEqualTo(Actors.id, actor.id.id)
|
||||
.isEqualTo(Actors.name, actor.name.name)
|
||||
.isEqualTo(Actors.domain, actor.domain.domain)
|
||||
.isEqualTo(Actors.screenName, actor.screenName.screenName)
|
||||
.isEqualTo(Actors.description, actor.description.description)
|
||||
.value(Actors.url).isEqualTo(actor.url.toString())
|
||||
.value(Actors.inbox).isEqualTo(actor.inbox.toString())
|
||||
.value(Actors.outbox).isEqualTo(actor.outbox.toString())
|
||||
.isEqualTo(Actors.publicKey, actor.publicKey.publicKey)
|
||||
.isEqualTo(Actors.privateKey, actor.privateKey?.privateKey)
|
||||
}
|
||||
|
||||
@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("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto(ActorsAlsoKnownAs.tableName) {
|
||||
columns(ActorsAlsoKnownAs.columns)
|
||||
values(1, 2)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val actor = TestActorFactory.create(1, alsoKnownAs = setOf(ActorId(1)))
|
||||
|
||||
repository.save(actor)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(1)
|
||||
.isEqualTo(Actors.id, actor.id.id)
|
||||
.isEqualTo(Actors.name, actor.name.name)
|
||||
.isEqualTo(Actors.domain, actor.domain.domain)
|
||||
.isEqualTo(Actors.screenName, actor.screenName.screenName)
|
||||
.isEqualTo(Actors.description, actor.description.description)
|
||||
.value(Actors.url).isEqualTo(actor.url.toString())
|
||||
.value(Actors.inbox).isEqualTo(actor.inbox.toString())
|
||||
.value(Actors.outbox).isEqualTo(actor.outbox.toString())
|
||||
.isEqualTo(Actors.publicKey, actor.publicKey.publicKey)
|
||||
.isEqualTo(Actors.privateKey, actor.privateKey?.privateKey)
|
||||
|
||||
assertThat(getTable(ActorsAlsoKnownAs.tableName))
|
||||
.row(0)
|
||||
.isEqualTo(ActorsAlsoKnownAs.actorId, 1)
|
||||
.isEqualTo(ActorsAlsoKnownAs.alsoKnownAs, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除される() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto(ActorsAlsoKnownAs.tableName) {
|
||||
columns(ActorsAlsoKnownAs.columns)
|
||||
values(1, 1)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actor = TestActorFactory.create(1, alsoKnownAs = setOf(ActorId(1)))
|
||||
|
||||
val changes = Changes(dataSource)
|
||||
changes.withSuspend {
|
||||
repository.delete(actor)
|
||||
}
|
||||
|
||||
assertThat(changes)
|
||||
.changeOfDeletionOnTable(Actors.tableName)
|
||||
.rowAtStartPoint()
|
||||
.value(Actors.id.name).isEqualTo(actor.id.id)
|
||||
.changeOfDeletionOnTable(ActorsAlsoKnownAs.tableName)
|
||||
.rowAtStartPoint()
|
||||
.value(ActorsAlsoKnownAs.alsoKnownAs.name)
|
||||
.isEqualTo(actor.alsoKnownAs.first().id)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdがあれば返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val expect = TestActorFactory.create(
|
||||
id = 1,
|
||||
actorName = "b",
|
||||
domain = "test-hideout-dev.usbharu.dev",
|
||||
actorScreenName = "b",
|
||||
description = "",
|
||||
inbox = URI.create("https://test-hideout-dev.usbharu.dev/users/b/inbox"),
|
||||
outbox = URI.create("https://test-hideout-dev.usbharu.dev/users/b/outbox"),
|
||||
uri = URI.create("https://test-hideout-dev.usbharu.dev/users/b"),
|
||||
publicKey = ActorPublicKey("-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----"),
|
||||
privateKey = ActorPrivateKey(
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
),
|
||||
createdAt = Timestamp.valueOf("2024-09-09 17:12:03.941339").toInstant(),
|
||||
keyId = "https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
followingEndpoint = URI.create("https://test-hideout-dev.usbharu.dev/users/b/following"),
|
||||
followersEndpoint = URI.create("https://test-hideout-dev.usbharu.dev/users/b/followers"),
|
||||
instanceId = 1,
|
||||
locked = false,
|
||||
followersCount = 0,
|
||||
followingCount = 0,
|
||||
postCount = 0,
|
||||
lastPostDate = null,
|
||||
lastUpdateAt = Timestamp.valueOf("2024-09-09 17:12:03.941339").toInstant(),
|
||||
suspend = false,
|
||||
alsoKnownAs = emptySet(),
|
||||
moveTo = null,
|
||||
emojiIds = emptySet(),
|
||||
deleted = false,
|
||||
banner = null,
|
||||
icon = null
|
||||
)
|
||||
|
||||
val actual = repository.findById(ActorId(1))
|
||||
|
||||
assertEquals(actual, expect)
|
||||
}
|
||||
|
||||
private fun assertEquals(
|
||||
actual: Actor?,
|
||||
expect: Actor
|
||||
) {
|
||||
assertNotNull(actual)
|
||||
kotlin.test.assertEquals(expect, actual)
|
||||
assertEquals(expect.id, actual.id)
|
||||
assertEquals(expect.name, actual.name)
|
||||
assertEquals(expect.domain, actual.domain)
|
||||
assertEquals(expect.screenName, actual.screenName)
|
||||
assertEquals(expect.description, actual.description)
|
||||
assertEquals(expect.inbox, actual.inbox)
|
||||
assertEquals(expect.outbox, actual.outbox)
|
||||
assertEquals(expect.url, actual.url)
|
||||
assertEquals(expect.publicKey, actual.publicKey)
|
||||
assertEquals(expect.privateKey, actual.privateKey)
|
||||
assertEquals(expect.createdAt, actual.createdAt)
|
||||
assertEquals(expect.keyId, actual.keyId)
|
||||
assertEquals(expect.followingEndpoint, actual.followingEndpoint)
|
||||
assertEquals(expect.followersEndpoint, actual.followersEndpoint)
|
||||
assertEquals(expect.postsCount, actual.postsCount)
|
||||
assertEquals(expect.lastPostAt, actual.lastPostAt)
|
||||
assertEquals(expect.lastUpdateAt, actual.lastUpdateAt)
|
||||
assertEquals(expect.suspend, actual.suspend)
|
||||
assertEquals(expect.moveTo, actual.moveTo)
|
||||
assertEquals(expect.emojis, actual.emojis)
|
||||
assertEquals(expect.deleted, actual.deleted)
|
||||
assertEquals(expect.banner, actual.banner)
|
||||
assertEquals(expect.icon, actual.icon)
|
||||
assertEquals(expect.banner, actual.banner)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdがなければnull() = runTest {
|
||||
assertNull(repository.findById(ActorId(1)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByNameAndDomain_指定されたNameとDomainがあれば返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val expect = TestActorFactory.create(
|
||||
id = 1,
|
||||
actorName = "b",
|
||||
domain = "test-hideout-dev.usbharu.dev",
|
||||
actorScreenName = "b",
|
||||
description = "",
|
||||
inbox = URI.create("https://test-hideout-dev.usbharu.dev/users/b/inbox"),
|
||||
outbox = URI.create("https://test-hideout-dev.usbharu.dev/users/b/outbox"),
|
||||
uri = URI.create("https://test-hideout-dev.usbharu.dev/users/b"),
|
||||
publicKey = ActorPublicKey("-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----"),
|
||||
privateKey = ActorPrivateKey(
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
),
|
||||
createdAt = Timestamp.valueOf("2024-09-09 17:12:03.941339").toInstant(),
|
||||
keyId = "https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
followingEndpoint = URI.create("https://test-hideout-dev.usbharu.dev/users/b/following"),
|
||||
followersEndpoint = URI.create("https://test-hideout-dev.usbharu.dev/users/b/followers"),
|
||||
instanceId = 1,
|
||||
locked = false,
|
||||
followersCount = 0,
|
||||
followingCount = 0,
|
||||
postCount = 0,
|
||||
lastPostDate = null,
|
||||
lastUpdateAt = Timestamp.valueOf("2024-09-09 17:12:03.941339").toInstant(),
|
||||
suspend = false,
|
||||
alsoKnownAs = emptySet(),
|
||||
moveTo = null,
|
||||
emojiIds = emptySet(),
|
||||
deleted = false,
|
||||
banner = null,
|
||||
icon = null
|
||||
)
|
||||
|
||||
val actual = repository.findByNameAndDomain("b", "test-hideout-dev.usbharu.dev")
|
||||
|
||||
assertEquals(actual, expect)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByNameAndDomain_指定されたNameとDomainがなければnull() = runTest {
|
||||
assertNull(repository.findByNameAndDomain("a", "b"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findAllById_指定されたIdすべて返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
values(
|
||||
2,
|
||||
"a",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"a",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val findAllById = repository.findAllById(listOf(ActorId(1), ActorId(2)))
|
||||
|
||||
assertThat(findAllById)
|
||||
.hasSize(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val actor = TestActorFactory.create()
|
||||
actor.checkUpdate()
|
||||
repository.save(actor)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto(ActorsAlsoKnownAs.tableName) {
|
||||
columns(ActorsAlsoKnownAs.columns)
|
||||
values(1, 1)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actor = TestActorFactory.create(1, alsoKnownAs = setOf(ActorId(1)))
|
||||
actor.delete()
|
||||
|
||||
repository.delete(actor)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.instance.*
|
||||
import dev.usbharu.hideout.core.domain.model.instance.Instance
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import utils.AbstractRepositoryTest
|
||||
import utils.columns
|
||||
import utils.isEqualTo
|
||||
import utils.value
|
||||
import java.net.URI
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Instance as InstanceTable
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class ExposedInstanceRepositoryTest : AbstractRepositoryTest(InstanceTable) {
|
||||
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがない場合はinsertされる() = runTest {
|
||||
ExposedInstanceRepository().save(
|
||||
Instance(
|
||||
id = InstanceId(1),
|
||||
name = InstanceName("test"),
|
||||
description = InstanceDescription("id"),
|
||||
url = URI.create("https://www.example.com"),
|
||||
iconUrl = URI.create("https://www.example.com"),
|
||||
sharedInbox = null,
|
||||
software = InstanceSoftware(""),
|
||||
version = InstanceVersion(""),
|
||||
isBlocked = false,
|
||||
isMuted = false,
|
||||
moderationNote = InstanceModerationNote(""),
|
||||
createdAt = Instant.parse("2020-01-01T00:00:00Z"),
|
||||
)
|
||||
)
|
||||
|
||||
val table = assertTable
|
||||
assertThat(table).row(1).isEqualTo(InstanceTable.id, 1).isEqualTo(InstanceTable.name, "test")
|
||||
.value(InstanceTable.url).isEqualTo("https://www.example.com")
|
||||
.value(InstanceTable.iconUrl).isEqualTo("https://www.example.com")
|
||||
.isEqualTo(InstanceTable.sharedInbox, null)
|
||||
.isEqualTo(InstanceTable.software, "").isEqualTo(InstanceTable.version, "")
|
||||
.isEqualTo(InstanceTable.isBlocked, false).isEqualTo(InstanceTable.isMuted, false)
|
||||
.isEqualTo(InstanceTable.moderationNote, "").value(InstanceTable.createdAt)
|
||||
.isEqualTo(Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがある場合はupdateされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
insertInto(InstanceTable.tableName) {
|
||||
columns(
|
||||
InstanceTable.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"system",
|
||||
"",
|
||||
"https://example.com",
|
||||
"",
|
||||
null,
|
||||
"",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"2024-09-10 16:59:50.160202"
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
|
||||
ExposedInstanceRepository().save(
|
||||
Instance(
|
||||
id = InstanceId(1),
|
||||
name = InstanceName("test"),
|
||||
description = InstanceDescription("id"),
|
||||
url = URI.create("https://www.example.com"),
|
||||
iconUrl = URI.create("https://www.example.com"),
|
||||
sharedInbox = null,
|
||||
software = InstanceSoftware(""),
|
||||
version = InstanceVersion(""),
|
||||
isBlocked = false,
|
||||
isMuted = false,
|
||||
moderationNote = InstanceModerationNote(""),
|
||||
createdAt = Instant.parse("2020-01-01T00:00:00Z"),
|
||||
)
|
||||
)
|
||||
|
||||
val table = assertTable
|
||||
assertThat(table).row(1).isEqualTo(InstanceTable.id, 1).isEqualTo(InstanceTable.name, "test")
|
||||
.value(InstanceTable.url).isEqualTo("https://www.example.com")
|
||||
.value(InstanceTable.iconUrl).isEqualTo("https://www.example.com")
|
||||
.isEqualTo(InstanceTable.sharedInbox, null)
|
||||
.isEqualTo(InstanceTable.software, "").isEqualTo(InstanceTable.version, "")
|
||||
.isEqualTo(InstanceTable.isBlocked, false).isEqualTo(InstanceTable.isMuted, false)
|
||||
.isEqualTo(InstanceTable.moderationNote, "").value(InstanceTable.createdAt)
|
||||
.isEqualTo(Timestamp.from(Instant.parse("2020-01-01T00:00:00Z")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定したidで存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
insertInto(InstanceTable.tableName) {
|
||||
columns(
|
||||
InstanceTable.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"test",
|
||||
"description",
|
||||
"https://www.example.com",
|
||||
"https://www.example.com",
|
||||
null,
|
||||
"",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
Timestamp.from(Instant.parse("2020-01-01T00:00:00Z"))
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actual = ExposedInstanceRepository().findById(InstanceId(1))
|
||||
val expected = Instance(
|
||||
id = InstanceId(1),
|
||||
name = InstanceName("test"),
|
||||
description = InstanceDescription("description"),
|
||||
url = URI.create("https://www.example.com"),
|
||||
iconUrl = URI.create("https://www.example.com"),
|
||||
sharedInbox = null,
|
||||
software = InstanceSoftware(""),
|
||||
version = InstanceVersion(""),
|
||||
isBlocked = false,
|
||||
isMuted = false,
|
||||
moderationNote = InstanceModerationNote(""),
|
||||
createdAt = Instant.parse("2020-01-01T00:00:00Z"),
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定したIDで存在しないとnull() = runTest {
|
||||
assertNull(ExposedInstanceRepository().findById(InstanceId(1)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByUrl_指定したURLで存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
insertInto(InstanceTable.tableName) {
|
||||
columns(
|
||||
InstanceTable.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"test",
|
||||
"description",
|
||||
"https://www.example.com",
|
||||
"https://www.example.com",
|
||||
null,
|
||||
"",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
Timestamp.from(Instant.parse("2020-01-01T00:00:00Z"))
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actual = ExposedInstanceRepository().findByUrl(URI.create("https://www.example.com"))
|
||||
val expected = Instance(
|
||||
id = InstanceId(1),
|
||||
name = InstanceName("test"),
|
||||
description = InstanceDescription("description"),
|
||||
url = URI.create("https://www.example.com"),
|
||||
iconUrl = URI.create("https://www.example.com"),
|
||||
sharedInbox = null,
|
||||
software = InstanceSoftware(""),
|
||||
version = InstanceVersion(""),
|
||||
isBlocked = false,
|
||||
isMuted = false,
|
||||
moderationNote = InstanceModerationNote(""),
|
||||
createdAt = Instant.parse("2020-01-01T00:00:00Z"),
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByUrl_指定したURLで存在しないとnull() = runTest {
|
||||
assertNull(ExposedInstanceRepository().findByUrl(URI.create("https://www.example.com")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
insertInto(InstanceTable.tableName) {
|
||||
columns(
|
||||
InstanceTable.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"test",
|
||||
"description",
|
||||
"https://www.example.com",
|
||||
"https://www.example.com",
|
||||
null,
|
||||
"",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
Timestamp.from(Instant.parse("2020-01-01T00:00:00Z"))
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val instance = Instance(
|
||||
id = InstanceId(1),
|
||||
name = InstanceName("test"),
|
||||
description = InstanceDescription("description"),
|
||||
url = URI.create("https://www.example.com"),
|
||||
iconUrl = URI.create("https://www.example.com"),
|
||||
sharedInbox = null,
|
||||
software = InstanceSoftware(""),
|
||||
version = InstanceVersion(""),
|
||||
isBlocked = false,
|
||||
isMuted = false,
|
||||
moderationNote = InstanceModerationNote(""),
|
||||
createdAt = Instant.parse("2020-01-01T00:00:00Z"),
|
||||
)
|
||||
|
||||
change.setStartPointNow()
|
||||
|
||||
ExposedInstanceRepository().delete(instance)
|
||||
|
||||
change.setEndPointNow()
|
||||
|
||||
assertThat(change)
|
||||
.hasNumberOfChanges(1)
|
||||
.changeOfDeletionOnTable(InstanceTable.tableName)
|
||||
.rowAtStartPoint()
|
||||
.value(InstanceTable.id.name).isEqualTo(1)
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun assertEquals(expected: Instance, actual: Instance?) {
|
||||
assertNotNull(actual)
|
||||
kotlin.test.assertEquals(expected, actual)
|
||||
assertEquals(expected.name, actual.name)
|
||||
assertEquals(expected.description, actual.description)
|
||||
assertEquals(expected.url, actual.url)
|
||||
assertEquals(expected.iconUrl, actual.iconUrl)
|
||||
assertEquals(expected.sharedInbox, actual.sharedInbox)
|
||||
assertEquals(expected.software, actual.software)
|
||||
assertEquals(expected.version, actual.version)
|
||||
assertEquals(expected.isBlocked, actual.isBlocked)
|
||||
assertEquals(expected.moderationNote, actual.moderationNote)
|
||||
assertEquals(expected.createdAt, actual.createdAt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,363 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.media.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import utils.*
|
||||
import java.net.URI
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia
|
||||
|
||||
|
||||
class ExposedMediaRepositoryTest : AbstractRepositoryTest(Media) {
|
||||
@Test
|
||||
fun save_idが同じレコードが存在しないとinsert() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
val media = EntityMedia(
|
||||
id = MediaId(1),
|
||||
name = MediaName("name"),
|
||||
url = URI.create("https://www.example.com"),
|
||||
remoteUrl = null,
|
||||
thumbnailUrl = null,
|
||||
type = FileType.Audio,
|
||||
mimeType = MimeType("audio", "mp3", FileType.Audio),
|
||||
blurHash = null,
|
||||
description = null,
|
||||
actorId = ActorId(1)
|
||||
)
|
||||
ExposedMediaRepository().save(media)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(0)
|
||||
.isEqualTo(Media.id, 1)
|
||||
.isEqualTo(Media.name, "name")
|
||||
.value(Media.url).isEqualTo("https://www.example.com")
|
||||
.isEqualTo(Media.remoteUrl, null)
|
||||
.isEqualTo(Media.thumbnailUrl, null)
|
||||
.isEqualTo(Media.type, "Audio")
|
||||
.isEqualTo(Media.mimeType, "audio/mp3")
|
||||
.isEqualTo(Media.blurhash, null)
|
||||
.isEqualTo(Media.description, null)
|
||||
.isEqualTo(Media.actorId, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードが存在したらupdate() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto("public.media") {
|
||||
columns(
|
||||
"id",
|
||||
"name",
|
||||
"url",
|
||||
"remote_url",
|
||||
"thumbnail_url",
|
||||
"type",
|
||||
"blurhash",
|
||||
"mime_type",
|
||||
"description",
|
||||
"actor_id"
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"pnc__picked_media_256f8e6d-68cd-4a76-bb38-57e35f6ca8c6.jpg",
|
||||
"http://localhost:8081/files/1833054358862827520.jpeg",
|
||||
null,
|
||||
"http://localhost:8081/files/thumbnail-1833054358862827520.jpeg",
|
||||
"Image",
|
||||
"U\$JuAZWBxut7~qoLoft6j]t7Rjj[RjayWBay",
|
||||
"image/jpeg",
|
||||
null,
|
||||
1
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val media = EntityMedia(
|
||||
id = MediaId(1),
|
||||
name = MediaName("name"),
|
||||
url = URI.create("https://www.example.com"),
|
||||
remoteUrl = null,
|
||||
thumbnailUrl = null,
|
||||
type = FileType.Audio,
|
||||
mimeType = MimeType("audio", "mp3", FileType.Audio),
|
||||
blurHash = null,
|
||||
description = null,
|
||||
actorId = ActorId(1)
|
||||
)
|
||||
ExposedMediaRepository().save(media)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(0)
|
||||
.isEqualTo(Media.id, 1)
|
||||
.isEqualTo(Media.name, "name")
|
||||
.value(Media.url).isEqualTo("https://www.example.com")
|
||||
.isEqualTo(Media.remoteUrl, null)
|
||||
.isEqualTo(Media.thumbnailUrl, null)
|
||||
.isEqualTo(Media.type, "Audio")
|
||||
.isEqualTo(Media.mimeType, "audio/mp3")
|
||||
.isEqualTo(Media.blurhash, null)
|
||||
.isEqualTo(Media.description, null)
|
||||
.isEqualTo(Media.actorId, 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除される() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.media") {
|
||||
columns(
|
||||
"id",
|
||||
"name",
|
||||
"url",
|
||||
"remote_url",
|
||||
"thumbnail_url",
|
||||
"type",
|
||||
"blurhash",
|
||||
"mime_type",
|
||||
"description",
|
||||
"actor_id"
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"pnc__picked_media_256f8e6d-68cd-4a76-bb38-57e35f6ca8c6.jpg",
|
||||
"http://localhost:8081/files/1833054358862827520.jpeg",
|
||||
null,
|
||||
"http://localhost:8081/files/thumbnail-1833054358862827520.jpeg",
|
||||
"Image",
|
||||
"U\$JuAZWBxut7~qoLoft6j]t7Rjj[RjayWBay",
|
||||
"image/jpeg",
|
||||
null,
|
||||
1
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
val media = EntityMedia(
|
||||
id = MediaId(1),
|
||||
name = MediaName("name"),
|
||||
url = URI.create("https://www.example.com"),
|
||||
remoteUrl = null,
|
||||
thumbnailUrl = null,
|
||||
type = FileType.Audio,
|
||||
mimeType = MimeType("audio", "mp3", FileType.Audio),
|
||||
blurHash = null,
|
||||
description = null,
|
||||
actorId = ActorId(1)
|
||||
)
|
||||
|
||||
change.withSuspend {
|
||||
ExposedMediaRepository().delete(media)
|
||||
}
|
||||
|
||||
assertThat(change)
|
||||
.changeOfDeletionOnTable(Media.tableName)
|
||||
.rowAtStartPoint()
|
||||
.value(Media.id.name)
|
||||
.isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdで存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.media") {
|
||||
columns(
|
||||
"id",
|
||||
"name",
|
||||
"url",
|
||||
"remote_url",
|
||||
"thumbnail_url",
|
||||
"type",
|
||||
"blurhash",
|
||||
"mime_type",
|
||||
"description",
|
||||
"actor_id"
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"pnc__picked_media_256f8e6d-68cd-4a76-bb38-57e35f6ca8c6.jpg",
|
||||
"http://localhost:8081/files/1833054358862827520.jpeg",
|
||||
"http://localhost:8081/files/183305453584862827520.jpeg",
|
||||
"http://localhost:8081/files/thumbnail-1833054358862827520.jpeg",
|
||||
"Image",
|
||||
"U\$JuAZWBxut7~qoLoft6j]t7Rjj[RjayWBay",
|
||||
"image/jpeg",
|
||||
null,
|
||||
1
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val expect = EntityMedia(
|
||||
id = MediaId(1),
|
||||
name = MediaName("pnc__picked_media_256f8e6d-68cd-4a76-bb38-57e35f6ca8c6.jpg"),
|
||||
url = URI.create("http://localhost:8081/files/1833054358862827520.jpeg"),
|
||||
remoteUrl = URI.create("http://localhost:8081/files/183305453584862827520.jpeg"),
|
||||
thumbnailUrl = URI.create("http://localhost:8081/files/thumbnail-1833054358862827520.jpeg"),
|
||||
type = FileType.Image,
|
||||
mimeType = MimeType("image", "jpeg", FileType.Image),
|
||||
blurHash = MediaBlurHash("U\$JuAZWBxut7~qoLoft6j]t7Rjj[RjayWBay"),
|
||||
description = null,
|
||||
actorId = ActorId(1)
|
||||
)
|
||||
|
||||
val actual = ExposedMediaRepository().findById(MediaId(1))
|
||||
|
||||
assertNotNull(actual)
|
||||
assertEquals(expect, actual)
|
||||
assertEquals(expect.id, actual.id)
|
||||
assertEquals(expect.name, actual.name)
|
||||
assertEquals(expect.url, actual.url)
|
||||
assertEquals(expect.remoteUrl, actual.remoteUrl)
|
||||
assertEquals(expect.thumbnailUrl, actual.thumbnailUrl)
|
||||
assertEquals(expect.type, actual.type)
|
||||
assertEquals(expect.mimeType, actual.mimeType)
|
||||
assertEquals(expect.blurHash, actual.blurHash)
|
||||
assertEquals(expect.description, actual.description)
|
||||
assertEquals(expect.actorId, actual.actorId)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdで存在しないとnull() = runTest {
|
||||
assertNull(ExposedMediaRepository().findById(MediaId(1)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByIdIn_指定されたIdすべて返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.media") {
|
||||
columns(
|
||||
"id",
|
||||
"name",
|
||||
"url",
|
||||
"remote_url",
|
||||
"thumbnail_url",
|
||||
"type",
|
||||
"blurhash",
|
||||
"mime_type",
|
||||
"description",
|
||||
"actor_id"
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"pnc__picked_media_256f8e6d-68cd-4a76-bb38-57e35f6ca8c6.jpg",
|
||||
"http://localhost:8081/files/1833054358862827520.jpeg",
|
||||
null,
|
||||
null,
|
||||
"Image",
|
||||
"U\$JuAZWBxut7~qoLoft6j]t7Rjj[RjayWBay",
|
||||
"image/jpeg",
|
||||
"",
|
||||
1
|
||||
)
|
||||
values(
|
||||
3,
|
||||
"pnc__picked_media_256f8e6d-68cd-4a76-bb38-57e35f6ca8c6.jpg",
|
||||
"http://localhost:8081/files/18330354358862827520.jpeg",
|
||||
null,
|
||||
"http://localhost:8081/files/thumbn3ail-1833054358862827520.jpeg",
|
||||
"Image",
|
||||
null,
|
||||
"image/jpeg",
|
||||
null,
|
||||
1
|
||||
)
|
||||
values(
|
||||
2,
|
||||
"pnc__picked_media_256f8e6d-68cd-4a76-bb38-57e35f6ca8c6.jpg",
|
||||
"http://localhost:8081/files/18330545358862827520.jpeg",
|
||||
"http://localhost:8081/files/183305453584862827520.jpeg",
|
||||
null,
|
||||
"Image",
|
||||
"U\$JuAZWBxut7~qoLoft6j]t7Rjj[RjayWBay",
|
||||
"image/jpeg",
|
||||
null,
|
||||
1
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val actual = ExposedMediaRepository().findByIdIn(listOf(MediaId(1), MediaId(3)))
|
||||
|
||||
assertThat(actual)
|
||||
.hasSize(2)
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,440 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiId
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.UnicodeEmoji
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.reaction.Reaction
|
||||
import dev.usbharu.hideout.core.domain.model.reaction.ReactionId
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.jupiter.MockitoExtension
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import utils.*
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
import kotlin.test.*
|
||||
|
||||
@ExtendWith(MockitoExtension::class)
|
||||
class ExposedReactionRepositoryTest : AbstractRepositoryTest(Reactions) {
|
||||
|
||||
@InjectMocks
|
||||
lateinit var repository: ExposedReactionRepository
|
||||
|
||||
@Mock
|
||||
lateinit var domainEventPublisher: DomainEventPublisher
|
||||
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがなければinsert() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Posts.tableName) {
|
||||
columns(Posts.columns)
|
||||
values(
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
null,
|
||||
"test",
|
||||
"test",
|
||||
Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")),
|
||||
"PUBLIC",
|
||||
"https://example.com",
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
"https://example.com",
|
||||
false,
|
||||
false,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto(CustomEmojis.tableName) {
|
||||
columns(CustomEmojis.columns)
|
||||
values(1, "emoji", "example.com", 1, "https://example.com", null, Timestamp.from(Instant.now()))
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val create = Reaction.create(
|
||||
id = ReactionId(1),
|
||||
postId = PostId(1),
|
||||
actorId = ActorId(1),
|
||||
customEmojiId = CustomEmojiId(1),
|
||||
unicodeEmoji = UnicodeEmoji("❤"),
|
||||
createdAt = Instant.parse("2021-01-01T00:00:00Z")
|
||||
)
|
||||
|
||||
repository.save(create)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(0)
|
||||
.isEqualTo(Reactions.id, create.id.value)
|
||||
.isEqualTo(Reactions.postId, create.postId.id)
|
||||
.isEqualTo(Reactions.actorId, create.actorId.id)
|
||||
.isEqualTo(Reactions.customEmojiId, create.customEmojiId?.emojiId)
|
||||
.isEqualTo(Reactions.unicodeEmoji, create.unicodeEmoji.name)
|
||||
.value(Reactions.createdAt).isEqualTo(Timestamp.from(create.createdAt))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードが存在したらupdate() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Posts.tableName) {
|
||||
columns(Posts.columns)
|
||||
values(
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
null,
|
||||
"test",
|
||||
"test",
|
||||
Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")),
|
||||
"PUBLIC",
|
||||
"https://example.com",
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
"https://example.com",
|
||||
false,
|
||||
false,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto(CustomEmojis.tableName) {
|
||||
columns(CustomEmojis.columns)
|
||||
values(1, "emoji", "example.com", 1, "https://example.com", null, Timestamp.from(Instant.now()))
|
||||
}
|
||||
insertInto(Reactions.tableName) {
|
||||
columns(Reactions.columns)
|
||||
values(1, 1, 1, 2, "☠️", Timestamp.from(Instant.now()))
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val create = Reaction.create(
|
||||
id = ReactionId(1),
|
||||
postId = PostId(1),
|
||||
actorId = ActorId(1),
|
||||
customEmojiId = CustomEmojiId(1),
|
||||
unicodeEmoji = UnicodeEmoji("❤"),
|
||||
createdAt = Instant.parse("2021-01-01T00:00:00Z")
|
||||
)
|
||||
|
||||
repository.save(create)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(0)
|
||||
.isEqualTo(Reactions.id, create.id.value)
|
||||
.isEqualTo(Reactions.postId, create.postId.id)
|
||||
.isEqualTo(Reactions.actorId, create.actorId.id)
|
||||
.isEqualTo(Reactions.customEmojiId, create.customEmojiId?.emojiId)
|
||||
.isEqualTo(Reactions.unicodeEmoji, create.unicodeEmoji.name)
|
||||
.value(Reactions.createdAt).isEqualTo(Timestamp.from(create.createdAt))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdが存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Reactions.tableName) {
|
||||
columns(Reactions.columns)
|
||||
values(1, 1, 1, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val expected = Reaction.create(
|
||||
id = ReactionId(1),
|
||||
postId = PostId(1),
|
||||
actorId = ActorId(1),
|
||||
customEmojiId = CustomEmojiId(1),
|
||||
unicodeEmoji = UnicodeEmoji("❤"),
|
||||
createdAt = Instant.parse("2021-01-01T00:00:00Z")
|
||||
)
|
||||
|
||||
val actual = repository.findById(ReactionId(1))
|
||||
|
||||
assertEquals(expected, actual)
|
||||
|
||||
}
|
||||
|
||||
private fun assertEquals(
|
||||
expected: Reaction,
|
||||
actual: Reaction?
|
||||
) {
|
||||
kotlin.test.assertEquals(expected, actual)
|
||||
assertNotNull(actual)
|
||||
assertEquals(expected.id, actual.id)
|
||||
assertEquals(expected.postId, actual.postId)
|
||||
assertEquals(expected.actorId, actual.actorId)
|
||||
assertEquals(expected.customEmojiId, actual.customEmojiId)
|
||||
assertEquals(expected.unicodeEmoji, actual.unicodeEmoji)
|
||||
assertEquals(expected.createdAt, actual.createdAt)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdがなければnull() = runTest {
|
||||
assertNull(repository.findById(ReactionId(1)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByPostId_指定されたId全部返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Reactions.tableName) {
|
||||
columns(Reactions.columns)
|
||||
values(1, 1, 1, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(2, 3, 2, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(3, 1, 3, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actual = repository.findByPostId(PostId(1))
|
||||
|
||||
assertThat(actual)
|
||||
.hasSize(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji_指定された条件で存在したらtrue() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Reactions.tableName) {
|
||||
columns(Reactions.columns)
|
||||
values(1, 1, 1, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(2, 3, 2, null, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(3, 1, 3, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actual1 = repository.existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji(
|
||||
PostId(1),
|
||||
ActorId(1), CustomEmojiId
|
||||
(1), "❤"
|
||||
)
|
||||
val actual2 = repository.existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji(
|
||||
PostId(3),
|
||||
ActorId(2), null, "❤"
|
||||
)
|
||||
|
||||
assertTrue(actual1)
|
||||
assertTrue(actual2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji_指定された条件で存在しないとfalse() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Reactions.tableName) {
|
||||
columns(Reactions.columns)
|
||||
values(1, 1, 1, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(2, 3, 2, null, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(3, 1, 3, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actual1 = repository.existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji(
|
||||
PostId(3),
|
||||
ActorId(1), CustomEmojiId
|
||||
(1), "❤"
|
||||
)
|
||||
val actual2 = repository.existsByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji(
|
||||
PostId(2),
|
||||
ActorId(2), null, "❤"
|
||||
)
|
||||
|
||||
assertFalse(actual1)
|
||||
assertFalse(actual2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除される() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Reactions.tableName) {
|
||||
columns(Reactions.columns)
|
||||
values(1, 1, 1, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(2, 3, 2, null, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(3, 1, 3, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val reaction = Reaction(
|
||||
ReactionId(1),
|
||||
PostId(1),
|
||||
ActorId(1),
|
||||
CustomEmojiId(1),
|
||||
UnicodeEmoji("❤"),
|
||||
Instant.parse("2021-01-01T00:00:00Z")
|
||||
)
|
||||
|
||||
repository.delete(reaction)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji_指定された条件で存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Reactions.tableName) {
|
||||
columns(Reactions.columns)
|
||||
values(1, 1, 1, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(2, 3, 2, null, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(3, 1, 3, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val expected = Reaction(
|
||||
ReactionId(1),
|
||||
PostId(1),
|
||||
ActorId(1),
|
||||
CustomEmojiId(1),
|
||||
UnicodeEmoji("❤"),
|
||||
Instant.parse("2021-01-01T00:00:00Z")
|
||||
)
|
||||
|
||||
val actual =
|
||||
repository.findByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji(
|
||||
PostId(1),
|
||||
ActorId(1), CustomEmojiId
|
||||
(1), "❤"
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji_指定された条件で存在しないとnull() = runTest {
|
||||
assertNull(
|
||||
repository.findByPostIdAndActorIdAndCustomEmojiIdOrUnicodeEmoji(
|
||||
PostId(1),
|
||||
ActorId(1), CustomEmojiId
|
||||
(1), "❤"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
repository.save(
|
||||
Reaction.create(
|
||||
ReactionId(1),
|
||||
PostId(1), ActorId
|
||||
(1), CustomEmojiId
|
||||
(1), UnicodeEmoji("❤"), Instant.now
|
||||
()
|
||||
)
|
||||
)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Reactions.tableName) {
|
||||
columns(Reactions.columns)
|
||||
values(1, 1, 1, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(2, 3, 2, null, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
values(3, 1, 3, 1, "❤", Timestamp.from(Instant.parse("2021-01-01T00:00:00Z")))
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val reaction = Reaction(
|
||||
ReactionId(1),
|
||||
PostId(1), ActorId
|
||||
(1), CustomEmojiId
|
||||
(1), UnicodeEmoji("❤"), Instant.now
|
||||
()
|
||||
)
|
||||
reaction.delete()
|
||||
repository.delete(
|
||||
reaction
|
||||
)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,503 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.relationship.Relationship
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.jupiter.MockitoExtension
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import utils.*
|
||||
import kotlin.test.assertContentEquals
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
@ExtendWith(MockitoExtension::class)
|
||||
class ExposedRelationshipRepositoryTest : AbstractRepositoryTest(Relationships) {
|
||||
|
||||
@InjectMocks
|
||||
lateinit var repository: ExposedRelationshipRepository
|
||||
|
||||
@Mock
|
||||
lateinit var domainEventPublisher: DomainEventPublisher
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがなければinsert() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Actors.tableName) {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
values(
|
||||
2,
|
||||
"a",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"a",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val relationship = Relationship.default(
|
||||
ActorId(1), ActorId(2)
|
||||
)
|
||||
|
||||
repository.save(relationship)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(0)
|
||||
.isEqualTo(Relationships.actorId, relationship.actorId.id)
|
||||
.isEqualTo(Relationships.targetActorId, relationship.targetActorId.id)
|
||||
.isEqualTo(Relationships.following, relationship.following)
|
||||
.isEqualTo(Relationships.blocking, relationship.blocking)
|
||||
.isEqualTo(Relationships.muting, relationship.muting)
|
||||
.isEqualTo(Relationships.followRequesting, relationship.followRequesting)
|
||||
.isEqualTo(Relationships.mutingFollowRequest, relationship.mutingFollowRequest)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがあればupdate() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Actors.tableName) {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
values(
|
||||
2,
|
||||
"a",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"a",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto(Relationships.tableName) {
|
||||
columns(Relationships.columns)
|
||||
values(1, 2, true, false, false, false, false)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val relationship = Relationship(
|
||||
actorId = ActorId(1),
|
||||
targetActorId = ActorId(2),
|
||||
following = false,
|
||||
blocking = true,
|
||||
muting = false,
|
||||
followRequesting = false,
|
||||
mutingFollowRequest = false,
|
||||
)
|
||||
|
||||
repository.save(relationship)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(0)
|
||||
.isEqualTo(Relationships.actorId, relationship.actorId.id)
|
||||
.isEqualTo(Relationships.targetActorId, relationship.targetActorId.id)
|
||||
.isEqualTo(Relationships.following, relationship.following)
|
||||
.isEqualTo(Relationships.blocking, relationship.blocking)
|
||||
.isEqualTo(Relationships.muting, relationship.muting)
|
||||
.isEqualTo(Relationships.followRequesting, relationship.followRequesting)
|
||||
.isEqualTo(Relationships.mutingFollowRequest, relationship.mutingFollowRequest)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除される() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Actors.tableName) {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
values(
|
||||
2,
|
||||
"a",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"a",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/a/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto(Relationships.tableName) {
|
||||
columns(Relationships.columns)
|
||||
values(1, 2, true, false, false, false, false)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val relationship = Relationship.default(
|
||||
ActorId(1), ActorId(2)
|
||||
)
|
||||
|
||||
change.withSuspend {
|
||||
repository.delete(relationship)
|
||||
}
|
||||
|
||||
assertThat(change)
|
||||
.changeOfDeletionOnTable(Relationships.tableName)
|
||||
.rowAtStartPoint()
|
||||
.value(Relationships.actorId.name).isEqualTo(relationship.actorId.id)
|
||||
.value(Relationships.targetActorId.name).isEqualTo(relationship.targetActorId.id)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorIdAndTargetId_指定された条件で存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Relationships.tableName) {
|
||||
columns(Relationships.columns)
|
||||
values(1, 2, true, false, true, true, false)
|
||||
values(2, 1, true, false, false, false, false)
|
||||
values(4, 3, true, false, false, false, true)
|
||||
values(3, 5, true, false, false, true, false)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val expected = Relationship(
|
||||
actorId = ActorId(1),
|
||||
targetActorId = ActorId(2),
|
||||
following = true,
|
||||
blocking = false,
|
||||
muting = true,
|
||||
followRequesting = true,
|
||||
mutingFollowRequest = false
|
||||
)
|
||||
|
||||
val actual = repository.findByActorIdAndTargetId(ActorId(1), ActorId(2))
|
||||
|
||||
assertEquals(expected, actual)
|
||||
assertNotNull(actual)
|
||||
assertEquals(expected.actorId, actual.actorId)
|
||||
assertEquals(expected.targetActorId, actual.targetActorId)
|
||||
assertEquals(expected.following, actual.following)
|
||||
assertEquals(expected.blocking, actual.blocking)
|
||||
assertEquals(expected.muting, actual.muting)
|
||||
assertEquals(expected.followRequesting, actual.followRequesting)
|
||||
assertEquals(expected.mutingFollowRequest, actual.mutingFollowRequest)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorIdAndTargetId_指定された条件で存在しないとnull() = runTest {
|
||||
assertNull(repository.findByActorIdAndTargetId(ActorId(1), ActorId(2)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorIdsAndTargetIdAndBlocking_指定された条件全部返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Relationships.tableName) {
|
||||
columns(Relationships.columns)
|
||||
values(1, 2, true, false, true, true, false)
|
||||
values(1, 3, false, true, true, true, false)
|
||||
values(1, 4, true, false, true, true, false)
|
||||
values(2, 1, true, false, false, false, false)
|
||||
values(4, 3, true, false, false, false, true)
|
||||
values(3, 5, true, false, false, true, false)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val expected = listOf(
|
||||
Relationship(
|
||||
actorId = ActorId(1),
|
||||
targetActorId = ActorId(3),
|
||||
following = false,
|
||||
blocking = true,
|
||||
muting = true,
|
||||
followRequesting = true,
|
||||
mutingFollowRequest = false
|
||||
)
|
||||
)
|
||||
|
||||
val actual = repository.findByActorIdsAndTargetIdAndBlocking(
|
||||
listOf(ActorId(1), ActorId(4)), ActorId(3), blocking = true
|
||||
)
|
||||
|
||||
assertContentEquals(expected, actual)
|
||||
|
||||
val expected2 = listOf(
|
||||
Relationship(
|
||||
actorId = ActorId(4),
|
||||
targetActorId = ActorId(3),
|
||||
following = true,
|
||||
blocking = false,
|
||||
muting = false,
|
||||
followRequesting = false,
|
||||
mutingFollowRequest = true
|
||||
)
|
||||
)
|
||||
|
||||
val actual2 = repository.findByActorIdsAndTargetIdAndBlocking(
|
||||
listOf(ActorId(1), ActorId(4)), ActorId(3), blocking = false
|
||||
)
|
||||
|
||||
assertContentEquals(expected2, actual2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorIdAndTargetIdsAndFollowing_指定された条件全部返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Relationships.tableName) {
|
||||
columns(Relationships.columns)
|
||||
values(1, 2, true, false, true, true, false)
|
||||
values(1, 3, false, false, true, true, false)
|
||||
values(1, 4, true, false, true, true, false)
|
||||
values(2, 1, true, false, false, false, false)
|
||||
values(4, 3, true, false, false, false, true)
|
||||
values(3, 5, true, false, false, true, false)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val expected = listOf(
|
||||
Relationship(
|
||||
actorId = ActorId(1),
|
||||
targetActorId = ActorId(2),
|
||||
following = false,
|
||||
blocking = true,
|
||||
muting = true,
|
||||
followRequesting = true,
|
||||
mutingFollowRequest = false
|
||||
), Relationship(
|
||||
actorId = ActorId(1),
|
||||
targetActorId = ActorId(4),
|
||||
following = false,
|
||||
blocking = true,
|
||||
muting = true,
|
||||
followRequesting = true,
|
||||
mutingFollowRequest = false
|
||||
)
|
||||
)
|
||||
|
||||
val actual = repository.findByActorIdAndTargetIdsAndFollowing(
|
||||
ActorId(1), listOf(ActorId(2), ActorId(3), ActorId(4)), following = true
|
||||
)
|
||||
|
||||
assertContentEquals(expected, actual)
|
||||
|
||||
val expected2 = listOf(
|
||||
Relationship(
|
||||
actorId = ActorId(1),
|
||||
targetActorId = ActorId(3),
|
||||
following = true,
|
||||
blocking = false,
|
||||
muting = false,
|
||||
followRequesting = false,
|
||||
mutingFollowRequest = true
|
||||
)
|
||||
)
|
||||
|
||||
val actual2 = repository.findByActorIdAndTargetIdsAndFollowing(
|
||||
ActorId(1), listOf(ActorId(2), ActorId(3), ActorId(4)), following = false
|
||||
)
|
||||
|
||||
assertContentEquals(expected2, actual2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val relationship = Relationship(
|
||||
actorId = ActorId(1),
|
||||
targetActorId = ActorId(2),
|
||||
following = false,
|
||||
blocking = true,
|
||||
muting = false,
|
||||
followRequesting = false,
|
||||
mutingFollowRequest = false,
|
||||
)
|
||||
|
||||
relationship.block()
|
||||
|
||||
repository.save(relationship)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Relationships.tableName) {
|
||||
columns(Relationships.columns)
|
||||
values(1, 2, true, false, false, false, false)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val relationship = Relationship(
|
||||
actorId = ActorId(1),
|
||||
targetActorId = ActorId(2),
|
||||
following = false,
|
||||
blocking = true,
|
||||
muting = false,
|
||||
followRequesting = false,
|
||||
mutingFollowRequest = false,
|
||||
)
|
||||
relationship.block()
|
||||
|
||||
repository.delete(relationship)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,254 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationship
|
||||
import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipId
|
||||
import dev.usbharu.hideout.core.domain.model.timelinerelationship.Visible
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import utils.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
class ExposedTimelineRelationshipRepositoryTest : AbstractRepositoryTest(TimelineRelationships) {
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがなければinsert() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Timelines.tableName) {
|
||||
columns(Timelines.columns)
|
||||
values(1, 1, "time-line", "PUBLIC", false)
|
||||
}
|
||||
insertInto("public.actors") {
|
||||
columns(
|
||||
Actors.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val relationship = TimelineRelationship(
|
||||
TimelineRelationshipId(1), TimelineId(1), ActorId(1), Visible.PUBLIC
|
||||
)
|
||||
ExposedTimelineRelationshipRepository().save(relationship)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(0)
|
||||
.isEqualTo(TimelineRelationships.id, relationship.id.value)
|
||||
.isEqualTo(TimelineRelationships.timelineId, relationship.timelineId.value)
|
||||
.isEqualTo(TimelineRelationships.actorId, relationship.actorId.id)
|
||||
.isEqualTo(TimelineRelationships.visible, relationship.visible.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがあればupdate() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Timelines.tableName) {
|
||||
columns(Timelines.columns)
|
||||
values(1, 1, "time-line", "PUBLIC", false)
|
||||
}
|
||||
insertInto(TimelineRelationships.tableName) {
|
||||
columns(TimelineRelationships.columns)
|
||||
values(1, 2, 3, "PUBLIC")
|
||||
}
|
||||
insertInto("public.actors") {
|
||||
columns(
|
||||
Actors.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val relationship = TimelineRelationship(
|
||||
TimelineRelationshipId(1), TimelineId(1), ActorId(1), Visible.PUBLIC
|
||||
)
|
||||
ExposedTimelineRelationshipRepository().save(relationship)
|
||||
|
||||
assertThat(assertTable)
|
||||
.row(0)
|
||||
.isEqualTo(TimelineRelationships.id, relationship.id.value)
|
||||
.isEqualTo(TimelineRelationships.timelineId, relationship.timelineId.value)
|
||||
.isEqualTo(TimelineRelationships.actorId, relationship.actorId.id)
|
||||
.isEqualTo(TimelineRelationships.visible, relationship.visible.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除される() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(TimelineRelationships.tableName) {
|
||||
columns(TimelineRelationships.columns)
|
||||
values(1, 2, 3, "PUBLIC")
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val timelineRelationship = TimelineRelationship(
|
||||
TimelineRelationshipId(1),
|
||||
TimelineId(1), ActorId
|
||||
(3), Visible.PUBLIC
|
||||
)
|
||||
|
||||
change.withSuspend {
|
||||
ExposedTimelineRelationshipRepository().delete(timelineRelationship)
|
||||
}
|
||||
|
||||
assertThat(change)
|
||||
.changeOfDeletionOnTable(TimelineRelationships.tableName)
|
||||
.rowAtStartPoint()
|
||||
.value(TimelineRelationships.id.name).isEqualTo(timelineRelationship.id.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorId_指定されたid全部返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(TimelineRelationships.tableName) {
|
||||
columns(TimelineRelationships.columns)
|
||||
values(1, 2, 3, "PUBLIC")
|
||||
values(2, 3, 3, "PUBLIC")
|
||||
values(3, 3, 4, "PUBLIC")
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
|
||||
val findByActorId = ExposedTimelineRelationshipRepository().findByActorId(actorId = ActorId(3))
|
||||
|
||||
assertThat(findByActorId)
|
||||
.hasSize(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたidで存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(TimelineRelationships.tableName) {
|
||||
columns(TimelineRelationships.columns)
|
||||
values(1, 2, 3, "PUBLIC")
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val expected = TimelineRelationship(
|
||||
id = TimelineRelationshipId(1),
|
||||
timelineId = TimelineId(2),
|
||||
actorId = ActorId
|
||||
(3),
|
||||
visible = Visible.PUBLIC
|
||||
)
|
||||
|
||||
val actual = ExposedTimelineRelationshipRepository().findById(TimelineRelationshipId(1))
|
||||
|
||||
assertEquals(expected, actual)
|
||||
assertNotNull(actual)
|
||||
assertEquals(expected.id, actual.id)
|
||||
assertEquals(expected.actorId, actual.actorId)
|
||||
assertEquals(expected.timelineId, actual.timelineId)
|
||||
assertEquals(expected.visible, actual.visible)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdで存在しないとnull() = runTest {
|
||||
assertNull(ExposedTimelineRelationshipRepository().findById(TimelineRelationshipId(1)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByTimelineIdAndActorId_指定された条件で存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(TimelineRelationships.tableName) {
|
||||
columns(TimelineRelationships.columns)
|
||||
values(1, 2, 3, "PUBLIC")
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val expected = TimelineRelationship(
|
||||
id = TimelineRelationshipId(1),
|
||||
timelineId = TimelineId(2),
|
||||
actorId = ActorId
|
||||
(3),
|
||||
visible = Visible.PUBLIC
|
||||
)
|
||||
|
||||
val actual = ExposedTimelineRelationshipRepository().findByTimelineIdAndActorId(TimelineId(2), ActorId(3))
|
||||
|
||||
assertEquals(expected, actual)
|
||||
assertNotNull(actual)
|
||||
assertEquals(expected.id, actual.id)
|
||||
assertEquals(expected.actorId, actual.actorId)
|
||||
assertEquals(expected.timelineId, actual.timelineId)
|
||||
assertEquals(expected.visible, actual.visible)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByTimelineIdAndActorId_指定された条件で存在しないとnull() = runTest {
|
||||
ExposedTimelineRelationshipRepository().findByTimelineIdAndActorId(TimelineId(1), ActorId(1))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.Timeline
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineName
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineVisibility
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailHashedPassword
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.jupiter.MockitoExtension
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import utils.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
@ExtendWith(MockitoExtension::class)
|
||||
class ExposedTimelineRepositoryTest : AbstractRepositoryTest(Timelines) {
|
||||
@InjectMocks
|
||||
lateinit var repository: ExposedTimelineRepository
|
||||
|
||||
@Mock
|
||||
lateinit var domainEventPublisher: DomainEventPublisher
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードが存在しない場合insert() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(UserDetails.tableName) {
|
||||
columns(UserDetails.columns)
|
||||
values(1, 1, "veeeeeeeeeeeeeeryStrongPassword", true, null, null)
|
||||
}
|
||||
}.launch()
|
||||
val timeline = Timeline(
|
||||
id = TimelineId(1),
|
||||
userDetailId = UserDetailId(1),
|
||||
name = TimelineName("timeline"),
|
||||
visibility = TimelineVisibility.PUBLIC,
|
||||
isSystem = false
|
||||
)
|
||||
|
||||
repository.save(timeline)
|
||||
|
||||
assertThat(assertTable).row(0).isEqualTo(Timelines.id, timeline.id.value)
|
||||
.isEqualTo(Timelines.userDetailId, timeline.userDetailId.id).isEqualTo(Timelines.name, timeline.name.value)
|
||||
.isEqualTo(Timelines.visibility, timeline.visibility.name).isEqualTo(Timelines.isSystem, timeline.isSystem)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードが存在する場合update() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(UserDetails.tableName) {
|
||||
columns(UserDetails.columns)
|
||||
values(1, 1, "veeeeeeeeeeeeeeryStrongPassword", true, null, null)
|
||||
}
|
||||
insertInto(Timelines.tableName) {
|
||||
columns(Timelines.columns)
|
||||
values(1, 1, "test-timeline", "PUBLIC", true)
|
||||
}
|
||||
|
||||
}.launch()
|
||||
val timeline = Timeline(
|
||||
id = TimelineId(1),
|
||||
userDetailId = UserDetailId(1),
|
||||
name = TimelineName("timeline"),
|
||||
visibility = TimelineVisibility.PRIVATE,
|
||||
isSystem = false
|
||||
)
|
||||
|
||||
repository.save(timeline)
|
||||
|
||||
assertThat(assertTable).row(0).isEqualTo(Timelines.id, timeline.id.value)
|
||||
.isEqualTo(Timelines.userDetailId, timeline.userDetailId.id).isEqualTo(Timelines.name, timeline.name.value)
|
||||
.isEqualTo(Timelines.visibility, timeline.visibility.name).isEqualTo(Timelines.isSystem, timeline.isSystem)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除される() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(UserDetails.tableName) {
|
||||
columns(UserDetails.columns)
|
||||
values(1, 1, "veeeeeeeeeeeeeeryStrongPassword", true, null, null)
|
||||
}
|
||||
insertInto(Timelines.tableName) {
|
||||
columns(Timelines.columns)
|
||||
values(1, 1, "test-timeline", "PUBLIC", true)
|
||||
}
|
||||
|
||||
}.launch()
|
||||
val timeline = Timeline(
|
||||
id = TimelineId(1),
|
||||
userDetailId = UserDetailId(1),
|
||||
name = TimelineName("timeline"),
|
||||
visibility = TimelineVisibility.PRIVATE,
|
||||
isSystem = false
|
||||
)
|
||||
|
||||
change.withSuspend {
|
||||
repository.delete(timeline)
|
||||
}
|
||||
|
||||
assertThat(change).changeOfDeletionOnTable(Timelines.tableName).rowAtStartPoint().value(Timelines.id.name)
|
||||
.isEqualTo(timeline.id.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByIds_指定されたIdすべて返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Timelines.tableName) {
|
||||
columns(Timelines.columns)
|
||||
values(1, 1, "test-timeline", "PUBLIC", true)
|
||||
values(2, 1, "test-timeline2", "PUBLIC", true)
|
||||
values(3, 1, "test-timeline3", "PUBLIC", true)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val findByIds = repository.findByIds(listOf(TimelineId(1), TimelineId(3)))
|
||||
|
||||
assertThat(findByIds).hasSize(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdが存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Timelines.tableName) {
|
||||
columns(Timelines.columns)
|
||||
values(1, 1, "test-timeline", "PUBLIC", true)
|
||||
values(2, 1, "test-timeline2", "PUBLIC", true)
|
||||
values(3, 1, "test-timeline3", "PUBLIC", true)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val actual = repository.findById(TimelineId(1))
|
||||
|
||||
val expected = Timeline(
|
||||
TimelineId(1), UserDetailId(1), TimelineName("test-timeline"), TimelineVisibility.PUBLIC, true
|
||||
)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
assertNotNull(actual)
|
||||
assertEquals(expected.id, actual.id)
|
||||
assertEquals(expected.userDetailId, actual.userDetailId)
|
||||
assertEquals(expected.name, actual.name)
|
||||
assertEquals(expected.visibility, actual.visibility)
|
||||
assertEquals(expected.isSystem, actual.isSystem)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定されたIdがなければnull() = runTest {
|
||||
assertNull(repository.findById(TimelineId(1)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findAllByUserDetailIdANdVisibilityIn_指定されたVisibilityで指定されたUserDetailId全部返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(Timelines.tableName) {
|
||||
columns(Timelines.columns)
|
||||
values(1, 1, "test-timeline", "PUBLIC", true)
|
||||
values(2, 1, "test-timeline2", "PRIVATE", true)
|
||||
values(3, 1, "test-timeline3", "PUBLIC", true)
|
||||
}
|
||||
}.launch()
|
||||
|
||||
val timelines =
|
||||
repository.findAllByUserDetailIdAndVisibilityIn(UserDetailId(1), listOf(TimelineVisibility.PUBLIC))
|
||||
|
||||
assertThat(timelines).hasSize(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
val timeline = Timeline(
|
||||
id = TimelineId(1),
|
||||
userDetailId = UserDetailId(1),
|
||||
name = TimelineName("timeline"),
|
||||
visibility = TimelineVisibility.PRIVATE,
|
||||
isSystem = false
|
||||
)
|
||||
|
||||
timeline.setVisibility(
|
||||
TimelineVisibility.PUBLIC, UserDetail.create(
|
||||
UserDetailId(1), ActorId(1),
|
||||
UserDetailHashedPassword("aaaaaa"),
|
||||
)
|
||||
)
|
||||
|
||||
repository.save(timeline)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto(UserDetails.tableName) {
|
||||
columns(UserDetails.columns)
|
||||
values(1, 1, "veeeeeeeeeeeeeeryStrongPassword", true, null, null)
|
||||
}
|
||||
insertInto(Timelines.tableName) {
|
||||
columns(Timelines.columns)
|
||||
values(1, 1, "test-timeline", "PUBLIC", true)
|
||||
}
|
||||
|
||||
}.launch()
|
||||
val timeline = Timeline(
|
||||
id = TimelineId(1),
|
||||
userDetailId = UserDetailId(1),
|
||||
name = TimelineName("timeline"),
|
||||
visibility = TimelineVisibility.PRIVATE,
|
||||
isSystem = false
|
||||
)
|
||||
|
||||
timeline.setVisibility(
|
||||
TimelineVisibility.PUBLIC, UserDetail.create(
|
||||
UserDetailId(1), ActorId(1),
|
||||
UserDetailHashedPassword("aaaaaa"),
|
||||
)
|
||||
)
|
||||
|
||||
repository.delete(timeline)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,367 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.timeline.TimelineId
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailHashedPassword
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.db.api.Assertions.assertThat
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.jupiter.MockitoExtension
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import utils.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
@ExtendWith(MockitoExtension::class)
|
||||
class ExposedUserDetailRepositoryTest : AbstractRepositoryTest(UserDetails) {
|
||||
|
||||
@InjectMocks
|
||||
lateinit var userDetailRepository: ExposedUserDetailRepository
|
||||
|
||||
@Mock
|
||||
lateinit var domainEventPublisher: DomainEventPublisher
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがない場合insert() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
userDetailRepository.save(
|
||||
UserDetail.create(
|
||||
UserDetailId(1),
|
||||
ActorId(1),
|
||||
UserDetailHashedPassword("VeeeeeeeeeeeeeryStrongPassword"),
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(assertTable).row(0).isEqualTo(UserDetails.id, 1).isEqualTo(UserDetails.actorId, 1)
|
||||
.isEqualTo(UserDetails.password, "VeeeeeeeeeeeeeryStrongPassword")
|
||||
.isEqualTo(UserDetails.lastMigration, null).isEqualTo(UserDetails.autoAcceptFolloweeFollowRequest, false)
|
||||
.isEqualTo(UserDetails.homeTimelineId, null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_idが同じレコードがある場合update() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.actors") {
|
||||
columns(Actors.columns)
|
||||
values(
|
||||
1,
|
||||
"b",
|
||||
"test-hideout-dev.usbharu.dev",
|
||||
"b",
|
||||
"",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/inbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/outbox",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b",
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyuMjzmQBsSxzK6NkOpZh\nWuohaUbzCY7AafXt+3+tiL6LulYNg/YRIqKc7Q/vTJE6CHrqo7RA/OqYrSMxF/LC\nf8aX5aHwJE1A2gSgCcs1IL5GJaYRlp4NcuazpBC9NO4xIrvH//jcVnZGXGWsCbls\nHXZGZdurWOF0Bl3mYN8CdupVumrGuOPs+wbI/Gh+OHw611TcXMyAwFwU2UjvPEgk\nEACW9OvJaq1K40jVCAa3b1nXt53vlXXZEUlL78L0C9xuFbJG0K/GKMBN44GyftJO\nhA95Rf1Nhd0vKDLBiRocGcARmBo9PaSCR5651gJEk5/wfLUnNAf0xj3R8LBoOhnT\nCQIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDK4yPOZAGxLHMr\no2Q6lmFa6iFpRvMJjsBp9e37f62Ivou6Vg2D9hEiopztD+9MkToIeuqjtED86pit\nIzEX8sJ/xpflofAkTUDaBKAJyzUgvkYlphGWng1y5rOkEL007jEiu8f/+NxWdkZc\nZawJuWwddkZl26tY4XQGXeZg3wJ26lW6asa44+z7Bsj8aH44fDrXVNxczIDAXBTZ\nSO88SCQQAJb068lqrUrjSNUIBrdvWde3ne+VddkRSUvvwvQL3G4VskbQr8YowE3j\ngbJ+0k6ED3lF/U2F3S8oMsGJGhwZwBGYGj09pIJHnrnWAkSTn/B8tSc0B/TGPdHw\nsGg6GdMJAgMBAAECggEAHkEhLEb70kdOGgJLUR9D/5zYBE0eXdz/MsMyd1AH+Shs\n9AmetKsYzWDmuhp9Cp5swyn328Hmn7B+DvInVn+5YvjNhY07SbaJcVls4g5UQFXk\nu6WC4ZfKap7IyAeaUg54858r8677xcWXuByN5dn+1iU2hJGYK3Cx7rx0PRrUURYG\n2BRaEEwkcPNm9u679OOTyvTmA3NhewUuDaTMkZnnAml87uYYnmFKjQcR+S2UqOm6\nvBZ/devG4TfPBeKEAya/ba8JJ8frGOtjmR9EIliTQoxI2izeAfoGs1OsCSpuPy6s\nV5f0X3HYM7CA+Fpkt2pnixuwg96LaVr4OpVxujhNlwKBgQD1827VuKFGrneNO+c+\n4EIvh+vLh462bJiaVsMHfRhNZF1/5i8gfNJ16ST60hJo11E4riHPzi3q6GWuxOYl\nCkVKvhJ2g3mgnhoehcgnT7UBkasaC7JYd+LsFDnWOTVSJOy2OqfLdLDGAuSTN3kO\nBF4p0ZqQ/AouFNin57WNRGVZ7wKBgQDTLUZtfTkOU3G1nIMTRKmZjqdER5glzHCm\n9o/1ZsQktL+nzSXqYeoWh9fr7fkmC0k/07+SHzzfWvOhWWWlRenUVL5mj7FRq+L9\n9kDjChLR3Jr4L6Sj1iaQ+0uqDSQNYSYO9ctMjAVjFiNhiAd+S6B451Q1VbDKTCHt\nkRW9omz6hwKBgBFTsgY6eJorJl77zmG+mMsSb0kqZqJxahrNa/X2GSUyoeelxsIq\nKQWHhERrUkKykJVGpzkllFSNRMSYOIJ5g8ItO82/m2z2Vm66DAzA78aJhZ1TH6Bd\n6c2p6x0tcJU15rs7zKBnuyBoCcRZTxzur9eQXaxDJVBzxYOmrkKig+VfAoGBAMCP\n2Fiehxh5HobsYNmBEuXjHsM0RZiyA0c8LakoPFL8PodUme5PupUw6cNJDJeUUwbQ\nny8vLOK+nMnUKsu6JK5pV/VNsfM3OZU6p5Bf7ylOcEE/sHF1JVWu0CAQO3+3xmx9\n1RPH2mGwHjMhRzPy4jFdP3wi10KgiY+HbLuvEJChAoGAYCsh3UhtTzGUOlPBkmLL\n17bD0wN4J/fOv8BoXPZ8H2CdqVgWy0s+s+QaPqRxNcA6YyGymBqrmQAn1Uii25r9\nKAwVAjg3S2KDEMSI2RbMMmQJSZ1u0GkxqOUC/MMeZqBYTYxVeqcQPoqJZ0Nk7IOA\nZPFif8bVfcZqeimxrFaV6YI=\n-----END PRIVATE KEY-----",
|
||||
"2024-09-09 17:12:03.941339",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b#main-key",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/following",
|
||||
"https://test-hideout-dev.usbharu.dev/users/b/followers",
|
||||
1,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
"2024-09-09 17:12:03.941339",
|
||||
false,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
insertInto("public.user_details") {
|
||||
columns(UserDetails.columns)
|
||||
values(
|
||||
1,
|
||||
1,
|
||||
"$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm",
|
||||
false,
|
||||
null,
|
||||
1832779979297918976
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
userDetailRepository.save(
|
||||
UserDetail.create(
|
||||
UserDetailId(1),
|
||||
ActorId(1),
|
||||
UserDetailHashedPassword("VeeeeeeeeeeeeeryStrongPassword"),
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(assertTable).row(0).isEqualTo(UserDetails.id, 1).isEqualTo(UserDetails.actorId, 1)
|
||||
.isEqualTo(UserDetails.password, "VeeeeeeeeeeeeeryStrongPassword")
|
||||
.isEqualTo(UserDetails.lastMigration, null).isEqualTo(UserDetails.autoAcceptFolloweeFollowRequest, false)
|
||||
.isEqualTo(UserDetails.homeTimelineId, null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_削除される() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.user_details") {
|
||||
columns(UserDetails.columns)
|
||||
values(
|
||||
1,
|
||||
1,
|
||||
"$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm",
|
||||
false,
|
||||
null,
|
||||
1832779979297918976
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val userDetail = UserDetail(
|
||||
UserDetailId(1), ActorId(1), UserDetailHashedPassword("VeeeeeeeeeeeeeryStrongPassword"), false, null, null
|
||||
)
|
||||
|
||||
change.withSuspend {
|
||||
userDetailRepository.delete(userDetail)
|
||||
}
|
||||
|
||||
assertThat(change).changeOfDeletionOnTable(UserDetails.tableName).rowAtStartPoint().value(UserDetails.id.name)
|
||||
.isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorId_指定したActorIdで存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.user_details") {
|
||||
columns(UserDetails.columns)
|
||||
values(
|
||||
1,
|
||||
1,
|
||||
"$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm",
|
||||
false,
|
||||
null,
|
||||
1832779979297918976
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val expect = UserDetail(
|
||||
id = UserDetailId(1),
|
||||
actorId = ActorId(1),
|
||||
password = UserDetailHashedPassword("$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm"),
|
||||
autoAcceptFolloweeFollowRequest = false,
|
||||
lastMigration = null,
|
||||
homeTimelineId = TimelineId(1832779979297918976)
|
||||
)
|
||||
|
||||
val actual = userDetailRepository.findByActorId(1)
|
||||
|
||||
assertEquals(actual, expect)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findByActorId_指定したActorIdで存在しないとnull() = runTest {
|
||||
assertNull(userDetailRepository.findByActorId(1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定したIdで存在したら返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.user_details") {
|
||||
columns(UserDetails.columns)
|
||||
values(
|
||||
1,
|
||||
1,
|
||||
"$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm",
|
||||
false,
|
||||
null,
|
||||
1832779979297918976
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val expect = UserDetail(
|
||||
id = UserDetailId(1),
|
||||
actorId = ActorId(1),
|
||||
password = UserDetailHashedPassword("$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm"),
|
||||
autoAcceptFolloweeFollowRequest = false,
|
||||
lastMigration = null,
|
||||
homeTimelineId = TimelineId(1832779979297918976)
|
||||
)
|
||||
|
||||
val actual = userDetailRepository.findById(UserDetailId(1))
|
||||
|
||||
assertEquals(actual, expect)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findById_指定したIdで存在しないとnull() = runTest {
|
||||
assertNull(userDetailRepository.findById(UserDetailId(1)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun findAllById_指定されたidすべて返す() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.user_details") {
|
||||
columns(UserDetails.columns)
|
||||
values(
|
||||
1, 1, "$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm", false, null, null
|
||||
)
|
||||
values(
|
||||
2,
|
||||
2,
|
||||
"$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm",
|
||||
false,
|
||||
null,
|
||||
1832779979297918976
|
||||
)
|
||||
values(
|
||||
3,
|
||||
3,
|
||||
"$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm",
|
||||
false,
|
||||
null,
|
||||
1832779979297918976
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
val userDetailList = userDetailRepository.findAllById(listOf(UserDetailId(1), UserDetailId(3)))
|
||||
|
||||
assertThat(userDetailList).hasSize(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun save_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
userDetailRepository.save(
|
||||
UserDetail.create(
|
||||
UserDetailId(1),
|
||||
ActorId(1),
|
||||
UserDetailHashedPassword("VeeeeeeeeeeeeeryStrongPassword"),
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delete_ドメインイベントがパブリッシュされる() = runTest {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(disableReferenceIntegrityConstraints)
|
||||
insertInto("public.user_details") {
|
||||
columns(
|
||||
UserDetails.columns
|
||||
)
|
||||
values(
|
||||
1,
|
||||
1,
|
||||
"$2a$10\$EBj3lstVOv0wz3CxLpzYJu8FFrUJ2MPJW9Vlklyg.bfGEOn5sqIwm",
|
||||
false,
|
||||
null,
|
||||
1832779979297918976
|
||||
)
|
||||
}
|
||||
execute(enableReferenceIntegrityConstraints)
|
||||
}.launch()
|
||||
|
||||
userDetailRepository.delete(
|
||||
UserDetail.create(
|
||||
UserDetailId(1),
|
||||
ActorId(1),
|
||||
UserDetailHashedPassword("VeeeeeeeeeeeeeryStrongPassword"),
|
||||
false,
|
||||
null,
|
||||
null
|
||||
)
|
||||
)
|
||||
|
||||
TransactionManager.current().commit()
|
||||
|
||||
verify(domainEventPublisher, times(1)).publishEvent(any())
|
||||
}
|
||||
|
||||
private fun assertEquals(
|
||||
actual: UserDetail?, expect: UserDetail
|
||||
) {
|
||||
assertNotNull(actual)
|
||||
kotlin.test.assertEquals(expect, actual)
|
||||
assertEquals(expect.id, actual.id)
|
||||
assertEquals(expect.actorId, actual.actorId)
|
||||
assertEquals(expect.password, actual.password)
|
||||
assertEquals(expect.autoAcceptFolloweeFollowRequest, actual.autoAcceptFolloweeFollowRequest)
|
||||
assertEquals(expect.lastMigration, actual.lastMigration)
|
||||
assertEquals(expect.homeTimelineId, actual.homeTimelineId)
|
||||
}
|
||||
}
|
|
@ -59,7 +59,7 @@ class UserDetailsServiceImplTest {
|
|||
fun userDetailが見つからない場合失敗() = runTest {
|
||||
whenever(actorRepository.findByNameAndDomain(eq("test"), eq("example.com"))).doReturn(
|
||||
TestActorFactory.create(
|
||||
actorName = "test", id = 1
|
||||
id = 1, actorName = "test"
|
||||
)
|
||||
)
|
||||
assertThrows<UsernameNotFoundException> {
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
package utils
|
||||
|
||||
import com.ninja_squad.dbsetup.Operations
|
||||
import com.ninja_squad.dbsetup.operation.Insert
|
||||
import com.ninja_squad.dbsetup_kotlin.dbSetup
|
||||
import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import org.assertj.db.api.TableRowAssert
|
||||
import org.assertj.db.api.TableRowValueAssert
|
||||
import org.assertj.db.type.Changes
|
||||
import org.assertj.db.type.Table
|
||||
import org.flywaydb.core.Flyway
|
||||
import org.jetbrains.exposed.sql.Column
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.jetbrains.exposed.sql.DatabaseConfig
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import java.sql.Connection
|
||||
import javax.sql.DataSource
|
||||
|
||||
abstract class AbstractRepositoryTest(private val exposedTable: org.jetbrains.exposed.sql.Table) {
|
||||
|
||||
protected val assertTable: Table
|
||||
get() {
|
||||
return Table(dataSource, exposedTable.tableName)
|
||||
}
|
||||
|
||||
protected fun getTable(name: String): Table {
|
||||
return Table(dataSource, name)
|
||||
}
|
||||
|
||||
private lateinit var transaction: Transaction
|
||||
|
||||
protected lateinit var change: Changes
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
flyway.clean()
|
||||
flyway.migrate()
|
||||
transaction = TransactionManager.manager.newTransaction(Connection.TRANSACTION_READ_UNCOMMITTED)
|
||||
change = Changes(assertTable)
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
dbSetup(to = dataSource) {
|
||||
execute(Operations.sql("SET REFERENTIAL_INTEGRITY TRUE"))
|
||||
}.launch()
|
||||
transaction.rollback()
|
||||
transaction.close()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
lateinit var dataSource: DataSource
|
||||
lateinit var flyway: Flyway
|
||||
|
||||
@JvmStatic
|
||||
@BeforeAll
|
||||
fun setup() {
|
||||
val hikariConfig = HikariConfig()
|
||||
hikariConfig.jdbcUrl =
|
||||
"jdbc:h2:mem:test;MODE=POSTGRESQL;DB_CLOSE_DELAY=-1;CASE_INSENSITIVE_IDENTIFIERS=true;TRACE_LEVEL_FILE=4;"
|
||||
hikariConfig.driverClassName = "org.h2.Driver"
|
||||
hikariConfig.transactionIsolation = "TRANSACTION_READ_UNCOMMITTED"
|
||||
dataSource = HikariDataSource(hikariConfig)
|
||||
|
||||
|
||||
flyway = Flyway.configure().cleanDisabled(false).dataSource(dataSource).load()
|
||||
Database.connect(dataSource, databaseConfig = DatabaseConfig {
|
||||
defaultMaxAttempts = 1
|
||||
|
||||
})
|
||||
flyway.clean()
|
||||
flyway.migrate()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@AfterAll
|
||||
fun clean() {
|
||||
// flyway.clean()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> TableRowAssert.value(column: Column<T>): TableRowValueAssert = value(column.name)
|
||||
fun <T> TableRowValueAssert.value(column: Column<T>): TableRowValueAssert = value(column.name)
|
||||
|
||||
fun <T> TableRowAssert.isEqualTo(column: Column<T>, value: T): TableRowValueAssert {
|
||||
return value(column).isEqualTo(value)
|
||||
}
|
||||
|
||||
fun <T> TableRowValueAssert.isEqualTo(column: Column<T>, value: T): TableRowValueAssert {
|
||||
return value(column).isEqualTo(value)
|
||||
}
|
||||
|
||||
fun Insert.Builder.columns(columns: List<Column<*>>): Insert.Builder {
|
||||
columns(*columns.map { it.name }.toTypedArray())
|
||||
return this
|
||||
}
|
||||
|
||||
fun Insert.Builder.columns(vararg columns: Column<*>): Insert.Builder {
|
||||
columns(*columns.map { it.name }.toTypedArray())
|
||||
return this
|
||||
}
|
||||
|
||||
fun Changes.with(block: () -> Unit) {
|
||||
setStartPointNow()
|
||||
block()
|
||||
setEndPointNow()
|
||||
}
|
||||
|
||||
suspend fun Changes.withSuspend(block: suspend () -> Unit) {
|
||||
setStartPointNow()
|
||||
block()
|
||||
setEndPointNow()
|
||||
}
|
||||
|
||||
val disableReferenceIntegrityConstraints = Operations.sql("SET REFERENTIAL_INTEGRITY FALSE")
|
||||
val enableReferenceIntegrityConstraints = Operations.sql("SET REFERENTIAL_INTEGRITY TRUE")
|
|
@ -50,7 +50,7 @@ class ExposedAccountQueryServiceImpl(private val applicationConfig: ApplicationC
|
|||
id = resultRow[Actors.id].toString(),
|
||||
username = resultRow[Actors.name],
|
||||
acct = "${resultRow[Actors.name]}@${resultRow[Actors.domain]}",
|
||||
url = resultRow[Actors.url],
|
||||
url = resultRow[Actors.url].toString(),
|
||||
displayName = resultRow[Actors.screenName],
|
||||
note = resultRow[Actors.description],
|
||||
avatar = "$userUrl/icon.jpg",
|
||||
|
|
|
@ -225,13 +225,13 @@ private fun toStatus(it: ResultRow, queryAlias: QueryAlias, inReplyToAlias: Alia
|
|||
id = it[Actors.id].toString(),
|
||||
username = it[Actors.name],
|
||||
acct = "${it[Actors.name]}@${it[Actors.domain]}",
|
||||
url = it[Actors.url],
|
||||
url = it[Actors.url].toString(),
|
||||
displayName = it[Actors.screenName],
|
||||
note = it[Actors.description],
|
||||
avatar = it[Actors.url] + "/icon.jpg",
|
||||
avatarStatic = it[Actors.url] + "/icon.jpg",
|
||||
header = it[Actors.url] + "/header.jpg",
|
||||
headerStatic = it[Actors.url] + "/header.jpg",
|
||||
avatar = "${it[Actors.url]}/icon.jpg",
|
||||
avatarStatic = "${it[Actors.url]}/icon.jpg",
|
||||
header = "${it[Actors.url]}/header.jpg",
|
||||
headerStatic = "${it[Actors.url]}/header.jpg",
|
||||
locked = it[Actors.locked],
|
||||
fields = emptyList(),
|
||||
emojis = emptyList(),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
kotlin.code.style=official
|
||||
org.gradle.daemon=true
|
||||
org.gradle.parallel=true
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED
|
||||
kotlin.compiler.preciseCompilationResultsBackup=true
|
Loading…
Reference in New Issue