Files
element-x-ios/UnitTests/Sources/RoomChangePermissionsScreenViewModelTests.swift
T
Michael ff5dcb040d Replace the ServiceLocator with direct dependency injection (#5548)
Removes the ServiceLocator singleton and instead directly injects the dependencies it was holding for more control over instantiation of the various component subtrees and better visibility over how they're being used.
2026-05-14 09:45:49 +03:00

131 lines
6.0 KiB
Swift

//
// Copyright 2025 Element Creations Ltd.
// Copyright 2022-2025 New Vector 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
@MainActor
struct RoomChangePermissionsScreenViewModelTests {
var roomProxy: JoinedRoomProxyMock!
var viewModel: RoomChangePermissionsScreenViewModelProtocol!
var context: RoomChangePermissionsScreenViewModelType.Context {
viewModel.context
}
@Test
mutating func changeSetting() throws {
setup(isSpace: false)
// Given a screen with no changes.
let index = try #require(context.settings[.roomDetails]?.firstIndex { $0.keyPath == \.roomAvatar },
"There should be a setting for the room avatar.")
#expect(context.settings[.roomDetails]?[index].roleValue == .moderator)
#expect(!context.viewState.hasChanges)
// When updating a setting.
let setting = RoomPermissionsSetting(title: "",
value: RoomRole.user.powerLevelValue,
ownPowerLevel: RoomRole.creator.powerLevel,
keyPath: \.roomAvatar)
#expect(!setting.isDisabled)
#expect(setting.availableValues.map(\.tag) == RoomPermissionsSetting.allValues.map(\.tag))
context.settings[.roomDetails]?[index] = setting
// Then the setting should update and the changes should be flagged.
#expect(context.settings[.roomDetails]?[index].roleValue == .user)
#expect(context.viewState.hasChanges)
}
@Test
mutating func settingsCantBeChanged() throws {
setup(isSpace: false, ownPowerLevel: .value(25))
// Given a screen with no changes.
var index = try #require(context.settings[.roomDetails]?.firstIndex { $0.keyPath == \.roomAvatar },
"There should be a setting for the room avatar.")
#expect(context.settings[.roomDetails]?[index].roleValue == .moderator)
#expect(context.settings[.roomDetails]?[index].isDisabled == true)
#expect(context.settings[.roomDetails]?[index].availableValues.count == 1)
#expect(!context.viewState.hasChanges)
index = try #require(context.settings[.messagesAndContent]?.firstIndex { $0.keyPath == \.eventsDefault },
"There should be a setting for the events.")
#expect(context.settings[.messagesAndContent]?[index].roleValue == .user)
#expect(context.settings[.messagesAndContent]?[index].isDisabled == false)
#expect(context.settings[.messagesAndContent]?[index].availableValues.count == 1)
}
@Test
mutating func save() async throws {
setup(isSpace: false)
// Given a screen with changes.
let index = try #require(context.settings[.roomDetails]?.firstIndex { $0.keyPath == \.roomAvatar },
"There should be a setting for the room avatar.")
context.settings[.roomDetails]?[index] = RoomPermissionsSetting(title: "",
value: RoomRole.user.powerLevelValue,
ownPowerLevel: RoomRole.creator.powerLevel,
keyPath: \.roomAvatar)
#expect(context.settings[.roomDetails]?[index].roleValue == .user)
#expect(context.settings[.roomDetails]?[index].isDisabled == false)
#expect(context.settings[.roomDetails]?[index].availableValues.map(\.tag) == RoomPermissionsSetting.allValues.map(\.tag))
#expect(context.viewState.hasChanges)
#expect(context.settings.count == 3)
// When saving changes.
context.send(viewAction: .save)
// Nothing to await right now,
try await Task.sleep(for: .milliseconds(100))
// Then the changes should be applied.
#expect(roomProxy.applyPowerLevelChangesCalled)
#expect(roomProxy.applyPowerLevelChangesReceivedChanges == .init(roomAvatar: 0),
"Only the avatar setting should be applied. No other settings were changed so they should be nil to remain left alone.")
}
@Test
mutating func saveNoChanges() {
setup(isSpace: false)
// Given a screen with no changes.
#expect(!context.viewState.hasChanges)
// When saving changes.
context.send(viewAction: .save)
// Then nothing should happen.
#expect(!roomProxy.applyPowerLevelChangesCalled)
}
@Test
mutating func defaultStateRoom() {
setup(isSpace: false)
#expect(context.settings[.roomDetails] != nil)
#expect(context.settings[.memberModeration] != nil)
#expect(context.settings[.messagesAndContent] != nil)
#expect(context.settings[.manageSpace] == nil)
}
@Test
mutating func defaultStateSpace() {
setup(isSpace: true)
#expect(context.settings[.roomDetails] != nil)
#expect(context.settings[.memberModeration] != nil)
#expect(context.settings[.messagesAndContent] == nil)
#expect(context.settings[.manageSpace] != nil)
}
// MARK: - Helpers
private mutating func setup(isSpace: Bool, ownPowerLevel: RoomPowerLevel = RoomRole.creator.powerLevel) {
roomProxy = JoinedRoomProxyMock(.init(isSpace: isSpace))
viewModel = RoomChangePermissionsScreenViewModel(currentPermissions: .init(powerLevels: .mock),
ownPowerLevel: ownPowerLevel,
roomProxy: roomProxy,
userIndicatorController: UserIndicatorControllerMock(),
analytics: .mock())
}
}