// // HistoryTests.swift // AutoCatTests // // Created by Selim Mustafaev on 09.02.2025. // Copyright © 2025 Selim Mustafaev. All rights reserved. // import Testing import Mockable import AutoCatCore @testable import AutoCat import Foundation @MainActor struct HistoryTests { let storageServiceMock = MockStorageServiceProtocol() let apiServiceMock = MockApiServiceProtocol() let vehicleServiceMock = MockVehicleServiceProtocol() var viewModel: HistoryViewModel init() async { viewModel = HistoryViewModel( apiService: apiServiceMock, storageService: storageServiceMock, vehicleService: vehicleServiceMock ) } @Test("History (show filtered vehicles)", arguments: HistoryFilter.allCases) func historyShowFilteredVehicles(_ filter: HistoryFilter) async { let dbURL = URL(fileURLWithPath: "testDbUrl") let vehicles: [VehicleDto] = switch filter { case .all: [.normal, .unrecognizedVehicle, .outdatedVehicle, .needSyncVehicle] case .unrecognized: [.unrecognizedVehicle] case .outdated: [.outdatedVehicle] case .notSynced: [.needSyncVehicle] } given(storageServiceMock) .loadVehicles() .willReturn(vehicles) given(storageServiceMock) .dbFileURL .willReturn(dbURL) await viewModel.onAppear() viewModel.filter = filter viewModel.applyFilters() #expect(viewModel.vehicles == vehicles) #expect(viewModel.vehiclesFiltered == vehicles) #expect(viewModel.vehicleSections.count == 1) #expect(viewModel.dbFileURL == dbURL) #expect(viewModel.hud == nil) } @Test("History (search vehicles)") func historySearchVehicles() async { let vehicles: [VehicleDto] = [ .init(number: "А123АА761"), .init(number: "А456ВВ761"), .init(number: "А456ЕЕ761"), .init(number: "А456ОО761"), .init(number: "А123ММ161"), .init(number: "А123НН761") ] given(storageServiceMock) .loadVehicles() .willReturn(vehicles) given(storageServiceMock) .dbFileURL .willReturn(nil) await viewModel.onAppear() viewModel.searchText = "123..761" #expect(viewModel.vehicles.count == 6) #expect(viewModel.vehiclesFiltered.count == 2) #expect(viewModel.vehiclesFiltered[0].number == "А123АА761") #expect(viewModel.vehiclesFiltered[1].number == "А123НН761") #expect(viewModel.dbFileURL == nil) } @Test("History (delete vehicle)") func historyDeleteVehicle() async { given(storageServiceMock) .loadVehicles() .willReturn([.normal]) given(storageServiceMock) .dbFileURL .willReturn(nil) given(storageServiceMock) .deleteVehicle(number: .any) .willReturn() when(storageServiceMock) .loadVehicles() .perform { given(storageServiceMock) .loadVehicles() .willReturn([]) } await viewModel.onAppear() await viewModel.deleteVehicle(.normal) verify(storageServiceMock) .deleteVehicle(number: .any) .called(.once) verify(storageServiceMock) .loadVehicles() .called(.exactly(2)) #expect(viewModel.vehicles.isEmpty) #expect(viewModel.vehiclesFiltered.isEmpty) #expect(viewModel.vehicleSections.isEmpty) } @Test("History (update vehicle)") func historyUpdateVehicle() async { let updatedVehicle: VehicleDto = .normal.addNote(text: "123") given(storageServiceMock) .loadVehicles() .willReturn([.normal]) given(storageServiceMock) .dbFileURL .willReturn(nil) given(vehicleServiceMock) .updateHistory(number: .any) .willReturn((vehicle: updatedVehicle, errors: [])) when(storageServiceMock) .loadVehicles() .perform { given(storageServiceMock) .loadVehicles() .willReturn([updatedVehicle]) } await viewModel.onAppear() await viewModel.updateVehicle(.normal) verify(vehicleServiceMock) .updateHistory(number: .any) .called(.once) verify(storageServiceMock) .loadVehicles() .called(.exactly(3)) #expect(viewModel.vehicles.count == 1) #expect(viewModel.vehiclesFiltered.count == 1) #expect(viewModel.vehicles.first?.notes.first?.text == "123") } @Test("History (error deleting)") func historyErrorDeleting() async { given(storageServiceMock) .loadVehicles() .willReturn([.normal]) given(storageServiceMock) .dbFileURL .willReturn(nil) given(storageServiceMock) .deleteVehicle(number: .any) .willThrow(TestError.generic) await viewModel.onAppear() await viewModel.deleteVehicle(.normal) #expect(viewModel.vehicles.count == 1) #expect(viewModel.vehiclesFiltered.count == 1) #expect(viewModel.hud == .error(TestError.generic)) } @Test("History (error updating)") func historyErrorUpdating() async { given(storageServiceMock) .loadVehicles() .willReturn([.normal]) given(storageServiceMock) .dbFileURL .willReturn(nil) given(vehicleServiceMock) .updateHistory(number: .any) .willThrow(TestError.generic) await viewModel.onAppear() await viewModel.updateVehicle(.normal) #expect(viewModel.hud == .error(TestError.generic)) } }