test: isolate ConversationStore default storage from .standard

The ~48 no-arg `ConversationStore()` call sites in the test target run in
the real app host and wrote `conversation.lastActive` into `.standard`,
polluting the developer's actual app state and letting back-to-back local
runs see each other's persisted selection.

Point the init default at a new `defaultStorage` static that returns
`.standard` in production but a wiped ephemeral `UserDefaults(suiteName:)`
under test, mirroring the existing `ChatViewModel.defaultReadReceiptsDefaults`
idiom. Production behavior is unchanged (still `.standard`); no call sites
change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ecgang 2026-07-06 10:18:38 -07:00
parent c01be3b359
commit 7db98c4d40

View File

@ -376,7 +376,21 @@ final class ConversationStore: ObservableObject {
case deferToChannelRestore
}
init(storage: UserDefaults = .standard) {
/// Default persistence store for the last-active conversation. Production
/// uses `.standard`. Under test, a dedicated scratch suite is used instead
/// wiped at first use per process so the ~48 no-arg `ConversationStore()`
/// tests never pollute the real app's `.standard` `conversation.lastActive`
/// and back-to-back local runs never see each other's persisted selection.
/// Mirrors `ChatViewModel.defaultReadReceiptsDefaults`.
static let defaultStorage: UserDefaults = {
guard TestEnvironment.isRunningTests else { return .standard }
let suiteName = "chat.bitchat.tests.conversationStore"
guard let scratch = UserDefaults(suiteName: suiteName) else { return .standard }
scratch.removePersistentDomain(forName: suiteName)
return scratch
}()
init(storage: UserDefaults = ConversationStore.defaultStorage) {
self.storage = storage
if let data = storage.data(forKey: lastActiveKey),
let record = try? JSONDecoder().decode(LastActiveRecord.self, from: data) {