mirror of https://github.com/usbharu/Hideout.git
feat: ドメイン層に認可的なものを追加
This commit is contained in:
parent
86daf1041b
commit
54e3af2253
|
@ -16,15 +16,23 @@
|
|||
|
||||
package dev.usbharu.hideout.core.application.post
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class DeleteLocalPostApplicationService(private val postRepository: PostRepository) {
|
||||
suspend fun delete(postId: Long) {
|
||||
class DeleteLocalPostApplicationService(
|
||||
private val postRepository: PostRepository,
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
private val actorRepository: ActorRepository,
|
||||
) {
|
||||
suspend fun delete(postId: Long, userDetailId: Long) {
|
||||
val findById = postRepository.findById(PostId(postId))!!
|
||||
findById.delete()
|
||||
val user = userDetailRepository.findById(userDetailId)!!
|
||||
val actor = actorRepository.findById(user.actorId)!!
|
||||
findById.delete(actor)
|
||||
postRepository.save(findById)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,15 +47,19 @@ class RegisterLocalPostApplicationService(
|
|||
val actorId = (userDetailRepository.findById(command.userDetailId)
|
||||
?: throw IllegalStateException("actor not found")).actorId
|
||||
|
||||
val post = postFactory.createLocal(actorId,
|
||||
actorRepository.findById(actorId)!!.name,
|
||||
command.overview?.let { PostOverview(it) },
|
||||
command.content,
|
||||
command.visibility,
|
||||
command.repostId?.let { PostId(it) },
|
||||
command.replyId?.let { PostId(it) },
|
||||
command.sensitive,
|
||||
command.mediaIds.map { MediaId(it) })
|
||||
val actor = actorRepository.findById(actorId)!!
|
||||
|
||||
val post = postFactory.createLocal(
|
||||
actor = actor,
|
||||
actorName = actor.name,
|
||||
overview = command.overview?.let { PostOverview(it) },
|
||||
content = command.content,
|
||||
visibility = command.visibility,
|
||||
repostId = command.repostId?.let { PostId(it) },
|
||||
replyId = command.replyId?.let { PostId(it) },
|
||||
sensitive = command.sensitive,
|
||||
mediaIds = command.mediaIds.map { MediaId(it) },
|
||||
)
|
||||
|
||||
postRepository.save(post)
|
||||
|
||||
|
|
|
@ -16,30 +16,45 @@
|
|||
|
||||
package dev.usbharu.hideout.core.application.post
|
||||
|
||||
import dev.usbharu.hideout.core.application.shared.AbstractApplicationService
|
||||
import dev.usbharu.hideout.core.application.shared.CommandExecutor
|
||||
import dev.usbharu.hideout.core.application.shared.Transaction
|
||||
import dev.usbharu.hideout.core.application.shared.UserDetailGettableCommandExecutor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostId
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostOverview
|
||||
import dev.usbharu.hideout.core.domain.model.post.PostRepository
|
||||
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository
|
||||
import dev.usbharu.hideout.core.infrastructure.factory.PostContentFactoryImpl
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class UpdateLocalNoteApplicationService(
|
||||
private val transaction: Transaction,
|
||||
transaction: Transaction,
|
||||
private val postRepository: PostRepository,
|
||||
private val postContentFactoryImpl: PostContentFactoryImpl,
|
||||
) {
|
||||
suspend fun update(updateLocalNote: UpdateLocalNote) {
|
||||
transaction.transaction {
|
||||
val post = postRepository.findById(PostId(updateLocalNote.postId))!!
|
||||
private val userDetailRepository: UserDetailRepository,
|
||||
private val actorRepository: ActorRepository,
|
||||
) : AbstractApplicationService<UpdateLocalNote, Unit>(transaction, logger) {
|
||||
|
||||
post.content = postContentFactoryImpl.create(updateLocalNote.content)
|
||||
post.overview = updateLocalNote.overview?.let { PostOverview(it) }
|
||||
post.addMediaIds(updateLocalNote.mediaIds.map { MediaId(it) })
|
||||
post.sensitive = updateLocalNote.sensitive
|
||||
override suspend fun internalExecute(command: UpdateLocalNote, executor: CommandExecutor) {
|
||||
require(executor is UserDetailGettableCommandExecutor)
|
||||
|
||||
val userDetail = userDetailRepository.findById(executor.userDetailId)!!
|
||||
val actor = actorRepository.findById(userDetail.actorId)!!
|
||||
val post = postRepository.findById(PostId(command.postId))!!
|
||||
|
||||
post.setContent(postContentFactoryImpl.create(command.content), actor)
|
||||
post.setOverview(command.overview?.let { PostOverview(it) }, actor)
|
||||
post.addMediaIds(command.mediaIds.map { MediaId(it) }, actor)
|
||||
post.setSensitive(command.sensitive, actor)
|
||||
|
||||
postRepository.save(post)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = LoggerFactory.getLogger(UpdateLocalNoteApplicationService::class.java)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,3 +19,7 @@ package dev.usbharu.hideout.core.application.shared
|
|||
interface CommandExecutor {
|
||||
val executor: String
|
||||
}
|
||||
|
||||
interface UserDetailGettableCommandExecutor : CommandExecutor {
|
||||
val userDetailId: Long
|
||||
}
|
|
@ -16,20 +16,21 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.event.post
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEvent
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventBody
|
||||
|
||||
class PostDomainEventFactory(private val post: Post) {
|
||||
class PostDomainEventFactory(private val post: Post, private val actor: Actor? = null) {
|
||||
fun createEvent(postEvent: PostEvent): DomainEvent {
|
||||
return DomainEvent.create(
|
||||
postEvent.eventName,
|
||||
PostEventBody(post)
|
||||
PostEventBody(post, actor)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class PostEventBody(post: Post) : DomainEventBody(mapOf("post" to post))
|
||||
class PostEventBody(post: Post, actor: Actor?) : DomainEventBody(mapOf("post" to post, "actor" to actor))
|
||||
|
||||
enum class PostEvent(val eventName: String) {
|
||||
delete("PostDelete"),
|
||||
|
|
|
@ -52,8 +52,18 @@ class Actor(
|
|||
moveTo: ActorId? = null,
|
||||
emojiIds: Set<EmojiId>,
|
||||
deleted: Boolean,
|
||||
roles: Set<Role>,
|
||||
) : DomainEventStorable() {
|
||||
|
||||
var roles = roles
|
||||
private set
|
||||
|
||||
fun setRole(roles: Set<Role>, actor: Actor) {
|
||||
require(actor.roles.contains(Role.ADMINISTRATOR).not())
|
||||
|
||||
this.roles = roles
|
||||
}
|
||||
|
||||
var suspend = suspend
|
||||
set(value) {
|
||||
if (field != value && value) {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2024 usbharu
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package dev.usbharu.hideout.core.domain.model.actor
|
||||
|
||||
enum class Role {
|
||||
LOCAL, MODERATOR, ADMINISTRATOR, REMOTE
|
||||
}
|
|
@ -18,9 +18,12 @@ package dev.usbharu.hideout.core.domain.model.post
|
|||
|
||||
import dev.usbharu.hideout.core.domain.event.post.PostDomainEventFactory
|
||||
import dev.usbharu.hideout.core.domain.event.post.PostEvent
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Role
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.EmojiId
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post.Companion.Action.*
|
||||
import dev.usbharu.hideout.core.domain.shared.domainevent.DomainEventStorable
|
||||
import java.net.URI
|
||||
import java.time.Instant
|
||||
|
@ -28,7 +31,7 @@ import java.time.Instant
|
|||
class Post(
|
||||
val id: PostId,
|
||||
actorId: ActorId,
|
||||
overview: PostOverview? = null,
|
||||
overview: PostOverview?,
|
||||
content: PostContent,
|
||||
val createdAt: Instant,
|
||||
visibility: Visibility,
|
||||
|
@ -39,13 +42,12 @@ class Post(
|
|||
val apId: URI,
|
||||
deleted: Boolean,
|
||||
mediaIds: List<MediaId>,
|
||||
visibleActors: Set<ActorId> = emptySet(),
|
||||
hide: Boolean = false,
|
||||
moveTo: PostId? = null,
|
||||
visibleActors: Set<ActorId>,
|
||||
hide: Boolean,
|
||||
moveTo: PostId?,
|
||||
) : DomainEventStorable() {
|
||||
|
||||
var actorId = actorId
|
||||
private set
|
||||
val actorId = actorId
|
||||
get() {
|
||||
if (deleted) {
|
||||
return ActorId.ghost
|
||||
|
@ -54,25 +56,33 @@ class Post(
|
|||
}
|
||||
|
||||
var visibility = visibility
|
||||
set(value) {
|
||||
private set
|
||||
|
||||
fun setVisibility(visibility: Visibility, actor: Actor) {
|
||||
|
||||
require(isAllow(actor, UPDATE, this))
|
||||
require(this.visibility != Visibility.DIRECT)
|
||||
require(visibility != Visibility.DIRECT)
|
||||
require(value != Visibility.DIRECT)
|
||||
require(field.ordinal >= value.ordinal)
|
||||
require(this.visibility.ordinal >= visibility.ordinal)
|
||||
|
||||
require(deleted.not())
|
||||
|
||||
if (field != value) {
|
||||
addDomainEvent(PostDomainEventFactory(this).createEvent(PostEvent.update))
|
||||
if (this.visibility != visibility) {
|
||||
addDomainEvent(PostDomainEventFactory(this, actor).createEvent(PostEvent.update))
|
||||
}
|
||||
field = value
|
||||
this.visibility = visibility
|
||||
}
|
||||
|
||||
var visibleActors = visibleActors
|
||||
set(value) {
|
||||
private set
|
||||
|
||||
fun setVisibleActors(visibleActors: Set<ActorId>, actor: Actor) {
|
||||
|
||||
require(isAllow(actor, UPDATE, this))
|
||||
require(deleted.not())
|
||||
if (visibility == Visibility.DIRECT) {
|
||||
addDomainEvent(PostDomainEventFactory(this).createEvent(PostEvent.update))
|
||||
field = field.plus(value)
|
||||
addDomainEvent(PostDomainEventFactory(this, actor).createEvent(PostEvent.update))
|
||||
this.visibleActors = this.visibleActors.plus(visibleActors)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,12 +93,15 @@ class Post(
|
|||
}
|
||||
return field
|
||||
}
|
||||
set(value) {
|
||||
private set
|
||||
|
||||
fun setContent(content: PostContent, actor: Actor) {
|
||||
require(isAllow(actor, UPDATE, this))
|
||||
require(deleted.not())
|
||||
if (field != value) {
|
||||
addDomainEvent(PostDomainEventFactory(this).createEvent(PostEvent.update))
|
||||
if (this.content != content) {
|
||||
addDomainEvent(PostDomainEventFactory(this, actor).createEvent(PostEvent.update))
|
||||
}
|
||||
field = value
|
||||
this.content = content
|
||||
}
|
||||
|
||||
var overview = overview
|
||||
|
@ -98,21 +111,27 @@ class Post(
|
|||
}
|
||||
return field
|
||||
}
|
||||
set(value) {
|
||||
private set
|
||||
|
||||
fun setOverview(overview: PostOverview?, actor: Actor) {
|
||||
require(isAllow(actor, UPDATE, this))
|
||||
require(deleted.not())
|
||||
if (field != value) {
|
||||
addDomainEvent(PostDomainEventFactory(this).createEvent(PostEvent.update))
|
||||
if (this.overview != overview) {
|
||||
addDomainEvent(PostDomainEventFactory(this, actor).createEvent(PostEvent.update))
|
||||
}
|
||||
field = value
|
||||
this.overview = overview
|
||||
}
|
||||
|
||||
var sensitive = sensitive
|
||||
set(value) {
|
||||
private set
|
||||
|
||||
fun setSensitive(sensitive: Boolean, actor: Actor) {
|
||||
isAllow(actor, UPDATE, this)
|
||||
require(deleted.not())
|
||||
if (field != value) {
|
||||
addDomainEvent(PostDomainEventFactory(this).createEvent(PostEvent.update))
|
||||
if (this.sensitive != sensitive) {
|
||||
addDomainEvent(PostDomainEventFactory(this, actor).createEvent(PostEvent.update))
|
||||
}
|
||||
field = value
|
||||
this.sensitive = sensitive
|
||||
}
|
||||
|
||||
val text: String
|
||||
|
@ -140,18 +159,20 @@ class Post(
|
|||
}
|
||||
private set
|
||||
|
||||
fun addMediaIds(mediaIds: List<MediaId>) {
|
||||
fun addMediaIds(mediaIds: List<MediaId>, actor: Actor) {
|
||||
require(isAllow(actor, UPDATE, this))
|
||||
require(deleted.not())
|
||||
addDomainEvent(PostDomainEventFactory(this).createEvent(PostEvent.update))
|
||||
addDomainEvent(PostDomainEventFactory(this, actor).createEvent(PostEvent.update))
|
||||
this.mediaIds = this.mediaIds.plus(mediaIds).distinct()
|
||||
}
|
||||
|
||||
var deleted = deleted
|
||||
private set
|
||||
|
||||
fun delete() {
|
||||
fun delete(actor: Actor) {
|
||||
isAllow(actor, DELETE, this)
|
||||
if (deleted.not()) {
|
||||
addDomainEvent(PostDomainEventFactory(this).createEvent(PostEvent.delete))
|
||||
addDomainEvent(PostDomainEventFactory(this, actor).createEvent(PostEvent.delete))
|
||||
content = PostContent.empty
|
||||
overview = null
|
||||
mediaIds = emptyList()
|
||||
|
@ -185,7 +206,8 @@ class Post(
|
|||
var moveTo = moveTo
|
||||
private set
|
||||
|
||||
fun moveTo(moveTo: PostId) {
|
||||
fun moveTo(moveTo: PostId, actor: Actor) {
|
||||
require(isAllow(actor, MOVE, this))
|
||||
require(this.moveTo == null)
|
||||
this.moveTo = moveTo
|
||||
}
|
||||
|
@ -203,6 +225,27 @@ class Post(
|
|||
return id.hashCode()
|
||||
}
|
||||
|
||||
fun reconstructWith(mediaIds: List<MediaId>, emojis: List<EmojiId>, visibleActors: Set<ActorId>): Post {
|
||||
return Post(
|
||||
id = id,
|
||||
actorId = actorId,
|
||||
overview = overview,
|
||||
content = PostContent(this.content.text, this.content.content, emojis),
|
||||
createdAt = createdAt,
|
||||
visibility = visibility,
|
||||
url = url,
|
||||
repostId = repostId,
|
||||
replyId = replyId,
|
||||
sensitive = sensitive,
|
||||
apId = apId,
|
||||
deleted = deleted,
|
||||
mediaIds = mediaIds,
|
||||
visibleActors = visibleActors,
|
||||
hide = hide,
|
||||
moveTo = moveTo
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
id: PostId,
|
||||
|
@ -221,14 +264,25 @@ class Post(
|
|||
visibleActors: Set<ActorId> = emptySet(),
|
||||
hide: Boolean = false,
|
||||
moveTo: PostId? = null,
|
||||
actor: Actor,
|
||||
): Post {
|
||||
|
||||
require(actor.deleted.not())
|
||||
require(actor.moveTo == null)
|
||||
|
||||
val visibility1 = if (actor.suspend && visibility == Visibility.PUBLIC) {
|
||||
Visibility.UNLISTED
|
||||
} else {
|
||||
visibility
|
||||
}
|
||||
|
||||
val post = Post(
|
||||
id,
|
||||
actorId,
|
||||
overview,
|
||||
content,
|
||||
createdAt,
|
||||
visibility,
|
||||
visibility1,
|
||||
url,
|
||||
repostId,
|
||||
replyId,
|
||||
|
@ -243,5 +297,30 @@ class Post(
|
|||
post.addDomainEvent(PostDomainEventFactory(post).createEvent(PostEvent.create))
|
||||
return post
|
||||
}
|
||||
|
||||
fun isAllow(actor: Actor, action: Action, resource: Post): Boolean {
|
||||
return when (action) {
|
||||
UPDATE -> {
|
||||
if (actor.deleted) {
|
||||
return true
|
||||
}
|
||||
resource.actorId == actor.id || actor.roles.contains(Role.ADMINISTRATOR) || actor.roles.contains(
|
||||
Role.MODERATOR
|
||||
)
|
||||
}
|
||||
|
||||
MOVE -> resource.actorId == actor.id && actor.deleted.not()
|
||||
DELETE -> resource.actorId == actor.id ||
|
||||
actor.roles.contains(Role.ADMINISTRATOR) ||
|
||||
actor.roles.contains(Role.MODERATOR)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
enum class Action {
|
||||
UPDATE,
|
||||
MOVE,
|
||||
DELETE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
package dev.usbharu.hideout.core.domain.shared.domainevent
|
||||
|
||||
abstract class DomainEventBody(val map: Map<String, Any>) {
|
||||
fun toMap(): Map<String, Any> {
|
||||
abstract class DomainEventBody(val map: Map<String, Any?>) {
|
||||
fun toMap(): Map<String, Any?> {
|
||||
return map
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@ class ActorResultRowMapper : ResultRowMapper<Actor> {
|
|||
.filter { it.isNotEmpty() }
|
||||
.map { EmojiId(it.toLong()) }
|
||||
.toSet(),
|
||||
deleted = resultRow[Actors.deleted]
|
||||
deleted = resultRow[Actors.deleted],
|
||||
roles = emptySet()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,26 +39,25 @@ class PostQueryMapper(private val postResultRowMapper: ResultRowMapper<Post>) :
|
|||
.first()
|
||||
.let(postResultRowMapper::map)
|
||||
.apply {
|
||||
addMediaIds(
|
||||
it.mapNotNull { resultRow: ResultRow ->
|
||||
reconstructWith(
|
||||
mediaIds = it.mapNotNull { resultRow: ResultRow ->
|
||||
resultRow
|
||||
.getOrNull(PostsMedia.mediaId)
|
||||
?.let { mediaId -> MediaId(mediaId) }
|
||||
}
|
||||
)
|
||||
content = content.copy(emojiIds = it
|
||||
},
|
||||
emojis = it
|
||||
.mapNotNull { resultRow: ResultRow ->
|
||||
resultRow
|
||||
.getOrNull(PostsEmojis.emojiId)
|
||||
?.let { emojiId -> EmojiId(emojiId) }
|
||||
}
|
||||
)
|
||||
},
|
||||
visibleActors = it.mapNotNull { resultRow: ResultRow ->
|
||||
resultRow
|
||||
.getOrNull(PostsVisibleActors.actorId)
|
||||
?.let { actorId -> ActorId(actorId) }
|
||||
}.toSet()
|
||||
clearDomainEvents()
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ class ActorFactoryImpl(
|
|||
lastPostAt = null,
|
||||
suspend = false,
|
||||
emojiIds = emptySet(),
|
||||
deleted = false
|
||||
deleted = false,
|
||||
roles = emptySet()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package dev.usbharu.hideout.core.infrastructure.factory
|
||||
|
||||
import dev.usbharu.hideout.core.config.ApplicationConfig
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.Actor
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorName
|
||||
import dev.usbharu.hideout.core.domain.model.media.MediaId
|
||||
import dev.usbharu.hideout.core.domain.model.post.Post
|
||||
|
@ -36,7 +36,7 @@ class PostFactoryImpl(
|
|||
private val applicationConfig: ApplicationConfig,
|
||||
) {
|
||||
suspend fun createLocal(
|
||||
actorId: ActorId,
|
||||
actor: Actor,
|
||||
actorName: ActorName,
|
||||
overview: PostOverview?,
|
||||
content: String,
|
||||
|
@ -49,19 +49,20 @@ class PostFactoryImpl(
|
|||
val id = idGenerateService.generateId()
|
||||
val url = URI.create(applicationConfig.url.toString() + "/users/" + actorName.name + "/posts/" + id)
|
||||
return Post.create(
|
||||
PostId(id),
|
||||
actorId,
|
||||
overview,
|
||||
postContentFactoryImpl.create(content),
|
||||
Instant.now(),
|
||||
visibility,
|
||||
url,
|
||||
repostId,
|
||||
replyId,
|
||||
sensitive,
|
||||
url,
|
||||
false,
|
||||
mediaIds,
|
||||
id = PostId(id),
|
||||
actorId = actor.id,
|
||||
overview = overview,
|
||||
content = postContentFactoryImpl.create(content),
|
||||
createdAt = Instant.now(),
|
||||
visibility = visibility,
|
||||
url = url,
|
||||
repostId = repostId,
|
||||
replyId = replyId,
|
||||
sensitive = sensitive,
|
||||
apId = url,
|
||||
deleted = false,
|
||||
mediaIds = mediaIds,
|
||||
actor = actor,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ object TestActorFactory {
|
|||
inbox: URI = URI.create("https://example.com/$id/inbox"),
|
||||
outbox: URI = URI.create("https://example.com/$id/outbox"),
|
||||
uri: URI = URI.create("https://example.com/$id"),
|
||||
publicKey: ActorPublicKey,
|
||||
publicKey: ActorPublicKey = ActorPublicKey(""),
|
||||
privateKey: ActorPrivateKey? = null,
|
||||
createdAt: Instant = Instant.now(),
|
||||
keyId: String = "https://example.com/$id#key-id",
|
||||
|
@ -65,6 +65,7 @@ object TestActorFactory {
|
|||
moveTo = moveTo,
|
||||
emojiIds = emojiIds,
|
||||
deleted = deleted,
|
||||
roles = emptySet()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package dev.usbharu.hideout.core.domain.model.post
|
|||
|
||||
import dev.usbharu.hideout.core.domain.event.post.PostEvent
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorId
|
||||
import dev.usbharu.hideout.core.domain.model.actor.ActorPublicKey
|
||||
import dev.usbharu.hideout.core.domain.model.actor.TestActorFactory
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertDoesNotThrow
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
|
@ -29,100 +31,102 @@ class PostTest {
|
|||
fun visibilityがDIRECTのとき変更できない() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.DIRECT)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.PUBLIC
|
||||
post.setVisibility(Visibility.PUBLIC, actor)
|
||||
}
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.UNLISTED
|
||||
post.setVisibility(Visibility.UNLISTED, actor)
|
||||
}
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.FOLLOWERS
|
||||
post.setVisibility(Visibility.FOLLOWERS, actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibilityを小さくすることはできないPUBLIC() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.PUBLIC)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.DIRECT
|
||||
post.setVisibility(Visibility.DIRECT, actor)
|
||||
}
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.UNLISTED
|
||||
post.setVisibility(Visibility.UNLISTED, actor)
|
||||
}
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.FOLLOWERS
|
||||
post.setVisibility(Visibility.FOLLOWERS, actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibilityを小さくすることはできないUNLISTED() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.UNLISTED)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.DIRECT
|
||||
post.setVisibility(Visibility.DIRECT, actor)
|
||||
}
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.FOLLOWERS
|
||||
post.setVisibility(Visibility.FOLLOWERS, actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibilityを小さくすることはできないFOLLOWERS() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.FOLLOWERS)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.DIRECT
|
||||
post.setVisibility(Visibility.DIRECT, actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibilityをDIRECTにあとからすることはできない() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.DIRECT)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.DIRECT
|
||||
post.setVisibility(Visibility.DIRECT, actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibilityを大きくすることができるFOLLOWERS() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.FOLLOWERS)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertDoesNotThrow {
|
||||
post.visibility = Visibility.UNLISTED
|
||||
post.setVisibility(Visibility.UNLISTED, actor)
|
||||
}
|
||||
|
||||
val post2 = TestPostFactory.create(visibility = Visibility.FOLLOWERS)
|
||||
|
||||
assertDoesNotThrow {
|
||||
post2.visibility = Visibility.PUBLIC
|
||||
post2.setVisibility(Visibility.PUBLIC, actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibilityを大きくすることができるUNLISTED() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.UNLISTED)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertDoesNotThrow {
|
||||
post.visibility = Visibility.PUBLIC
|
||||
post.setVisibility(Visibility.PUBLIC, actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deletedがtrueのときvisibilityを変更できない() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.UNLISTED, deleted = true)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibility = Visibility.PUBLIC
|
||||
post.setVisibility(Visibility.PUBLIC, actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibilityが変更されない限りドメインイベントは発生しない() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.UNLISTED)
|
||||
|
||||
post.visibility = Visibility.UNLISTED
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
post.setVisibility(Visibility.UNLISTED, actor)
|
||||
assertEmpty(post)
|
||||
|
||||
}
|
||||
|
@ -130,7 +134,8 @@ class PostTest {
|
|||
@Test
|
||||
fun visibilityが変更されるとupdateイベントが発生する() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.UNLISTED)
|
||||
post.visibility = Visibility.PUBLIC
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
post.setVisibility(Visibility.PUBLIC, actor)
|
||||
|
||||
assertContainsEvent(post, PostEvent.update.eventName)
|
||||
}
|
||||
|
@ -138,51 +143,51 @@ class PostTest {
|
|||
@Test
|
||||
fun deletedがtrueのときvisibleActorsを変更できない() {
|
||||
val post = TestPostFactory.create(deleted = true)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.visibleActors = setOf(ActorId(100))
|
||||
post.setVisibleActors(setOf(ActorId(100)), actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ゔvisibilityがDIRECT以外の時visibleActorsを変更できない() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.FOLLOWERS)
|
||||
|
||||
post.visibleActors = setOf(ActorId(100))
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
post.setVisibleActors(setOf(ActorId(100)), actor)
|
||||
assertEmpty(post)
|
||||
|
||||
val post2 = TestPostFactory.create(visibility = Visibility.UNLISTED)
|
||||
|
||||
post2.visibleActors = setOf(ActorId(100))
|
||||
post2.setVisibleActors(setOf(ActorId(100)), actor)
|
||||
assertEmpty(post2)
|
||||
|
||||
val post3 = TestPostFactory.create(visibility = Visibility.PUBLIC)
|
||||
|
||||
post3.visibleActors = setOf(ActorId(100))
|
||||
post3.setVisibleActors(setOf(ActorId(100)), actor)
|
||||
assertEmpty(post3)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibilityがDIRECTの時visibleActorsを変更できる() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.DIRECT)
|
||||
|
||||
post.visibleActors = setOf(ActorId(100))
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
post.setVisibleActors(setOf(ActorId(100)), actor)
|
||||
assertEquals(setOf(ActorId(100)), post.visibleActors)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibleActorsから削除されることはない() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.DIRECT, visibleActors = listOf(100))
|
||||
|
||||
post.visibleActors = setOf(ActorId(200))
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
post.setVisibleActors(setOf(ActorId(200)), actor)
|
||||
assertEquals(setOf(ActorId(100), ActorId(200)), post.visibleActors)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun visibleActorsに追加された時updateイベントが発生する() {
|
||||
val post = TestPostFactory.create(visibility = Visibility.DIRECT)
|
||||
|
||||
post.visibleActors = setOf(ActorId(100))
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
post.setVisibleActors(setOf(ActorId(100)), actor)
|
||||
|
||||
assertContainsEvent(post, PostEvent.update.eventName)
|
||||
}
|
||||
|
@ -197,17 +202,17 @@ class PostTest {
|
|||
@Test
|
||||
fun deletedがtrueの時contentをセットできない() {
|
||||
val post = TestPostFactory.create(deleted = true)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.content = PostContent("test", "test", emptyList())
|
||||
post.setContent(PostContent("test", "test", emptyList()), actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun contentの内容が変更されたらupdateイベントが発生する() {
|
||||
val post = TestPostFactory.create()
|
||||
|
||||
post.content = PostContent("test", "test", emptyList())
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
post.setContent(PostContent("test", "test", emptyList()), actor)
|
||||
assertContainsEvent(post, PostEvent.update.eventName)
|
||||
}
|
||||
|
||||
|
@ -228,19 +233,19 @@ class PostTest {
|
|||
@Test
|
||||
fun deletedがtrueのときセットできない() {
|
||||
val post = TestPostFactory.create(deleted = true)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
assertThrows<IllegalArgumentException> {
|
||||
post.overview = PostOverview("aaaa")
|
||||
post.setOverview(PostOverview("aaaa"), actor)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deletedがfalseのときセットできる() {
|
||||
val post = TestPostFactory.create(deleted = false)
|
||||
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
val overview = PostOverview("aaaa")
|
||||
assertDoesNotThrow {
|
||||
post.overview = overview
|
||||
post.setOverview(overview, actor)
|
||||
}
|
||||
assertEquals(overview, post.overview)
|
||||
|
||||
|
@ -250,11 +255,10 @@ class PostTest {
|
|||
@Test
|
||||
fun overviewの内容が更新されなかった時イベントが発生しない() {
|
||||
val post = TestPostFactory.create(overview = "aaaa")
|
||||
post.overview = PostOverview("aaaa")
|
||||
val actor = TestActorFactory.create(id = post.actorId.id, publicKey = ActorPublicKey(""))
|
||||
post.setOverview(PostOverview("aaaa"), actor)
|
||||
assertEmpty(post)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue