mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Fix various flakey unit tests (#1783)
* Fix flakey emoji provider tests * Fix flakey RoomScreenViewModel tests * Fix flakey HomeScreenViewModel tests * Fix flakey RoomMemberListScreen tests, problem with bindings getting overriden and deferFulfillment cancellable not getting stored * Fix flakey RoomNotificationSettingsScreen tests and crashes * Fix flakey RoomMemberDetailsScreen tests * Deprecate old `deferFulfillment` and `nextViewState` methods * Convert more files to the new `deferFulfillment` * Converted the rest of the tests to the new deferFulfillment * Removed now unused `nextViewState` and `deferFulfillment` * Remove automatic retries from unit tests * Reset analytics flag after running unit tests * Address PR comments * Introduce a new `deferFulfillment(publisher, keyPath, transitionValues)` method and use it where appropiate
This commit is contained in:
@@ -282,11 +282,14 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
// Test
|
||||
let deferred = deferFulfillment(viewModel.context.$viewState.collect(3).first(),
|
||||
message: "The existing view state plus one new one should be published.")
|
||||
let deferred = deferFulfillment(viewModel.context.$viewState) { value in
|
||||
value.bindings.alertInfo != nil
|
||||
}
|
||||
|
||||
viewModel.context.send(viewAction: .tappedOnUser(userID: "bob"))
|
||||
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssertFalse(viewModel.state.bindings.alertInfo.isNil)
|
||||
XCTAssert(roomProxyMock.getMemberUserIDCallsCount == 1)
|
||||
XCTAssertEqual(roomProxyMock.getMemberUserIDReceivedUserID, "bob")
|
||||
@@ -295,7 +298,6 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
// MARK: - Sending
|
||||
|
||||
func testRetrySend() async throws {
|
||||
// Setup
|
||||
let timelineController = MockRoomTimelineController()
|
||||
let roomProxyMock = RoomProxyMock(with: .init(displayName: ""))
|
||||
|
||||
@@ -306,16 +308,15 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: userIndicatorControllerMock)
|
||||
|
||||
// Test
|
||||
viewModel.context.send(viewAction: .retrySend(itemID: .init(timelineID: UUID().uuidString, transactionID: "test retry send id")))
|
||||
await Task.yield()
|
||||
try? await Task.sleep(for: .microseconds(500))
|
||||
|
||||
try? await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
XCTAssert(roomProxyMock.retrySendTransactionIDCallsCount == 1)
|
||||
XCTAssert(roomProxyMock.retrySendTransactionIDReceivedInvocations == ["test retry send id"])
|
||||
}
|
||||
|
||||
func testRetrySendNoTransactionID() async {
|
||||
// Setup
|
||||
let timelineController = MockRoomTimelineController()
|
||||
let roomProxyMock = RoomProxyMock(with: .init(displayName: ""))
|
||||
|
||||
@@ -326,14 +327,14 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: userIndicatorControllerMock)
|
||||
|
||||
// Test
|
||||
viewModel.context.send(viewAction: .retrySend(itemID: .random))
|
||||
await Task.yield()
|
||||
|
||||
try? await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
XCTAssert(roomProxyMock.retrySendTransactionIDCallsCount == 0)
|
||||
}
|
||||
|
||||
func testCancelSend() async {
|
||||
// Setup
|
||||
let timelineController = MockRoomTimelineController()
|
||||
let roomProxyMock = RoomProxyMock(with: .init(displayName: ""))
|
||||
|
||||
@@ -344,15 +345,15 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: userIndicatorControllerMock)
|
||||
|
||||
// Test
|
||||
viewModel.context.send(viewAction: .cancelSend(itemID: .init(timelineID: UUID().uuidString, transactionID: "test cancel send id")))
|
||||
try? await Task.sleep(for: .microseconds(500))
|
||||
|
||||
try? await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
XCTAssert(roomProxyMock.cancelSendTransactionIDCallsCount == 1)
|
||||
XCTAssert(roomProxyMock.cancelSendTransactionIDReceivedInvocations == ["test cancel send id"])
|
||||
}
|
||||
|
||||
func testCancelSendNoTransactionID() async {
|
||||
// Setup
|
||||
let timelineController = MockRoomTimelineController()
|
||||
let roomProxyMock = RoomProxyMock(with: .init(displayName: ""))
|
||||
|
||||
@@ -363,16 +364,16 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: userIndicatorControllerMock)
|
||||
|
||||
// Test
|
||||
viewModel.context.send(viewAction: .cancelSend(itemID: .random))
|
||||
await Task.yield()
|
||||
|
||||
try? await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
XCTAssert(roomProxyMock.cancelSendTransactionIDCallsCount == 0)
|
||||
}
|
||||
|
||||
// MARK: - Read Receipts
|
||||
|
||||
// swiftlint:disable force_unwrapping
|
||||
|
||||
func testSendReadReceipt() async throws {
|
||||
// Given a room with only text items in the timeline
|
||||
let items = [TextRoomTimelineItem(eventID: "t1"),
|
||||
@@ -382,7 +383,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
|
||||
// When sending a read receipt for the last item.
|
||||
viewModel.context.send(viewAction: .sendReadReceiptIfNeeded(items.last!.id))
|
||||
try await Task.sleep(for: .microseconds(100))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
// Then the receipt should be sent.
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForCalled, true)
|
||||
@@ -401,13 +402,13 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
TextRoomTimelineItem(eventID: "t3")]
|
||||
let (viewModel, roomProxy, timelineController, _) = readReceiptsConfiguration(with: items)
|
||||
viewModel.context.send(viewAction: .sendReadReceiptIfNeeded(items.last!.id))
|
||||
try await Task.sleep(for: .microseconds(100))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForCallsCount, 1)
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForReceivedEventID, "t3")
|
||||
|
||||
// When sending a receipt for the first item in the timeline.
|
||||
viewModel.context.send(viewAction: .sendReadReceiptIfNeeded(items.first!.id))
|
||||
try await Task.sleep(for: .microseconds(100))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
// Then the request should be ignored.
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForCallsCount, 1)
|
||||
@@ -417,10 +418,10 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
let newMessage = TextRoomTimelineItem(eventID: "t4")
|
||||
timelineController.timelineItems.append(newMessage)
|
||||
timelineController.callbacks.send(.updatedTimelineItems)
|
||||
try await Task.sleep(for: .microseconds(500))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
viewModel.context.send(viewAction: .sendReadReceiptIfNeeded(newMessage.id))
|
||||
try await Task.sleep(for: .microseconds(100))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
// Then the request should be made.
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForCallsCount, 2)
|
||||
@@ -436,7 +437,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
|
||||
// When sending a read receipt for the last item.
|
||||
viewModel.context.send(viewAction: .sendReadReceiptIfNeeded(items.last!.id))
|
||||
try await Task.sleep(for: .microseconds(100))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
// Then nothing should be sent.
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForCalled, false)
|
||||
@@ -451,7 +452,7 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
|
||||
// When sending a read receipt for the last item.
|
||||
viewModel.context.send(viewAction: .sendReadReceiptIfNeeded(items.last!.id))
|
||||
try await Task.sleep(for: .microseconds(100))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
// Then a read receipt should be sent for the item before it.
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForCalled, true)
|
||||
@@ -465,13 +466,13 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
SeparatorRoomTimelineItem(timelineID: "v3")]
|
||||
let (viewModel, roomProxy, _, _) = readReceiptsConfiguration(with: items)
|
||||
viewModel.context.send(viewAction: .sendReadReceiptIfNeeded(items.last!.id))
|
||||
try await Task.sleep(for: .microseconds(100))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForCallsCount, 1)
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForReceivedEventID, "t2")
|
||||
|
||||
// When sending the same receipt again
|
||||
viewModel.context.send(viewAction: .sendReadReceiptIfNeeded(items.last!.id))
|
||||
try await Task.sleep(for: .microseconds(100))
|
||||
try await Task.sleep(for: .milliseconds(100))
|
||||
|
||||
// Then the second call should be ignored.
|
||||
XCTAssertEqual(roomProxy.sendReadReceiptForCallsCount, 1)
|
||||
|
||||
Reference in New Issue
Block a user