From 64d89d1e2ab38f17fceeb854a6d181398cfb612c Mon Sep 17 00:00:00 2001 From: Jason Ross Date: Fri, 3 Jul 2026 20:24:25 -0500 Subject: [PATCH] fix(accounts): break AccountDao sortOrder ties by email MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AccountDaoTest (added by #270's coverage lane) asserts email ordering, but AccountDao.observeAll()/getAll() now order by the user-defined sortOrder (#164) with no tiebreaker. Two accounts inserted via plain upsert() both land on the default sortOrder (0), so they came back in rowid/insertion order instead — failing the test deterministically on CI (API 30 & 31): expected [ada, zed], got [zed, ada]. Add `email` as a secondary ORDER BY key. Real accounts always get distinct sortOrders via insertAtEnd()/reorder(), so drag order is untouched; only equal-sortOrder rows now fall back to a stable, deterministic email order. This also matches the "rank by email" convention already used to seed sortOrder in ACCOUNT_MIGRATION_1_2 and AccountDataMigrator.copyAccountTables, so the existing coverage test passes unchanged. No schema/migration change is needed since this only edits a @Query string, not the entity. Co-Authored-By: Claude Opus 4.8 --- .../kotlin/org/libremail/data/local/dao/AccountDao.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/org/libremail/data/local/dao/AccountDao.kt b/app/src/main/kotlin/org/libremail/data/local/dao/AccountDao.kt index af87c1b..dba0662 100644 --- a/app/src/main/kotlin/org/libremail/data/local/dao/AccountDao.kt +++ b/app/src/main/kotlin/org/libremail/data/local/dao/AccountDao.kt @@ -11,10 +11,17 @@ import org.libremail.data.local.entity.AccountEntity @Dao interface AccountDao { - @Query("SELECT * FROM accounts ORDER BY sortOrder") + /** + * Every listing surface (Settings, the drawer switcher, the unified-inbox filter chips) follows + * the user-defined [AccountEntity.sortOrder] (issue #164); `email` is only a tiebreaker for rows + * that share a sortOrder (e.g. inserted via plain [upsert] rather than [insertAtEnd]/[reorder]), + * so equal-sortOrder accounts still list in a stable, deterministic order. + */ + @Query("SELECT * FROM accounts ORDER BY sortOrder, email") fun observeAll(): Flow> - @Query("SELECT * FROM accounts ORDER BY sortOrder") + /** See [observeAll] — same ordering: sortOrder, then email as a tiebreaker. */ + @Query("SELECT * FROM accounts ORDER BY sortOrder, email") suspend fun getAll(): List @Query("SELECT * FROM accounts WHERE id = :id LIMIT 1")