Link new device with QR code tweaks. (#5563)

* Hook up Rust's InvalidCheckCode failure to the right state when linking a new device.

* Automatically regenerate a new QR code instead of ending the flow when it expires.
This commit is contained in:
Doug
2026-05-11 14:22:34 +01:00
committed by GitHub
parent ded86dd66e
commit e235e3ba81
11 changed files with 106 additions and 31 deletions
@@ -9,6 +9,7 @@
import Combine
@testable import ElementX
import MatrixRustSDKMocks
import SwiftUI
import Testing
@MainActor
@@ -18,6 +19,7 @@ struct QRCodeLoginScreenViewModelTests {
var qrLoginProgressSubject: CurrentValueSubject<QRLoginProgress, AuthenticationServiceError>!
var qrCodeLoginService: QRCodeLoginServiceMock!
var regeneratedQRCodeImage: UIImage!
var linkMobileProgressSubject: CurrentValueSubject<LinkNewDeviceService.LinkMobileProgress, QRCodeLoginError>!
var linkDesktopProgressSubject: CurrentValueSubject<LinkNewDeviceService.LinkDesktopProgress, QRCodeLoginError>!
var linkNewDeviceService: LinkNewDeviceServiceMock!
@@ -202,6 +204,17 @@ struct QRCodeLoginScreenViewModelTests {
try await deferredAction.fulfill()
}
@Test
mutating func linkMobileDeviceQRCodeExpiry() async throws {
setup(mode: .linkMobile)
#expect(context.viewState.state.isDisplayQR)
let deferred = deferFulfillment(context.$viewState, keyPath: \.state, transitionValues: [.displayQR(.expired),
.displayQR(.active(regeneratedQRCodeImage))])
linkMobileProgressSubject.send(completion: .failure(.expired))
try await deferred.fulfill()
}
// MARK: - Helpers
private mutating func setup(mode: Mode) {
@@ -214,6 +227,11 @@ struct QRCodeLoginScreenViewModelTests {
linkNewDeviceService = LinkNewDeviceServiceMock(.init(linkMobileProgressPublisher: linkMobileProgressSubject.asCurrentValuePublisher(),
linkDesktopProgressPublisher: linkDesktopProgressSubject.asCurrentValuePublisher()))
regeneratedQRCodeImage = LinkNewDeviceServiceMock.mockQRCodeImage
let clientProxy = ClientProxyMock(.init())
clientProxy.linkNewDeviceServiceReturnValue = LinkNewDeviceServiceMock(.init(linkMobileProgressPublisher: .init(.qrReady(regeneratedQRCodeImage)),
linkDesktopProgressPublisher: .init(.starting)))
let screenMode: QRCodeLoginScreenMode
switch mode {
case .login:
@@ -221,7 +239,7 @@ struct QRCodeLoginScreenViewModelTests {
case .linkDesktop:
screenMode = .linkDesktop(linkNewDeviceService)
case .linkMobile:
screenMode = .linkMobile(linkNewDeviceService.linkMobileDevice())
screenMode = .linkMobile(linkNewDeviceService.linkMobileDevice(), clientProxy)
}
appMediator = AppMediatorMock.default