refactor: Repositoryに不要な関数を削除

This commit is contained in:
usbharu 2023-08-10 19:42:18 +09:00
parent 4fcc096a42
commit ab73da01a7
13 changed files with 73 additions and 517 deletions

View File

@ -2,7 +2,7 @@ package dev.usbharu.hideout.plugins
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.ap.JsonLd
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.service.user.UserAuthService
import dev.usbharu.hideout.util.HttpUtil.Activity
import io.ktor.client.*
@ -164,15 +164,15 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo
}
}
class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap {
class KtorKeyMap(private val userQueryService: UserQueryService) : KeyMap {
override fun getPublicKey(keyId: String?): PublicKey = runBlocking {
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
.substringAfterLast("/")
val publicBytes = Base64.getDecoder().decode(
userAuthRepository.findByNameAndDomain(
userQueryService.findByNameAndDomain(
username,
Config.configData.domain
)?.run {
).run {
publicKey
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
@ -187,10 +187,10 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap {
val username = (keyId ?: throw IllegalArgumentException("keyId is null")).substringBeforeLast("#pubkey")
.substringAfterLast("/")
val publicBytes = Base64.getDecoder().decode(
userAuthRepository.findByNameAndDomain(
userQueryService.findByNameAndDomain(
username,
Config.configData.domain
)?.privateKey?.run {
).privateKey?.run {
replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("\n", "")

View File

@ -47,7 +47,7 @@ fun Application.configureRouting(
route("/api/internal/v1") {
posts(postService, reactionService)
users(userService, userApiService)
auth(userAuthService, userRepository, jwtService)
auth(userAuthService, jwtService, userQueryService)
}
}
}

View File

@ -8,35 +8,10 @@ interface IUserRepository {
suspend fun findById(id: Long): User?
suspend fun findByIds(ids: List<Long>): List<User>
suspend fun findByName(name: String): List<User>
suspend fun findByNameAndDomain(name: String, domain: String): User?
suspend fun findByDomain(domain: String): List<User>
suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User>
suspend fun findByUrl(url: String): User?
suspend fun findByUrls(urls: List<String>): List<User>
@Deprecated("", ReplaceWith("save(userEntity)"))
suspend fun update(userEntity: User) = save(userEntity)
suspend fun delete(id: Long)
suspend fun findAll(): List<User>
suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long = 0): List<User>
suspend fun createFollower(id: Long, follower: Long)
suspend fun deleteFollower(id: Long, follower: Long)
suspend fun findFollowersById(id: Long): List<User>
suspend fun addFollowRequest(id: Long, follower: Long)
suspend fun deleteFollowRequest(id: Long, follower: Long)
suspend fun findFollowRequestsById(id: Long, follower: Long): Boolean
suspend fun nextId(): Long

View File

@ -66,15 +66,6 @@ class UserRepository(private val database: Database, private val idGenerateServi
}
}
override suspend fun createFollower(id: Long, follower: Long) {
return query {
UsersFollowers.insert {
it[userId] = id
it[followerId] = follower
}
}
}
override suspend fun findById(id: Long): User? {
return query {
Users.select { Users.id eq id }.map {
@ -83,114 +74,6 @@ class UserRepository(private val database: Database, private val idGenerateServi
}
}
override suspend fun findByIds(ids: List<Long>): List<User> {
return query {
Users.select { Users.id inList ids }.map {
it.toUser()
}
}
}
override suspend fun findByName(name: String): List<User> {
return query {
Users.select { Users.name eq name }.map {
it.toUser()
}
}
}
override suspend fun findByNameAndDomain(name: String, domain: String): User? {
return query {
Users.select { Users.name eq name and (Users.domain eq domain) }.singleOrNull()?.toUser()
}
}
override suspend fun findByDomain(domain: String): List<User> {
return query {
Users.select { Users.domain eq domain }.map {
it.toUser()
}
}
}
override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> {
return query {
val selectAll = Users.selectAll()
names.forEach { (name, domain) ->
selectAll.orWhere { Users.name eq name and (Users.domain eq domain) }
}
selectAll.map { it.toUser() }
}
}
override suspend fun findByUrl(url: String): User? {
return query {
Users.select { Users.url eq url }.singleOrNull()?.toUser()
}
}
override suspend fun findByUrls(urls: List<String>): List<User> {
return query {
Users.select { Users.url inList urls }.map { it.toUser() }
}
}
override suspend fun findFollowersById(id: Long): List<User> {
return query {
val followers = Users.alias("FOLLOWERS")
Users.innerJoin(
otherTable = UsersFollowers,
onColumn = { Users.id },
otherColumn = { userId }
)
.innerJoin(
otherTable = followers,
onColumn = { UsersFollowers.followerId },
otherColumn = { followers[Users.id] }
)
.slice(
followers.get(Users.id),
followers.get(Users.name),
followers.get(Users.domain),
followers.get(Users.screenName),
followers.get(Users.description),
followers.get(Users.password),
followers.get(Users.inbox),
followers.get(Users.outbox),
followers.get(Users.url),
followers.get(Users.publicKey),
followers.get(Users.privateKey),
followers.get(Users.createdAt)
)
.select { Users.id eq id }
.map {
User(
id = it[followers[Users.id]],
name = it[followers[Users.name]],
domain = it[followers[Users.domain]],
screenName = it[followers[Users.screenName]],
description = it[followers[Users.description]],
password = it[followers[Users.password]],
inbox = it[followers[Users.inbox]],
outbox = it[followers[Users.outbox]],
url = it[followers[Users.url]],
publicKey = it[followers[Users.publicKey]],
privateKey = it[followers[Users.privateKey]],
createdAt = Instant.ofEpochMilli(it[followers[Users.createdAt]])
)
}
}
}
override suspend fun addFollowRequest(id: Long, follower: Long) {
query {
FollowRequests.insert {
it[userId] = id
it[followerId] = follower
}
}
}
override suspend fun deleteFollowRequest(id: Long, follower: Long) {
query {
FollowRequests.deleteWhere { userId.eq(id) and followerId.eq(follower) }
@ -210,24 +93,6 @@ class UserRepository(private val database: Database, private val idGenerateServi
}
}
override suspend fun deleteFollower(id: Long, follower: Long) {
query {
UsersFollowers.deleteWhere { (userId eq id).and(followerId eq follower) }
}
}
override suspend fun findAll(): List<User> {
return query {
Users.selectAll().map { it.toUser() }
}
}
override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<User> {
return query {
Users.selectAll().limit(limit, offset).map { it.toUser() }
}
}
override suspend fun nextId(): Long = idGenerateService.generateId()
}

View File

@ -3,9 +3,8 @@ package dev.usbharu.hideout.routing.api.internal.v1
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken
import dev.usbharu.hideout.domain.model.hideout.form.UserLogin
import dev.usbharu.hideout.exception.UserNotFoundException
import dev.usbharu.hideout.plugins.TOKEN_AUTH
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.service.auth.IJwtService
import dev.usbharu.hideout.service.user.IUserAuthService
import io.ktor.http.*
@ -18,8 +17,8 @@ import io.ktor.server.routing.*
fun Route.auth(
userAuthService: IUserAuthService,
userRepository: IUserRepository,
jwtService: IJwtService
jwtService: IJwtService,
userQueryService: UserQueryService
) {
post("/login") {
val loginUser = call.receive<UserLogin>()
@ -28,8 +27,7 @@ fun Route.auth(
return@post call.respond(HttpStatusCode.Unauthorized)
}
val user = userRepository.findByNameAndDomain(loginUser.username, Config.configData.domain)
?: throw UserNotFoundException("${loginUser.username} was not found.")
val user = userQueryService.findByNameAndDomain(loginUser.username, Config.configData.domain)
return@post call.respond(jwtService.createToken(user))
}

View File

@ -1,15 +1,15 @@
package dev.usbharu.hideout.service.auth
import dev.usbharu.hideout.plugins.KtorKeyMap
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.query.UserQueryService
import io.ktor.http.*
import org.koin.core.annotation.Single
import tech.barbero.http.message.signing.SignatureHeaderVerifier
@Single
class HttpSignatureVerifyServiceImpl(private val userAuthService: IUserRepository) : HttpSignatureVerifyService {
class HttpSignatureVerifyServiceImpl(private val userQueryService: UserQueryService) : HttpSignatureVerifyService {
override fun verify(headers: Headers): Boolean {
val build = SignatureHeaderVerifier.builder().keyMap(KtorKeyMap(userAuthService)).build()
val build = SignatureHeaderVerifier.builder().keyMap(KtorKeyMap(userQueryService)).build()
return true
// build.verify(object : HttpMessage {
// override fun headerValues(name: String?): MutableList<String> {

View File

@ -1,7 +1,7 @@
package dev.usbharu.hideout.service.user
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.query.UserQueryService
import io.ktor.util.*
import org.koin.core.annotation.Single
import java.security.*
@ -9,7 +9,7 @@ import java.util.*
@Single
class UserAuthService(
val userRepository: IUserRepository
val userQueryService: UserQueryService
) : IUserAuthService {
override fun hash(password: String): String {
@ -18,13 +18,12 @@ class UserAuthService(
}
override suspend fun usernameAlreadyUse(username: String): Boolean {
userRepository.findByName(username)
userQueryService.findByName(username)
return true
}
override suspend fun verifyAccount(username: String, password: String): Boolean {
val userEntity = userRepository.findByNameAndDomain(username, Config.configData.domain)
?: return false
val userEntity = userQueryService.findByNameAndDomain(username, Config.configData.domain)
return userEntity.password == hash(password)
}

View File

@ -6,6 +6,8 @@ import dev.usbharu.hideout.domain.model.hideout.dto.SendFollowDto
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.exception.UserNotFoundException
import dev.usbharu.hideout.query.FollowerQueryService
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.service.activitypub.ActivityPubSendFollowService
import org.koin.core.annotation.Single
@ -15,12 +17,14 @@ import java.time.Instant
class UserService(
private val userRepository: IUserRepository,
private val userAuthService: IUserAuthService,
private val activityPubSendFollowService: ActivityPubSendFollowService
private val activityPubSendFollowService: ActivityPubSendFollowService,
private val userQueryService: UserQueryService,
private val followerQueryService: FollowerQueryService
) :
IUserService {
override suspend fun usernameAlreadyUse(username: String): Boolean {
val findByNameAndDomain = userRepository.findByNameAndDomain(username, Config.configData.domain)
val findByNameAndDomain = userQueryService.findByNameAndDomain(username, Config.configData.domain)
return findByNameAndDomain != null
}
@ -80,14 +84,14 @@ class UserService(
}
override suspend fun follow(id: Long, followerId: Long) {
userRepository.createFollower(id, followerId)
followerQueryService.appendFollower(id, followerId)
if (userRepository.findFollowRequestsById(id, followerId)) {
userRepository.deleteFollowRequest(id, followerId)
}
}
override suspend fun unfollow(id: Long, followerId: Long): Boolean {
userRepository.deleteFollower(id, followerId)
followerQueryService.removeFollower(id, followerId)
return false
}
}

View File

@ -2,41 +2,28 @@ package dev.usbharu.hideout.plugins
import dev.usbharu.hideout.domain.model.ap.JsonLd
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.service.user.toPem
import io.ktor.client.*
import io.ktor.client.engine.mock.*
import io.ktor.client.plugins.logging.*
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.mock
import java.security.KeyPairGenerator
import java.time.Instant
class ActivityPubKtTest {
@Test
fun HttpSignTest(): Unit = runBlocking {
val ktorKeyMap = KtorKeyMap(object : IUserRepository {
override suspend fun save(user: User): User {
TODO("Not yet implemented")
}
override suspend fun findById(id: Long): User? {
TODO("Not yet implemented")
}
override suspend fun findByIds(ids: List<Long>): List<User> {
TODO("Not yet implemented")
}
override suspend fun findByName(name: String): List<User> {
TODO()
}
override suspend fun findByNameAndDomain(name: String, domain: String): User {
fun HttpSignTest() {
val userQueryService = mock<UserQueryService> {
onBlocking { findByNameAndDomain(any(), any()) } doAnswer {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(1024)
val generateKeyPair = keyPairGenerator.generateKeyPair()
return User(
User(
1,
"test",
"localhost",
@ -51,63 +38,9 @@ class ActivityPubKtTest {
Instant.now()
)
}
override suspend fun findByDomain(domain: String): List<User> {
TODO("Not yet implemented")
}
override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> {
TODO("Not yet implemented")
}
override suspend fun findByUrl(url: String): User? {
TODO("Not yet implemented")
}
override suspend fun findByUrls(urls: List<String>): List<User> {
TODO("Not yet implemented")
}
override suspend fun delete(id: Long) {
TODO("Not yet implemented")
}
override suspend fun findAll(): List<User> {
TODO("Not yet implemented")
}
override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<User> {
TODO("Not yet implemented")
}
override suspend fun createFollower(id: Long, follower: Long) {
TODO("Not yet implemented")
}
override suspend fun deleteFollower(id: Long, follower: Long) {
TODO("Not yet implemented")
}
override suspend fun findFollowersById(id: Long): List<User> {
TODO("Not yet implemented")
}
override suspend fun addFollowRequest(id: Long, follower: Long) {
TODO("Not yet implemented")
}
override suspend fun deleteFollowRequest(id: Long, follower: Long) {
TODO("Not yet implemented")
}
override suspend fun findFollowRequestsById(id: Long, follower: Long): Boolean {
TODO("Not yet implemented")
}
override suspend fun nextId(): Long {
TODO("Not yet implemented")
}
})
runBlocking {
val ktorKeyMap = KtorKeyMap(userQueryService)
val httpClient = HttpClient(
MockEngine { httpRequestData ->
@ -125,4 +58,5 @@ class ActivityPubKtTest {
httpClient.postAp("https://localhost", "test", JsonLd(emptyList()))
}
}
}

View File

@ -1,9 +1,12 @@
package dev.usbharu.hideout.plugins
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.service.user.toPem
import org.junit.jupiter.api.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.mock
import java.security.KeyPairGenerator
import java.time.Instant
@ -11,28 +14,12 @@ class KtorKeyMapTest {
@Test
fun getPrivateKey() {
val ktorKeyMap = KtorKeyMap(object : IUserRepository {
override suspend fun save(user: User): User {
TODO("Not yet implemented")
}
override suspend fun findById(id: Long): User? {
TODO("Not yet implemented")
}
override suspend fun findByIds(ids: List<Long>): List<User> {
TODO("Not yet implemented")
}
override suspend fun findByName(name: String): List<User> {
TODO()
}
override suspend fun findByNameAndDomain(name: String, domain: String): User {
val userQueryService = mock<UserQueryService> {
onBlocking { findByNameAndDomain(any(), any()) } doAnswer {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(1024)
val generateKeyPair = keyPairGenerator.generateKeyPair()
return User(
User(
1,
"test",
"localhost",
@ -47,63 +34,8 @@ class KtorKeyMapTest {
createdAt = Instant.now()
)
}
override suspend fun findByDomain(domain: String): List<User> {
TODO("Not yet implemented")
}
override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> {
TODO("Not yet implemented")
}
override suspend fun findByUrl(url: String): User? {
TODO("Not yet implemented")
}
override suspend fun findByUrls(urls: List<String>): List<User> {
TODO("Not yet implemented")
}
override suspend fun delete(id: Long) {
TODO("Not yet implemented")
}
override suspend fun findAll(): List<User> {
TODO("Not yet implemented")
}
override suspend fun findAllByLimitAndByOffset(limit: Int, offset: Long): List<User> {
TODO("Not yet implemented")
}
override suspend fun createFollower(id: Long, follower: Long) {
TODO("Not yet implemented")
}
override suspend fun deleteFollower(id: Long, follower: Long) {
TODO("Not yet implemented")
}
override suspend fun findFollowersById(id: Long): List<User> {
TODO("Not yet implemented")
}
override suspend fun addFollowRequest(id: Long, follower: Long) {
TODO("Not yet implemented")
}
override suspend fun deleteFollowRequest(id: Long, follower: Long) {
TODO("Not yet implemented")
}
override suspend fun findFollowRequestsById(id: Long, follower: Long): Boolean {
TODO("Not yet implemented")
}
override suspend fun nextId(): Long {
TODO("Not yet implemented")
}
})
val ktorKeyMap = KtorKeyMap(userQueryService)
ktorKeyMap.getPrivateKey("test")
}

View File

@ -14,7 +14,7 @@ import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken
import dev.usbharu.hideout.domain.model.hideout.form.UserLogin
import dev.usbharu.hideout.exception.InvalidRefreshTokenException
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.routing.api.internal.v1.auth
import dev.usbharu.hideout.service.auth.IJwtService
import dev.usbharu.hideout.service.core.IMetaService
@ -49,7 +49,7 @@ class SecurityKtTest {
onBlocking { verifyAccount(eq("testUser"), eq("password")) } doReturn true
}
val metaService = mock<IMetaService>()
val userRepository = mock<IUserRepository> {
val userQueryService = mock<UserQueryService> {
onBlocking { findByNameAndDomain(eq("testUser"), eq("example.com")) } doReturn User(
id = 1L,
name = "testUser",
@ -74,7 +74,7 @@ class SecurityKtTest {
configureSerialization()
configureSecurity(jwkProvider, metaService)
routing {
auth(userAuthService, userRepository, jwtService)
auth(userAuthService, jwtService, userQueryService)
}
}
@ -97,14 +97,14 @@ class SecurityKtTest {
onBlocking { verifyAccount(anyString(), anyString()) }.doReturn(false)
}
val metaService = mock<IMetaService>()
val userRepository = mock<IUserRepository>()
val userQueryService = mock<UserQueryService>()
val jwtService = mock<IJwtService>()
val jwkProvider = mock<JwkProvider>()
application {
configureSerialization()
configureSecurity(jwkProvider, metaService)
routing {
auth(userAuthService, userRepository, jwtService)
auth(userAuthService, jwtService, userQueryService)
}
}
client.post("/login") {
@ -125,14 +125,14 @@ class SecurityKtTest {
onBlocking { verifyAccount(anyString(), eq("InvalidPassword")) } doReturn false
}
val metaService = mock<IMetaService>()
val userRepository = mock<IUserRepository>()
val userQueryService = mock<UserQueryService>()
val jwtService = mock<IJwtService>()
val jwkProvider = mock<JwkProvider>()
application {
configureSerialization()
configureSecurity(jwkProvider, metaService)
routing {
auth(userAuthService, userRepository, jwtService)
auth(userAuthService, jwtService, userQueryService)
}
}
client.post("/login") {
@ -531,7 +531,7 @@ class SecurityKtTest {
configureSerialization()
configureSecurity(mock(), mock())
routing {
auth(mock(), mock(), jwtService)
auth(mock(), jwtService, mock())
}
}
client.post("/refresh-token") {
@ -556,7 +556,7 @@ class SecurityKtTest {
configureSerialization()
configureSecurity(mock(), mock())
routing {
auth(mock(), mock(), jwtService)
auth(mock(), jwtService, mock())
}
}
client.post("/refresh-token") {

View File

@ -1,151 +0,0 @@
@file:OptIn(ExperimentalCoroutinesApi::class)
package dev.usbharu.hideout.repository
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.service.core.IdGenerateService
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertIterableEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.time.Clock
import java.time.Instant
import java.time.ZoneId
class UserRepositoryTest {
lateinit var db: Database
@BeforeEach
fun beforeEach() {
db = Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver")
transaction(db) {
SchemaUtils.create(Users)
SchemaUtils.create(UsersFollowers)
SchemaUtils.create(FollowRequests)
}
}
@AfterEach
fun tearDown() {
transaction(db) {
SchemaUtils.drop(UsersFollowers)
SchemaUtils.drop(FollowRequests)
SchemaUtils.drop(Users)
}
}
@Test
fun `findFollowersById フォロワー一覧を取得`() = runTest {
val userRepository = UserRepository(
db,
object : IdGenerateService {
override suspend fun generateId(): Long {
TODO("Not yet implemented")
}
}
)
val user = userRepository.save(
User(
id = 0L,
name = "test",
domain = "example.com",
screenName = "testUser",
description = "This user is test user.",
password = "https://example.com/inbox",
inbox = "",
outbox = "https://example.com/outbox",
url = "https://example.com",
publicKey = "",
createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault()))
)
)
val follower = userRepository.save(
User(
id = 1L,
name = "follower",
domain = "follower.example.com",
screenName = "followerUser",
description = "This user is follower user.",
password = "",
inbox = "https://follower.example.com/inbox",
outbox = "https://follower.example.com/outbox",
url = "https://follower.example.com",
publicKey = "",
createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault()))
)
)
val follower2 = userRepository.save(
User(
id = 3L,
name = "follower2",
domain = "follower2.example.com",
screenName = "followerUser2",
description = "This user is follower user 2.",
password = "",
inbox = "https://follower2.example.com/inbox",
outbox = "https://follower2.example.com/outbox",
url = "https://follower2.example.com",
publicKey = "",
createdAt = Instant.now(Clock.tickMillis(ZoneId.systemDefault()))
)
)
userRepository.createFollower(user.id, follower.id)
userRepository.createFollower(user.id, follower2.id)
assertIterableEquals(listOf(follower, follower2), userRepository.findFollowersById(user.id))
}
@Test
fun `createFollower フォロワー追加`() = runTest {
val userRepository = UserRepository(
db,
object : IdGenerateService {
override suspend fun generateId(): Long {
TODO("Not yet implemented")
}
}
)
val user = userRepository.save(
User(
0L,
"test",
"example.com",
"testUser",
"This user is test user.",
"https://example.com/inbox",
"",
"https://example.com/outbox",
"https://example.com",
publicKey = "",
createdAt = Instant.now()
)
)
val follower = userRepository.save(
User(
1L,
"follower",
"follower.example.com",
"followerUser",
"This user is follower user.",
"",
"https://follower.example.com/inbox",
"https://follower.example.com/outbox",
"https://follower.example.com",
publicKey = "",
createdAt = Instant.now()
)
)
userRepository.createFollower(user.id, follower.id)
transaction {
val followerIds =
UsersFollowers.select { UsersFollowers.userId eq user.id }.map { it[UsersFollowers.followerId] }
assertIterableEquals(listOf(follower.id), followerIds)
}
}
}

View File

@ -28,7 +28,7 @@ class UserServiceTest {
onBlocking { hash(anyString()) } doReturn "hashedPassword"
onBlocking { generateKeyPair() } doReturn generateKeyPair
}
val userService = UserService(userRepository, userAuthService, mock())
val userService = UserService(userRepository, userAuthService, mock(), mock(), mock())
userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test"))
verify(userRepository, times(1)).save(any())
argumentCaptor<dev.usbharu.hideout.domain.model.hideout.entity.User> {
@ -54,7 +54,7 @@ class UserServiceTest {
val userRepository = mock<IUserRepository> {
onBlocking { nextId() } doReturn 113345L
}
val userService = UserService(userRepository, mock(), mock())
val userService = UserService(userRepository, mock(), mock(), mock(), mock())
val user = RemoteUserCreateDto(
"test",
"example.com",