Skip to content

Commit eb3dd28

Browse files
authored
feat: 알송파트 유즈케이스 적용 (#666)
* refactor: 로그인 기능 유즈케이스 구현 * refactor: 이미 로그인이 되어 있는 디바이스인지 확인하는 기능에 유즈케이스 적용 * refactor: 네이밍 개선 * style: 필요 없어진 코드 제거 * refactor: 공모글 작성 기능에 유즈케이스 적용 * refactor: 유즈케이스를 도메인 레이어로 이동 * style: ktlint format 적용 * refactor: 이미지 업로드 기능에 유즈케이스 적용 * refactor: 이미지 업로드 기능에 유즈케이스 적용 * refactor: 공모글 수정 기능에 유즈케이스 적용 * refactor: 채팅방 목록 조회 기능에 유즈케이스 적용 * test: 댓글방 목록을 불러오는 유즈케이스 테스트 * test: 로그인 유즈케이스 테스트 * test: 유즈케이스 적용으로 인한 공모글 작성 뷰모델 테스트 수정 * test: 유즈케이스 적용으로 인한 댓글방 목록 조회 뷰모델 테스트 수정 * style: ktlint format 적용
1 parent 5d7a739 commit eb3dd28

31 files changed

+635
-203
lines changed

android/app/src/main/java/com/zzang/chongdae/auth/repository/AuthRepository.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.zzang.chongdae.common.handler.DataError
55
import com.zzang.chongdae.common.handler.Result
66

77
interface AuthRepository {
8-
suspend fun saveLogin(
8+
suspend fun postLogin(
99
accessToken: String,
1010
fcmToken: String,
1111
): Result<Member, DataError.Network>

android/app/src/main/java/com/zzang/chongdae/auth/repository/AuthRepositoryImpl.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class AuthRepositoryImpl
1414
constructor(
1515
@AuthDataSourceQualifier private val authRemoteDataSource: AuthRemoteDataSource,
1616
) : AuthRepository {
17-
override suspend fun saveLogin(
17+
override suspend fun postLogin(
1818
accessToken: String,
1919
fcmToken: String,
2020
): Result<Member, DataError.Network> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.zzang.chongdae.di.annotations
2+
3+
import javax.inject.Qualifier
4+
5+
@Qualifier
6+
@Retention(AnnotationRetention.BINARY)
7+
annotation class CheckAlreadyLoggedInUseCaseQualifier
8+
9+
@Qualifier
10+
@Retention(AnnotationRetention.BINARY)
11+
annotation class PostLoginUseCaseQualifier
12+
13+
@Qualifier
14+
@Retention(AnnotationRetention.BINARY)
15+
annotation class PostOfferingUseCaseQualifier
16+
17+
@Qualifier
18+
@Retention(AnnotationRetention.BINARY)
19+
annotation class UploadImageFileUseCaseQualifier
20+
21+
@Qualifier
22+
@Retention(AnnotationRetention.BINARY)
23+
annotation class PostProductImageOgUseCaseQualifier
24+
25+
@Qualifier
26+
@Retention(AnnotationRetention.BINARY)
27+
annotation class FetchOfferingDetailUseCaseQualifier
28+
29+
@Qualifier
30+
@Retention(AnnotationRetention.BINARY)
31+
annotation class PostOfferingModifyUseCaseQualifier
32+
33+
@Qualifier
34+
@Retention(AnnotationRetention.BINARY)
35+
annotation class UpdateCommentRoomsUseCaseQualifier
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.zzang.chongdae.di.module
2+
3+
import com.zzang.chongdae.di.annotations.CheckAlreadyLoggedInUseCaseQualifier
4+
import com.zzang.chongdae.di.annotations.FetchOfferingDetailUseCaseQualifier
5+
import com.zzang.chongdae.di.annotations.PostLoginUseCaseQualifier
6+
import com.zzang.chongdae.di.annotations.PostOfferingModifyUseCaseQualifier
7+
import com.zzang.chongdae.di.annotations.PostOfferingUseCaseQualifier
8+
import com.zzang.chongdae.di.annotations.PostProductImageOgUseCaseQualifier
9+
import com.zzang.chongdae.di.annotations.UpdateCommentRoomsUseCaseQualifier
10+
import com.zzang.chongdae.di.annotations.UploadImageFileUseCaseQualifier
11+
import com.zzang.chongdae.domain.usecase.comment.UpdateCommentRoomsUseCase
12+
import com.zzang.chongdae.domain.usecase.comment.UpdateCommentRoomsUseCaseImpl
13+
import com.zzang.chongdae.domain.usecase.login.CheckIfAlreadyLoggedInUseCase
14+
import com.zzang.chongdae.domain.usecase.login.CheckIfAlreadyLoggedInUseCaseImpl
15+
import com.zzang.chongdae.domain.usecase.login.PostLoginUseCase
16+
import com.zzang.chongdae.domain.usecase.login.PostLoginUseCaseImpl
17+
import com.zzang.chongdae.domain.usecase.offeringmodify.FetchOfferingDetailUseCase
18+
import com.zzang.chongdae.domain.usecase.offeringmodify.FetchOfferingDetailUseCaseImpl
19+
import com.zzang.chongdae.domain.usecase.offeringmodify.PostOfferingModifyUseCase
20+
import com.zzang.chongdae.domain.usecase.offeringmodify.PostOfferingModifyUseCaseImpl
21+
import com.zzang.chongdae.domain.usecase.write.PostOfferingUseCase
22+
import com.zzang.chongdae.domain.usecase.write.PostOfferingUseCaseImpl
23+
import com.zzang.chongdae.domain.usecase.write.PostProductImageOgUseCase
24+
import com.zzang.chongdae.domain.usecase.write.PostProductImageOgUseCaseImpl
25+
import com.zzang.chongdae.domain.usecase.write.UploadImageFileUseCase
26+
import com.zzang.chongdae.domain.usecase.write.UploadImageFileUseCaseImpl
27+
import dagger.Binds
28+
import dagger.Module
29+
import dagger.hilt.InstallIn
30+
import dagger.hilt.components.SingletonComponent
31+
import javax.inject.Singleton
32+
33+
@InstallIn(SingletonComponent::class)
34+
@Module
35+
abstract class UseCaseDependencyModule {
36+
@Binds
37+
@Singleton
38+
@CheckAlreadyLoggedInUseCaseQualifier
39+
abstract fun provideCheckIfAlreadyLoggedInUseCase(impl: CheckIfAlreadyLoggedInUseCaseImpl): CheckIfAlreadyLoggedInUseCase
40+
41+
@Binds
42+
@Singleton
43+
@PostLoginUseCaseQualifier
44+
abstract fun providePostLoginUseCase(impl: PostLoginUseCaseImpl): PostLoginUseCase
45+
46+
@Binds
47+
@Singleton
48+
@PostOfferingUseCaseQualifier
49+
abstract fun providePostOfferingUseCase(impl: PostOfferingUseCaseImpl): PostOfferingUseCase
50+
51+
@Binds
52+
@Singleton
53+
@UploadImageFileUseCaseQualifier
54+
abstract fun provideUploadImageFileUseCase(impl: UploadImageFileUseCaseImpl): UploadImageFileUseCase
55+
56+
@Binds
57+
@Singleton
58+
@PostProductImageOgUseCaseQualifier
59+
abstract fun providePostProductImageOgUseCase(impl: PostProductImageOgUseCaseImpl): PostProductImageOgUseCase
60+
61+
@Binds
62+
@Singleton
63+
@FetchOfferingDetailUseCaseQualifier
64+
abstract fun provideFetchOfferingDetailUseCase(impl: FetchOfferingDetailUseCaseImpl): FetchOfferingDetailUseCase
65+
66+
@Binds
67+
@Singleton
68+
@PostOfferingModifyUseCaseQualifier
69+
abstract fun providePostOfferingModifyUseCase(impl: PostOfferingModifyUseCaseImpl): PostOfferingModifyUseCase
70+
71+
@Binds
72+
@Singleton
73+
@UpdateCommentRoomsUseCaseQualifier
74+
abstract fun provideUpdateCommentRoomsUseCase(impl: UpdateCommentRoomsUseCaseImpl): UpdateCommentRoomsUseCase
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.zzang.chongdae.domain.usecase.comment
2+
3+
import com.zzang.chongdae.common.handler.DataError
4+
import com.zzang.chongdae.common.handler.Result
5+
import com.zzang.chongdae.domain.model.CommentRoom
6+
7+
interface UpdateCommentRoomsUseCase {
8+
suspend operator fun invoke(): Result<List<CommentRoom>, DataError.Network>
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.zzang.chongdae.domain.usecase.comment
2+
3+
import com.zzang.chongdae.auth.repository.AuthRepository
4+
import com.zzang.chongdae.common.handler.DataError
5+
import com.zzang.chongdae.common.handler.Result
6+
import com.zzang.chongdae.di.annotations.AuthRepositoryQualifier
7+
import com.zzang.chongdae.di.annotations.CommentRoomsRepositoryQualifier
8+
import com.zzang.chongdae.domain.model.CommentRoom
9+
import com.zzang.chongdae.domain.repository.CommentRoomsRepository
10+
import javax.inject.Inject
11+
12+
class UpdateCommentRoomsUseCaseImpl
13+
@Inject
14+
constructor(
15+
@AuthRepositoryQualifier private val authRepository: AuthRepository,
16+
@CommentRoomsRepositoryQualifier private val commentRoomsRepository: CommentRoomsRepository,
17+
) : UpdateCommentRoomsUseCase {
18+
override suspend fun invoke(): Result<List<CommentRoom>, DataError.Network> {
19+
return when (val result = commentRoomsRepository.fetchCommentRooms()) {
20+
is Result.Success -> Result.Success(result.data)
21+
is Result.Error -> {
22+
when (result.error) {
23+
DataError.Network.UNAUTHORIZED -> {
24+
when (authRepository.saveRefresh()) {
25+
is Result.Success -> invoke()
26+
is Result.Error -> result
27+
}
28+
}
29+
30+
else -> result
31+
}
32+
}
33+
}
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.zzang.chongdae.domain.usecase.login
2+
3+
interface CheckIfAlreadyLoggedInUseCase {
4+
suspend operator fun invoke(): Boolean
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.zzang.chongdae.domain.usecase.login
2+
3+
import com.zzang.chongdae.common.datastore.UserPreferencesDataStore
4+
import kotlinx.coroutines.flow.first
5+
import javax.inject.Inject
6+
7+
class CheckIfAlreadyLoggedInUseCaseImpl
8+
@Inject
9+
constructor(
10+
private val userPreferencesDataStore: UserPreferencesDataStore,
11+
) : CheckIfAlreadyLoggedInUseCase {
12+
override suspend fun invoke(): Boolean {
13+
val accessToken = userPreferencesDataStore.accessTokenFlow.first()
14+
return accessToken != null
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.zzang.chongdae.domain.usecase.login
2+
3+
import com.zzang.chongdae.common.handler.DataError
4+
import com.zzang.chongdae.common.handler.Result
5+
6+
interface PostLoginUseCase {
7+
suspend operator fun invoke(
8+
accessToken: String,
9+
fcmToken: String,
10+
): Result<Unit, DataError.Network>
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.zzang.chongdae.domain.usecase.login
2+
3+
import com.zzang.chongdae.auth.repository.AuthRepository
4+
import com.zzang.chongdae.common.datastore.UserPreferencesDataStore
5+
import com.zzang.chongdae.common.handler.DataError
6+
import com.zzang.chongdae.common.handler.Result
7+
import com.zzang.chongdae.di.annotations.AuthRepositoryQualifier
8+
import javax.inject.Inject
9+
10+
class PostLoginUseCaseImpl
11+
@Inject
12+
constructor(
13+
@AuthRepositoryQualifier private val authRepository: AuthRepository,
14+
private val userPreferencesDataStore: UserPreferencesDataStore,
15+
) : PostLoginUseCase {
16+
override suspend fun invoke(
17+
accessToken: String,
18+
fcmToken: String,
19+
): Result<Unit, DataError.Network> {
20+
return when (val result = authRepository.postLogin(accessToken, fcmToken)) {
21+
is Result.Success -> {
22+
userPreferencesDataStore.saveMember(result.data.memberId, result.data.nickName)
23+
userPreferencesDataStore.saveFcmToken(fcmToken)
24+
Result.Success(Unit)
25+
}
26+
27+
is Result.Error -> result
28+
}
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.zzang.chongdae.domain.usecase.offeringmodify
2+
3+
import com.zzang.chongdae.common.handler.DataError
4+
import com.zzang.chongdae.common.handler.Result
5+
import com.zzang.chongdae.domain.model.OfferingDetail
6+
7+
interface FetchOfferingDetailUseCase {
8+
suspend operator fun invoke(offeringId: Long): Result<OfferingDetail, DataError.Network>
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.zzang.chongdae.domain.usecase.offeringmodify
2+
3+
import com.zzang.chongdae.auth.repository.AuthRepository
4+
import com.zzang.chongdae.common.handler.DataError
5+
import com.zzang.chongdae.common.handler.Result
6+
import com.zzang.chongdae.di.annotations.AuthRepositoryQualifier
7+
import com.zzang.chongdae.di.annotations.OfferingDetailRepositoryQualifier
8+
import com.zzang.chongdae.domain.model.OfferingDetail
9+
import com.zzang.chongdae.domain.repository.OfferingDetailRepository
10+
import javax.inject.Inject
11+
12+
class FetchOfferingDetailUseCaseImpl
13+
@Inject
14+
constructor(
15+
@OfferingDetailRepositoryQualifier private val offeringDetailRepository: OfferingDetailRepository,
16+
@AuthRepositoryQualifier private val authRepository: AuthRepository,
17+
) : FetchOfferingDetailUseCase {
18+
override suspend fun invoke(offeringId: Long): Result<OfferingDetail, DataError.Network> {
19+
return when (val result = offeringDetailRepository.fetchOfferingDetail(offeringId)) {
20+
is Result.Success -> Result.Success(result.data)
21+
is Result.Error -> {
22+
when (result.error) {
23+
DataError.Network.UNAUTHORIZED -> {
24+
when (authRepository.saveRefresh()) {
25+
is Result.Success -> invoke(offeringId)
26+
is Result.Error -> result
27+
}
28+
}
29+
30+
else -> result
31+
}
32+
}
33+
}
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.zzang.chongdae.domain.usecase.offeringmodify
2+
3+
import com.zzang.chongdae.common.handler.DataError
4+
import com.zzang.chongdae.common.handler.Result
5+
import com.zzang.chongdae.domain.model.OfferingModifyDomainRequest
6+
7+
interface PostOfferingModifyUseCase {
8+
suspend operator fun invoke(
9+
offeringId: Long,
10+
offeringModifyDomainRequest: OfferingModifyDomainRequest,
11+
): Result<Unit, DataError.Network>
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.zzang.chongdae.domain.usecase.offeringmodify
2+
3+
import com.zzang.chongdae.auth.repository.AuthRepository
4+
import com.zzang.chongdae.common.handler.DataError
5+
import com.zzang.chongdae.common.handler.Result
6+
import com.zzang.chongdae.di.annotations.AuthRepositoryQualifier
7+
import com.zzang.chongdae.di.annotations.OfferingRepositoryQualifier
8+
import com.zzang.chongdae.domain.model.OfferingModifyDomainRequest
9+
import com.zzang.chongdae.domain.repository.OfferingRepository
10+
import javax.inject.Inject
11+
12+
class PostOfferingModifyUseCaseImpl
13+
@Inject
14+
constructor(
15+
@OfferingRepositoryQualifier private val offeringRepository: OfferingRepository,
16+
@AuthRepositoryQualifier private val authRepository: AuthRepository,
17+
) : PostOfferingModifyUseCase {
18+
override suspend fun invoke(
19+
offeringId: Long,
20+
offeringModifyDomainRequest: OfferingModifyDomainRequest,
21+
): Result<Unit, DataError.Network> {
22+
return when (
23+
val result =
24+
offeringRepository.patchOffering(offeringId, offeringModifyDomainRequest)
25+
) {
26+
is Result.Success -> Result.Success(Unit)
27+
is Result.Error -> {
28+
when (result.error) {
29+
DataError.Network.UNAUTHORIZED -> {
30+
when (authRepository.saveRefresh()) {
31+
is Result.Success -> invoke(offeringId, offeringModifyDomainRequest)
32+
is Result.Error -> result
33+
}
34+
}
35+
36+
else -> result
37+
}
38+
}
39+
}
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.zzang.chongdae.domain.usecase.write
2+
3+
import com.zzang.chongdae.common.handler.DataError
4+
import com.zzang.chongdae.common.handler.Result
5+
import com.zzang.chongdae.domain.model.OfferingWrite
6+
7+
interface PostOfferingUseCase {
8+
suspend operator fun invoke(offeringWrite: OfferingWrite): Result<Unit, DataError.Network>
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.zzang.chongdae.domain.usecase.write
2+
3+
import com.zzang.chongdae.auth.repository.AuthRepository
4+
import com.zzang.chongdae.common.handler.DataError
5+
import com.zzang.chongdae.common.handler.Result
6+
import com.zzang.chongdae.di.annotations.AuthRepositoryQualifier
7+
import com.zzang.chongdae.di.annotations.OfferingRepositoryQualifier
8+
import com.zzang.chongdae.domain.model.OfferingWrite
9+
import com.zzang.chongdae.domain.repository.OfferingRepository
10+
import javax.inject.Inject
11+
12+
class PostOfferingUseCaseImpl
13+
@Inject
14+
constructor(
15+
@OfferingRepositoryQualifier private val offeringRepository: OfferingRepository,
16+
@AuthRepositoryQualifier private val authRepository: AuthRepository,
17+
) : PostOfferingUseCase {
18+
override suspend fun invoke(offeringWrite: OfferingWrite): Result<Unit, DataError.Network> {
19+
return when (val result = offeringRepository.saveOffering(offeringWrite)) {
20+
is Result.Success -> Result.Success(Unit)
21+
is Result.Error -> {
22+
when (result.error) {
23+
DataError.Network.UNAUTHORIZED -> {
24+
when (authRepository.saveRefresh()) {
25+
is Result.Success -> invoke(offeringWrite)
26+
is Result.Error -> result
27+
}
28+
}
29+
else -> result
30+
}
31+
}
32+
}
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.zzang.chongdae.domain.usecase.write
2+
3+
import com.zzang.chongdae.common.handler.DataError
4+
import com.zzang.chongdae.common.handler.Result
5+
import com.zzang.chongdae.domain.model.ProductUrl
6+
7+
interface PostProductImageOgUseCase {
8+
suspend operator fun invoke(productUrl: String): Result<ProductUrl, DataError.Network>
9+
}

0 commit comments

Comments
 (0)