Fix more unit tests. (#1406)

- Randomise test order.
- Use deferred fulfilment in more places.
- Make sure to change something before awaiting the fulfilment.
- Build a fresh AppSettings after reset().
- Retry tests on failure.
This commit is contained in:
Doug 2023-07-27 12:38:48 +01:00 committed by GitHub
parent 1529b5b8ca
commit 8f2904701b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 92 additions and 75 deletions

View File

@ -219,6 +219,18 @@ extension RoomDetailsNotificationSettingsState {
return false
}
/// Returns `true` when the settings are loaded and `isDefault` is true.
var isDefault: Bool {
guard case let .loaded(settings) = self else { return false }
return settings.isDefault
}
/// Returns `true` when the settings are loaded and `isDefault` is false.
var isCustom: Bool {
guard case let .loaded(settings) = self else { return false }
return !settings.isDefault
}
var isError: Bool {
if case .error = self {
return true

View File

@ -20,18 +20,20 @@ import XCTest
@MainActor
class AnalyticsSettingsScreenViewModelTests: XCTestCase {
private var appSettings: AppSettings!
private var viewModel: AnalyticsSettingsScreenViewModelProtocol!
private var context: AnalyticsSettingsScreenViewModelType.Context!
@MainActor override func setUpWithError() throws {
AppSettings.reset()
appSettings = AppSettings()
let analyticsClient = AnalyticsClientMock()
analyticsClient.isRunning = false
ServiceLocator.shared.register(analytics: AnalyticsService(client: analyticsClient,
appSettings: ServiceLocator.shared.settings,
appSettings: appSettings,
bugReportService: ServiceLocator.shared.bugReportService))
viewModel = AnalyticsSettingsScreenViewModel(appSettings: ServiceLocator.shared.settings,
viewModel = AnalyticsSettingsScreenViewModel(appSettings: appSettings,
analytics: ServiceLocator.shared.analytics)
context = viewModel.context
}
@ -41,13 +43,13 @@ class AnalyticsSettingsScreenViewModelTests: XCTestCase {
}
func testOptIn() {
ServiceLocator.shared.settings.analyticsConsentState = .optedOut
appSettings.analyticsConsentState = .optedOut
context.send(viewAction: .toggleAnalytics)
XCTAssertTrue(context.enableAnalytics)
}
func testOptOut() {
ServiceLocator.shared.settings.analyticsConsentState = .optedIn
appSettings.analyticsConsentState = .optedIn
context.send(viewAction: .toggleAnalytics)
XCTAssertFalse(context.enableAnalytics)
}

View File

@ -19,12 +19,13 @@ import AnalyticsEvents
import XCTest
class AnalyticsTests: XCTestCase {
private var appSettings: AppSettings { ServiceLocator.shared.settings }
private var appSettings: AppSettings!
private var analyticsClient: AnalyticsClientMock!
private var bugReportService: BugReportServiceMock!
override func setUp() {
AppSettings.reset()
appSettings = AppSettings()
bugReportService = BugReportServiceMock()
bugReportService.isRunning = false
@ -32,7 +33,7 @@ class AnalyticsTests: XCTestCase {
analyticsClient = AnalyticsClientMock()
analyticsClient.isRunning = false
ServiceLocator.shared.register(analytics: AnalyticsService(client: analyticsClient,
appSettings: ServiceLocator.shared.settings,
appSettings: appSettings,
bugReportService: ServiceLocator.shared.bugReportService))
}
@ -69,7 +70,7 @@ class AnalyticsTests: XCTestCase {
func testAnalyticsPromptNotDisplayed() {
// Given a fresh install of the app both Analytics and BugReportService should be disabled
XCTAssertEqual(ServiceLocator.shared.settings.analyticsConsentState, .unknown)
XCTAssertEqual(appSettings.analyticsConsentState, .unknown)
XCTAssertFalse(ServiceLocator.shared.analytics.isEnabled)
XCTAssertFalse(ServiceLocator.shared.analytics.isRunning)
XCTAssertFalse(analyticsClient.startAnalyticsConfigurationCalled)
@ -174,7 +175,7 @@ class AnalyticsTests: XCTestCase {
numFavouriteRooms: nil,
numSpaces: nil,
allChatsActiveFilter: nil))
client.start(analyticsConfiguration: ServiceLocator.shared.settings.analyticsConfiguration)
client.start(analyticsConfiguration: appSettings.analyticsConfiguration)
XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.")
XCTAssertEqual(client.pendingUserProperties?.ftueUseCaseSelection, .PersonalMessaging, "The use case selection should match.")

View File

@ -378,6 +378,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
XCTAssertFalse(context.viewState.canEdit)
}
// MARK: - Notifications
func testNotificationLoadingSettingsFailure() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountThrowableError = NotificationSettingsError.Generic(message: "error")
viewModel = RoomDetailsScreenViewModel(accountUserID: "@owner:somewhere.com",
@ -389,6 +391,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.filter(\.isError)
.first())
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
let expectedAlertInfo = AlertInfo(id: RoomDetailsScreenErrorType.alert,
@ -401,8 +404,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
func testNotificationDefaultMode() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .allMessages, isDefault: true))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState).first(where: \.isLoaded))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
XCTAssertEqual(context.viewState.notificationSettingsState.label, "Default")
@ -410,8 +413,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
func testNotificationCustomMode() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .allMessages, isDefault: false))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState).first(where: \.isCustom))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
XCTAssertEqual(context.viewState.notificationSettingsState.label, "Custom")
@ -419,8 +422,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
func testNotificationRoomMuted() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .mute, isDefault: false))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState).first(where: \.isLoaded))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
XCTAssertEqual(context.viewState.notificationShortcutButtonTitle, L10n.commonUnmute)
@ -429,8 +432,8 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
func testNotificationRoomNotMuted() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .mentionsAndKeywordsOnly, isDefault: false))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState).first(where: \.isLoaded))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
XCTAssertEqual(context.viewState.notificationShortcutButtonTitle, L10n.commonMute)
@ -438,12 +441,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
}
func testUnmuteTappedFailure() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .mute, isDefault: false))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
try await deferred.fulfill()
XCTAssertEqual(context.viewState.notificationShortcutButtonTitle, L10n.commonUnmute)
try await testNotificationRoomMuted()
let expectation = expectation(description: #function)
notificationSettingsProxyMock.unmuteRoomRoomIdIsEncryptedActiveMembersCountClosure = { _, _, _ in
@ -468,12 +466,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
}
func testMuteTappedFailure() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .allMessages, isDefault: false))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
try await deferred.fulfill()
XCTAssertEqual(context.viewState.notificationShortcutButtonTitle, L10n.commonMute)
try await testNotificationRoomNotMuted()
let expectation = expectation(description: #function)
notificationSettingsProxyMock.setNotificationModeRoomIdModeClosure = { _, _ in
@ -498,10 +491,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
}
func testMuteTapped() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .allMessages, isDefault: false))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
try await deferred.fulfill()
try await testNotificationRoomNotMuted()
let expectation = expectation(description: #function)
notificationSettingsProxyMock.setNotificationModeRoomIdModeClosure = { [weak notificationSettingsProxyMock] _, mode in
@ -528,10 +518,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
}
func testUnmuteTapped() async throws {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .mute, isDefault: false))
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
try await deferred.fulfill()
try await testNotificationRoomMuted()
let expectation = expectation(description: #function)
notificationSettingsProxyMock.unmuteRoomRoomIdIsEncryptedActiveMembersCountClosure = { [weak notificationSettingsProxyMock] _, _, _ in

View File

@ -44,87 +44,90 @@ class RoomFlowCoordinatorTests: XCTestCase {
userIndicatorController: ServiceLocator.shared.userIndicatorController)
}
func testRoomPresentation() async {
await process(route: .room(roomID: "1"), expectedAction: .presentedRoom("1"))
func testRoomPresentation() async throws {
try await process(route: .room(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomScreenCoordinator)
await process(route: .roomList, expectedAction: .dismissedRoom)
try await process(route: .roomList, expectedAction: .dismissedRoom)
XCTAssertNil(navigationStackCoordinator.rootCoordinator)
await process(route: .room(roomID: "1"), expectedAction: .presentedRoom("1"))
try await process(route: .room(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomScreenCoordinator)
await process(route: .room(roomID: "2"), expectedAction: .presentedRoom("2"))
try await process(route: .room(roomID: "2"), expectedAction: .presentedRoom("2"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomScreenCoordinator)
await process(route: .roomList, expectedAction: .dismissedRoom)
try await process(route: .roomList, expectedAction: .dismissedRoom)
XCTAssertNil(navigationStackCoordinator.rootCoordinator)
}
func testRoomDetailsPresentation() async {
await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
func testRoomDetailsPresentation() async throws {
try await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomDetailsScreenCoordinator)
await process(route: .roomList, expectedAction: .dismissedRoom)
try await process(route: .roomList, expectedAction: .dismissedRoom)
XCTAssertNil(navigationStackCoordinator.rootCoordinator)
}
func testStackUnwinding() async {
await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
func testStackUnwinding() async throws {
try await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomDetailsScreenCoordinator)
await process(route: .room(roomID: "2"), expectedAction: .presentedRoom("2"))
try await process(route: .room(roomID: "2"), expectedAction: .presentedRoom("2"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomScreenCoordinator)
}
func testNoOp() async {
await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
func testNoOp() async throws {
try await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomDetailsScreenCoordinator)
roomFlowCoordinator.handleAppRoute(.roomDetails(roomID: "1"), animated: true)
await Task.yield()
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomDetailsScreenCoordinator)
}
func testSwitchToDifferentDetails() async {
await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
func testSwitchToDifferentDetails() async throws {
try await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomDetailsScreenCoordinator)
await process(route: .roomDetails(roomID: "2"), expectedAction: .presentedRoom("2"))
try await process(route: .roomDetails(roomID: "2"), expectedAction: .presentedRoom("2"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomDetailsScreenCoordinator)
}
func testPushDetails() async {
await process(route: .room(roomID: "1"), expectedAction: .presentedRoom("1"))
func testPushDetails() async throws {
try await process(route: .room(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomScreenCoordinator)
await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
try await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomScreenCoordinator)
XCTAssertEqual(navigationStackCoordinator.stackCoordinators.count, 1)
XCTAssert(navigationStackCoordinator.stackCoordinators.first is RoomDetailsScreenCoordinator)
}
func testReplaceDetailsWithTimeline() async {
await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
func testReplaceDetailsWithTimeline() async throws {
try await process(route: .roomDetails(roomID: "1"), expectedAction: .presentedRoom("1"))
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomDetailsScreenCoordinator)
await process(route: .room(roomID: "1"), expectedActions: [.dismissedRoom, .presentedRoom("1")])
try await process(route: .room(roomID: "1"), expectedActions: [.dismissedRoom, .presentedRoom("1")])
XCTAssert(navigationStackCoordinator.rootCoordinator is RoomScreenCoordinator)
}
// MARK: - Private
private func process(route: AppRoute, expectedAction: RoomFlowCoordinatorAction) async {
await process(route: route, expectedActions: [expectedAction])
private func process(route: AppRoute, expectedAction: RoomFlowCoordinatorAction) async throws {
try await process(route: route, expectedActions: [expectedAction])
}
private func process(route: AppRoute, expectedActions: [RoomFlowCoordinatorAction]) async {
private func process(route: AppRoute, expectedActions: [RoomFlowCoordinatorAction]) async throws {
let deferred = deferFulfillment(roomFlowCoordinator.actions.collect(expectedActions.count).first(),
message: "The expected number of actions should be published.")
Task {
await Task.yield()
self.roomFlowCoordinator.handleAppRoute(route, animated: true)
}
if !expectedActions.isEmpty {
let actions = await roomFlowCoordinator.actions.collect(expectedActions.count).values.first()
let actions = try await deferred.fulfill()
XCTAssertEqual(actions, expectedActions)
}
}

View File

@ -39,6 +39,7 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
roomProxy: roomProxyMock)
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
XCTAssertFalse(context.allowCustomSetting)
@ -50,6 +51,7 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
roomProxy: roomProxyMock)
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
XCTAssertTrue(context.allowCustomSetting)
@ -61,6 +63,7 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
roomProxy: roomProxyMock)
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isError))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
let expectedAlertInfo = AlertInfo(id: RoomNotificationSettingsScreenErrorType.loadingSettingsFailed,
@ -77,6 +80,7 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
roomProxy: roomProxyMock)
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
let deferredIsRestoringDefaultSettings = deferFulfillment(context.$viewState.map(\.isRestoringDefautSetting)
@ -95,13 +99,14 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .mentionsAndKeywordsOnly, isDefault: true))
viewModel = RoomNotificationSettingsScreenViewModel(notificationSettingsProxy: notificationSettingsProxyMock,
roomProxy: roomProxyMock)
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
var deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState).first(where: \.isLoaded))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferred.fulfill()
deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState).first(where: \.isLoaded))
viewModel.state.bindings.allowCustomSetting = true
context.send(viewAction: .changedAllowCustomSettings)
await context.nextViewState()
try await deferred.fulfill()
XCTAssertEqual(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.0, roomProxyMock.id)
XCTAssertEqual(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.1, .mentionsAndKeywordsOnly)
@ -112,13 +117,14 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
notificationSettingsProxyMock.getNotificationSettingsRoomIdIsEncryptedActiveMembersCountReturnValue = RoomNotificationSettingsProxyMock(with: .init(mode: .mentionsAndKeywordsOnly, isDefault: false))
viewModel = RoomNotificationSettingsScreenViewModel(notificationSettingsProxy: notificationSettingsProxyMock,
roomProxy: roomProxyMock)
let deferred = deferFulfillment(context.$viewState.map(\.notificationSettingsState)
.first(where: \.isLoaded))
try await deferred.fulfill()
let deferredState = deferFulfillment(context.$viewState.map(\.notificationSettingsState).first(where: \.isLoaded))
notificationSettingsProxyMock.callbacks.send(.settingsDidChange)
try await deferredState.fulfill()
do {
var deferredViewState = deferFulfillment(context.$viewState.collect(2).first())
context.send(viewAction: .setCustomMode(.allMessages))
await context.nextViewState()
try await deferredViewState.fulfill()
XCTAssertEqual(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.0, roomProxyMock.id)
XCTAssertEqual(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.1, .allMessages)
@ -126,8 +132,9 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
}
do {
var deferredViewState = deferFulfillment(context.$viewState.collect(2).first())
context.send(viewAction: .setCustomMode(.mute))
await context.nextViewState()
try await deferredViewState.fulfill()
XCTAssertEqual(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.0, roomProxyMock.id)
XCTAssertEqual(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.1, .mute)
@ -135,8 +142,9 @@ class RoomNotificationSettingsScreenViewModelTests: XCTestCase {
}
do {
var deferredViewState = deferFulfillment(context.$viewState.collect(2).first())
context.send(viewAction: .setCustomMode(.mentionsAndKeywordsOnly))
await context.nextViewState()
try await deferredViewState.fulfill()
XCTAssertEqual(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.0, roomProxyMock.id)
XCTAssertEqual(notificationSettingsProxyMock.setNotificationModeRoomIdModeReceivedArguments?.1, .mentionsAndKeywordsOnly)

View File

@ -248,7 +248,7 @@ class RoomScreenViewModelTests: XCTestCase {
XCTAssertEqual(roomProxyMock.getMemberUserIDReceivedUserID, "bob")
}
func testGoToUserDetailsFailure() async {
func testGoToUserDetailsFailure() async throws {
// Setup
let timelineController = MockRoomTimelineController()
let roomProxyMock = RoomProxyMock(with: .init(displayName: ""))
@ -269,14 +269,16 @@ class RoomScreenViewModelTests: XCTestCase {
}
// Test
let deferred = deferFulfillment(viewModel.context.$viewState.collect(2).first(),
message: "The existing view state plus one new one should be published.")
viewModel.context.send(viewAction: .tappedOnUser(userID: "bob"))
await viewModel.context.nextViewState()
try await deferred.fulfill()
XCTAssertFalse(viewModel.state.bindings.alertInfo.isNil)
XCTAssert(roomProxyMock.getMemberUserIDCallsCount == 1)
XCTAssertEqual(roomProxyMock.getMemberUserIDReceivedUserID, "bob")
}
func testRetrySend() async {
func testRetrySend() async throws {
// Setup
let timelineController = MockRoomTimelineController()
let roomProxyMock = RoomProxyMock(with: .init(displayName: ""))

View File

@ -16,6 +16,7 @@
"value" : "1"
}
],
"testExecutionOrdering" : "random",
"testTimeoutsEnabled" : true
},
"testTargets" : [

View File

@ -99,6 +99,7 @@ lane :unit_tests do
run_tests(
scheme: "UnitTests",
result_bundle: true,
number_of_retries: 3,
)
slather(