Skip to content

Commit 5ed018e

Browse files
Merge pull request #75 from kirill-markin/codex/progress-review-schedule
Add cross-platform review-schedule progress
2 parents 6e5b01f + 630b57f commit 5ed018e

120 files changed

Lines changed: 11915 additions & 187 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/android/app/src/androidTest/java/com/flashcardsopensourceapp/app/RepositorySeedExecutor.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,11 @@ internal class RepositorySeedExecutor(
165165
cardId = cardId,
166166
tags = seedCard.tags
167167
)
168-
appGraph.syncLocalStore.enqueueCardUpsert(card = card, tags = resolvedTags)
168+
appGraph.syncLocalStore.enqueueCardUpsert(
169+
card = card,
170+
tags = resolvedTags,
171+
affectsReviewSchedule = true
172+
)
169173
resolvedTags
170174
}
171175
return RepositorySeededCard(

apps/android/app/src/main/java/com/flashcardsopensourceapp/app/ProgressContextRefreshController.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ class ProgressContextRefreshController(
6060
error = error
6161
)
6262
}
63+
64+
try {
65+
progressRepository.refreshReviewScheduleIfInvalidated()
66+
} catch (error: CancellationException) {
67+
throw error
68+
} catch (error: Exception) {
69+
logProgressContextRefreshFailure(
70+
message = "Failed to refresh invalidated progress review schedule.",
71+
error = error
72+
)
73+
}
6374
}
6475
}
6576
}

apps/android/app/src/test/java/com/flashcardsopensourceapp/app/ProgressContextRefreshControllerTest.kt

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.flashcardsopensourceapp.app
22

33
import com.flashcardsopensourceapp.core.ui.VisibleAppScreen
4+
import com.flashcardsopensourceapp.data.local.model.ProgressReviewScheduleSnapshot
45
import com.flashcardsopensourceapp.data.local.model.ProgressSeriesSnapshot
56
import com.flashcardsopensourceapp.data.local.model.ProgressSummarySnapshot
67
import com.flashcardsopensourceapp.data.local.repository.ProgressRepository
@@ -36,10 +37,11 @@ class ProgressContextRefreshControllerTest {
3637

3738
assertEquals(1, repository.summaryRefreshCallCount)
3839
assertEquals(0, repository.seriesRefreshCallCount)
40+
assertEquals(0, repository.reviewScheduleRefreshCallCount)
3941
}
4042

4143
@Test
42-
fun refreshIfInvalidatedRefreshesSummaryAndSeriesOnProgressScreen() = runBlocking {
44+
fun refreshIfInvalidatedRefreshesAllProgressSectionsOnProgressScreen() = runBlocking {
4345
val repository = FakeProgressRepository()
4446
val appScope = CoroutineScope(context = Dispatchers.Default)
4547
val controller = ProgressContextRefreshController(
@@ -52,14 +54,16 @@ class ProgressContextRefreshControllerTest {
5254

5355
awaitUntil {
5456
repository.summaryRefreshCallCount == 1 &&
55-
repository.seriesRefreshCallCount == 1
57+
repository.seriesRefreshCallCount == 1 &&
58+
repository.reviewScheduleRefreshCallCount == 1
5659
}
5760
} finally {
5861
appScope.cancel()
5962
}
6063

6164
assertEquals(1, repository.summaryRefreshCallCount)
6265
assertEquals(1, repository.seriesRefreshCallCount)
66+
assertEquals(1, repository.reviewScheduleRefreshCallCount)
6367
}
6468

6569
@Test
@@ -81,19 +85,22 @@ class ProgressContextRefreshControllerTest {
8185

8286
assertEquals(1, repository.summaryRefreshCallCount)
8387
assertEquals(0, repository.seriesRefreshCallCount)
88+
assertEquals(0, repository.reviewScheduleRefreshCallCount)
8489

8590
repository.releaseFirstSummaryRefresh()
8691

8792
awaitUntil {
8893
repository.summaryRefreshCallCount == 2 &&
89-
repository.seriesRefreshCallCount == 0
94+
repository.seriesRefreshCallCount == 0 &&
95+
repository.reviewScheduleRefreshCallCount == 0
9096
}
9197
} finally {
9298
appScope.cancel()
9399
}
94100

95101
assertEquals(2, repository.summaryRefreshCallCount)
96102
assertEquals(0, repository.seriesRefreshCallCount)
103+
assertEquals(0, repository.reviewScheduleRefreshCallCount)
97104
}
98105

99106
@Test
@@ -109,20 +116,23 @@ class ProgressContextRefreshControllerTest {
109116
controller.refreshIfInvalidated(visibleScreen = VisibleAppScreen.PROGRESS)
110117
awaitUntil {
111118
repository.summaryRefreshCallCount == 1 &&
112-
repository.seriesRefreshCallCount == 1
119+
repository.seriesRefreshCallCount == 1 &&
120+
repository.reviewScheduleRefreshCallCount == 1
113121
}
114122

115123
controller.refreshIfInvalidated(visibleScreen = VisibleAppScreen.PROGRESS)
116124
awaitUntil {
117125
repository.summaryRefreshCallCount == 2 &&
118-
repository.seriesRefreshCallCount == 2
126+
repository.seriesRefreshCallCount == 2 &&
127+
repository.reviewScheduleRefreshCallCount == 2
119128
}
120129
} finally {
121130
appScope.cancel()
122131
}
123132

124133
assertEquals(2, repository.summaryRefreshCallCount)
125134
assertEquals(2, repository.seriesRefreshCallCount)
135+
assertEquals(2, repository.reviewScheduleRefreshCallCount)
126136
}
127137
}
128138

@@ -138,6 +148,9 @@ private class FakeProgressRepository(
138148
@Volatile
139149
var seriesRefreshCallCount: Int = 0
140150

151+
@Volatile
152+
var reviewScheduleRefreshCallCount: Int = 0
153+
141154
override fun observeSummarySnapshot(): Flow<ProgressSummarySnapshot?> {
142155
return emptyFlow()
143156
}
@@ -146,6 +159,10 @@ private class FakeProgressRepository(
146159
return emptyFlow()
147160
}
148161

162+
override fun observeReviewScheduleSnapshot(): Flow<ProgressReviewScheduleSnapshot?> {
163+
return emptyFlow()
164+
}
165+
149166
override suspend fun refreshSummaryIfInvalidated() {
150167
summaryRefreshCallCount += 1
151168
if (failFirstSummaryRefresh && summaryRefreshCallCount == 1) {
@@ -160,6 +177,10 @@ private class FakeProgressRepository(
160177
seriesRefreshCallCount += 1
161178
}
162179

180+
override suspend fun refreshReviewScheduleIfInvalidated() {
181+
reviewScheduleRefreshCallCount += 1
182+
}
183+
163184
override suspend fun refreshSummaryManually() {
164185
throw UnsupportedOperationException("Not used in ProgressContextRefreshControllerTest.")
165186
}
@@ -168,6 +189,10 @@ private class FakeProgressRepository(
168189
throw UnsupportedOperationException("Not used in ProgressContextRefreshControllerTest.")
169190
}
170191

192+
override suspend fun refreshReviewScheduleManually() {
193+
throw UnsupportedOperationException("Not used in ProgressContextRefreshControllerTest.")
194+
}
195+
171196
fun releaseFirstSummaryRefresh() {
172197
releaseFirstSummaryRefreshSignal.complete(value = Unit)
173198
}

0 commit comments

Comments
 (0)