fix: make the server pace label say what it counts

The tile said "Pace (other devices)", but the pace comes from every
sitting the server holds, which includes the ones this phone uploaded.
What it leaves out is reading captured here that has not been sent. It
now reads "Pace (synced reading)".

The test that checked a headline reports no pace when the snapshot has
none had been renamed into the new server-only case rather than kept
beside it, so nothing covered the absent pace any more. It is back, and
also asserts the headline makes no server-only claim.

A test added alongside the pace work passed reading sessions straight to
a function that takes spans, so the unit tests did not compile.
This commit is contained in:
Chmouel Boudjnah 2026-09-14 16:59:15 +02:00
parent ed27ea5b51
commit 41008c22be
3 changed files with 25 additions and 2 deletions

View file

@ -791,7 +791,7 @@
<string name="reading_stats_by_year">Year by year</string>
<string name="reading_stats_calendar">Day by day</string>
<string name="reading_stats_pace">Pace</string>
<string name="reading_stats_pace_server_only">Pace (other devices)</string>
<string name="reading_stats_pace_server_only">Pace (synced reading)</string>
<string name="reading_stats_pace_value">%1$d%%/h</string>
<string name="reading_stats_book_sessions">Read in %1$d sittings</string>
<string name="reading_stats_book_sessions_one">Read in one sitting</string>

View file

@ -589,7 +589,17 @@ class LiseurSyncSnapshotsTest {
read()
assertEquals(1, requests.single().getJSONArray("candidates").length())
val local = readingStats(
db.readingSessionDao().allOnce(),
db.readingSessionDao().allOnce().map {
SessionSpan(
bookUrl = it.bookUrl,
startedAt = it.startedAt,
durationMs = it.durationMs,
lastReadAt = it.endedAt ?: it.lastCheckpointAt,
uploaded = it.uploadedAt != null,
startProgression = it.startProgression,
endProgression = it.endProgression,
)
},
mapOf("book" to StatsBook("book", "Book", null, 0.2, false)),
zone, today, StatsRange.THIS_MONTH,
)

View file

@ -98,6 +98,19 @@ class StatsSnapshotUnionTest {
assertEquals(true, result.headline.serverOnlyPace)
}
@Test
fun `combined headline omits pace the snapshot cannot supply`() {
val local = readingStats(
listOf(SessionSpan("book", at, 20 * 60_000, at, uploaded = false)),
books, zone, today,
)
// snapshot() leaves progressionPerHour null, which is a server
// that counted no progression rather than one that paced at zero.
val result = uniteSnapshot(local, books, emptyMap(), snapshot(overlapMinutes = 0.0))!!
assertNull(result.headline.progressionPerHour)
assertEquals(false, result.headline.serverOnlyPace)
}
@Test
fun `merged totals count each closed session once`() {
val local = readingStats(