Skip to content

Commit 22657e0

Browse files
committed
Add in-memory repositories for testing user and article data
1 parent 9716540 commit 22657e0

File tree

3 files changed

+180
-0
lines changed

3 files changed

+180
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.github.gunkim.realworld.share
2+
3+
import io.github.gunkim.realworld.domain.article.model.ArticleId
4+
import io.github.gunkim.realworld.domain.user.model.UserId
5+
6+
object InMemoryDatabase {
7+
val users: MutableMap<UserId, Any> = mutableMapOf() // User 저장소
8+
val articles: MutableMap<ArticleId, Any> = mutableMapOf() // Article 저장소
9+
10+
val followings: MutableMap<UserId, MutableSet<UserId>> = mutableMapOf()
11+
val favorites: MutableMap<ArticleId, MutableSet<UserId>> = mutableMapOf()
12+
13+
// 테스트 실행 전후 데이터를 초기화하기 위한 메서드
14+
fun clear() {
15+
users.clear()
16+
articles.clear()
17+
followings.clear()
18+
favorites.clear()
19+
}
20+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package io.github.gunkim.realworld.share
2+
3+
import io.github.gunkim.realworld.domain.article.model.Article
4+
import io.github.gunkim.realworld.domain.article.model.ArticleId
5+
import io.github.gunkim.realworld.domain.article.model.Slug
6+
import io.github.gunkim.realworld.domain.article.repository.ArticleCountProjection
7+
import io.github.gunkim.realworld.domain.article.repository.ArticleRepository
8+
import io.github.gunkim.realworld.domain.user.model.User
9+
import io.github.gunkim.realworld.domain.user.model.UserId
10+
11+
data class ArticleCountProjectionImpl(
12+
override val articleId: ArticleId,
13+
override val count: Int,
14+
) : ArticleCountProjection
15+
16+
class MockArticleRepository : ArticleRepository {
17+
override fun save(article: Article): Article {
18+
val updatedAuthor: User = InMemoryDatabase.users[article.author.id] as? User ?: article.author
19+
val updatedArticle = if (article is Article.Companion.Model) {
20+
article.copy(author = updatedAuthor)
21+
} else {
22+
article
23+
}
24+
InMemoryDatabase.articles[updatedArticle.id] = updatedArticle
25+
return updatedArticle
26+
}
27+
28+
override fun delete(article: Article) {
29+
InMemoryDatabase.articles.remove(article.id)
30+
InMemoryDatabase.favorites.remove(article.id)
31+
}
32+
33+
override fun favorite(article: Article, user: User) {
34+
val favoritesSet = InMemoryDatabase.favorites.getOrPut(article.id) { mutableSetOf() }
35+
favoritesSet.add(user.id)
36+
}
37+
38+
override fun unFavorite(article: Article, user: User) {
39+
InMemoryDatabase.favorites[article.id]?.remove(user.id)
40+
}
41+
42+
override fun find(
43+
tag: String?,
44+
author: String?,
45+
favoritedUsername: String?,
46+
limit: Int,
47+
offset: Int,
48+
): List<Article> {
49+
var filtered = InMemoryDatabase.articles.values.toList().mapNotNull { it as? Article }
50+
51+
if (tag != null) {
52+
filtered = filtered.filter { article ->
53+
article.tags.any { it.name == tag }
54+
}
55+
}
56+
57+
if (author != null) {
58+
filtered = filtered.filter { article ->
59+
article.author.name == author
60+
}
61+
}
62+
63+
if (favoritedUsername != null) {
64+
val favoriter = InMemoryDatabase.users.values
65+
.mapNotNull { it as? User }
66+
.find { it.name == favoritedUsername }
67+
filtered = if (favoriter != null) {
68+
filtered.filter { article ->
69+
InMemoryDatabase.favorites[article.id]?.contains(favoriter.id) ?: false
70+
}
71+
} else {
72+
emptyList()
73+
}
74+
}
75+
76+
return filtered.drop(offset).take(limit)
77+
}
78+
79+
override fun findFeedArticles(userId: UserId, limit: Int, offset: Int): List<Article> {
80+
val followedUserIds = InMemoryDatabase.followings[userId] ?: emptySet()
81+
val feedArticles = InMemoryDatabase.articles.values.toList().mapNotNull { it as? Article }
82+
.filter { article ->
83+
followedUserIds.contains(article.author.id)
84+
}
85+
return feedArticles.drop(offset).take(limit)
86+
}
87+
88+
override fun getCountAllByArticleIds(articleIds: List<ArticleId>): List<ArticleCountProjection> {
89+
return articleIds.map { articleId ->
90+
val count = InMemoryDatabase.favorites[articleId]?.size ?: 0
91+
ArticleCountProjectionImpl(articleId, count)
92+
}
93+
}
94+
95+
override fun getFavoritesArticleIds(userId: UserId): List<ArticleId> {
96+
return InMemoryDatabase.favorites.filter { (_, userIds) ->
97+
userIds.contains(userId)
98+
}.keys.toList()
99+
}
100+
101+
override fun findBySlug(slug: Slug): Article? {
102+
return InMemoryDatabase.articles.values
103+
.mapNotNull { it as? Article }
104+
.find { it.slug == slug }
105+
}
106+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.github.gunkim.realworld.share
2+
3+
import io.github.gunkim.realworld.domain.article.model.Article
4+
import io.github.gunkim.realworld.domain.user.model.User
5+
import io.github.gunkim.realworld.domain.user.model.UserId
6+
import io.github.gunkim.realworld.domain.user.repository.UserRepository
7+
8+
class MockUserRepository : UserRepository {
9+
override fun save(user: User): User {
10+
val existingUser = InMemoryDatabase.users[user.id]
11+
InMemoryDatabase.users[user.id] = user
12+
13+
if (existingUser != null) {
14+
InMemoryDatabase.articles.replaceAll { articleId, article ->
15+
if (article.author.id == user.id) {
16+
if (article is Article.Companion.Model) {
17+
article.copy(author = user)
18+
} else {
19+
article
20+
}
21+
} else {
22+
article
23+
}
24+
}
25+
}
26+
return user
27+
}
28+
29+
override fun follow(followerId: UserId, followeeId: UserId) {
30+
// followerId가 followeeId를 팔로우하도록 followings 맵을 업데이트합니다.
31+
val followingSet = InMemoryDatabase.followings.getOrPut(followerId) { mutableSetOf() }
32+
followingSet.add(followeeId)
33+
}
34+
35+
override fun unfollow(followerId: UserId, followeeId: UserId) {
36+
InMemoryDatabase.followings[followerId]?.remove(followeeId)
37+
}
38+
39+
override fun findByEmail(email: String): User? {
40+
return InMemoryDatabase.users.values.find { it.email == email }
41+
}
42+
43+
override fun findById(userId: UserId): User? {
44+
return InMemoryDatabase.users[userId]
45+
}
46+
47+
override fun findByUserName(name: String): User? {
48+
return InMemoryDatabase.users.values.find { it.name == name }
49+
}
50+
51+
override fun findFollowedUserIdsFor(userId: UserId): List<UserId> {
52+
return InMemoryDatabase.followings[userId]?.toList() ?: emptyList()
53+
}
54+
}

0 commit comments

Comments
 (0)