Improve detection of link device completion when linking a new device via QR (#5323)
* Improve detection of link device completion * Fix tests to match
This commit is contained in:
@@ -224,12 +224,10 @@ class QRCodeLoginScreenViewModel: QRCodeLoginScreenViewModelType, QRCodeLoginScr
|
|||||||
case .waitingForAuthorisation(let url):
|
case .waitingForAuthorisation(let url):
|
||||||
requestOIDCAuthorization(url: url)
|
requestOIDCAuthorization(url: url)
|
||||||
case .syncingSecrets:
|
case .syncingSecrets:
|
||||||
// break // Nothing to do.
|
break // Nothing to do.
|
||||||
// .done is rarely received at the moment, so lets consider linking to be done here.
|
case .done:
|
||||||
MXLog.info("Link with QR code completed.")
|
MXLog.info("Link with QR code completed.")
|
||||||
actionsSubject.send(.linkedDevice)
|
actionsSubject.send(.linkedDevice)
|
||||||
case .done:
|
|
||||||
break // Not necessary right now with the workaround above in place.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ class LinkNewDeviceService: LinkNewDeviceServiceProtocol {
|
|||||||
do {
|
do {
|
||||||
// Note: The SDK doesn't provide us with a way to cancel the 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.
|
||||||
|
// We send the .done progress in case the listener didn't get a chance to pass it on from the SDK before being deallocated
|
||||||
|
progressSubject.send(LinkMobileProgress.done)
|
||||||
} catch let error as HumanQrGrantLoginError {
|
} catch let error as HumanQrGrantLoginError {
|
||||||
MXLog.error("QR code reciprocate error: \(error)")
|
MXLog.error("QR code reciprocate error: \(error)")
|
||||||
progressSubject.send(completion: .failure(.init(rustError: error)))
|
progressSubject.send(completion: .failure(.init(rustError: error)))
|
||||||
@@ -105,6 +107,8 @@ class LinkNewDeviceService: LinkNewDeviceServiceProtocol {
|
|||||||
do {
|
do {
|
||||||
// Note: The SDK doesn't provide us with a way to cancel the 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.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.
|
||||||
|
// We send the .done progress in case the listener didn't get a chance to pass it on from the SDK before being deallocated
|
||||||
|
progressSubject.send(LinkDesktopProgress.done)
|
||||||
} catch let error as HumanQrGrantLoginError {
|
} catch let error as HumanQrGrantLoginError {
|
||||||
MXLog.error("QR code reciprocate error: \(error)")
|
MXLog.error("QR code reciprocate error: \(error)")
|
||||||
progressSubject.send(completion: .failure(.init(rustError: error)))
|
progressSubject.send(completion: .failure(.init(rustError: error)))
|
||||||
|
|||||||
@@ -189,18 +189,17 @@ struct QRCodeLoginScreenViewModelTests {
|
|||||||
linkMobileProgressSubject.send(.waitingForAuthorisation(verificationURL: .homeDirectory))
|
linkMobileProgressSubject.send(.waitingForAuthorisation(verificationURL: .homeDirectory))
|
||||||
try await deferredAction.fulfill()
|
try await deferredAction.fulfill()
|
||||||
|
|
||||||
// Note: The SDK rarely sends the done action, so this test has been updated for the workaround of finishing early.
|
let currentState = context.viewState.state
|
||||||
|
let deferredFailure = deferFailure(context.$viewState, timeout: .seconds(1)) { $0.state != currentState }
|
||||||
|
linkMobileProgressSubject.send(.syncingSecrets)
|
||||||
|
try await deferredFailure.fulfill()
|
||||||
|
|
||||||
deferredAction = deferFulfillment(viewModel.actionsPublisher) { action in
|
deferredAction = deferFulfillment(viewModel.actionsPublisher) { action in
|
||||||
guard case .linkedDevice = action else { return false }
|
guard case .linkedDevice = action else { return false }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
linkMobileProgressSubject.send(.syncingSecrets)
|
|
||||||
try await deferredAction.fulfill()
|
|
||||||
|
|
||||||
let currentState = context.viewState.state
|
|
||||||
let deferredFailure = deferFailure(context.$viewState, timeout: .seconds(1)) { $0.state != currentState }
|
|
||||||
linkMobileProgressSubject.send(.done)
|
linkMobileProgressSubject.send(.done)
|
||||||
try await deferredFailure.fulfill()
|
try await deferredAction.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Helpers
|
// MARK: - Helpers
|
||||||
|
|||||||
Reference in New Issue
Block a user