// // NotesTests.swift // AutoCatTests // // Created by Selim Mustafaev on 13.07.2024. // Copyright © 2024 Selim Mustafaev. All rights reserved. // import Testing import AutoCatCore import Mockable @testable import AutoCat @MainActor final class NotesTests { var storageServiceMock: MockStorageServiceProtocol var apiServiceMock: MockApiServiceProtocol var viewModel: NotesViewModel let noteText = "Test note text" let noteTextModified = "Test note text modified" lazy var vehicleWithNote: VehicleDto = .normal.addNote(text: noteText) lazy var unrecognizedVehicleWithNote: VehicleDto = .unrecognized.addNote(text: noteText) init() { storageServiceMock = MockStorageServiceProtocol() apiServiceMock = MockApiServiceProtocol() viewModel = NotesViewModel( storageService: storageServiceMock, apiService: apiServiceMock, vehicle: VehicleDto() ) } @Test("Add note (normal vehicle)") func addNote() async { given(apiServiceMock) .add(notes: .any, to: .any) .willReturn(vehicleWithNote) given(storageServiceMock) .updateVehicleIfExists(dto: .any) .willReturn() viewModel.vehicle = .normal await viewModel.addNote(text: noteText) verify(apiServiceMock) .add(notes: .any, to: .any).called(.once) verify(storageServiceMock) .addNote(text: .any, to: .any).called(.never) .updateVehicleIfExists(dto: .any).called(.once) #expect(viewModel.vehicle.notes.contains { $0.text == noteText }) #expect(viewModel.hud == nil) } @Test("Add note (unrecognized vehicle)") func addNoteUnrecognized() async throws { given(storageServiceMock) .addNote(text: .any, to: .any) .willReturn(vehicleWithNote) viewModel.vehicle = .unrecognized await viewModel.addNote(text: noteText) verify(apiServiceMock) .add(notes: .any, to: .any).called(.never) verify(storageServiceMock) .addNote(text: .any, to: .any).called(.once) .updateVehicleIfExists(dto: .any).called(.never) #expect(viewModel.vehicle.notes.contains { $0.text == noteText }) #expect(viewModel.hud == nil) } @Test("Edit note (normal vehicle)") func editNote() async throws { let noteId = try #require(vehicleWithNote.notes.first?.id) let modifiedVehicle: VehicleDto = .normal.addNote(text: noteTextModified, id: noteId) given(apiServiceMock) .edit(note: .any) .willReturn(modifiedVehicle) given(storageServiceMock) .updateVehicleIfExists(dto: .any) .willReturn() viewModel.vehicle = vehicleWithNote await viewModel.editNote(id: noteId, text: noteTextModified) verify(apiServiceMock) .edit(note: .any).called(.once) verify(storageServiceMock) .editNote(id: .any, text: .any, for: .any).called(.never) .updateVehicleIfExists(dto: .any).called(.once) #expect(viewModel.vehicle.notes.contains { $0.text == noteTextModified }) #expect(viewModel.hud == nil) } @Test("Edit note (unrecognized vehicle)") func editNoteUnrecognized() async throws { let vehicle: VehicleDto = .unrecognized.addNote(text: noteText) let noteId = try #require(vehicle.notes.first?.id) given(storageServiceMock) .editNote(id: .value(noteId), text: .value(noteTextModified), for: .any) .willReturn(.unrecognized.addNote(text: noteTextModified, id: noteId)) viewModel.vehicle = vehicle await viewModel.editNote(id: noteId, text: noteTextModified) verify(apiServiceMock) .edit(note: .any).called(.never) verify(storageServiceMock) .editNote(id: .any, text: .any, for: .any).called(.once) .updateVehicleIfExists(dto: .any).called(.never) #expect(viewModel.vehicle.notes.contains { $0.text == noteTextModified }) #expect(viewModel.hud == nil) } @Test("Delete note (normal vehicle)") func deleteNote() async throws { let noteId = try #require(vehicleWithNote.notes.first?.id) given(apiServiceMock) .remove(note: .value(noteId)) .willReturn(.normal) given(storageServiceMock) .updateVehicleIfExists(dto: .any) .willReturn() viewModel.vehicle = vehicleWithNote await viewModel.deleteNote(id: noteId) verify(apiServiceMock) .remove(note: .any).called(.once) verify(storageServiceMock) .deleteNote(id: .any, for: .any).called(.never) .updateVehicleIfExists(dto: .any).called(.once) #expect(!viewModel.vehicle.notes.contains { $0.text == noteText }) #expect(viewModel.hud == nil) } @Test("Delete note (unrecognized vehicle)") func deleteNoteUnrecognized() async throws { let noteId = try #require(unrecognizedVehicleWithNote.notes.first?.id) given(storageServiceMock) .deleteNote(id: .value(noteId), for: .any) .willReturn(.unrecognized) viewModel.vehicle = unrecognizedVehicleWithNote await viewModel.deleteNote(id: noteId) verify(apiServiceMock) .remove(note: .any).called(.never) verify(storageServiceMock) .deleteNote(id: .value(noteId), for: .any).called(.once) .updateVehicleIfExists(dto: .any).called(.never) #expect(!viewModel.vehicle.notes.contains { $0.text == noteText }) #expect(viewModel.hud == nil) } }