mirror of https://github.com/usbharu/Hideout.git
commit
5f97c45906
|
@ -1,4 +1,5 @@
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.configureondemand=true
|
org.gradle.configureondemand=true
|
||||||
org.gradle.caching=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.ktor.client.mock)
|
||||||
testImplementation(libs.h2db)
|
testImplementation(libs.h2db)
|
||||||
testImplementation(libs.mockito.kotlin)
|
testImplementation(libs.mockito.kotlin)
|
||||||
|
testImplementation("org.assertj:assertj-db:2.0.2")
|
||||||
|
testImplementation("com.ninja-squad:DbSetup-kotlin:2.1.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
detekt {
|
detekt {
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
kotlin.code.style=official
|
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.configureondemand=true
|
org.gradle.configureondemand=true
|
||||||
org.gradle.caching=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 =
|
val canAccountMigration =
|
||||||
localActorMigrationCheckDomainService.canAccountMigration(userDetail, fromActor, toActor)
|
localActorMigrationCheckDomainService.canAccountMigration(userDetail, fromActor, toActor)
|
||||||
if (canAccountMigration.canMigration) {
|
if (canAccountMigration.canMigration) {
|
||||||
fromActor.moveTo = toActorId
|
fromActor.setMoveTo(toActorId)
|
||||||
actorRepository.save(fromActor)
|
actorRepository.save(fromActor)
|
||||||
} else {
|
} else {
|
||||||
when (canAccountMigration) {
|
when (canAccountMigration) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ class GetPostDetailApplicationService(
|
||||||
|
|
||||||
val iconMedia = actor.icon?.let { mediaRepository.findById(it) }
|
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)
|
val reactions = reactionsQueryService.findAllByPostId(post.id)
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ class GetPostDetailApplicationService(
|
||||||
actor to iconMedia
|
actor to iconMedia
|
||||||
}
|
}
|
||||||
|
|
||||||
val mediaList = mediaRepository.findByIds(post.mediaIds)
|
val mediaList = mediaRepository.findByIdIn(post.mediaIds)
|
||||||
return PostDetail.of(
|
return PostDetail.of(
|
||||||
post = post,
|
post = post,
|
||||||
actor = first,
|
actor = first,
|
||||||
|
|
|
@ -85,31 +85,40 @@ class Actor(
|
||||||
}
|
}
|
||||||
|
|
||||||
var alsoKnownAs = alsoKnownAs
|
var alsoKnownAs = alsoKnownAs
|
||||||
set(value) {
|
private set
|
||||||
require(value.none { it == id })
|
|
||||||
field = value
|
fun setAlsoKnownAs(alsoKnownAs: Set<ActorId>) {
|
||||||
}
|
require(alsoKnownAs.none { it == id })
|
||||||
|
this.alsoKnownAs = alsoKnownAs
|
||||||
|
}
|
||||||
|
|
||||||
var moveTo = moveTo
|
var moveTo = moveTo
|
||||||
set(value) {
|
private set
|
||||||
require(value != id)
|
|
||||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(MOVE))
|
fun setMoveTo(moveTo: ActorId?) {
|
||||||
field = value
|
require(moveTo != id)
|
||||||
}
|
addDomainEvent(ActorDomainEventFactory(this).createEvent(MOVE))
|
||||||
|
this.moveTo = moveTo
|
||||||
|
}
|
||||||
|
|
||||||
var emojis = emojiIds
|
var emojis = emojiIds
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var description = description
|
var description = description
|
||||||
set(value) {
|
private set
|
||||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(UPDATE))
|
|
||||||
field = value
|
fun setDescription(description: ActorDescription) {
|
||||||
}
|
addDomainEvent(ActorDomainEventFactory(this).createEvent(UPDATE))
|
||||||
|
this.description = description
|
||||||
|
}
|
||||||
|
|
||||||
var screenName = screenName
|
var screenName = screenName
|
||||||
set(value) {
|
private set
|
||||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(UPDATE))
|
|
||||||
field = value
|
fun setScreenName(screenName: ActorScreenName) {
|
||||||
}
|
addDomainEvent(ActorDomainEventFactory(this).createEvent(UPDATE))
|
||||||
|
this.screenName = screenName
|
||||||
|
}
|
||||||
|
|
||||||
var deleted = deleted
|
var deleted = deleted
|
||||||
private set
|
private set
|
||||||
|
@ -135,4 +144,48 @@ class Actor(
|
||||||
fun checkUpdate() {
|
fun checkUpdate() {
|
||||||
addDomainEvent(ActorDomainEventFactory(this).createEvent(CHECK_UPDATE))
|
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) {
|
class ActorDescription(description: String) {
|
||||||
val description: String = description.take(LENGTH)
|
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 {
|
companion object {
|
||||||
const val LENGTH = 10000
|
const val LENGTH = 10000
|
||||||
val empty = ActorDescription("")
|
val empty = ActorDescription("")
|
||||||
|
|
|
@ -20,6 +20,17 @@ class ActorScreenName(screenName: String) {
|
||||||
|
|
||||||
val screenName: String = screenName.take(LENGTH)
|
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 {
|
companion object {
|
||||||
const val LENGTH = 300
|
const val LENGTH = 300
|
||||||
val empty = ActorScreenName("")
|
val empty = ActorScreenName("")
|
||||||
|
|
|
@ -4,4 +4,17 @@ class FilterKeyword(
|
||||||
val id: FilterKeywordId,
|
val id: FilterKeywordId,
|
||||||
var keyword: FilterKeywordKeyword,
|
var keyword: FilterKeywordKeyword,
|
||||||
val mode: FilterMode
|
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)
|
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 {
|
companion object {
|
||||||
const val LENGTH = 300
|
const val LENGTH = 300
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,6 @@ package dev.usbharu.hideout.core.domain.model.media
|
||||||
interface MediaRepository {
|
interface MediaRepository {
|
||||||
suspend fun save(media: Media): Media
|
suspend fun save(media: Media): Media
|
||||||
suspend fun findById(id: MediaId): 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)
|
suspend fun delete(media: Media)
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,18 +34,4 @@ interface RelationshipRepository {
|
||||||
targetIds: List<ActorId>,
|
targetIds: List<ActorId>,
|
||||||
following: Boolean
|
following: Boolean
|
||||||
): List<Relationship>
|
): 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))
|
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 {
|
companion object {
|
||||||
fun create(
|
fun create(
|
||||||
id: TimelineId,
|
id: TimelineId,
|
||||||
|
|
|
@ -35,7 +35,7 @@ class ActorQueryMapper(private val actorResultRowMapper: ResultRowMapper<Actor>)
|
||||||
.first()
|
.first()
|
||||||
.let(actorResultRowMapper::map)
|
.let(actorResultRowMapper::map)
|
||||||
.apply {
|
.apply {
|
||||||
alsoKnownAs = buildAlsoKnownAs(it)
|
setAlsoKnownAs(buildAlsoKnownAs(it))
|
||||||
clearDomainEvents()
|
clearDomainEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import dev.usbharu.hideout.core.domain.model.support.domain.Domain
|
||||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
|
import dev.usbharu.hideout.core.infrastructure.exposedrepository.Actors
|
||||||
import org.jetbrains.exposed.sql.ResultRow
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import java.net.URI
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class ActorResultRowMapper : ResultRowMapper<Actor> {
|
class ActorResultRowMapper : ResultRowMapper<Actor> {
|
||||||
|
@ -35,15 +34,15 @@ class ActorResultRowMapper : ResultRowMapper<Actor> {
|
||||||
domain = Domain(resultRow[Actors.domain]),
|
domain = Domain(resultRow[Actors.domain]),
|
||||||
screenName = ActorScreenName(resultRow[Actors.screenName]),
|
screenName = ActorScreenName(resultRow[Actors.screenName]),
|
||||||
description = ActorDescription(resultRow[Actors.description]),
|
description = ActorDescription(resultRow[Actors.description]),
|
||||||
inbox = URI.create(resultRow[Actors.inbox]),
|
inbox = resultRow[Actors.inbox],
|
||||||
outbox = URI.create(resultRow[Actors.outbox]),
|
outbox = resultRow[Actors.outbox],
|
||||||
url = URI.create(resultRow[Actors.url]),
|
url = resultRow[Actors.url],
|
||||||
publicKey = ActorPublicKey(resultRow[Actors.publicKey]),
|
publicKey = ActorPublicKey(resultRow[Actors.publicKey]),
|
||||||
privateKey = resultRow[Actors.privateKey]?.let { ActorPrivateKey(it) },
|
privateKey = resultRow[Actors.privateKey]?.let { ActorPrivateKey(it) },
|
||||||
createdAt = resultRow[Actors.createdAt],
|
createdAt = resultRow[Actors.createdAt],
|
||||||
keyId = ActorKeyId(resultRow[Actors.keyId]),
|
keyId = ActorKeyId(resultRow[Actors.keyId]),
|
||||||
followersEndpoint = resultRow[Actors.followers]?.let { URI.create(it) },
|
followersEndpoint = resultRow[Actors.followers],
|
||||||
followingEndpoint = resultRow[Actors.following]?.let { URI.create(it) },
|
followingEndpoint = resultRow[Actors.following],
|
||||||
instance = InstanceId(resultRow[Actors.instance]),
|
instance = InstanceId(resultRow[Actors.instance]),
|
||||||
locked = resultRow[Actors.locked],
|
locked = resultRow[Actors.locked],
|
||||||
followersCount = resultRow[Actors.followersCount]?.let { ActorRelationshipCount(it) },
|
followersCount = resultRow[Actors.followersCount]?.let { ActorRelationshipCount(it) },
|
||||||
|
|
|
@ -33,7 +33,7 @@ class FilterQueryMapper(private val filterResultRowMapper: ResultRowMapper<Filte
|
||||||
it
|
it
|
||||||
.first()
|
.first()
|
||||||
.let(filterResultRowMapper::map)
|
.let(filterResultRowMapper::map)
|
||||||
.apply {
|
.run {
|
||||||
reconstructWith(
|
reconstructWith(
|
||||||
it.mapNotNull { resultRow: ResultRow ->
|
it.mapNotNull { resultRow: ResultRow ->
|
||||||
FilterKeyword(
|
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],
|
name = it[Actors.name],
|
||||||
domain = it[Actors.domain],
|
domain = it[Actors.domain],
|
||||||
screenName = it[Actors.screenName],
|
screenName = it[Actors.screenName],
|
||||||
url = URI.create(it[Actors.url]),
|
url = it[Actors.url],
|
||||||
locked = it[Actors.locked],
|
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]],
|
overview = it[authorizedQuery[Posts.overview]],
|
||||||
text = it[authorizedQuery[Posts.text]],
|
text = it[authorizedQuery[Posts.text]],
|
||||||
|
|
|
@ -75,6 +75,7 @@ class ExposedActorInstanceRelationshipRepository(override val domainEventPublish
|
||||||
ActorInstanceRelationships.actorId eq actorId.id and
|
ActorInstanceRelationships.actorId eq actorId.id and
|
||||||
(ActorInstanceRelationships.instanceId eq instanceId.instanceId)
|
(ActorInstanceRelationships.instanceId eq instanceId.instanceId)
|
||||||
}
|
}
|
||||||
|
.limit(1)
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
?.toActorInstanceRelationship()
|
?.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.domainevent.DomainEventPublisher
|
||||||
import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository
|
import dev.usbharu.hideout.core.domain.shared.repository.DomainEventPublishableRepository
|
||||||
import dev.usbharu.hideout.core.infrastructure.exposed.QueryMapper
|
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.*
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.javatime.timestamp
|
import org.jetbrains.exposed.sql.javatime.timestamp
|
||||||
|
@ -30,15 +31,15 @@ class ExposedActorRepository(
|
||||||
it[domain] = actor.domain.domain
|
it[domain] = actor.domain.domain
|
||||||
it[screenName] = actor.screenName.screenName
|
it[screenName] = actor.screenName.screenName
|
||||||
it[description] = actor.description.description
|
it[description] = actor.description.description
|
||||||
it[inbox] = actor.inbox.toString()
|
it[inbox] = actor.inbox
|
||||||
it[outbox] = actor.outbox.toString()
|
it[outbox] = actor.outbox
|
||||||
it[url] = actor.url.toString()
|
it[url] = actor.url
|
||||||
it[publicKey] = actor.publicKey.publicKey
|
it[publicKey] = actor.publicKey.publicKey
|
||||||
it[privateKey] = actor.privateKey?.privateKey
|
it[privateKey] = actor.privateKey?.privateKey
|
||||||
it[createdAt] = actor.createdAt
|
it[createdAt] = actor.createdAt
|
||||||
it[keyId] = actor.keyId.keyId
|
it[keyId] = actor.keyId.keyId
|
||||||
it[following] = actor.followingEndpoint?.toString()
|
it[following] = actor.followingEndpoint
|
||||||
it[followers] = actor.followersEndpoint?.toString()
|
it[followers] = actor.followersEndpoint
|
||||||
it[instance] = actor.instance.instanceId
|
it[instance] = actor.instance.instanceId
|
||||||
it[locked] = actor.locked
|
it[locked] = actor.locked
|
||||||
it[followingCount] = actor.followingCount?.relationshipCount
|
it[followingCount] = actor.followingCount?.relationshipCount
|
||||||
|
@ -69,8 +70,8 @@ class ExposedActorRepository(
|
||||||
|
|
||||||
override suspend fun delete(actor: Actor) {
|
override suspend fun delete(actor: Actor) {
|
||||||
query {
|
query {
|
||||||
Actors.deleteWhere { id eq actor.id.id }
|
|
||||||
ActorsAlsoKnownAs.deleteWhere { actorId eq actor.id.id }
|
ActorsAlsoKnownAs.deleteWhere { actorId eq actor.id.id }
|
||||||
|
Actors.deleteWhere { id eq actor.id.id }
|
||||||
onComplete {
|
onComplete {
|
||||||
update(actor)
|
update(actor)
|
||||||
}
|
}
|
||||||
|
@ -126,15 +127,15 @@ object Actors : Table("actors") {
|
||||||
val domain = varchar("domain", Domain.LENGTH)
|
val domain = varchar("domain", Domain.LENGTH)
|
||||||
val screenName = varchar("screen_name", ActorScreenName.LENGTH)
|
val screenName = varchar("screen_name", ActorScreenName.LENGTH)
|
||||||
val description = varchar("description", ActorDescription.LENGTH)
|
val description = varchar("description", ActorDescription.LENGTH)
|
||||||
val inbox = varchar("inbox", 1000).uniqueIndex()
|
val inbox = uri("inbox", 1000).uniqueIndex()
|
||||||
val outbox = varchar("outbox", 1000).uniqueIndex()
|
val outbox = uri("outbox", 1000).uniqueIndex()
|
||||||
val url = varchar("url", 1000).uniqueIndex()
|
val url = uri("url", 1000).uniqueIndex()
|
||||||
val publicKey = varchar("public_key", 10000)
|
val publicKey = varchar("public_key", 10000)
|
||||||
val privateKey = varchar("private_key", 100000).nullable()
|
val privateKey = varchar("private_key", 100000).nullable()
|
||||||
val createdAt = timestamp("created_at")
|
val createdAt = timestamp("created_at")
|
||||||
val keyId = varchar("key_id", 1000)
|
val keyId = varchar("key_id", 1000)
|
||||||
val following = varchar("following", 1000).nullable()
|
val following = uri("following", 1000).nullable()
|
||||||
val followers = varchar("followers", 1000).nullable()
|
val followers = uri("followers", 1000).nullable()
|
||||||
val instance = long("instance").references(Instance.id)
|
val instance = long("instance").references(Instance.id)
|
||||||
val locked = bool("locked")
|
val locked = bool("locked")
|
||||||
val followingCount = integer("following_count").nullable()
|
val followingCount = integer("following_count").nullable()
|
||||||
|
|
|
@ -31,8 +31,7 @@ import org.springframework.stereotype.Repository
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class CustomEmojiRepositoryImpl : CustomEmojiRepository,
|
class ExposedCustomEmojiRepository : CustomEmojiRepository, AbstractRepository() {
|
||||||
AbstractRepository() {
|
|
||||||
override val logger: Logger
|
override val logger: Logger
|
||||||
get() = Companion.logger
|
get() = Companion.logger
|
||||||
|
|
||||||
|
@ -50,7 +49,12 @@ class CustomEmojiRepositoryImpl : CustomEmojiRepository,
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findById(id: Long): CustomEmoji? = query {
|
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 {
|
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 {
|
override suspend fun findByNamesAndDomain(names: List<String>, domain: String): List<CustomEmoji> = query {
|
||||||
return@query CustomEmojis
|
CustomEmojis
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.where {
|
.where {
|
||||||
CustomEmojis.name inList names and (CustomEmojis.domain eq domain)
|
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 {
|
override suspend fun findByIds(ids: List<Long>): List<CustomEmoji> = query {
|
||||||
return@query CustomEmojis
|
CustomEmojis
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.where {
|
.where {
|
||||||
CustomEmojis.id inList ids
|
CustomEmojis.id inList ids
|
||||||
|
@ -76,7 +80,7 @@ class CustomEmojiRepositoryImpl : CustomEmojiRepository,
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
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
|
val filterId = FilterKeywords
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.where { FilterKeywords.id eq filterKeywordId.id }
|
.where { FilterKeywords.id eq filterKeywordId.id }
|
||||||
|
.limit(1)
|
||||||
.firstOrNull()?.get(FilterKeywords.filterId) ?: return@query null
|
.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()
|
return@query filterQueryMapper.map(where).firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByFilterId(filterId: FilterId): Filter? = query {
|
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()
|
return@query filterQueryMapper.map(where).firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByUserDetailId(userDetailId: UserDetailId): List<Filter> = query {
|
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 {
|
companion object {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||||
|
|
||||||
import dev.usbharu.hideout.core.domain.model.instance.*
|
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.*
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.jetbrains.exposed.sql.javatime.timestamp
|
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
|
import dev.usbharu.hideout.core.domain.model.instance.Instance as InstanceEntity
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class InstanceRepositoryImpl : InstanceRepository,
|
class ExposedInstanceRepository : InstanceRepository,
|
||||||
AbstractRepository() {
|
AbstractRepository() {
|
||||||
override val logger: Logger
|
override val logger: Logger
|
||||||
get() = Companion.logger
|
get() = Companion.logger
|
||||||
|
@ -37,9 +38,9 @@ class InstanceRepositoryImpl : InstanceRepository,
|
||||||
it[id] = instance.id.instanceId
|
it[id] = instance.id.instanceId
|
||||||
it[name] = instance.name.name
|
it[name] = instance.name.name
|
||||||
it[description] = instance.description.description
|
it[description] = instance.description.description
|
||||||
it[url] = instance.url.toString()
|
it[url] = instance.url
|
||||||
it[iconUrl] = instance.iconUrl.toString()
|
it[iconUrl] = instance.iconUrl
|
||||||
it[sharedInbox] = instance.sharedInbox?.toString()
|
it[sharedInbox] = instance.sharedInbox
|
||||||
it[software] = instance.software.software
|
it[software] = instance.software.software
|
||||||
it[version] = instance.version.version
|
it[version] = instance.version.version
|
||||||
it[isBlocked] = instance.isBlocked
|
it[isBlocked] = instance.isBlocked
|
||||||
|
@ -52,7 +53,7 @@ class InstanceRepositoryImpl : InstanceRepository,
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findById(id: InstanceId): InstanceEntity? = query {
|
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()
|
.singleOrNull()?.toInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,11 +62,11 @@ class InstanceRepositoryImpl : InstanceRepository,
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByUrl(url: URI): dev.usbharu.hideout.core.domain.model.instance.Instance? = query {
|
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 {
|
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]),
|
id = InstanceId(this[Instance.id]),
|
||||||
name = InstanceName(this[Instance.name]),
|
name = InstanceName(this[Instance.name]),
|
||||||
description = InstanceDescription(this[Instance.description]),
|
description = InstanceDescription(this[Instance.description]),
|
||||||
url = URI.create(this[Instance.url]),
|
url = this[Instance.url],
|
||||||
iconUrl = URI.create(this[Instance.iconUrl]),
|
iconUrl = this[Instance.iconUrl],
|
||||||
sharedInbox = this[Instance.sharedInbox]?.let { URI.create(it) },
|
sharedInbox = this[Instance.sharedInbox],
|
||||||
software = InstanceSoftware(this[Instance.software]),
|
software = InstanceSoftware(this[Instance.software]),
|
||||||
version = InstanceVersion(this[Instance.version]),
|
version = InstanceVersion(this[Instance.version]),
|
||||||
isBlocked = this[Instance.isBlocked],
|
isBlocked = this[Instance.isBlocked],
|
||||||
|
@ -90,9 +91,9 @@ object Instance : Table("instance") {
|
||||||
val id = long("id")
|
val id = long("id")
|
||||||
val name = varchar("name", 1000)
|
val name = varchar("name", 1000)
|
||||||
val description = varchar("description", 5000)
|
val description = varchar("description", 5000)
|
||||||
val url = varchar("url", 255).uniqueIndex()
|
val url = uri("url", 255).uniqueIndex()
|
||||||
val iconUrl = varchar("icon_url", 255)
|
val iconUrl = uri("icon_url", 255)
|
||||||
val sharedInbox = varchar("shared_inbox", 255).nullable().uniqueIndex()
|
val sharedInbox = uri("shared_inbox", 255).nullable().uniqueIndex()
|
||||||
val software = varchar("software", 255)
|
val software = varchar("software", 255)
|
||||||
val version = varchar("version", 255)
|
val version = varchar("version", 255)
|
||||||
val isBlocked = bool("is_blocked")
|
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.actor.ActorId
|
||||||
import dev.usbharu.hideout.core.domain.model.media.*
|
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.*
|
||||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
import java.net.URI
|
|
||||||
import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia
|
import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
class ExposedMediaRepository : MediaRepository, AbstractRepository() {
|
||||||
override val logger: Logger
|
override val logger: Logger
|
||||||
get() = Companion.logger
|
get() = Companion.logger
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@ class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
||||||
Media.upsert {
|
Media.upsert {
|
||||||
it[id] = media.id.id
|
it[id] = media.id.id
|
||||||
it[name] = media.name.name
|
it[name] = media.name.name
|
||||||
it[url] = media.url.toString()
|
it[url] = media.url
|
||||||
it[remoteUrl] = media.remoteUrl?.toString()
|
it[remoteUrl] = media.remoteUrl
|
||||||
it[thumbnailUrl] = media.thumbnailUrl?.toString()
|
it[thumbnailUrl] = media.thumbnailUrl
|
||||||
it[type] = media.type.name
|
it[type] = media.type.name
|
||||||
it[blurhash] = media.blurHash?.hash
|
it[blurhash] = media.blurHash?.hash
|
||||||
it[mimeType] = media.mimeType.type + "/" + media.mimeType.subtype
|
it[mimeType] = media.mimeType.type + "/" + media.mimeType.subtype
|
||||||
|
@ -51,12 +51,13 @@ class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
||||||
return query {
|
return query {
|
||||||
return@query Media
|
return@query Media
|
||||||
.selectAll().where { Media.id eq id.id }
|
.selectAll().where { Media.id eq id.id }
|
||||||
|
.limit(1)
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
?.toMedia()
|
?.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 {
|
||||||
return@query Media
|
return@query Media
|
||||||
.selectAll()
|
.selectAll()
|
||||||
|
@ -72,7 +73,7 @@ class MediaRepositoryImpl : MediaRepository, AbstractRepository() {
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
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(
|
return EntityMedia(
|
||||||
id = MediaId(this[Media.id]),
|
id = MediaId(this[Media.id]),
|
||||||
name = MediaName(this[Media.name]),
|
name = MediaName(this[Media.name]),
|
||||||
url = URI.create(this[Media.url]),
|
url = this[Media.url],
|
||||||
remoteUrl = this[Media.remoteUrl]?.let { URI.create(it) },
|
remoteUrl = this[Media.remoteUrl],
|
||||||
thumbnailUrl = this[Media.thumbnailUrl]?.let { URI.create(it) },
|
thumbnailUrl = this[Media.thumbnailUrl],
|
||||||
type = fileType,
|
type = fileType,
|
||||||
blurHash = this[Media.blurhash]?.let { MediaBlurHash(it) },
|
blurHash = this[Media.blurhash]?.let { MediaBlurHash(it) },
|
||||||
mimeType = MimeType(mimeType.substringBefore("/"), mimeType.substringAfter("/"), fileType),
|
mimeType = MimeType(mimeType.substringBefore("/"), mimeType.substringAfter("/"), fileType),
|
||||||
|
@ -99,9 +100,9 @@ fun ResultRow.toMediaOrNull(): EntityMedia? {
|
||||||
return EntityMedia(
|
return EntityMedia(
|
||||||
id = MediaId(this.getOrNull(Media.id) ?: return null),
|
id = MediaId(this.getOrNull(Media.id) ?: return null),
|
||||||
name = MediaName(this.getOrNull(Media.name) ?: return null),
|
name = MediaName(this.getOrNull(Media.name) ?: return null),
|
||||||
url = URI.create(this.getOrNull(Media.url) ?: return null),
|
url = this.getOrNull(Media.url) ?: return null,
|
||||||
remoteUrl = this[Media.remoteUrl]?.let { URI.create(it) },
|
remoteUrl = this[Media.remoteUrl],
|
||||||
thumbnailUrl = this[Media.thumbnailUrl]?.let { URI.create(it) },
|
thumbnailUrl = this[Media.thumbnailUrl],
|
||||||
type = FileType.valueOf(this[Media.type]),
|
type = FileType.valueOf(this[Media.type]),
|
||||||
blurHash = this[Media.blurhash]?.let { MediaBlurHash(it) },
|
blurHash = this[Media.blurhash]?.let { MediaBlurHash(it) },
|
||||||
mimeType = MimeType(mimeType.substringBefore("/"), mimeType.substringAfter("/"), fileType),
|
mimeType = MimeType(mimeType.substringBefore("/"), mimeType.substringAfter("/"), fileType),
|
||||||
|
@ -113,9 +114,9 @@ fun ResultRow.toMediaOrNull(): EntityMedia? {
|
||||||
object Media : Table("media") {
|
object Media : Table("media") {
|
||||||
val id = long("id")
|
val id = long("id")
|
||||||
val name = varchar("name", 255)
|
val name = varchar("name", 255)
|
||||||
val url = varchar("url", 255).uniqueIndex()
|
val url = uri("url", 255).uniqueIndex()
|
||||||
val remoteUrl = varchar("remote_url", 255).uniqueIndex().nullable()
|
val remoteUrl = uri("remote_url", 255).uniqueIndex().nullable()
|
||||||
val thumbnailUrl = varchar("thumbnail_url", 255).uniqueIndex().nullable()
|
val thumbnailUrl = uri("thumbnail_url", 255).uniqueIndex().nullable()
|
||||||
val type = varchar("type", 100)
|
val type = varchar("type", 100)
|
||||||
val blurhash = varchar("blurhash", 255).nullable()
|
val blurhash = varchar("blurhash", 255).nullable()
|
||||||
val mimeType = varchar("mime_type", 255)
|
val mimeType = varchar("mime_type", 255)
|
|
@ -163,6 +163,8 @@ class ExposedPostRepository(
|
||||||
override suspend fun findById(id: PostId): Post? = query {
|
override suspend fun findById(id: PostId): Post? = query {
|
||||||
Posts
|
Posts
|
||||||
.leftJoin(PostsMedia)
|
.leftJoin(PostsMedia)
|
||||||
|
.leftJoin(PostsEmojis)
|
||||||
|
.leftJoin(PostsVisibleActors)
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.where {
|
.where {
|
||||||
Posts.id eq id.id
|
Posts.id eq id.id
|
||||||
|
@ -174,6 +176,9 @@ class ExposedPostRepository(
|
||||||
override suspend fun findAllById(ids: List<PostId>): List<Post> {
|
override suspend fun findAllById(ids: List<PostId>): List<Post> {
|
||||||
return query {
|
return query {
|
||||||
Posts
|
Posts
|
||||||
|
.leftJoin(PostsMedia)
|
||||||
|
.leftJoin(PostsEmojis)
|
||||||
|
.leftJoin(PostsVisibleActors)
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.where {
|
.where {
|
||||||
Posts.id inList ids.map { it.id }
|
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(
|
override suspend fun findByActorId(id: ActorId, page: Page?): PaginationList<Post, PostId> {
|
||||||
query {
|
val postList = query {
|
||||||
Posts
|
val query = Posts
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.where {
|
.where {
|
||||||
actorId eq actorId
|
actorId eq id.id
|
||||||
}
|
}
|
||||||
.let(postQueryMapper::map)
|
|
||||||
},
|
page(page, query)
|
||||||
null,
|
|
||||||
null
|
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) {
|
override suspend fun delete(post: Post) {
|
||||||
query {
|
query {
|
||||||
|
PostsMedia.deleteWhere {
|
||||||
|
postId eq post.id.id
|
||||||
|
}
|
||||||
|
PostsEmojis.deleteWhere {
|
||||||
|
postId eq post.id.id
|
||||||
|
}
|
||||||
|
PostsVisibleActors.deleteWhere {
|
||||||
|
postId eq post.id.id
|
||||||
|
}
|
||||||
Posts.deleteWhere {
|
Posts.deleteWhere {
|
||||||
id eq post.id.id
|
id eq post.id.id
|
||||||
}
|
}
|
||||||
|
@ -218,17 +245,7 @@ class ExposedPostRepository(
|
||||||
Posts.actorId eq actorId.id and (visibility inList visibilityList.map { it.name })
|
Posts.actorId eq actorId.id and (visibility inList visibilityList.map { it.name })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (of?.minId != null) {
|
page(of, query)
|
||||||
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) }
|
|
||||||
|
|
||||||
query.let(postQueryMapper::map)
|
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 {
|
companion object {
|
||||||
private val logger = LoggerFactory.getLogger(ExposedPostRepository::class.java)
|
private val logger = LoggerFactory.getLogger(ExposedPostRepository::class.java)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
package dev.usbharu.hideout.core.infrastructure.exposedrepository
|
||||||
|
|
||||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
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.Relationship
|
||||||
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository
|
||||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventPublisher
|
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 {
|
override suspend fun findByActorIdAndTargetId(actorId: ActorId, targetId: ActorId): Relationship? = query {
|
||||||
Relationships.selectAll().where {
|
Relationships.selectAll().where {
|
||||||
Relationships.actorId eq actorId.id and (Relationships.targetActorId eq targetId.id)
|
Relationships.actorId eq actorId.id and (Relationships.targetActorId eq targetId.id)
|
||||||
}.singleOrNull()?.toRelationships()
|
}.limit(1).singleOrNull()?.toRelationships()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findByActorIdsAndTargetIdAndBlocking(
|
override suspend fun findByActorIdsAndTargetIdAndBlocking(
|
||||||
|
@ -78,7 +77,9 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve
|
||||||
blocking: Boolean
|
blocking: Boolean
|
||||||
): List<Relationship> = query {
|
): List<Relationship> = query {
|
||||||
Relationships.selectAll().where {
|
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() }
|
}.map { it.toRelationships() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,49 +89,19 @@ class ExposedRelationshipRepository(override val domainEventPublisher: DomainEve
|
||||||
following: Boolean
|
following: Boolean
|
||||||
): List<Relationship> = query {
|
): List<Relationship> = query {
|
||||||
Relationships.selectAll().where {
|
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() }
|
}.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 {
|
companion object {
|
||||||
private val logger = LoggerFactory.getLogger(ExposedRelationshipRepository::class.java)
|
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(
|
fun ResultRow.toRelationships(): Relationship = Relationship(
|
||||||
actorId = ActorId(this[Relationships.actorId]),
|
actorId = ActorId(this[Relationships.actorId]),
|
||||||
targetActorId = ActorId(this[Relationships.targetActorId]),
|
targetActorId = ActorId(this[Relationships.targetActorId]),
|
||||||
|
|
|
@ -54,7 +54,7 @@ class ExposedTimelineRepository(override val domainEventPublisher: DomainEventPu
|
||||||
|
|
||||||
override suspend fun findById(id: TimelineId): Timeline? {
|
override suspend fun findById(id: TimelineId): Timeline? {
|
||||||
return query {
|
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
|
import org.springframework.stereotype.Repository
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPublisher) :
|
class ExposedUserDetailRepository(override val domainEventPublisher: DomainEventPublisher) :
|
||||||
UserDetailRepository,
|
UserDetailRepository,
|
||||||
AbstractRepository(),
|
AbstractRepository(),
|
||||||
DomainEventPublishableRepository<UserDetail> {
|
DomainEventPublishableRepository<UserDetail> {
|
||||||
override val logger: Logger
|
override val logger: Logger
|
||||||
get() = Companion.logger
|
get() = Companion.logger
|
||||||
|
|
||||||
override suspend fun save(userDetail: UserDetail): UserDetail {
|
override suspend fun save(userDetail: UserDetail): UserDetail = query {
|
||||||
val userDetail1 = query {
|
UserDetails.upsert {
|
||||||
UserDetails.upsert {
|
it[id] = userDetail.id.id
|
||||||
it[id] = userDetail.id.id
|
it[actorId] = userDetail.actorId.id
|
||||||
it[actorId] = userDetail.actorId.id
|
it[password] = userDetail.password.password
|
||||||
it[password] = userDetail.password.password
|
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
|
||||||
it[autoAcceptFolloweeFollowRequest] = userDetail.autoAcceptFolloweeFollowRequest
|
it[lastMigration] = userDetail.lastMigration
|
||||||
it[lastMigration] = userDetail.lastMigration
|
it[homeTimelineId] = userDetail.homeTimelineId?.value
|
||||||
it[homeTimelineId] = userDetail.homeTimelineId?.value
|
|
||||||
}
|
|
||||||
|
|
||||||
onComplete {
|
|
||||||
update(userDetail)
|
|
||||||
}
|
|
||||||
userDetail
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return userDetail1
|
onComplete {
|
||||||
|
update(userDetail)
|
||||||
|
}
|
||||||
|
userDetail
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun delete(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 {
|
override suspend fun findByActorId(actorId: Long): UserDetail? = query {
|
||||||
return@query UserDetails
|
return@query UserDetails
|
||||||
.selectAll().where { UserDetails.actorId eq actorId }
|
.selectAll().where { UserDetails.actorId eq actorId }
|
||||||
|
.limit(1)
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
?.let {
|
?.let {
|
||||||
userDetail(it)
|
userDetail(it)
|
||||||
|
@ -80,6 +77,7 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub
|
||||||
override suspend fun findById(id: UserDetailId): UserDetail? = query {
|
override suspend fun findById(id: UserDetailId): UserDetail? = query {
|
||||||
UserDetails
|
UserDetails
|
||||||
.selectAll().where { UserDetails.id eq id.id }
|
.selectAll().where { UserDetails.id eq id.id }
|
||||||
|
.limit(1)
|
||||||
.singleOrNull()
|
.singleOrNull()
|
||||||
?.let {
|
?.let {
|
||||||
userDetail(it)
|
userDetail(it)
|
||||||
|
@ -107,7 +105,7 @@ class UserDetailRepositoryImpl(override val domainEventPublisher: DomainEventPub
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
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 }
|
actorRepository.findAllById(actorIds).associateBy { it.id }
|
||||||
|
|
||||||
override suspend fun getMedias(mediaIds: List<MediaId>): Map<MediaId, Media> =
|
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>> =
|
override suspend fun getReactions(postIds: List<PostId>): Map<PostId, List<Reactions>> =
|
||||||
reactionsQueryService.findAllByPostIdIn(postIds).groupBy { PostId(it.postId) }
|
reactionsQueryService.findAllByPostIdIn(postIds).groupBy { PostId(it.postId) }
|
||||||
|
|
|
@ -34,7 +34,7 @@ class ActorsTest {
|
||||||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||||
|
|
||||||
val actorIds = setOf(ActorId(100), ActorId(200))
|
val actorIds = setOf(ActorId(100), ActorId(200))
|
||||||
actor.alsoKnownAs = actorIds
|
actor.setAlsoKnownAs(actorIds)
|
||||||
|
|
||||||
assertEquals(actorIds, actor.alsoKnownAs)
|
assertEquals(actorIds, actor.alsoKnownAs)
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ class ActorsTest {
|
||||||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||||
|
|
||||||
|
|
||||||
actor.moveTo = ActorId(100)
|
actor.setMoveTo(ActorId(100))
|
||||||
|
|
||||||
assertContainsEvent(actor, ActorEvent.MOVE.eventName)
|
assertContainsEvent(actor, ActorEvent.MOVE.eventName)
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ class ActorsTest {
|
||||||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||||
|
|
||||||
assertThrows<IllegalArgumentException> {
|
assertThrows<IllegalArgumentException> {
|
||||||
actor.alsoKnownAs = setOf(actor.id)
|
actor.setAlsoKnownAs(setOf(actor.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class ActorsTest {
|
||||||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||||
|
|
||||||
assertThrows<IllegalArgumentException> {
|
assertThrows<IllegalArgumentException> {
|
||||||
actor.moveTo = actor.id
|
actor.setMoveTo(actor.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class ActorsTest {
|
||||||
fun descriptionが更新されたときupdateイベントが発生する() {
|
fun descriptionが更新されたときupdateイベントが発生する() {
|
||||||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||||
|
|
||||||
actor.description = ActorDescription("hoge fuga")
|
actor.setDescription(ActorDescription("hoge fuga"))
|
||||||
|
|
||||||
assertContainsEvent(actor, ActorEvent.UPDATE.eventName)
|
assertContainsEvent(actor, ActorEvent.UPDATE.eventName)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ class ActorsTest {
|
||||||
fun screenNameが更新されたときupdateイベントが発生する() {
|
fun screenNameが更新されたときupdateイベントが発生する() {
|
||||||
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
val actor = TestActorFactory.create(publicKey = ActorPublicKey(""))
|
||||||
|
|
||||||
actor.screenName = ActorScreenName("fuga hoge")
|
actor.setScreenName(ActorScreenName("fuga hoge"))
|
||||||
|
|
||||||
assertContainsEvent(actor, ActorEvent.UPDATE.eventName)
|
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.emoji.CustomEmojiId
|
||||||
import dev.usbharu.hideout.core.domain.model.instance.InstanceId
|
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.domain.model.support.domain.Domain
|
||||||
import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService
|
import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
@ -32,12 +33,14 @@ object TestActorFactory {
|
||||||
followingCount: Int = 0,
|
followingCount: Int = 0,
|
||||||
postCount: Int = 0,
|
postCount: Int = 0,
|
||||||
lastPostDate: Instant? = null,
|
lastPostDate: Instant? = null,
|
||||||
|
lastUpdateAt: Instant = createdAt,
|
||||||
suspend: Boolean = false,
|
suspend: Boolean = false,
|
||||||
alsoKnownAs: Set<ActorId> = emptySet(),
|
alsoKnownAs: Set<ActorId> = emptySet(),
|
||||||
moveTo: Long? = null,
|
moveTo: Long? = null,
|
||||||
emojiIds: Set<CustomEmojiId> = emptySet(),
|
emojiIds: Set<CustomEmojiId> = emptySet(),
|
||||||
deleted: Boolean = false,
|
deleted: Boolean = false,
|
||||||
roles: Set<Role> = emptySet(),
|
icon: Long? = null,
|
||||||
|
banner: Long? = null,
|
||||||
): Actor {
|
): Actor {
|
||||||
return runBlocking {
|
return runBlocking {
|
||||||
Actor(
|
Actor(
|
||||||
|
@ -61,13 +64,14 @@ object TestActorFactory {
|
||||||
followingCount = ActorRelationshipCount(followingCount),
|
followingCount = ActorRelationshipCount(followingCount),
|
||||||
postsCount = ActorPostsCount(postCount),
|
postsCount = ActorPostsCount(postCount),
|
||||||
lastPostAt = lastPostDate,
|
lastPostAt = lastPostDate,
|
||||||
|
lastUpdateAt = lastUpdateAt,
|
||||||
suspend = suspend,
|
suspend = suspend,
|
||||||
alsoKnownAs = alsoKnownAs,
|
alsoKnownAs = alsoKnownAs,
|
||||||
moveTo = moveTo?.let { ActorId(it) },
|
moveTo = moveTo?.let { ActorId(it) },
|
||||||
emojiIds = emojiIds,
|
emojiIds = emojiIds,
|
||||||
deleted = deleted,
|
deleted = deleted,
|
||||||
icon = null,
|
icon = icon?.let { MediaId(it) },
|
||||||
banner = null,
|
banner = banner?.let { MediaId(it) },
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dev.usbharu.hideout.core.domain.model.post
|
package dev.usbharu.hideout.core.domain.model.post
|
||||||
|
|
||||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
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.instance.InstanceId
|
||||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||||
import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService
|
import dev.usbharu.hideout.core.infrastructure.other.TwitterSnowflakeIdGenerateService
|
||||||
|
@ -29,13 +30,14 @@ object TestPostFactory {
|
||||||
visibleActors: List<Long> = emptyList(),
|
visibleActors: List<Long> = emptyList(),
|
||||||
hide: Boolean = false,
|
hide: Boolean = false,
|
||||||
moveTo: Long? = null,
|
moveTo: Long? = null,
|
||||||
|
emojiIds: List<Long> = emptyList(),
|
||||||
): Post {
|
): Post {
|
||||||
return Post(
|
return Post(
|
||||||
PostId(id),
|
PostId(id),
|
||||||
ActorId(actorId),
|
ActorId(actorId),
|
||||||
instanceId = InstanceId(instanceId),
|
instanceId = InstanceId(instanceId),
|
||||||
overview = overview?.let { PostOverview(it) },
|
overview = overview?.let { PostOverview(it) },
|
||||||
content = PostContent(content, content, emptyList()),
|
content = PostContent(content, content, emojiIds.map { CustomEmojiId(it) }),
|
||||||
createdAt = createdAt,
|
createdAt = createdAt,
|
||||||
visibility = visibility,
|
visibility = visibility,
|
||||||
url = url,
|
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 {
|
fun userDetailが見つからない場合失敗() = runTest {
|
||||||
whenever(actorRepository.findByNameAndDomain(eq("test"), eq("example.com"))).doReturn(
|
whenever(actorRepository.findByNameAndDomain(eq("test"), eq("example.com"))).doReturn(
|
||||||
TestActorFactory.create(
|
TestActorFactory.create(
|
||||||
actorName = "test", id = 1
|
id = 1, actorName = "test"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
assertThrows<UsernameNotFoundException> {
|
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(),
|
id = resultRow[Actors.id].toString(),
|
||||||
username = resultRow[Actors.name],
|
username = resultRow[Actors.name],
|
||||||
acct = "${resultRow[Actors.name]}@${resultRow[Actors.domain]}",
|
acct = "${resultRow[Actors.name]}@${resultRow[Actors.domain]}",
|
||||||
url = resultRow[Actors.url],
|
url = resultRow[Actors.url].toString(),
|
||||||
displayName = resultRow[Actors.screenName],
|
displayName = resultRow[Actors.screenName],
|
||||||
note = resultRow[Actors.description],
|
note = resultRow[Actors.description],
|
||||||
avatar = "$userUrl/icon.jpg",
|
avatar = "$userUrl/icon.jpg",
|
||||||
|
|
|
@ -225,13 +225,13 @@ private fun toStatus(it: ResultRow, queryAlias: QueryAlias, inReplyToAlias: Alia
|
||||||
id = it[Actors.id].toString(),
|
id = it[Actors.id].toString(),
|
||||||
username = it[Actors.name],
|
username = it[Actors.name],
|
||||||
acct = "${it[Actors.name]}@${it[Actors.domain]}",
|
acct = "${it[Actors.name]}@${it[Actors.domain]}",
|
||||||
url = it[Actors.url],
|
url = it[Actors.url].toString(),
|
||||||
displayName = it[Actors.screenName],
|
displayName = it[Actors.screenName],
|
||||||
note = it[Actors.description],
|
note = it[Actors.description],
|
||||||
avatar = it[Actors.url] + "/icon.jpg",
|
avatar = "${it[Actors.url]}/icon.jpg",
|
||||||
avatarStatic = it[Actors.url] + "/icon.jpg",
|
avatarStatic = "${it[Actors.url]}/icon.jpg",
|
||||||
header = it[Actors.url] + "/header.jpg",
|
header = "${it[Actors.url]}/header.jpg",
|
||||||
headerStatic = it[Actors.url] + "/header.jpg",
|
headerStatic = "${it[Actors.url]}/header.jpg",
|
||||||
locked = it[Actors.locked],
|
locked = it[Actors.locked],
|
||||||
fields = emptyList(),
|
fields = emptyList(),
|
||||||
emojis = emptyList(),
|
emojis = emptyList(),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
kotlin.code.style=official
|
|
||||||
org.gradle.daemon=true
|
|
||||||
org.gradle.parallel=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