mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Silence some warnings. (#4969)
This commit is contained in:
@@ -96,7 +96,6 @@ class SpacesTabFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
// swiftlint:disable:next cyclomatic_complexity
|
|
||||||
private func configureStateMachine() {
|
private func configureStateMachine() {
|
||||||
stateMachine.addRoutes(event: .start, transitions: [.initial => .spacesScreen(selectedSpaceID: nil)]) { [weak self] _ in
|
stateMachine.addRoutes(event: .start, transitions: [.initial => .spacesScreen(selectedSpaceID: nil)]) { [weak self] _ in
|
||||||
self?.presentSpacesScreen()
|
self?.presentSpacesScreen()
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
|||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
appSettings: ServiceLocator.shared.settings)
|
appSettings: ServiceLocator.shared.settings)
|
||||||
viewModel.updateAvatar(fileURL: Bundle.main.url(forResource: "preview_avatar_room", withExtension: "jpg")!)
|
viewModel.updateAvatar(fileURL: Bundle.main.url(forResource: "preview_avatar_room", withExtension: "jpg") ?? .picturesDirectory)
|
||||||
return viewModel
|
return viewModel
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -331,7 +331,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
|||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
appSettings: ServiceLocator.shared.settings)
|
appSettings: ServiceLocator.shared.settings)
|
||||||
viewModel.updateAvatar(fileURL: Bundle.main.url(forResource: "preview_avatar_room", withExtension: "jpg")!)
|
viewModel.updateAvatar(fileURL: Bundle.main.url(forResource: "preview_avatar_room", withExtension: "jpg") ?? .picturesDirectory)
|
||||||
return viewModel
|
return viewModel
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
@@ -37,33 +37,36 @@ enum QRCodeLoginScreenMode {
|
|||||||
|
|
||||||
struct QRCodeLoginScreenViewState: BindableState {
|
struct QRCodeLoginScreenViewState: BindableState {
|
||||||
var state: QRCodeLoginState
|
var state: QRCodeLoginState
|
||||||
|
let mode: QRCodeLoginScreenMode
|
||||||
/// Whether or not it is possible for the screen to start the manual sign in flow. This was added to avoid
|
/// Whether or not it is possible for the screen to start the manual sign in flow. This was added to avoid
|
||||||
/// having to handle server configuration when ``AppSettings.allowOtherAccountProviders`` is false.
|
/// having to handle server configuration when ``AppSettings.allowOtherAccountProviders`` is false.
|
||||||
let canSignInManually: Bool
|
let canSignInManually: Bool
|
||||||
let isPresentedModally: Bool
|
|
||||||
|
|
||||||
let instructions = QRCodeLoginScreenInstructions()
|
let instructions = QRCodeLoginScreenInstructions()
|
||||||
var bindings = QRCodeLoginScreenViewStateBindings()
|
var bindings = QRCodeLoginScreenViewStateBindings()
|
||||||
|
|
||||||
var shouldDisplayCancelButton: Bool {
|
var shouldDisplayCancelButton: Bool {
|
||||||
// TODO: Simplify/validate these assumptions.
|
switch mode {
|
||||||
if isPresentedModally {
|
case .login:
|
||||||
switch state {
|
switch state {
|
||||||
case .loginInstructions, .scan, .error(.noCameraPermission): true
|
case .loginInstructions, .scan, .error(.noCameraPermission): true
|
||||||
default: false
|
case .error: false
|
||||||
|
case .linkDesktopInstructions, .displayCode, .displayQR, .confirmCode: false // Unreachable states.
|
||||||
}
|
}
|
||||||
} else {
|
case .linkDesktop, .linkMobile:
|
||||||
switch state {
|
switch state {
|
||||||
case .displayCode, .confirmCode, .scan, .error(.noCameraPermission): true
|
case .displayCode, .confirmCode, .scan, .error(.noCameraPermission): true
|
||||||
case .loginInstructions, .linkDesktopInstructions, .displayQR, .error: false
|
case .linkDesktopInstructions, .displayQR, .error: false
|
||||||
|
case .loginInstructions: false // Unreachable state.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var shouldDisplayBackButton: Bool {
|
var shouldDisplayBackButton: Bool {
|
||||||
if isPresentedModally {
|
switch mode {
|
||||||
false
|
case .login:
|
||||||
} else {
|
false // Login is presented modally, never show the back button.
|
||||||
|
case .linkDesktop, .linkMobile:
|
||||||
switch state {
|
switch state {
|
||||||
case .loginInstructions, .linkDesktopInstructions, .displayQR: true
|
case .loginInstructions, .linkDesktopInstructions, .displayQR: true
|
||||||
case .displayCode, .confirmCode, .scan, .error: false
|
case .displayCode, .confirmCode, .scan, .error: false
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import Foundation
|
|||||||
typealias QRCodeLoginScreenViewModelType = StateStoreViewModel<QRCodeLoginScreenViewState, QRCodeLoginScreenViewAction>
|
typealias QRCodeLoginScreenViewModelType = StateStoreViewModel<QRCodeLoginScreenViewState, QRCodeLoginScreenViewAction>
|
||||||
|
|
||||||
class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScreenViewModelProtocol {
|
class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScreenViewModelProtocol {
|
||||||
private let mode: QRCodeLoginScreenMode
|
|
||||||
private let appMediator: AppMediatorProtocol
|
private let appMediator: AppMediatorProtocol
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<QRCodeLoginScreenViewModelAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<QRCodeLoginScreenViewModelAction, Never> = .init()
|
||||||
@@ -26,24 +25,19 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
init(mode: QRCodeLoginScreenMode,
|
init(mode: QRCodeLoginScreenMode,
|
||||||
canSignInManually: Bool,
|
canSignInManually: Bool,
|
||||||
appMediator: AppMediatorProtocol) {
|
appMediator: AppMediatorProtocol) {
|
||||||
self.mode = mode
|
|
||||||
self.appMediator = appMediator
|
self.appMediator = appMediator
|
||||||
|
|
||||||
let initialState: QRCodeLoginScreenViewState = switch mode {
|
let initialViewState: QRCodeLoginState = switch mode {
|
||||||
case .login:
|
case .login: .loginInstructions
|
||||||
.init(state: .loginInstructions, canSignInManually: canSignInManually, isPresentedModally: true)
|
case .linkDesktop: .linkDesktopInstructions
|
||||||
case .linkDesktop:
|
|
||||||
.init(state: .linkDesktopInstructions, canSignInManually: canSignInManually, isPresentedModally: false)
|
|
||||||
case .linkMobile(let progressPublisher):
|
case .linkMobile(let progressPublisher):
|
||||||
switch progressPublisher.value {
|
switch progressPublisher.value {
|
||||||
case .qrReady(let image):
|
case .qrReady(let image): .displayQR(image)
|
||||||
.init(state: .displayQR(image), canSignInManually: canSignInManually, isPresentedModally: false)
|
default: .error(.unknown)
|
||||||
default:
|
|
||||||
.init(state: .error(.unknown), canSignInManually: canSignInManually, isPresentedModally: false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.init(initialViewState: initialState)
|
super.init(initialViewState: .init(state: initialViewState, mode: mode, canSignInManually: canSignInManually))
|
||||||
setupSubscriptions()
|
setupSubscriptions()
|
||||||
|
|
||||||
if case .linkMobile(let progressPublisher) = mode {
|
if case .linkMobile(let progressPublisher) = mode {
|
||||||
@@ -62,7 +56,7 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
case .sendCheckCode:
|
case .sendCheckCode:
|
||||||
Task { await sendCheckCode() }
|
Task { await sendCheckCode() }
|
||||||
case .errorAction(.startOver):
|
case .errorAction(.startOver):
|
||||||
switch mode {
|
switch state.mode {
|
||||||
case .login:
|
case .login:
|
||||||
Task { await startScanIfPossible() }
|
Task { await startScanIfPossible() }
|
||||||
case .linkDesktop, .linkMobile:
|
case .linkDesktop, .linkMobile:
|
||||||
@@ -88,7 +82,7 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] qrData in
|
.sink { [weak self] qrData in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
switch mode {
|
switch state.mode {
|
||||||
case .login(let qrCodeLoginService):
|
case .login(let qrCodeLoginService):
|
||||||
handleScan(qrData: qrData, loginService: qrCodeLoginService)
|
handleScan(qrData: qrData, loginService: qrCodeLoginService)
|
||||||
case .linkDesktop(let linkNewDeviceService):
|
case .linkDesktop(let linkNewDeviceService):
|
||||||
@@ -152,8 +146,6 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: when user cancels in UI then the underlying login needs to be cancelled too. It's unclear if we have that exposed in the bindings yet.
|
|
||||||
|
|
||||||
private func handleScan(qrData: Data, linkService: LinkNewDeviceServiceProtocol) {
|
private func handleScan(qrData: Data, linkService: LinkNewDeviceServiceProtocol) {
|
||||||
guard currentTask == nil else { return }
|
guard currentTask == nil else { return }
|
||||||
|
|
||||||
@@ -314,24 +306,23 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Only for mocking initial states
|
/// Only for mocking initial states
|
||||||
fileprivate init(state: QRCodeLoginState, canSignInManually: Bool, isPresentedModally: Bool, checkCodeInput: String) {
|
fileprivate init(state: QRCodeLoginState, mode: QRCodeLoginScreenMode, canSignInManually: Bool, checkCodeInput: String) {
|
||||||
mode = .login(QRCodeLoginServiceMock())
|
|
||||||
appMediator = AppMediatorMock.default
|
appMediator = AppMediatorMock.default
|
||||||
super.init(initialViewState: .init(state: state,
|
super.init(initialViewState: .init(state: state,
|
||||||
|
mode: mode,
|
||||||
canSignInManually: canSignInManually,
|
canSignInManually: canSignInManually,
|
||||||
isPresentedModally: isPresentedModally,
|
|
||||||
bindings: .init(checkCodeInput: checkCodeInput)))
|
bindings: .init(checkCodeInput: checkCodeInput)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension QRCodeLoginScreenViewModel {
|
extension QRCodeLoginScreenViewModel {
|
||||||
static func mock(state: QRCodeLoginState,
|
static func mock(state: QRCodeLoginState,
|
||||||
|
mode: QRCodeLoginScreenMode = .login(QRCodeLoginServiceMock()),
|
||||||
canSignInManually: Bool = true,
|
canSignInManually: Bool = true,
|
||||||
isPresentedModally: Bool = true,
|
|
||||||
checkCodeInput: String = "") -> QRCodeLoginScreenViewModel {
|
checkCodeInput: String = "") -> QRCodeLoginScreenViewModel {
|
||||||
QRCodeLoginScreenViewModel(state: state,
|
QRCodeLoginScreenViewModel(state: state,
|
||||||
|
mode: mode,
|
||||||
canSignInManually: canSignInManually,
|
canSignInManually: canSignInManually,
|
||||||
isPresentedModally: isPresentedModally,
|
|
||||||
checkCodeInput: checkCodeInput)
|
checkCodeInput: checkCodeInput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ class AudioRecorder: AudioRecorderProtocol {
|
|||||||
MXLog.info("setup audio session")
|
MXLog.info("setup audio session")
|
||||||
|
|
||||||
try audioSession.setAllowHapticsAndSystemSoundsDuringRecording(true)
|
try audioSession.setAllowHapticsAndSystemSoundsDuringRecording(true)
|
||||||
try audioSession.setCategory(.playAndRecord, mode: .default, options: [.allowBluetooth])
|
try audioSession.setCategory(.playAndRecord, mode: .default, options: [.allowBluetoothHFP])
|
||||||
try audioSession.setActive(true)
|
try audioSession.setActive(true)
|
||||||
addObservers()
|
addObservers()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,9 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
return progressSubject.asCurrentValuePublisher()
|
return progressSubject.asCurrentValuePublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At some stage the SDK will have a `qrCodeData.intent` which we should check before continuing here.
|
||||||
|
// Note the equivalent check will also happen for linking a device by QR in the LinkNewDeviceService.
|
||||||
|
|
||||||
guard let scannedServerName = qrData.serverName() else {
|
guard let scannedServerName = qrData.serverName() else {
|
||||||
MXLog.error("The QR code is from a device that is not yet signed in.")
|
MXLog.error("The QR code is from a device that is not yet signed in.")
|
||||||
progressSubject.send(completion: .failure(.qrCodeError(.deviceNotSignedIn)))
|
progressSubject.send(completion: .failure(.qrCodeError(.deviceNotSignedIn)))
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class LinkNewDeviceService: LinkNewDeviceServiceProtocol {
|
|||||||
|
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
// TODO: we need a way to cancel the in progress grant if the user hit the cancel button
|
// Note: The SDK doesn't provide us with a way to cancel the grant if the user hit the cancel button 🤷♂️
|
||||||
try await grantLoginHandler.generate(progressListener: listener) // The success state is handled by the listener.
|
try await grantLoginHandler.generate(progressListener: listener) // The success state is handled by the listener.
|
||||||
} catch let error as HumanQrGrantLoginError {
|
} catch let error as HumanQrGrantLoginError {
|
||||||
MXLog.error("QR code reciprocate error: \(error)")
|
MXLog.error("QR code reciprocate error: \(error)")
|
||||||
@@ -98,12 +98,12 @@ class LinkNewDeviceService: LinkNewDeviceServiceProtocol {
|
|||||||
return progressSubject.asCurrentValuePublisher()
|
return progressSubject.asCurrentValuePublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning("Check intent/server name??")
|
// At some stage the SDK will have a `qrCodeData.intent` which we should check before continuing here.
|
||||||
#warning("Check Element Pro here??")
|
// Note the equivalent check will also happen for sign in with QR code in the AuthenticationService.
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
// TODO: it would be nice to be able to cancel the grant at the SDK level if the user hits the cancel button
|
// Note: The SDK doesn't provide us with a way to cancel the grant if the user hit the cancel button 🤷♂️
|
||||||
try await grantLoginHandler.scan(qrCodeData: qrCodeData, progressListener: listener) // The success state is handled by the listener.
|
try await grantLoginHandler.scan(qrCodeData: qrCodeData, progressListener: listener) // The success state is handled by the listener.
|
||||||
} catch let error as HumanQrGrantLoginError {
|
} catch let error as HumanQrGrantLoginError {
|
||||||
MXLog.error("QR code reciprocate error: \(error)")
|
MXLog.error("QR code reciprocate error: \(error)")
|
||||||
@@ -216,7 +216,9 @@ class CheckCodeSenderProxy: Equatable {
|
|||||||
try await underlyingSender.send(code: code)
|
try await underlyingSender.send(code: code)
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning("Waiting for an SDK update to use the underlying sender.")
|
// Bypassed for now whilst we wait for an SDK update (however its worth noting that
|
||||||
|
// things should still fail if the wrong code is provided, just not necessarily with
|
||||||
|
// the right error being shown). https://github.com/matrix-org/matrix-rust-sdk/pull/5957
|
||||||
func validate(checkCode: UInt8) -> Bool { true }
|
func validate(checkCode: UInt8) -> Bool { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -451,9 +451,6 @@ struct MediaUploadingPreprocessor {
|
|||||||
|
|
||||||
try? FileManager.default.removeItem(at: outputURL)
|
try? FileManager.default.removeItem(at: outputURL)
|
||||||
|
|
||||||
exportSession.outputURL = outputURL
|
|
||||||
exportSession.outputFileType = AVFileType.mp4
|
|
||||||
|
|
||||||
guard exportSession.supportedFileTypes.contains(AVFileType.mp4) else {
|
guard exportSession.supportedFileTypes.contains(AVFileType.mp4) else {
|
||||||
throw .failedConvertingVideo
|
throw .failedConvertingVideo
|
||||||
}
|
}
|
||||||
@@ -463,9 +460,10 @@ struct MediaUploadingPreprocessor {
|
|||||||
exportSession.fileLengthLimit = Int64(Double(targetFileSize) * 0.9)
|
exportSession.fileLengthLimit = Int64(Double(targetFileSize) * 0.9)
|
||||||
}
|
}
|
||||||
|
|
||||||
await exportSession.export()
|
do {
|
||||||
|
try await exportSession.export(to: outputURL, as: .mp4)
|
||||||
guard exportSession.status == .completed else {
|
} catch {
|
||||||
|
MXLog.error("Video conversion failed: \(error)")
|
||||||
throw .failedConvertingVideo
|
throw .failedConvertingVideo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,9 +50,8 @@ class DateTests: XCTestCase {
|
|||||||
XCTAssertEqual(threeDaysAgo.formattedDateSeparator(), threeDaysAgo.formatted(.dateTime.weekday(.wide)))
|
XCTAssertEqual(threeDaysAgo.formattedDateSeparator(), threeDaysAgo.formatted(.dateTime.weekday(.wide)))
|
||||||
|
|
||||||
// This test will fail during the first 6 days of the year.
|
// This test will fail during the first 6 days of the year.
|
||||||
let startOfTheYear = calendar.date(bySetting: .dayOfYear, value: 1, of: startOfToday)!
|
let startOfTheYear = calendar.dateInterval(of: .year, for: startOfToday)!.start
|
||||||
// FIXME: Uncomment on the 7th Jan.
|
XCTAssertEqual(startOfTheYear.formattedDateSeparator(), startOfTheYear.formatted(.dateTime.weekday(.wide).day().month(.wide)))
|
||||||
// XCTAssertEqual(startOfTheYear.formattedDateSeparator(), startOfTheYear.formatted(.dateTime.weekday(.wide).day().month(.wide)))
|
|
||||||
|
|
||||||
let theMillennium = calendar.date(from: DateComponents(year: 2000, month: 1, day: 1))!
|
let theMillennium = calendar.date(from: DateComponents(year: 2000, month: 1, day: 1))!
|
||||||
XCTAssertEqual(theMillennium.formattedDateSeparator(), theMillennium.formatted(.dateTime.weekday(.wide).day().month(.wide).year()))
|
XCTAssertEqual(theMillennium.formattedDateSeparator(), theMillennium.formatted(.dateTime.weekday(.wide).day().month(.wide).year()))
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class LoggingTests: XCTestCase {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try XCTAssertTrue(String(contentsOf: logFile).contains(infoLog))
|
try XCTAssertTrue(String(contentsOf: logFile, encoding: .utf8).contains(infoLog))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testLogLevels() throws {
|
func testLogLevels() throws {
|
||||||
@@ -48,7 +48,7 @@ class LoggingTests: XCTestCase {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try XCTAssertFalse(String(contentsOf: logFile).contains(verboseLog))
|
try XCTAssertFalse(String(contentsOf: logFile, encoding: .utf8).contains(verboseLog))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is meant to test the `Target.tests.configure(…)`, but at this stage the test is somewhat pointless
|
/// This is meant to test the `Target.tests.configure(…)`, but at this stage the test is somewhat pointless
|
||||||
@@ -103,7 +103,7 @@ class LoggingTests: XCTestCase {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let content = try String(contentsOf: logFile)
|
let content = try String(contentsOf: logFile, encoding: .utf8)
|
||||||
XCTAssertTrue(content.contains(roomSummary.id))
|
XCTAssertTrue(content.contains(roomSummary.id))
|
||||||
XCTAssertFalse(content.contains(roomName))
|
XCTAssertFalse(content.contains(roomName))
|
||||||
XCTAssertFalse(content.contains(lastMessage))
|
XCTAssertFalse(content.contains(lastMessage))
|
||||||
@@ -185,7 +185,7 @@ class LoggingTests: XCTestCase {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let content = try String(contentsOf: logFile)
|
let content = try String(contentsOf: logFile, encoding: .utf8)
|
||||||
XCTAssertTrue(content.contains(textMessage.id.uniqueID.value))
|
XCTAssertTrue(content.contains(textMessage.id.uniqueID.value))
|
||||||
XCTAssertFalse(content.contains(textMessage.body))
|
XCTAssertFalse(content.contains(textMessage.body))
|
||||||
XCTAssertFalse(content.contains(textAttributedString))
|
XCTAssertFalse(content.contains(textAttributedString))
|
||||||
@@ -254,7 +254,7 @@ class LoggingTests: XCTestCase {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let content = try String(contentsOf: logFile)
|
let content = try String(contentsOf: logFile, encoding: .utf8)
|
||||||
XCTAssertTrue(content.contains(String(describing: TextMessageContent.self)))
|
XCTAssertTrue(content.contains(String(describing: TextMessageContent.self)))
|
||||||
XCTAssertFalse(content.contains(textString))
|
XCTAssertFalse(content.contains(textString))
|
||||||
|
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ final class NotificationManagerTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NotificationManagerTests: NotificationManagerDelegate {
|
extension NotificationManagerTests: @MainActor NotificationManagerDelegate {
|
||||||
func registerForRemoteNotifications() {
|
func registerForRemoteNotifications() {
|
||||||
authorizationStatusWasGranted = true
|
authorizationStatusWasGranted = true
|
||||||
registerForRemoteNotificationsDelegateCalled?()
|
registerForRemoteNotificationsDelegateCalled?()
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class RoomDetailsEditScreenViewModelTests: XCTestCase {
|
|||||||
XCTAssertFalse(context.viewState.canSave)
|
XCTAssertFalse(context.viewState.canSave)
|
||||||
XCTAssertNil(context.alertInfo)
|
XCTAssertNil(context.alertInfo)
|
||||||
|
|
||||||
var deferred = deferFulfillment(viewModel.actions) { $0 == .cancel }
|
let deferred = deferFulfillment(viewModel.actions) { $0 == .cancel }
|
||||||
context.send(viewAction: .cancel)
|
context.send(viewAction: .cancel)
|
||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
XCTAssertNil(context.alertInfo)
|
XCTAssertNil(context.alertInfo)
|
||||||
|
|||||||
Reference in New Issue
Block a user