Swift Testing for Unit Tests PART 1 (#5119)

* migrated a lot of unit tests to Swift Testing and added a new implementation for deferred fulfillment

more tests migration

Cleaned the code manually to establish some good patterns

more code improvements

some more code improvements

removed empty tests

update project

* more pr suggestions and cleanups

* removed the TestSetup pattern

* fixing claude not reusing tests

* pr suggestion + added indent rule to swiftformat so that we can prevent AIs to change that
This commit is contained in:
Mauro
2026-02-19 16:20:47 +01:00
committed by GitHub
parent fc03e05697
commit 7982aef855
118 changed files with 4630 additions and 4129 deletions
@@ -7,25 +7,22 @@
//
@testable import ElementX
import XCTest
import Testing
@MainActor
class KnockRequestsListScreenViewModelTests: XCTestCase {
var viewModel: KnockRequestsListScreenViewModelProtocol!
var context: KnockRequestsListScreenViewModelType.Context {
viewModel.context
}
override func setUpWithError() throws {
@Suite
struct KnockRequestsListScreenViewModelTests {
init() {
AppSettings.resetAllSettings()
}
func testLoadingState() async throws {
@Test
func loadingState() async throws {
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loading, joinRule: .knock))
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let context = viewModel.context
let deferred = deferFulfillment(context.$viewState) { state in
!state.shouldDisplayRequests &&
@@ -39,11 +36,13 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
try await deferred.fulfill()
}
func testEmptyState() async throws {
@Test
func emptyState() async throws {
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([]), joinRule: .knock))
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let context = viewModel.context
let deferred = deferFulfillment(context.$viewState) { state in
!state.shouldDisplayRequests &&
@@ -57,7 +56,8 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
try await deferred.fulfill()
}
func testLoadedState() async throws {
@Test
func loadedState() async throws {
let roomProxyMock = JoinedRoomProxyMock(.init(members: [.mockAdmin],
knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org")),
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org")),
@@ -65,9 +65,10 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]),
ownUserID: RoomMemberProxyMock.mockAdmin.userID,
joinRule: .knock))
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let context = viewModel.context
var deferred = deferFulfillment(context.$viewState) { state in
state.shouldDisplayRequests &&
@@ -99,10 +100,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
context.send(viewAction: .declineRequest(eventID: "2"))
try await deferred.fulfill()
guard let declineAlertInfo = context.alertInfo else {
XCTFail("Can't be nil")
return
}
let declineAlertInfo = try #require(context.alertInfo)
deferred = deferFulfillment(context.$viewState) { state in
state.shouldDisplayRequests &&
state.handledEventIDs == ["1", "2"] &&
@@ -119,10 +117,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
context.send(viewAction: .ban(eventID: "3"))
try await deferred.fulfill()
guard let banAlertInfo = context.alertInfo else {
XCTFail("Can't be nil")
return
}
let banAlertInfo = try #require(context.alertInfo)
deferred = deferFulfillment(context.$viewState) { state in
state.shouldDisplayRequests &&
state.handledEventIDs == ["1", "2", "3"] &&
@@ -134,15 +129,17 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
try await deferred.fulfill()
}
func testAcceptAll() async throws {
@Test
func acceptAll() async throws {
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org")),
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org")),
KnockRequestProxyMock(.init(eventID: "3", userID: "@charlie:matrix.org")),
KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]),
joinRule: .knock))
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let context = viewModel.context
var deferred = deferFulfillment(context.$viewState) { state in
state.shouldDisplayRequests &&
@@ -164,10 +161,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
context.send(viewAction: .acceptAllRequests)
try await deferred.fulfill()
guard let alertInfo = context.alertInfo else {
XCTFail("Can't be nil")
return
}
let alertInfo = try #require(context.alertInfo)
deferred = deferFulfillment(context.$viewState) { state in
!state.shouldDisplayRequests &&
@@ -179,7 +173,8 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
try await deferred.fulfill()
}
func testLoadedStateBecomesEmptyIfTheJoinRuleIsNotKnocking() async throws {
@Test
func loadedStateBecomesEmptyIfTheJoinRuleIsNotKnocking() async throws {
// If there is a sudden change in the rule, but the requests are still published, we want to hide all of them and show the empty view
let roomProxyMock = JoinedRoomProxyMock(.init(members: [.mockAdmin],
knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org")),
@@ -188,9 +183,10 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]),
ownUserID: RoomMemberProxyMock.mockAdmin.userID,
joinRule: .invite))
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let context = viewModel.context
let deferred = deferFulfillment(context.$viewState) { state in
!state.shouldDisplayRequests &&
@@ -201,7 +197,8 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
try await deferred.fulfill()
}
func testLoadedStateBecomesEmptyIfPermissionsAreRemoved() async throws {
@Test
func loadedStateBecomesEmptyIfPermissionsAreRemoved() async throws {
// If there is a sudden change in permissions, and the user can't do any other action, we hide all the requests and shoe the empty view
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org")),
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org")),
@@ -209,9 +206,10 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]),
joinRule: .knock,
powerLevelsConfiguration: .init(canUserInvite: false)))
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MediaProviderMock(),
userIndicatorController: UserIndicatorControllerMock())
let context = viewModel.context
let deferred = deferFulfillment(context.$viewState) { state in
!state.shouldDisplayRequests &&