Skip to content

Commit 0edc72f

Browse files
committed
Test: RoutineRepositoryImpl 동기화 재시도 및 디바운스 로직 테스트 수정
1 parent 09eb7bb commit 0edc72f

1 file changed

Lines changed: 41 additions & 7 deletions

File tree

data/src/test/java/com/threegap/bitnagil/data/routine/repositoryImpl/RoutineRepositoryImplTest.kt

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import com.threegap.bitnagil.domain.routine.model.RoutineSchedule
1414
import com.threegap.bitnagil.domain.routine.repository.RoutineRepository
1515
import kotlinx.coroutines.ExperimentalCoroutinesApi
1616
import kotlinx.coroutines.flow.first
17+
import kotlinx.coroutines.launch
1718
import kotlinx.coroutines.test.StandardTestDispatcher
1819
import kotlinx.coroutines.test.advanceTimeBy
1920
import kotlinx.coroutines.test.runCurrent
@@ -125,7 +126,7 @@ class RoutineRepositoryImplTest {
125126
repository.applyRoutineToggle(dateKey2, routineId2, RoutineCompletionInfo(routineId2, routineCompleteYn = true, subRoutineCompleteYn = emptyList()))
126127

127128
advanceTimeBy(501L)
128-
assertEquals(2, remoteDataSource.syncCount.get())
129+
assertEquals(1, remoteDataSource.syncCount.get())
129130
}
130131

131132
@Test
@@ -146,7 +147,7 @@ class RoutineRepositoryImplTest {
146147
@Test
147148
fun `sync 실패 시 서버 데이터로 로컬 캐시가 rollback되어야 한다`() = runTest {
148149
repository = createRepository(testScheduler)
149-
runCurrent() // repositoryScope의 syncTrigger collector 시작
150+
runCurrent()
150151
remoteDataSource.scheduleResponse = Result.success(RoutineScheduleResponse(emptyMap()))
151152
remoteDataSource.syncResult = Result.failure(Exception("네트워크 오류"))
152153
val (dateKey, routineId) = setupCacheWithRoutine(isCompleted = false)
@@ -156,10 +157,11 @@ class RoutineRepositoryImplTest {
156157
routineId = routineId,
157158
completionInfo = RoutineCompletionInfo(routineId, routineCompleteYn = true, subRoutineCompleteYn = emptyList()),
158159
)
159-
advanceTimeBy(501L)
160160

161-
// sync 실패 후 fetchAndSave 호출 → 서버 값(emptyMap)으로 덮어씀
162-
assertEquals(1, remoteDataSource.fetchCount.get())
161+
advanceTimeBy(1200L) // debounce(500) + retry delay(200 + 400) + 여유
162+
163+
assertEquals(3, remoteDataSource.syncCount.get()) // 1회 시도 + 2회 재시도
164+
assertEquals(1, remoteDataSource.fetchCount.get()) // 롤백 fetch 1회
163165
assertEquals(RoutineSchedule(emptyMap()), localDataSource.routineSchedule.value)
164166
}
165167

@@ -187,6 +189,33 @@ class RoutineRepositoryImplTest {
187189
assertEquals(0, remoteDataSource.fetchCount.get())
188190
}
189191

192+
@Test
193+
fun `sync 1차 실패 후 재시도 성공 시 syncError가 emit되지 않아야 한다`() = runTest {
194+
repository = createRepository(testScheduler)
195+
runCurrent()
196+
remoteDataSource.syncFailCount = 1 // 1번만 실패, 이후 성공
197+
val (dateKey, routineId) = setupCacheWithRoutine(isCompleted = false)
198+
199+
var syncErrorEmitted = false
200+
val job = launch {
201+
repository.syncError.collect { syncErrorEmitted = true }
202+
}
203+
204+
repository.applyRoutineToggle(
205+
dateKey = dateKey,
206+
routineId = routineId,
207+
completionInfo = RoutineCompletionInfo(routineId, routineCompleteYn = true, subRoutineCompleteYn = emptyList()),
208+
)
209+
210+
advanceTimeBy(1200L) // debounce + 재시도 여유 시간
211+
212+
assertEquals(2, remoteDataSource.syncCount.get()) // 1차 실패 + 2차 성공
213+
assertEquals(false, syncErrorEmitted) // 에러 다이얼로그 없음
214+
assertEquals(0, remoteDataSource.fetchCount.get()) // 롤백 fetch 없음
215+
216+
job.cancel()
217+
}
218+
190219
// --- Helpers ---
191220

192221
private fun setupCacheWithRoutine(isCompleted: Boolean): Pair<String, String> =
@@ -225,6 +254,7 @@ class RoutineRepositoryImplTest {
225254
var scheduleResponse: Result<RoutineScheduleResponse> = Result.success(RoutineScheduleResponse(emptyMap()))
226255
var syncResult: Result<Unit> = Result.success(Unit)
227256
var deleteResult: Result<Unit> = Result.success(Unit)
257+
var syncFailCount: Int = 0
228258
val fetchCount = AtomicInteger(0)
229259
val syncCount = AtomicInteger(0)
230260

@@ -234,8 +264,12 @@ class RoutineRepositoryImplTest {
234264
}
235265

236266
override suspend fun syncRoutineCompletion(routineCompletionRequest: RoutineCompletionRequest): Result<Unit> {
237-
syncCount.incrementAndGet()
238-
return syncResult
267+
val attempt = syncCount.incrementAndGet()
268+
return if (attempt <= syncFailCount) {
269+
Result.failure(Exception("네트워크 오류"))
270+
} else {
271+
syncResult
272+
}
239273
}
240274

241275
override suspend fun getRoutine(routineId: String): Result<com.threegap.bitnagil.data.routine.model.response.RoutineResponse> =

0 commit comments

Comments
 (0)