mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
added tests
This commit is contained in:
@@ -7,34 +7,26 @@
|
||||
//
|
||||
|
||||
import Combine
|
||||
import CoreLocation
|
||||
@testable import ElementX
|
||||
import Testing
|
||||
|
||||
@MainActor
|
||||
struct LocationSharingScreenViewModelTests {
|
||||
private let timelineProxy = TimelineProxyMock(.init())
|
||||
private var viewModel: LocationSharingScreenViewModelProtocol
|
||||
var timelineProxy: TimelineProxyMock!
|
||||
var viewModel: LocationSharingScreenViewModel!
|
||||
|
||||
private var context: LocationSharingScreenViewModel.Context {
|
||||
var context: LocationSharingScreenViewModel.Context {
|
||||
viewModel.context
|
||||
}
|
||||
|
||||
init() {
|
||||
let viewModel = LocationSharingScreenViewModel(interactionMode: .picker,
|
||||
mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration,
|
||||
liveLocationSharingEnabled: true,
|
||||
roomProxy: JoinedRoomProxyMock(.init()),
|
||||
timelineController: MockTimelineController(timelineProxy: timelineProxy),
|
||||
liveLocationManager: LiveLocationManagerMock(),
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
viewModel.state.bindings.isLocationAuthorized = true
|
||||
self.viewModel = viewModel
|
||||
AppSettings.resetAllSettings()
|
||||
}
|
||||
|
||||
@Test
|
||||
func userDidPan() {
|
||||
mutating func userDidPan() {
|
||||
setupViewModel()
|
||||
#expect(context.viewState.isSharingUserLocation)
|
||||
#expect(context.showsUserLocationMode == .showAndFollow)
|
||||
context.send(viewAction: .userDidPan)
|
||||
@@ -43,7 +35,8 @@ struct LocationSharingScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func centerOnUser() {
|
||||
mutating func centerOnUser() {
|
||||
setupViewModel()
|
||||
#expect(context.viewState.isSharingUserLocation)
|
||||
context.showsUserLocationMode = .show
|
||||
#expect(!context.viewState.isSharingUserLocation)
|
||||
@@ -53,7 +46,8 @@ struct LocationSharingScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func centerOnUserWithoutAuth() {
|
||||
mutating func centerOnUserWithoutAuth() {
|
||||
setupViewModel()
|
||||
context.showsUserLocationMode = .hide
|
||||
context.isLocationAuthorized = nil
|
||||
context.send(viewAction: .centerToUser)
|
||||
@@ -61,7 +55,8 @@ struct LocationSharingScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func centerOnUserWithDeniedAuth() {
|
||||
mutating func centerOnUserWithDeniedAuth() {
|
||||
setupViewModel()
|
||||
context.isLocationAuthorized = false
|
||||
context.showsUserLocationMode = .hide
|
||||
context.send(viewAction: .centerToUser)
|
||||
@@ -70,7 +65,8 @@ struct LocationSharingScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func errorMapping() {
|
||||
mutating func errorMapping() {
|
||||
setupViewModel()
|
||||
let mapError = AlertInfo(locationSharingViewError: .mapError(.failedLoadingMap))
|
||||
#expect(mapError.title == L10n.errorFailedLoadingMap(InfoPlistReader.main.bundleDisplayName))
|
||||
let locationError = AlertInfo(locationSharingViewError: .mapError(.failedLocatingUser))
|
||||
@@ -80,7 +76,8 @@ struct LocationSharingScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func sendUserLocation() async throws {
|
||||
mutating func sendUserLocation() async throws {
|
||||
setupViewModel()
|
||||
context.mapCenterLocation = .init(latitude: 0, longitude: 0)
|
||||
context.geolocationUncertainty = 10
|
||||
|
||||
@@ -101,7 +98,8 @@ struct LocationSharingScreenViewModelTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func sendPickedLocation() async throws {
|
||||
mutating func sendPickedLocation() async throws {
|
||||
setupViewModel()
|
||||
context.mapCenterLocation = .init(latitude: 0, longitude: 0)
|
||||
context.isLocationAuthorized = nil
|
||||
context.geolocationUncertainty = 10
|
||||
@@ -121,4 +119,101 @@ struct LocationSharingScreenViewModelTests {
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Live Location Authorization Tests
|
||||
|
||||
@Test
|
||||
mutating func startLiveLocationWithDeniedAuth() {
|
||||
setupViewModel(liveLocationManagerConfiguration: .init(authorizationStatus: .denied))
|
||||
context.send(viewAction: .startLiveLocation)
|
||||
#expect(context.alertInfo?.id == .missingAlwaysAuthorization)
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func startLiveLocationWithRestrictedAuth() {
|
||||
setupViewModel(liveLocationManagerConfiguration: .init(authorizationStatus: .restricted))
|
||||
context.send(viewAction: .startLiveLocation)
|
||||
#expect(context.alertInfo?.id == .missingAlwaysAuthorization)
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func startLiveLocationWithAlwaysAuth() {
|
||||
setupViewModel(liveLocationManagerConfiguration: .init(authorizationStatus: .authorizedAlways))
|
||||
context.send(viewAction: .startLiveLocation)
|
||||
#expect(context.alertInfo == nil)
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func startLiveLocationWithWhenInUseAuthAlreadyRequested() {
|
||||
setupViewModel(liveLocationManagerConfiguration: .init(authorizationStatus: .authorizedWhenInUse,
|
||||
requestAlwaysAuthorizationIfPossibleReturnValue: false))
|
||||
context.send(viewAction: .startLiveLocation)
|
||||
#expect(context.alertInfo?.id == .missingAlwaysAuthorization)
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func startLiveLocationWithWhenInUseAuthNotYetRequested() {
|
||||
setupViewModel(liveLocationManagerConfiguration: .init(authorizationStatus: .authorizedWhenInUse,
|
||||
requestAlwaysAuthorizationIfPossibleReturnValue: true))
|
||||
context.send(viewAction: .startLiveLocation)
|
||||
// The request can be made, so no alert should be shown — it waits for the user to respond to the system prompt
|
||||
#expect(context.alertInfo == nil)
|
||||
}
|
||||
|
||||
@Test
|
||||
mutating func startLiveLocationWithNotDeterminedAuthTransitionsToWhenInUse() async {
|
||||
let authorizationStatusSubject = CurrentValueSubject<CLAuthorizationStatus, Never>(.notDetermined)
|
||||
let liveLocationManagerMock = LiveLocationManagerMock()
|
||||
liveLocationManagerMock.underlyingAuthorizationStatus = .init(authorizationStatusSubject)
|
||||
liveLocationManagerMock.requestAlwaysAuthorizationIfPossibleReturnValue = true
|
||||
setupViewModel(liveLocationManagerMock: liveLocationManagerMock)
|
||||
|
||||
context.send(viewAction: .startLiveLocation)
|
||||
|
||||
// No alert yet — waiting for MapLibre to resolve the status to whenInUse
|
||||
#expect(context.alertInfo == nil)
|
||||
|
||||
// Simulate MapLibre resolving the authorization to whenInUse, and confirm that the ViewModel
|
||||
// recurses and calls requestAlwaysAuthorizationIfPossible as a result
|
||||
await waitForConfirmation { confirmation in
|
||||
liveLocationManagerMock.requestAlwaysAuthorizationIfPossibleClosure = {
|
||||
confirmation()
|
||||
return true
|
||||
}
|
||||
authorizationStatusSubject.send(.authorizedWhenInUse)
|
||||
}
|
||||
|
||||
// The request was made, so no alert — waiting for the always authorization prompt response
|
||||
#expect(context.alertInfo == nil)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private mutating func setupViewModel(liveLocationManagerConfiguration: LiveLocationManagerMock.Configuration = .init()) {
|
||||
timelineProxy = TimelineProxyMock(.init())
|
||||
viewModel = LocationSharingScreenViewModel(interactionMode: .picker,
|
||||
mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration,
|
||||
liveLocationSharingEnabled: true,
|
||||
roomProxy: JoinedRoomProxyMock(.init()),
|
||||
timelineController: MockTimelineController(timelineProxy: timelineProxy),
|
||||
liveLocationManager: LiveLocationManagerMock(liveLocationManagerConfiguration),
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
viewModel.state.bindings.isLocationAuthorized = true
|
||||
}
|
||||
|
||||
private mutating func setupViewModel(liveLocationManagerMock: LiveLocationManagerMock) {
|
||||
timelineProxy = TimelineProxyMock(.init())
|
||||
viewModel = LocationSharingScreenViewModel(interactionMode: .picker,
|
||||
mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration,
|
||||
liveLocationSharingEnabled: true,
|
||||
roomProxy: JoinedRoomProxyMock(.init()),
|
||||
timelineController: MockTimelineController(timelineProxy: timelineProxy),
|
||||
liveLocationManager: liveLocationManagerMock,
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
viewModel.state.bindings.isLocationAuthorized = true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user