// // LocationReportServiceTests.swift // suixinkanTests // import XCTest @testable import suixinkan @MainActor /// 位置上报共享服务测试。 final class LocationReportServiceTests: XCTestCase { private var appStore: AppStore! private var defaults: UserDefaults! override func setUp() { defaults = UserDefaults(suiteName: "LocationReportServiceTests")! defaults.removePersistentDomain(forName: "LocationReportServiceTests") appStore = AppStore(defaults: defaults) appStore.session.userId = "staff-1" appStore.session.currentScenicId = 100 } override func tearDown() { appStore.logout() super.tearDown() } func testReportLocationDecodesNumericStaffId() async throws { let reportJSON = """ {"code":100000,"msg":"success","data":{"staff_id":732,"expired":1783403917,"status":1,"store_user_id":732}} """.data(using: .utf8)! let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [reportJSON]))) let stateStore = HomeLocationStateStore(store: appStore) let service = LocationReportService(appStore: appStore, locationStateStore: stateStore) let result = try await service.reportWithCoordinates( api: api, latitude: 32.429921061197916, longitude: 119.44032958984376, address: "测试地址", type: 1 ) XCTAssertTrue(result.shouldShowSuccessDialog) XCTAssertTrue(stateStore.isOnline) } func testReportWithCoordinatesType2UsesProvidedLocation() async throws { let reportJSON = """ {"code":100000,"msg":"success","data":{"staff_id":"staff-1","expired":0,"status":1}} """.data(using: .utf8)! let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [reportJSON]))) let stateStore = HomeLocationStateStore(store: appStore) let service = LocationReportService(appStore: appStore, locationStateStore: stateStore) let result = try await service.reportWithCoordinates( api: api, latitude: 30.1, longitude: 120.2, address: "标记地址", type: 2 ) XCTAssertTrue(result.shouldShowSuccessDialog) XCTAssertEqual(result.locationInfoText, "标记地址") XCTAssertTrue(stateStore.isOnline) } func testManualReportUsesLowerLocationAccuracy() async throws { let reportJSON = """ {"code":100000,"msg":"success","data":{"staff_id":"staff-1","expired":0,"status":1}} """.data(using: .utf8)! let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [reportJSON]))) let stateStore = HomeLocationStateStore(store: appStore) let locationProvider = MockLocationProvider() let service = LocationReportService( appStore: appStore, locationStateStore: stateStore, locationProvider: locationProvider ) _ = try await service.manualReport(api: api) XCTAssertEqual( locationProvider.requestedSnapshotAccuracies, [LocationReportService.manualReportDesiredAccuracy] ) } func testTooFrequentManualReportThrows() async throws { let reportJSON = """ {"code":100000,"msg":"success","data":{"staff_id":"staff-1","expired":0,"status":1}} """.data(using: .utf8)! let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: [reportJSON, reportJSON]))) let stateStore = HomeLocationStateStore(store: appStore) let service = LocationReportService(appStore: appStore, locationStateStore: stateStore) _ = try await service.reportWithCoordinates( api: api, latitude: 30.0, longitude: 120.0, address: "测试地址", type: 1 ) do { _ = try await service.reportWithCoordinates( api: api, latitude: 30.0, longitude: 120.0, address: "测试地址", type: 1 ) XCTFail("Expected too frequent error") } catch let error as LocationReportServiceError { if case .tooFrequent = error { XCTAssertTrue(true) } else { XCTFail("Unexpected error \(error)") } } } func testMissingScenicThrows() async { appStore.session.currentScenicId = 0 let api = HomeAPI(client: APIClient(environment: .testing, session: MockURLSession(responses: []))) let stateStore = HomeLocationStateStore(store: appStore) let service = LocationReportService(appStore: appStore, locationStateStore: stateStore) do { _ = try await service.manualReport(api: api) XCTFail("Expected missing scenic") } catch let error as LocationReportServiceError { XCTAssertEqual(error, .missingScenic) } catch { XCTFail("Unexpected error \(error)") } } }