Addresses the two test gaps flagged in PR #54's review (mutation-verified in the ticket).
1. Attributes -> specialUse wiring now has coverage
The one production link between a server LIST response and the folder feature was never exercised with meaningful values:
FetchedFolder.toEntity deriving role (via FolderRole.roleOf) and specialUse (via FolderRole.isServerSpecial) from IMAP attributes (Mappers.kt), and
FolderEntity.toDomain's specialUse pass-through.
Every listFolders stub returned emptyList(), and other suites hand-set specialUse on their own layer, so deleting the specialUse assignment compiled and silently persisted a non-special folder for every folder.
New FolderMapperTest pins each RFC 6154 attribute to its expected (role, specialUse) through FetchedFolder.toEntity: \Sent/\Drafts/\Junk/\Trash/\Archive both classify the role and mark the folder special; \All/\Flagged mark it special but drive no role of their own; non-special / structural flags stay unmarked; and toDomain carries the flag back out.
New MailRepositoryImplTest.refreshFolders case stubs imapClient.listFolders with a \Drafts special folder plus an attribute-less user folder, slot-captures folderDao.replaceForAccount, and asserts persisted specialUse == [true, false] (and roles).
Extended observeFolders test asserts the toDomain special-use leg.
2. FolderLabelsTest fidelity claim corrected
baseLabelsOf's doc comment claimed it builds labels "the way the drawer does", but it is a hand-copied literal stand-in for folderDisplayLabel (which is @Composable and can't run in a JVM test). Reworded to state it is an independent literal fixture that pins the de-duplication logic, not the role-to-wording mapping. FolderDrawerTest now gives ARCHIVE a server name (All Mail) that differs from its friendly label so it can actually discriminate role-to-label drift.
Notes
The mapping itself was correct, only uncovered -- no production code changed. The attribute-to-role table refactor is out of scope (issue #65).
Fast CI gate green locally (JDK 21): assembleDebug, testDebugUnitTest, lintDebug, ktlintCheck, detekt, and compileDebugAndroidTestKotlin all pass. New tests: FolderMapperTest 6/6; MailRepositoryImplTest 24/24.
Closes #64.
Addresses the two test gaps flagged in PR #54's review (mutation-verified in the ticket).
## 1. Attributes -> specialUse wiring now has coverage
The one production link between a server LIST response and the folder feature was never exercised with meaningful values:
- `FetchedFolder.toEntity` deriving `role` (via `FolderRole.roleOf`) and `specialUse` (via `FolderRole.isServerSpecial`) from IMAP attributes (`Mappers.kt`), and
- `FolderEntity.toDomain`'s `specialUse` pass-through.
Every `listFolders` stub returned `emptyList()`, and other suites hand-set `specialUse` on their own layer, so deleting the `specialUse` assignment compiled and silently persisted a non-special folder for every folder.
- **New `FolderMapperTest`** pins each RFC 6154 attribute to its expected `(role, specialUse)` through `FetchedFolder.toEntity`: `\Sent`/`\Drafts`/`\Junk`/`\Trash`/`\Archive` both classify the role and mark the folder special; `\All`/`\Flagged` mark it special but drive no role of their own; non-special / structural flags stay unmarked; and `toDomain` carries the flag back out.
- **New `MailRepositoryImplTest.refreshFolders` case** stubs `imapClient.listFolders` with a `\Drafts` special folder plus an attribute-less user folder, slot-captures `folderDao.replaceForAccount`, and asserts persisted `specialUse == [true, false]` (and roles).
- **Extended `observeFolders` test** asserts the `toDomain` special-use leg.
## 2. FolderLabelsTest fidelity claim corrected
`baseLabelsOf`'s doc comment claimed it builds labels "the way the drawer does", but it is a hand-copied literal stand-in for `folderDisplayLabel` (which is `@Composable` and can't run in a JVM test). Reworded to state it is an independent literal fixture that pins the de-duplication logic, not the role-to-wording mapping. `FolderDrawerTest` now gives ARCHIVE a server name (`All Mail`) that differs from its friendly label so it can actually discriminate role-to-label drift.
## Notes
- The mapping itself was correct, only uncovered -- **no production code changed**. The attribute-to-role table refactor is out of scope (issue #65).
- Fast CI gate green locally (JDK 21): `assembleDebug`, `testDebugUnitTest`, `lintDebug`, `ktlintCheck`, `detekt`, and `compileDebugAndroidTestKotlin` all pass. New tests: FolderMapperTest 6/6; MailRepositoryImplTest 24/24.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #64.
Addresses the two test gaps flagged in PR #54's review (mutation-verified in the ticket).
1. Attributes -> specialUse wiring now has coverage
The one production link between a server LIST response and the folder feature was never exercised with meaningful values:
FetchedFolder.toEntityderivingrole(viaFolderRole.roleOf) andspecialUse(viaFolderRole.isServerSpecial) from IMAP attributes (Mappers.kt), andFolderEntity.toDomain'sspecialUsepass-through.Every
listFoldersstub returnedemptyList(), and other suites hand-setspecialUseon their own layer, so deleting thespecialUseassignment compiled and silently persisted a non-special folder for every folder.FolderMapperTestpins each RFC 6154 attribute to its expected(role, specialUse)throughFetchedFolder.toEntity:\Sent/\Drafts/\Junk/\Trash/\Archiveboth classify the role and mark the folder special;\All/\Flaggedmark it special but drive no role of their own; non-special / structural flags stay unmarked; andtoDomaincarries the flag back out.MailRepositoryImplTest.refreshFolderscase stubsimapClient.listFolderswith a\Draftsspecial folder plus an attribute-less user folder, slot-capturesfolderDao.replaceForAccount, and asserts persistedspecialUse == [true, false](and roles).observeFolderstest asserts thetoDomainspecial-use leg.2. FolderLabelsTest fidelity claim corrected
baseLabelsOf's doc comment claimed it builds labels "the way the drawer does", but it is a hand-copied literal stand-in forfolderDisplayLabel(which is@Composableand can't run in a JVM test). Reworded to state it is an independent literal fixture that pins the de-duplication logic, not the role-to-wording mapping.FolderDrawerTestnow gives ARCHIVE a server name (All Mail) that differs from its friendly label so it can actually discriminate role-to-label drift.Notes
assembleDebug,testDebugUnitTest,lintDebug,ktlintCheck,detekt, andcompileDebugAndroidTestKotlinall pass. New tests: FolderMapperTest 6/6; MailRepositoryImplTest 24/24.🤖 Generated with Claude Code