// // VehicleRecordServiceTests.swift // AutoCatCoreTests // // Created by Selim Mustafaev on 16.03.2025. // Copyright © 2025 Selim Mustafaev. All rights reserved. // import Testing import Mockable @testable import AutoCatCore import Foundation extension VehicleRecordService { func setUrl(_ url: URL) async { self.url = url } } struct VehicleRecordServiceTests { let locationServiceMock: MockLocationServiceProtocol let audioRecordServiceMock = MockAudioRecordServiceProtocol() let settingsServiceMock = MockSettingsServiceProtocol() var vehicleRecordService: VehicleRecordService init() async { self.locationServiceMock = await .init() self.vehicleRecordService = .init( recordService: audioRecordServiceMock, locationService: locationServiceMock, settingsService: settingsServiceMock ) } @Test("Requesting permissions") func requestPermissions() async throws { given(audioRecordServiceMock) .requestRecordPermissions() .willReturn(true) given(audioRecordServiceMock) .requestRecognitionAuthorization() .willReturn(.authorized) await vehicleRecordService.requestPermissionsIfNeeded() verify(audioRecordServiceMock) .requestRecordPermissions() .called(.once) verify(audioRecordServiceMock) .requestRecognitionAuthorization() .called(.once) } @Test("Start recording") func startRecording() async throws { given(audioRecordServiceMock) .startRecording(to: .any) .willReturn() given(locationServiceMock) .getRecentLocation() .willReturn(.valid) try await vehicleRecordService.startRecording() verify(audioRecordServiceMock) .startRecording(to: .any) .called(.once) await verify(locationServiceMock) .getRecentLocation() .calledEventually(1, before: .seconds(1)) await #expect(vehicleRecordService.url != nil) await #expect(vehicleRecordService.location != nil) await #expect(vehicleRecordService.locationTask != nil) } @Test("Start recording (location error)") func startRecordingLocationError() async throws { given(audioRecordServiceMock) .startRecording(to: .any) .willReturn() given(locationServiceMock) .getRecentLocation() .willThrow(TestError.generic) try await vehicleRecordService.startRecording() verify(audioRecordServiceMock) .startRecording(to: .any) .called(.once) await verify(locationServiceMock) .getRecentLocation() .calledEventually(1, before: .seconds(1)) await #expect(vehicleRecordService.url != nil) await #expect(vehicleRecordService.location == nil) await #expect(vehicleRecordService.locationTask != nil) } @Test("Stop recording") func stopRecording() async throws { await vehicleRecordService.setUrl(URL(string: "http://localhost")!) given(audioRecordServiceMock) .stopRecording() .willReturn() given(audioRecordServiceMock) .recognizeText(from: .any) .willReturn("123") given(audioRecordServiceMock) .getDuration(from: .any) .willReturn(123) let record = try await vehicleRecordService.stopRecording() verify(audioRecordServiceMock) .stopRecording() .called(.once) verify(audioRecordServiceMock) .recognizeText(from: .any) .called(.once) verify(audioRecordServiceMock) .getDuration(from: .any) .called(.once) #expect(await vehicleRecordService.url == nil) #expect(await vehicleRecordService.locationTask == nil) #expect(record.duration == 123) #expect(record.rawText == "123") } @Test("Stop recording (no URL)") func stopRecordingNoUrl() async throws { given(audioRecordServiceMock) .cancelRecording() .willReturn() await #expect(throws: VehicleRecordError.emptyUrl) { _ = try await vehicleRecordService.stopRecording() } verify(audioRecordServiceMock) .cancelRecording() .called(.once) } @Test("Cencel recording") func cancelRecording() async throws { await vehicleRecordService.setUrl(URL(string: "http://localhost")!) given(audioRecordServiceMock) .cancelRecording() .willReturn() given(audioRecordServiceMock) .startRecording(to: .any) .willReturn() given(locationServiceMock) .getRecentLocation() .willReturn(.valid) _ = try await vehicleRecordService.startRecording() await vehicleRecordService.cancelRecording() verify(audioRecordServiceMock) .startRecording(to: .any) .called(.once) verify(audioRecordServiceMock) .cancelRecording() .called(.once) #expect(await vehicleRecordService.url == nil) #expect(await vehicleRecordService.locationTask == nil) } }