Skip to content

Commit

Permalink
Merge pull request #46 from YAPP-Github/feature/tgyuu/PC-476
Browse files Browse the repository at this point in the history
[PC-476] 가치관 Pick, 가치관 Talk을 Splash 화면에서 동적으로 불러옵니다.
  • Loading branch information
tgyuuAn authored Feb 2, 2025
2 parents 2145355 + a7633bf commit 037071d
Show file tree
Hide file tree
Showing 33 changed files with 1,011 additions and 112 deletions.
1 change: 0 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission
android:name="android.permission.POST_NOTIFICATIONS"
tools:targetApi="33" />
Expand Down
8 changes: 8 additions & 0 deletions core/data/src/main/java/com/puzzle/data/di/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.puzzle.data.di

import com.puzzle.data.TokenManagerImpl
import com.puzzle.data.repository.AuthRepositoryImpl
import com.puzzle.data.repository.MatchingRepositoryImpl
import com.puzzle.data.repository.TermsRepositoryImpl
import com.puzzle.data.repository.UserRepositoryImpl
import com.puzzle.domain.repository.AuthRepository
import com.puzzle.domain.repository.MatchingRepository
import com.puzzle.domain.repository.TermsRepository
import com.puzzle.domain.repository.UserRepository
import com.puzzle.network.interceptor.TokenManager
Expand Down Expand Up @@ -36,6 +38,12 @@ abstract class DataModule {
userRepositoryImpl: UserRepositoryImpl,
): UserRepository

@Binds
@Singleton
abstract fun bindsMatchingRepository(
matchingRepositoryImpl: MatchingRepositoryImpl,
): MatchingRepository

