// // LocationServiceTests.swift // AutoCatCoreTests // // Created by Selim Mustafaev on 01.08.2024. // Copyright © 2024 Selim Mustafaev. All rights reserved. // import Testing import CoreLocation @testable import AutoCatCore @MainActor struct LocationServiceTests { let latitude: CLLocationDegrees = 10 let longitude: CLLocationDegrees = 10 let address = "Test Address" let geocoder = GeocoderMock() let locationManager = SwiftLocationMock() let locationService: LocationService init() { self.locationService = LocationService(geocoder: geocoder, locationManager: locationManager) } @Test func getValidAddress() async throws { geocoder.addLocation(latitude: latitude, longitude: longitude, address: address) let result = try await locationService.getAddressForLocation(latitude: latitude, longitude: longitude) #expect(result == address) } @Test func getNilAddress() async throws { geocoder.addLocation(latitude: latitude, longitude: longitude, address: nil) await #expect(throws: LocationError.reverseGeocode) { _ = try await locationService.getAddressForLocation(latitude: latitude, longitude: longitude) } } @Test func addressNotFound() async throws { await #expect(throws: LocationError.reverseGeocode) { _ = try await locationService.getAddressForLocation(latitude: latitude, longitude: longitude) } } @Test("Get location: denied") func getLocationDenied() async throws { locationManager.authorizationStatus = .denied await #expect(throws: CLError(.denied)) { _ = try await locationService.requestCurrentLocation() } } @Test("Get location: not determined -> denied") func getLocationNotDeterminedDenied() async throws { locationManager.authorizationStatus = .notDetermined locationManager.requestedStatus = .denied await #expect(throws: CLError(.denied)) { _ = try await locationService.requestCurrentLocation() } } @Test("Get location: not determined -> allow") func getLocationNotDeterminedAllow() async throws { locationManager.authorizationStatus = .notDetermined locationManager.requestedStatus = .authorizedWhenInUse locationManager.location = CLLocation(latitude: latitude, longitude: longitude) let event = try await locationService.requestCurrentLocation() #expect(event.latitude == latitude) #expect(event.longitude == longitude) } @Test("Get location: normal") func getLocationNormal() async throws { locationManager.authorizationStatus = .authorizedWhenInUse locationManager.location = CLLocation(latitude: latitude, longitude: longitude) let event = try await locationService.requestCurrentLocation() #expect(event.latitude == latitude) #expect(event.longitude == longitude) } @Test("Get location: no location") func getLocationNone() async throws { locationManager.authorizationStatus = .authorizedWhenInUse await #expect(throws: LocationError.generic) { _ = try await locationService.requestCurrentLocation() } } @Test("Get location: parallel requests") func getLocationParallel() async throws { locationManager.authorizationStatus = .authorizedWhenInUse locationManager.location = CLLocation(latitude: latitude, longitude: longitude) locationManager.requestLocationTime = 1 async let task1 = locationService.requestCurrentLocation() async let task2 = locationService.requestCurrentLocation() try await Task.sleep(nanoseconds: 1_500_000_000) async let task3 = locationService.requestCurrentLocation() let (event1, event2, event3) = try await (task1, task2, task3) #expect(locationManager.requestLocationCount == 2) #expect(event1.latitude == latitude) #expect(event1.longitude == longitude) #expect(event2.latitude == latitude) #expect(event2.longitude == longitude) #expect(event3.latitude == latitude) #expect(event3.longitude == longitude) } }