mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Initial implementation of AccountSettings. (#6275)
* Make the UserPreference macro also generate an accessor for the key name. * Initial implementation of AccountSettings. - Add an AccountUserDefaults storage with a userID prefix on the key. - Migrate the 2 values reset by AppSettings.resetSessionSpecificSettings to AccountSettings. * Rename UserSettings.volatile() to UserSettings.mock() Given it now has a userID parameter with a default value..
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
@testable import ElementX
|
||||
import Testing
|
||||
|
||||
struct AccountUserDefaultsTests {
|
||||
private let store = VolatileUserDefaults()
|
||||
private let aliceDefaults: AccountUserDefaults
|
||||
private let bobDefaults: AccountUserDefaults
|
||||
|
||||
init() {
|
||||
aliceDefaults = AccountUserDefaults(userID: "@alice:example.com", store: store)
|
||||
bobDefaults = AccountUserDefaults(userID: "@bob:example.com", store: store)
|
||||
}
|
||||
|
||||
@Test
|
||||
func dictionaryRepresentation() {
|
||||
// Given a store containing values for Alice, Bob and the app, all sharing a key.
|
||||
aliceDefaults.set("one", forKey: "first")
|
||||
aliceDefaults.set(2, forKey: "second")
|
||||
bobDefaults.set("bob", forKey: "first")
|
||||
store.set("global", forKey: "first")
|
||||
#expect(aliceDefaults.object(forKey: "first") as? String == "one")
|
||||
#expect(aliceDefaults.object(forKey: "second") as? Int == 2)
|
||||
#expect(bobDefaults.object(forKey: "first") as? String == "bob")
|
||||
#expect(store.object(forKey: "first") as? String == "global")
|
||||
|
||||
// When getting the dictionary representation of Alice's defaults.
|
||||
let representation = aliceDefaults.dictionaryRepresentation()
|
||||
|
||||
// Then it should only contain Alice's values.
|
||||
#expect(representation.count == 2)
|
||||
#expect(representation["first"] as? String == "one")
|
||||
#expect(representation["second"] as? Int == 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
func reset() {
|
||||
// Given a store containing values for Alice, Bob and the app, all sharing a key.
|
||||
aliceDefaults.set("one", forKey: "first")
|
||||
aliceDefaults.set(2, forKey: "second")
|
||||
bobDefaults.set("bob", forKey: "first")
|
||||
store.set("global", forKey: "first")
|
||||
#expect(aliceDefaults.object(forKey: "first") as? String == "one")
|
||||
#expect(aliceDefaults.object(forKey: "second") as? Int == 2)
|
||||
#expect(bobDefaults.object(forKey: "first") as? String == "bob")
|
||||
#expect(store.object(forKey: "first") as? String == "global")
|
||||
|
||||
// When resetting Alice's defaults.
|
||||
aliceDefaults.reset()
|
||||
|
||||
// Then only Alice's values should be removed.
|
||||
#expect(aliceDefaults.object(forKey: "first") == nil)
|
||||
#expect(aliceDefaults.object(forKey: "second") == nil)
|
||||
#expect(bobDefaults.object(forKey: "first") as? String == "bob")
|
||||
#expect(store.object(forKey: "first") as? String == "global")
|
||||
}
|
||||
|
||||
@Test
|
||||
func migrateAppSettingsValue() {
|
||||
// Given a store containing an app value.
|
||||
store.set("global", forKey: "first")
|
||||
#expect(store.object(forKey: "first") as? String == "global")
|
||||
#expect(aliceDefaults.object(forKey: "first") == nil)
|
||||
#expect(bobDefaults.object(forKey: "first") == nil)
|
||||
|
||||
// When migrating that value into Alice's defaults.
|
||||
aliceDefaults.migrateAppSettingsValue(forKey: "first")
|
||||
|
||||
// Then the value should be moved to Alice's defaults only.
|
||||
#expect(aliceDefaults.object(forKey: "first") as? String == "global")
|
||||
#expect(store.object(forKey: "first") == nil)
|
||||
#expect(bobDefaults.object(forKey: "first") == nil)
|
||||
}
|
||||
|
||||
@Test
|
||||
func migrateUnsetAppSettingsValue() {
|
||||
// Given an empty store.
|
||||
#expect(store.storage.isEmpty)
|
||||
|
||||
// When migrating a value that isn't set into Alice's defaults.
|
||||
aliceDefaults.migrateAppSettingsValue(forKey: "first")
|
||||
|
||||
// Then nothing should be written to the store.
|
||||
#expect(aliceDefaults.object(forKey: "first") == nil)
|
||||
#expect(store.storage.isEmpty)
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ final class AnalyticsSettingsScreenViewModelTests {
|
||||
client.isRunning = false
|
||||
analytics = AnalyticsService(client: client, appSettings: appSettings)
|
||||
|
||||
viewModel = AnalyticsSettingsScreenViewModel(userSettings: UserSettings(appSettings: appSettings, accountSettings: .init()),
|
||||
viewModel = AnalyticsSettingsScreenViewModel(userSettings: appSettings.userSettings(for: "@me:matrix.org"),
|
||||
analytics: analytics)
|
||||
context = viewModel.context
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ final class BugReportServiceTests {
|
||||
var bugReportService: BugReportServiceProtocol!
|
||||
|
||||
init() throws {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
userSettings.bugReportRageshakeURL.reset()
|
||||
|
||||
let bugReportServiceMock = BugReportServiceMock()
|
||||
|
||||
@@ -29,7 +29,7 @@ struct ChatsTabFlowCoordinatorTests {
|
||||
}
|
||||
|
||||
init() async throws {
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
clientProxy = ClientProxyMock(.init(userID: "hi@bob", roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms)))))
|
||||
timelineControllerFactory = TimelineControllerFactoryMock(.init())
|
||||
|
||||
@@ -84,7 +84,7 @@ final class ComposerToolbarViewModelTests {
|
||||
.init(suggestionType: .user(.init(id: "@user_mention_2:matrix.org", displayName: "User 2", avatarURL: nil)), range: .init(), rawSuggestionText: "")]
|
||||
let mockCompletionSuggestionService = CompletionSuggestionServiceMock(configuration: .init(suggestions: suggestions))
|
||||
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
viewModel = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()),
|
||||
wysiwygViewModel: wysiwygViewModel,
|
||||
@@ -803,7 +803,7 @@ final class ComposerToolbarViewModelTests {
|
||||
let mockSubject = CurrentValueSubject<[IdentityStatusChange], Never>([])
|
||||
roomProxyMock.identityStatusChangesPublisher = mockSubject.asCurrentValuePublisher()
|
||||
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
viewModel = ComposerToolbarViewModel(roomProxy: roomProxyMock,
|
||||
wysiwygViewModel: wysiwygViewModel,
|
||||
@@ -846,7 +846,7 @@ final class ComposerToolbarViewModelTests {
|
||||
|
||||
roomProxyMock.identityStatusChangesPublisher = mockSubject.asCurrentValuePublisher()
|
||||
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
viewModel = ComposerToolbarViewModel(roomProxy: roomProxyMock,
|
||||
wysiwygViewModel: wysiwygViewModel,
|
||||
@@ -886,7 +886,7 @@ final class ComposerToolbarViewModelTests {
|
||||
}
|
||||
|
||||
roomProxyMock.identityStatusChangesPublisher = CurrentValueSubject([IdentityStatusChange(userId: "@alice:localhost", changedTo: .pinViolation)]).asCurrentValuePublisher()
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
viewModel = ComposerToolbarViewModel(roomProxy: roomProxyMock,
|
||||
wysiwygViewModel: wysiwygViewModel,
|
||||
@@ -923,7 +923,7 @@ final class ComposerToolbarViewModelTests {
|
||||
draftServiceMock.loadDraftClosure = loadDraftClosure
|
||||
}
|
||||
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
viewModel = ComposerToolbarViewModel(initialText: initialText,
|
||||
roomProxy: JoinedRoomProxyMock(.init()),
|
||||
|
||||
@@ -24,7 +24,7 @@ final class CreateRoomScreenViewModelTests {
|
||||
}
|
||||
|
||||
init() {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
}
|
||||
|
||||
isolated deinit {
|
||||
|
||||
@@ -55,7 +55,7 @@ struct EmojiPickerScreenViewModelTests {
|
||||
emojiPickerStream = stream
|
||||
|
||||
viewModel = EmojiPickerScreenViewModel(selectedEmojis: selectedEmojis,
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
continuation: continuation)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ struct EmojiProviderTests {
|
||||
let emojiLoaderMock = EmojiLoaderMock()
|
||||
emojiLoaderMock.categories = [category]
|
||||
|
||||
let emojiProvider = EmojiProvider(loader: emojiLoaderMock, userSettings: .volatile())
|
||||
let emojiProvider = EmojiProvider(loader: emojiLoaderMock, userSettings: .mock())
|
||||
|
||||
let categories = await emojiProvider.categories()
|
||||
#expect(emojiLoaderMock.categories == categories)
|
||||
@@ -33,7 +33,7 @@ struct EmojiProviderTests {
|
||||
let emojiLoaderMock = EmojiLoaderMock()
|
||||
emojiLoaderMock.categories = [category]
|
||||
|
||||
let emojiProvider = EmojiProvider(loader: emojiLoaderMock, userSettings: .volatile())
|
||||
let emojiProvider = EmojiProvider(loader: emojiLoaderMock, userSettings: .mock())
|
||||
|
||||
let categories = await emojiProvider.categories(searchString: "")
|
||||
#expect(emojiLoaderMock.categories == categories)
|
||||
@@ -51,7 +51,7 @@ struct EmojiProviderTests {
|
||||
let emojiLoaderMock = EmojiLoaderMock()
|
||||
emojiLoaderMock.categories = categoriesForFirstLoad
|
||||
|
||||
let emojiProvider = EmojiProvider(loader: emojiLoaderMock, userSettings: .volatile())
|
||||
let emojiProvider = EmojiProvider(loader: emojiLoaderMock, userSettings: .mock())
|
||||
|
||||
_ = await emojiProvider.categories()
|
||||
emojiLoaderMock.categories = categoriesForSecondLoad
|
||||
@@ -82,7 +82,7 @@ struct EmojiProviderTests {
|
||||
let emojiLoaderMock = EmojiLoaderMock()
|
||||
emojiLoaderMock.categories = categories
|
||||
|
||||
let emojiProvider = EmojiProvider(loader: emojiLoaderMock, userSettings: .volatile())
|
||||
let emojiProvider = EmojiProvider(loader: emojiLoaderMock, userSettings: .mock())
|
||||
|
||||
_ = await emojiProvider.categories()
|
||||
let result = await emojiProvider.categories(searchString: searchString)
|
||||
|
||||
@@ -25,7 +25,7 @@ final class HomeScreenViewModelTests {
|
||||
var cancellables = Set<AnyCancellable>()
|
||||
|
||||
init() {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -109,7 +109,7 @@ struct IdentityConfirmationScreenViewModelTests {
|
||||
userSession.sessionSecurityStatePublisher = securityStateSubject.asCurrentValuePublisher()
|
||||
|
||||
viewModel = IdentityConfirmationScreenViewModel(userSession: userSession,
|
||||
userSettings: .volatile(),
|
||||
userSettings: .mock(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ final class JoinRoomScreenViewModelTests {
|
||||
private let userSettings: UserSettings
|
||||
|
||||
init() {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
}
|
||||
|
||||
isolated deinit {
|
||||
|
||||
@@ -228,7 +228,7 @@ final class LiveLocationManagerTests {
|
||||
}
|
||||
|
||||
private func setUp(accuracyAuthorization: CLAccuracyAuthorization = .fullAccuracy) {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
clientProxy = ClientProxyMock(.init())
|
||||
beaconInfoSubject = PassthroughSubject<LiveLocationOwnInfoUpdate, Never>()
|
||||
clientProxy.liveLocationOwnInfoUpdatesPublisher = beaconInfoSubject.eraseToAnyPublisher()
|
||||
|
||||
@@ -417,7 +417,7 @@ struct LocationSharingScreenViewModelTests {
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(members: .allMembers))
|
||||
roomProxyMock.makeLiveLocationServiceReturnValue = liveLocationServiceMock
|
||||
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
viewModel = LocationSharingScreenViewModel(interactionMode: .viewLive(sender: nil, initialLiveLocationShare: nil),
|
||||
mapURLBuilder: userSettings.mapTilerConfiguration.publisher.value,
|
||||
@@ -630,7 +630,7 @@ struct LocationSharingScreenViewModelTests {
|
||||
|
||||
private mutating func setupViewModel(liveLocationManagerMock: LiveLocationManagerMock,
|
||||
members: [RoomMemberProxyMock] = .allMembersAsAdmin) {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
timelineProxy = TimelineProxyMock(.init())
|
||||
viewModel = LocationSharingScreenViewModel(interactionMode: .picker(shouldShowLiveLocationOption: true),
|
||||
mapURLBuilder: userSettings.mapTilerConfiguration.publisher.value,
|
||||
@@ -649,7 +649,7 @@ struct LocationSharingScreenViewModelTests {
|
||||
liveLocationsSubject: CurrentValueSubject<[LiveLocationShare], Never>,
|
||||
members: [RoomMemberProxyMock] = .allMembers,
|
||||
isSharingLiveLocationFromThisDevice: Bool = false) {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
if isSharingLiveLocationFromThisDevice {
|
||||
userSettings.liveLocationSharingSessionsByRoomID[Self.roomID] = .init(eventID: "$event:matrix.org", expirationDate: .distantFuture)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ final class MediaUploadPreviewScreenViewModelTests {
|
||||
}
|
||||
|
||||
init() {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
userSettings.optimizeMediaUploads = false
|
||||
|
||||
userIndicatorController = UserIndicatorControllerMock()
|
||||
|
||||
@@ -17,7 +17,7 @@ final class MediaUploadingPreprocessorTests {
|
||||
var mediaUploadingPreprocessor: MediaUploadingPreprocessor!
|
||||
|
||||
init() {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
userSettings.optimizeMediaUploads = false
|
||||
mediaUploadingPreprocessor = MediaUploadingPreprocessor(userSettings: userSettings)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ struct NotificationSettingsScreenViewModelTests {
|
||||
init() throws {
|
||||
userNotificationCenter = UserNotificationCenterMock()
|
||||
userNotificationCenter.authorizationStatusReturnValue = .authorized
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
notificationSettingsProxy = NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())
|
||||
notificationSettingsProxy.getDefaultRoomNotificationModeIsEncryptedIsOneToOneReturnValue = .allMessages
|
||||
notificationSettingsProxy.isRoomMentionEnabledReturnValue = true
|
||||
|
||||
@@ -18,7 +18,7 @@ struct NotificationToneManagerTests {
|
||||
private let manager: NotificationToneManager
|
||||
|
||||
init() {
|
||||
manager = NotificationToneManager(userSettings: .volatile())
|
||||
manager = NotificationToneManager(userSettings: .mock())
|
||||
}
|
||||
|
||||
// MARK: - Deletion
|
||||
|
||||
@@ -28,7 +28,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .user(userID: id), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -60,7 +60,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .user(userID: id), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -84,7 +84,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .allUsers, font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -108,7 +108,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomID("1"), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -131,7 +131,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomID("1"), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -158,7 +158,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomAlias("#foundation-and-empire:matrix.org"), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -181,7 +181,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .roomAlias("#foundation-and-empire:matrix.org"), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -206,7 +206,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomID("1")), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -229,7 +229,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomID("1")), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -256,7 +256,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomAlias("#foundation-and-empire:matrix.org")), font: .preferredFont(forTextStyle: .body)))
|
||||
@@ -279,7 +279,7 @@ struct PillContextTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
let context = PillContext(timelineContext: mock.context, data: PillTextAttachmentData(type: .event(room: .roomAlias("#foundation-and-empire:matrix.org")), font: .preferredFont(forTextStyle: .body)))
|
||||
|
||||
@@ -21,7 +21,7 @@ struct PresenceServiceTests {
|
||||
|
||||
init() {
|
||||
clientProxy = ClientProxyMock(.init())
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
notificationCenter = NotificationCenter()
|
||||
|
||||
clientProxy.configurePresenceSendImmediatelyClosure = { [sendsSubject] presence, sendImmediately in
|
||||
|
||||
@@ -167,7 +167,7 @@ struct RoomDetailsEditScreenViewModelTests {
|
||||
userIndicatorController = UserIndicatorControllerMock()
|
||||
viewModel = .init(roomProxy: JoinedRoomProxyMock(roomProxyConfiguration),
|
||||
userSession: UserSessionMock(.init()),
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(userSettings: .volatile()),
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(userSettings: .mock()),
|
||||
userIndicatorController: userIndicatorController)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
notificationSettingsProxyMock = NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -44,7 +44,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", members: mockedMembers, joinRule: .public))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -65,7 +65,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -87,7 +87,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -146,7 +146,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -168,7 +168,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -201,7 +201,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -233,7 +233,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -266,7 +266,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: true, isEncrypted: true, members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -300,7 +300,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
powerLevelsConfiguration: .init(canUserInvite: false)))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -318,7 +318,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", members: mockedMembers, joinRule: .public))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -367,7 +367,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -403,7 +403,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -439,7 +439,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -460,7 +460,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: false, members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -481,7 +481,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: true, members: mockedMembers))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -500,7 +500,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedIsOneToOneThrowableError = NotificationSettingsError.Generic(msg: "error")
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -709,7 +709,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: false, knockRequestsState: .loaded(mockedRequests), joinRule: .knock))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -731,7 +731,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: false, knockRequestsState: .loading, joinRule: .knock))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -755,7 +755,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
powerLevelsConfiguration: .init(canUserInvite: false)))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -779,7 +779,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: true, members: mockedMembers, knockRequestsState: .loaded(mockedRequests), joinRule: .knock))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
@@ -807,7 +807,7 @@ struct RoomDetailsScreenViewModelTests {
|
||||
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init()),
|
||||
userSettings: UserSettings.volatile(),
|
||||
userSettings: UserSettings.mock(),
|
||||
appHooks: AppHooks(),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
|
||||
@@ -22,7 +22,7 @@ final class RoomFlowCoordinatorTests {
|
||||
private let userSettings: UserSettings
|
||||
|
||||
init() {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -17,7 +17,7 @@ final class RoomListFiltersStateTests {
|
||||
let defaultFilters = RoomListFilter.allCases.filter { $0 != .mentions && $0 != .lowPriority }
|
||||
|
||||
init() {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
state = RoomListFiltersState(userSettings: userSettings)
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ struct RoomMembersFlowCoordinatorTests {
|
||||
let clientProxy = ClientProxyMock(.init())
|
||||
clientProxy.directRoomForUserIDReturnValue = .success(nil)
|
||||
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
let flowParameters = CommonFlowParameters(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
bugReportService: BugReportServiceMock(.init()),
|
||||
|
||||
@@ -153,7 +153,7 @@ final class RoomScreenViewModelTests {
|
||||
|
||||
@Test
|
||||
func pinnedEventsBannerThreadedSelection() async throws {
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
userSettings.threadsEnabled = true
|
||||
let userSession = UserSessionMock(.init(userSettings: userSettings))
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ final class RoomSummaryProviderTests {
|
||||
// MARK: - Helpers
|
||||
|
||||
private func setup(isLowPriorityFilterEnabled: Bool = false, includesOnlyJoinedRooms: Bool = false, setsRoomList: Bool = true) {
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
userSettings.lowPriorityFilterEnabled = isLowPriorityFilterEnabled
|
||||
|
||||
let stateEventStringBuilder = RoomStateEventStringBuilder(userID: "@me:matrix.org")
|
||||
|
||||
@@ -54,7 +54,7 @@ struct SearchScreenViewModelTests {
|
||||
staticRoomListSubject.value.first { $0.id == identifier }
|
||||
}
|
||||
|
||||
userSettings = UserSettings.volatile()
|
||||
userSettings = UserSettings.mock()
|
||||
|
||||
viewModel = SearchScreenViewModel(roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))),
|
||||
clientProxy: clientProxy,
|
||||
|
||||
@@ -457,7 +457,7 @@ final class SecurityAndPrivacyScreenViewModelTests {
|
||||
topLevelSpaces: [SpaceServiceRoom] = [],
|
||||
joinRule: ElementX.JoinRule,
|
||||
forceDisableE2EE: Bool = false) {
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
userSettings.knockingEnabled = true
|
||||
userSettings.forceDisableE2EE.applyRemoteValue(forceDisableE2EE)
|
||||
roomProxy = JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
|
||||
@@ -21,7 +21,7 @@ struct SessionVerificationViewModelTests {
|
||||
sessionVerificationController = SessionVerificationControllerProxyMock.configureMock()
|
||||
viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: sessionVerificationController,
|
||||
flow: .deviceInitiator,
|
||||
userSettings: .volatile(),
|
||||
userSettings: .mock(),
|
||||
mediaProvider: MediaProviderMock(.init()))
|
||||
context = viewModel.context
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ struct SettingsScreenViewModelTests {
|
||||
|
||||
@Test
|
||||
mutating func addAccountButtonFollowsTheFeatureFlag() async throws {
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
setupViewModel(userSettings: userSettings)
|
||||
#expect(!context.viewState.showAddAccountButton)
|
||||
|
||||
@@ -200,7 +200,7 @@ struct SettingsScreenViewModelTests {
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private mutating func setupViewModel(status: UserStatus = .init(), userSettings: UserSettings = .volatile()) {
|
||||
private mutating func setupViewModel(status: UserStatus = .init(), userSettings: UserSettings = .mock()) {
|
||||
clientProxy = ClientProxyMock(.init(userID: "", status: status))
|
||||
viewModel = SettingsScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
userSettings: userSettings,
|
||||
|
||||
@@ -55,7 +55,7 @@ struct TimelineControllerTests {
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
stateEventStringBuilder: RoomStateEventStringBuilder(userID: "@alice:matrix.org")),
|
||||
mediaProvider: MediaProviderMock(.init()),
|
||||
userSettings: .volatile())
|
||||
userSettings: .mock())
|
||||
}
|
||||
|
||||
/// The live timeline's items are only published once any initial focus attempt has finished.
|
||||
|
||||
@@ -218,7 +218,7 @@ struct TimelineInteractionHandlerTests {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ struct TimelineItemMenuActionProviderTests {
|
||||
isViewSourceEnabled: true,
|
||||
areThreadsEnabled: true,
|
||||
timelineKind: timelineKind,
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()))
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()))
|
||||
.makeActions()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ final class TimelineViewModelTests {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
return (viewModel, roomProxy, timelineProxy, timelineController)
|
||||
@@ -326,7 +326,7 @@ final class TimelineViewModelTests {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -350,7 +350,7 @@ final class TimelineViewModelTests {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -386,7 +386,7 @@ final class TimelineViewModelTests {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -422,7 +422,7 @@ final class TimelineViewModelTests {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -464,7 +464,7 @@ final class TimelineViewModelTests {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
#expect(configuration.pinnedEventIDs == viewModel.context.viewState.pinnedEventIDs)
|
||||
@@ -492,7 +492,7 @@ final class TimelineViewModelTests {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -899,7 +899,7 @@ final class TimelineViewModelTests {
|
||||
@Test
|
||||
func disablingTheFlagClearsTheSelection() async throws {
|
||||
let items = [TextRoomTimelineItem(eventID: "$1")]
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
userSettings.messageMultiSelectEnabled = true
|
||||
let viewModel = makeViewModel(timelineController: TimelineControllerMock(.init(timelineItems: items)), userSettings: userSettings)
|
||||
|
||||
@@ -917,7 +917,7 @@ final class TimelineViewModelTests {
|
||||
focussedEventID: String? = nil,
|
||||
timelineController: TimelineControllerProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol = UserIndicatorControllerMock(),
|
||||
userSettings: UserSettings = .volatile()) -> TimelineViewModel {
|
||||
userSettings: UserSettings = .mock()) -> TimelineViewModel {
|
||||
TimelineViewModel(roomProxy: roomProxy ?? JoinedRoomProxyMock(.init(name: "")),
|
||||
focussedEventID: focussedEventID,
|
||||
timelineController: timelineController,
|
||||
@@ -926,7 +926,7 @@ final class TimelineViewModelTests {
|
||||
userIndicatorController: userIndicatorController,
|
||||
appMediator: AppMediatorMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock(.init()),
|
||||
emojiProvider: EmojiProvider(userSettings: .volatile()),
|
||||
emojiProvider: EmojiProvider(userSettings: .mock()),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
}
|
||||
@@ -944,7 +944,7 @@ final class TimelineViewModelTests {
|
||||
|
||||
private func makeSelectionViewModel(timelineController: TimelineControllerProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol = UserIndicatorControllerMock()) -> TimelineViewModel {
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
userSettings.messageMultiSelectEnabled = true
|
||||
return makeViewModel(timelineController: timelineController,
|
||||
userIndicatorController: userIndicatorController,
|
||||
|
||||
@@ -20,7 +20,7 @@ struct UserDetailsEditScreenViewModelTests {
|
||||
|
||||
init() {
|
||||
viewModel = .init(userSession: UserSessionMock(.init()),
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(userSettings: .volatile()),
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(userSettings: .mock()),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ struct UserSessionFlowCoordinatorTests {
|
||||
appMediator.networkMonitor = networkMonitor
|
||||
|
||||
userIndicatorController = UserIndicatorControllerMock()
|
||||
let userSettings = UserSettings.volatile()
|
||||
let userSettings = UserSettings.mock()
|
||||
|
||||
let flowParameters = CommonFlowParameters(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
bugReportService: BugReportServiceMock(.init()),
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
@testable import ElementX
|
||||
import Foundation
|
||||
import Testing
|
||||
|
||||
struct UserSettingsTests {
|
||||
private let store = VolatileUserDefaults()
|
||||
private let appSettings: AppSettings
|
||||
private let aliceSettings: UserSettings
|
||||
private let bobSettings: UserSettings
|
||||
|
||||
init() {
|
||||
appSettings = AppSettings(store: store)
|
||||
aliceSettings = appSettings.userSettings(for: "@alice:example.com")
|
||||
bobSettings = appSettings.userSettings(for: "@bob:example.com")
|
||||
}
|
||||
|
||||
@Test
|
||||
func accountSettingsAreScopedToAccount() {
|
||||
// Given settings for two different accounts.
|
||||
#expect(aliceSettings.searchBreadcrumbs.isEmpty)
|
||||
#expect(bobSettings.searchBreadcrumbs.isEmpty)
|
||||
|
||||
// When updating an account setting for Alice.
|
||||
aliceSettings.searchBreadcrumbs = [.query("Alice")]
|
||||
|
||||
// Then only Alice should see the change.
|
||||
#expect(aliceSettings.searchBreadcrumbs == [.query("Alice")])
|
||||
#expect(bobSettings.searchBreadcrumbs.isEmpty)
|
||||
}
|
||||
|
||||
@Test
|
||||
func appSettingsAreShared() {
|
||||
// Given settings for two different accounts.
|
||||
#expect(!appSettings.hasSignedInBefore)
|
||||
#expect(!aliceSettings.hasSignedInBefore)
|
||||
#expect(!bobSettings.hasSignedInBefore)
|
||||
|
||||
// When updating an app setting through Alice's settings.
|
||||
aliceSettings.hasSignedInBefore = true
|
||||
|
||||
// Then the change should be seen by the app and every account.
|
||||
#expect(appSettings.hasSignedInBefore)
|
||||
#expect(aliceSettings.hasSignedInBefore)
|
||||
#expect(bobSettings.hasSignedInBefore)
|
||||
}
|
||||
|
||||
@Test
|
||||
func migrateAppSettingsValueToAccountSettings() throws {
|
||||
// Given a store containing values saved under the keys previously used by the app settings.
|
||||
// These keys are hardcoded so that renaming a property breaks this test instead of the migration.
|
||||
store.set(true, forKey: "hasRunIdentityConfirmationOnboarding")
|
||||
try store.set(JSONEncoder().encode([SearchBreadcrumb.query("Alice")]), forKey: "searchBreadcrumbs")
|
||||
#expect(store.object(forKey: "hasRunIdentityConfirmationOnboarding") != nil)
|
||||
#expect(store.object(forKey: "searchBreadcrumbs") != nil)
|
||||
#expect(!aliceSettings.hasRunIdentityConfirmationOnboarding)
|
||||
#expect(aliceSettings.searchBreadcrumbs.isEmpty)
|
||||
|
||||
// When migrating those values into Alice's account settings.
|
||||
aliceSettings.migrateAppSettingsValueToAccountSettings(\.hasRunIdentityConfirmationOnboardingKey)
|
||||
aliceSettings.migrateAppSettingsValueToAccountSettings(\.searchBreadcrumbsKey)
|
||||
|
||||
// Then the values should belong to Alice only.
|
||||
#expect(aliceSettings.hasRunIdentityConfirmationOnboarding)
|
||||
#expect(aliceSettings.searchBreadcrumbs == [.query("Alice")])
|
||||
#expect(!bobSettings.hasRunIdentityConfirmationOnboarding)
|
||||
#expect(bobSettings.searchBreadcrumbs.isEmpty)
|
||||
#expect(store.object(forKey: "hasRunIdentityConfirmationOnboarding") == nil)
|
||||
#expect(store.object(forKey: "searchBreadcrumbs") == nil)
|
||||
}
|
||||
|
||||
@Test
|
||||
func resetSessionSpecificSettings() {
|
||||
// Given app settings and account settings for two different accounts.
|
||||
appSettings.hasSignedInBefore = true
|
||||
aliceSettings.hasRunIdentityConfirmationOnboarding = true
|
||||
aliceSettings.searchBreadcrumbs = [.query("Alice")]
|
||||
bobSettings.hasRunIdentityConfirmationOnboarding = true
|
||||
bobSettings.searchBreadcrumbs = [.query("Bob")]
|
||||
#expect(appSettings.hasSignedInBefore)
|
||||
#expect(aliceSettings.hasRunIdentityConfirmationOnboarding)
|
||||
#expect(aliceSettings.searchBreadcrumbs == [.query("Alice")])
|
||||
#expect(bobSettings.hasRunIdentityConfirmationOnboarding)
|
||||
#expect(bobSettings.searchBreadcrumbs == [.query("Bob")])
|
||||
|
||||
// When resetting Alice's session specific settings.
|
||||
aliceSettings.resetSessionSpecificSettings()
|
||||
|
||||
// Then only Alice's account settings should be reset.
|
||||
#expect(!aliceSettings.hasRunIdentityConfirmationOnboarding)
|
||||
#expect(aliceSettings.searchBreadcrumbs.isEmpty)
|
||||
#expect(bobSettings.hasRunIdentityConfirmationOnboarding)
|
||||
#expect(bobSettings.searchBreadcrumbs == [.query("Bob")])
|
||||
#expect(appSettings.hasSignedInBefore)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user