@Binds
@Singleton
abstract fun bindsTokenManager(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.puzzle.data.repository

import com.puzzle.common.suspendRunCatching
import com.puzzle.database.model.matching.ValuePickAnswer
import com.puzzle.database.model.matching.ValuePickEntity
import com.puzzle.database.model.matching.ValuePickQuestion
import com.puzzle.database.model.matching.ValueTalkEntity
import com.puzzle.database.source.LocalMatchingDataSource
import com.puzzle.domain.model.matching.ValuePick
import com.puzzle.domain.model.matching.ValueTalk
import com.puzzle.domain.repository.MatchingRepository
import com.puzzle.network.model.UNKNOWN_INT
import com.puzzle.network.source.MatchingDataSource
import javax.inject.Inject

class MatchingRepositoryImpl @Inject constructor(
private val matchingDataSource: MatchingDataSource,
private val localMatchingDataSource: LocalMatchingDataSource,
) : MatchingRepository {
override suspend fun loadValuePicks(): Result<Unit> = suspendRunCatching {
val valuePicks = matchingDataSource.loadValuePicks()
.getOrThrow()
.toDomain()
.filter { it.id != UNKNOWN_INT }

val valuePickEntities = valuePicks.map { valuePick ->
ValuePickEntity(
valuePickQuestion = ValuePickQuestion(
id = valuePick.id,
category = valuePick.category,
question = valuePick.question,
),
answers = valuePick.answers.map { answer ->
ValuePickAnswer(
questionsId = valuePick.id,
number = answer.number,
content = answer.content,
)
}
)
}

localMatchingDataSource.replaceValuePicks(valuePickEntities)
}

override suspend fun loadValueTalks(): Result<Unit> = suspendRunCatching {
val valueTalks = matchingDataSource.loadValueTalks()
.getOrThrow()
.toDomain()
.filter { it.id != UNKNOWN_INT }

val valueTalkEntities = valueTalks.map {
ValueTalkEntity(
id = it.id,
title = it.title,
category = it.category,
helpMessages = it.helpMessages,
)
}

localMatchingDataSource.replaceValueTalks(valueTalkEntities)
}

override suspend fun retrieveValuePick(): Result<List<ValuePick>> = suspendRunCatching {
localMatchingDataSource.retrieveValuePicks()
.map(ValuePickEntity::toDomain)
}

override suspend fun retrieveValueTalk(): Result<List<ValueTalk>> = suspendRunCatching {
localMatchingDataSource.retrieveValueTalks()
.map(ValueTalkEntity::toDomain)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.puzzle.data.repository

import com.puzzle.common.suspendRunCatching
import com.puzzle.database.model.terms.TermEntity
import com.puzzle.database.source.term.LocalTermDataSource
import com.puzzle.database.source.LocalTermDataSource
import com.puzzle.domain.model.terms.Term
import com.puzzle.domain.repository.TermsRepository
import com.puzzle.network.model.UNKNOWN_INT
Expand Down Expand Up @@ -32,7 +32,7 @@ class TermsRepositoryImpl @Inject constructor(
localTermDataSource.replaceTerms(termsEntity)
}

override suspend fun getTerms(): Result<List<Term>> = runCatching {
override suspend fun retrieveTerms(): Result<List<Term>> = suspendRunCatching {
localTermDataSource.retrieveTerms()
.map(TermEntity::toDomain)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package com.puzzle.data.repository

import com.puzzle.database.source.LocalMatchingDataSource
import com.puzzle.network.model.matching.LoadValuePicksResponse
import com.puzzle.network.model.matching.LoadValueTalksResponse
import com.puzzle.network.model.matching.ValuePickAnswerResponse
import com.puzzle.network.model.matching.ValuePickResponse
import com.puzzle.network.model.matching.ValueTalkResponse
import com.puzzle.network.source.MatchingDataSource
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class MatchingRepositoryImplTest {

private lateinit var matchingDataSource: MatchingDataSource
private lateinit var localMatchingDataSource: LocalMatchingDataSource
private lateinit var matchingRepository: MatchingRepositoryImpl

@BeforeEach
fun setUp() {
matchingDataSource = mockk()
localMatchingDataSource = mockk()
matchingRepository = MatchingRepositoryImpl(matchingDataSource, localMatchingDataSource)
}

@Test
fun `가치관Pick을 새로 갱신할 경우 id값이 올바르게 내려오지 않은 가치관Pick은 무시한다`() = runTest {
// given
val invalidValuePick = ValuePickResponse(
id = null,
category = null,
question = null,
answers = null
)
val validValuePick = ValuePickResponse(
id = 1,
category = "음주",
question = "술을 마시는 것에 대해 어떻게 생각하나요?",
answers = listOf(
ValuePickAnswerResponse(1, "함께 즐기고 싶어요"),
ValuePickAnswerResponse(2, "같이 즐길 수 없어도 괜찮아요")
)
)

coEvery { matchingDataSource.loadValuePicks() } returns
Result.success(LoadValuePicksResponse(listOf(invalidValuePick, validValuePick)))
coEvery { localMatchingDataSource.replaceValuePicks(any()) } returns Result.success(Unit)

// when
val result = matchingRepository.loadValuePicks()

// then
assertTrue(result.isSuccess)
coVerify(exactly = 1) {
localMatchingDataSource.replaceValuePicks(
match {
it.size == 1 && it.first().valuePickQuestion.id == validValuePick.id
}
)
}
}

@Test
fun `가치관Talk을 새로 갱신할 경우 id값이 올바르게 내려오지 않은 가치관Talk은 무시한다`() = runTest {
// given
val invalidValueTalk = ValueTalkResponse(
id = null,
category = null,
title = null,
guide = null
)
val validValueTalk = ValueTalkResponse(
id = 1,
category = "음주",
title = "술자리에 대한 대화",
guide = null
)

coEvery { matchingDataSource.loadValueTalks() } returns
Result.success(LoadValueTalksResponse(listOf(invalidValueTalk, validValueTalk)))
coEvery { localMatchingDataSource.replaceValueTalks(any()) } returns Result.success(Unit)

// when
val result = matchingRepository.loadValueTalks()

// then
assertTrue(result.isSuccess)
coVerify(exactly = 1) {
localMatchingDataSource.replaceValueTalks(
match {
it.size == 1 && it.first().id == validValueTalk.id
}
)
}
}

@Test
fun `갱신한 가치관Pick 데이터는 로컬 데이터베이스에 저장한다`() = runTest {
// given
val validValuePicks = listOf(
ValuePickResponse(
id = 1,
category = "음주",
question = "술을 마시는 것에 대해 어떻게 생각하나요?",
answers = listOf(
ValuePickAnswerResponse(1, "함께 즐기고 싶어요"),
ValuePickAnswerResponse(2, "같이 즐길 수 없어도 괜찮아요")
)
),
ValuePickResponse(
id = 2,
category = "취미",
question = "좋아하는 취미가 있나요?",
answers = listOf(
ValuePickAnswerResponse(1, "여행을 좋아해요"),
ValuePickAnswerResponse(2, "영화 감상을 좋아해요")
)
)
)

coEvery { matchingDataSource.loadValuePicks() } returns Result.success(
LoadValuePicksResponse(validValuePicks)
)
coEvery { localMatchingDataSource.replaceValuePicks(any()) } returns Result.success(Unit)

// when
val result = matchingRepository.loadValuePicks()

// then
assertTrue(result.isSuccess)
coVerify(exactly = 1) {
localMatchingDataSource.replaceValuePicks(
match {
it.size == validValuePicks.size && it.all { entity ->
validValuePicks.any { pick ->
pick.id == entity.valuePickQuestion.id &&
pick.category == entity.valuePickQuestion.category
}
}
}
)
}
}

@Test
fun `갱신한 가치관Talk 데이터는 로컬 데이터베이스에 저장한다`() = runTest {
// given
val validValueTalks = listOf(
ValueTalkResponse(
id = 1,
title = "술자리에 대한 대화",
category = "음주",
guide = null
),
ValueTalkResponse(
id = 2,
title = "취미 공유하기",
category = "취미",
guide = null
)
)

coEvery { matchingDataSource.loadValueTalks() } returns Result.success(
LoadValueTalksResponse(validValueTalks)
)
coEvery { localMatchingDataSource.replaceValueTalks(any()) } returns Result.success(Unit)

// when
val result = matchingRepository.loadValueTalks()

// then
assertTrue(result.isSuccess)
coVerify(exactly = 1) {
localMatchingDataSource.replaceValueTalks(
match {
it.size == validValueTalks.size && it.all { entity ->
validValueTalks.any { talk ->
talk.id == entity.id && talk.title == entity.title
}
}
}
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.puzzle.data.repository

import com.puzzle.database.source.term.LocalTermDataSource
import com.puzzle.database.source.LocalTermDataSource
import com.puzzle.network.model.UNKNOWN_INT
import com.puzzle.network.model.terms.LoadTermsResponse
import com.puzzle.network.model.terms.TermResponse
Expand Down
Loading

0 comments on commit 037071d

Please sign in to comment.