Fix LiveLocationManager flaky tests (#5389)
This commit is contained in:
@@ -192,6 +192,7 @@
|
||||
1C8BC70A18060677E295A846 /* ShareToMapsAppActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4481799F455B3DA243BDA2AC /* ShareToMapsAppActivity.swift */; };
|
||||
1C9BB74711E5F24C77B7FED0 /* RoomMembersListScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AEA0B743847CFA5B3C38EE4 /* RoomMembersListScreenCoordinator.swift */; };
|
||||
1CA094038D4D036A6F0A1314 /* VoiceMessageTrashButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABF84AA68B2B7584D9275769 /* VoiceMessageTrashButton.swift */; };
|
||||
1D2D713A5A269072D103AE37 /* CLLocationManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA46D6DD4B4AB17E1D45092E /* CLLocationManagerProtocol.swift */; };
|
||||
1D5DC685CED904386C89B7DA /* NSRegularExpresion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BAC0F6C9644336E9567EE6 /* NSRegularExpresion.swift */; };
|
||||
1D623953F970D11F6F38499C /* AppLockService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851B95BB98649B8E773D6790 /* AppLockService.swift */; };
|
||||
1D69E31913DF66426985909B /* EmojiPickerScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11151E78D6BB2B04A8FBD389 /* EmojiPickerScreenViewModelProtocol.swift */; };
|
||||
@@ -624,6 +625,7 @@
|
||||
69DE29C3E3180BB17D840690 /* ProgressCursorModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97C8E13A1FBA717B0C277ECC /* ProgressCursorModifier.swift */; };
|
||||
6A38D0A2BC3943A92D82576E /* EditRoomAddressScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7B18089ED50324583BB2FB7 /* EditRoomAddressScreenViewModelProtocol.swift */; };
|
||||
6A54F52443EC52AC5CD772C0 /* JoinRoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869A8A4632E511351BFE2EC4 /* JoinRoomScreen.swift */; };
|
||||
6A5FDF9306CBD62C7EDDB552 /* CLLocationManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C723327DC4A3093CD9675B27 /* CLLocationManagerMock.swift */; };
|
||||
6A64546ABE648ED9E6DBB459 /* RemoteSettingsHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D186A6DB8FAC5C9D0E4D61 /* RemoteSettingsHook.swift */; };
|
||||
6AB306367E56A6F6DFA0E2FF /* RoomSummaryProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46E441BA50705E6CEC89FE0 /* RoomSummaryProviderTests.swift */; };
|
||||
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
|
||||
@@ -2706,6 +2708,7 @@
|
||||
C6A9F49B3EE59147AF2F70BB /* SeparatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderAvatarImage.swift; sourceTree = "<group>"; };
|
||||
C715CFE00686DACA59D836EA /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||
C723327DC4A3093CD9675B27 /* CLLocationManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLLocationManagerMock.swift; sourceTree = "<group>"; };
|
||||
C729D95CB4588D4D9AAC3DFA /* RoomChangePermissionsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangePermissionsScreenModels.swift; sourceTree = "<group>"; };
|
||||
C75EF87651B00A176AB08E97 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
C75FE3F524B575D53787868C /* TimelineMediaPreviewRedactConfirmationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaPreviewRedactConfirmationView.swift; sourceTree = "<group>"; };
|
||||
@@ -2810,6 +2813,7 @@
|
||||
D9C5AA3EF7EC67C01C75CEDD /* LabsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabsScreen.swift; sourceTree = "<group>"; };
|
||||
DA14564EE143F73F7E4D1F79 /* RoomNotificationSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsScreenModels.swift; sourceTree = "<group>"; };
|
||||
DA3D82522494E78746B2214E /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||
DA46D6DD4B4AB17E1D45092E /* CLLocationManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLLocationManagerProtocol.swift; sourceTree = "<group>"; };
|
||||
DAB8D7926A5684E18196B538 /* VoiceMessageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageCache.swift; sourceTree = "<group>"; };
|
||||
DADECBBB672497BCD4822468 /* Result.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = "<group>"; };
|
||||
DB06F22CFA34885B40976061 /* RoomDetailsEditScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreen.swift; sourceTree = "<group>"; };
|
||||
@@ -3730,6 +3734,7 @@
|
||||
8F7FC9580CABF797A2E6213A /* BugReportServiceMock.swift */,
|
||||
633BAD3D9BB44B2AED7CBB93 /* ClassicAppManagerMock.swift */,
|
||||
E2F96CCBEAAA7F2185BFA354 /* ClientProxyMock.swift */,
|
||||
C723327DC4A3093CD9675B27 /* CLLocationManagerMock.swift */,
|
||||
4E600B315B920B9687F8EE1B /* ComposerDraftServiceMock.swift */,
|
||||
86E1BAA7232081635662A83F /* CXProviderMock.swift */,
|
||||
E321E840DCC63790049984F4 /* ElementCallServiceMock.swift */,
|
||||
@@ -5454,6 +5459,7 @@
|
||||
90FD376E9373246E4925CE95 /* Location */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA46D6DD4B4AB17E1D45092E /* CLLocationManagerProtocol.swift */,
|
||||
D17F49E39CC38DAB7B305701 /* LiveLocationManager.swift */,
|
||||
33752AE856E93CE62412B7A1 /* LiveLocationManagerProtocol.swift */,
|
||||
);
|
||||
@@ -8120,6 +8126,8 @@
|
||||
9A8E6FCD86B89970EC72EFD8 /* BugReportServiceMock.swift in Sources */,
|
||||
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */,
|
||||
E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */,
|
||||
6A5FDF9306CBD62C7EDDB552 /* CLLocationManagerMock.swift in Sources */,
|
||||
1D2D713A5A269072D103AE37 /* CLLocationManagerProtocol.swift in Sources */,
|
||||
5470E62F65AE1803BBF3D528 /* CXProviderMock.swift in Sources */,
|
||||
3D0DAED550E967AB49F1758C /* CXProviderProtocol.swift in Sources */,
|
||||
01B63F1A04A276B39AC17014 /* CallInviteRoomTimelineItem.swift in Sources */,
|
||||
|
||||
20
ElementX/Sources/Mocks/CLLocationManagerMock.swift
Normal file
20
ElementX/Sources/Mocks/CLLocationManagerMock.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import CoreLocation
|
||||
|
||||
extension CLLocationManagerMock {
|
||||
struct Configuration {
|
||||
var authorizationStatus: CLAuthorizationStatus = .authorizedAlways
|
||||
}
|
||||
|
||||
convenience init(_ configuration: Configuration) {
|
||||
self.init()
|
||||
|
||||
underlyingAuthorizationStatus = configuration.authorizationStatus
|
||||
}
|
||||
}
|
||||
@@ -2187,6 +2187,65 @@ class BugReportServiceMock: BugReportServiceProtocol, @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
}
|
||||
class CLLocationManagerMock: CLLocationManagerProtocol, @unchecked Sendable {
|
||||
weak var delegate: CLLocationManagerDelegate?
|
||||
var allowsBackgroundLocationUpdates: Bool {
|
||||
get { return underlyingAllowsBackgroundLocationUpdates }
|
||||
set(value) { underlyingAllowsBackgroundLocationUpdates = value }
|
||||
}
|
||||
var underlyingAllowsBackgroundLocationUpdates: Bool!
|
||||
var desiredAccuracy: CLLocationAccuracy {
|
||||
get { return underlyingDesiredAccuracy }
|
||||
set(value) { underlyingDesiredAccuracy = value }
|
||||
}
|
||||
var underlyingDesiredAccuracy: CLLocationAccuracy!
|
||||
var pausesLocationUpdatesAutomatically: Bool {
|
||||
get { return underlyingPausesLocationUpdatesAutomatically }
|
||||
set(value) { underlyingPausesLocationUpdatesAutomatically = value }
|
||||
}
|
||||
var underlyingPausesLocationUpdatesAutomatically: Bool!
|
||||
var authorizationStatus: CLAuthorizationStatus {
|
||||
get { return underlyingAuthorizationStatus }
|
||||
set(value) { underlyingAuthorizationStatus = value }
|
||||
}
|
||||
var underlyingAuthorizationStatus: CLAuthorizationStatus!
|
||||
|
||||
//MARK: - requestAlwaysAuthorization
|
||||
|
||||
var requestAlwaysAuthorizationUnderlyingCallsCount = 0
|
||||
var requestAlwaysAuthorizationCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return requestAlwaysAuthorizationUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = requestAlwaysAuthorizationUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
requestAlwaysAuthorizationUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
requestAlwaysAuthorizationUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var requestAlwaysAuthorizationCalled: Bool {
|
||||
return requestAlwaysAuthorizationCallsCount > 0
|
||||
}
|
||||
var requestAlwaysAuthorizationClosure: (() -> Void)?
|
||||
|
||||
func requestAlwaysAuthorization() {
|
||||
requestAlwaysAuthorizationCallsCount += 1
|
||||
requestAlwaysAuthorizationClosure?()
|
||||
}
|
||||
}
|
||||
class CXProviderMock: CXProviderProtocol, @unchecked Sendable {
|
||||
|
||||
//MARK: - setDelegate
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import CoreLocation
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol CLLocationManagerProtocol: AnyObject {
|
||||
var delegate: CLLocationManagerDelegate? { get set }
|
||||
var allowsBackgroundLocationUpdates: Bool { get set }
|
||||
var desiredAccuracy: CLLocationAccuracy { get set }
|
||||
var pausesLocationUpdatesAutomatically: Bool { get set }
|
||||
var authorizationStatus: CLAuthorizationStatus { get }
|
||||
|
||||
func requestAlwaysAuthorization()
|
||||
}
|
||||
|
||||
extension CLLocationManager: CLLocationManagerProtocol { }
|
||||
@@ -10,7 +10,7 @@ import CoreLocation
|
||||
|
||||
class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationManagerDelegate {
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
private let locationManager: CLLocationManager
|
||||
private let locationManager: CLLocationManagerProtocol
|
||||
private let appSettings: AppSettings
|
||||
|
||||
private let authorizationStatusSubject: CurrentValueSubject<CLAuthorizationStatus, Never>
|
||||
@@ -30,21 +30,22 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
||||
|
||||
@MainActor
|
||||
init(clientProxy: ClientProxyProtocol,
|
||||
appSettings: AppSettings) {
|
||||
appSettings: AppSettings,
|
||||
locationManager: @autoclosure @MainActor () -> CLLocationManagerProtocol = CLLocationManager()) {
|
||||
self.clientProxy = clientProxy
|
||||
self.appSettings = appSettings
|
||||
// Very important, the CLLocationManager needs to be initialised on the main thread
|
||||
// or the delegate functions won't be handled!
|
||||
// https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate
|
||||
locationManager = CLLocationManager()
|
||||
authorizationStatusSubject = CurrentValueSubject(locationManager.authorizationStatus)
|
||||
self.locationManager = locationManager()
|
||||
authorizationStatusSubject = CurrentValueSubject(self.locationManager.authorizationStatus)
|
||||
|
||||
super.init()
|
||||
|
||||
locationManager.delegate = self
|
||||
locationManager.allowsBackgroundLocationUpdates = true
|
||||
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
|
||||
locationManager.pausesLocationUpdatesAutomatically = false
|
||||
self.locationManager.delegate = self
|
||||
self.locationManager.allowsBackgroundLocationUpdates = true
|
||||
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
|
||||
self.locationManager.pausesLocationUpdatesAutomatically = false
|
||||
|
||||
setupSubscriptions()
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import Testing
|
||||
@MainActor
|
||||
final class LiveLocationManagerTests {
|
||||
private var clientProxy: ClientProxyMock!
|
||||
private var locationManagerMock: CLLocationManagerMock!
|
||||
private var manager: LiveLocationManager!
|
||||
|
||||
private let appSettings: AppSettings
|
||||
@@ -20,7 +21,8 @@ final class LiveLocationManagerTests {
|
||||
AppSettings.resetAllSettings()
|
||||
appSettings = AppSettings()
|
||||
clientProxy = ClientProxyMock(.init())
|
||||
manager = LiveLocationManager(clientProxy: clientProxy, appSettings: appSettings)
|
||||
locationManagerMock = CLLocationManagerMock(.init())
|
||||
manager = LiveLocationManager(clientProxy: clientProxy, appSettings: appSettings, locationManager: locationManagerMock)
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
||||
Reference in New Issue
Block a user