Some boilerplate for testing events view model

This commit is contained in:
Selim Mustafaev 2024-12-18 23:12:19 +03:00
parent 9257a4731c
commit 49f25e0c7e
6 changed files with 136 additions and 16 deletions

View File

@ -14,7 +14,7 @@ extension StorageServiceTests {
@Test("Add event") @Test("Add event")
func addEvent() async throws { func addEvent() async throws {
let event = VehicleEventDto(lat: testLat, lon: testLon) let event = VehicleEventDto(lat: testLat, lon: testLon, addedBy: nil)
let vehicle = try await storageService.add(event: event, to: existingVehicleNumber) let vehicle = try await storageService.add(event: event, to: existingVehicleNumber)
@ -27,7 +27,7 @@ extension StorageServiceTests {
@Test("Add event to non-existent vehicle") @Test("Add event to non-existent vehicle")
func addEventToNonExistentVehicle() async throws { func addEventToNonExistentVehicle() async throws {
let event = VehicleEventDto(lat: testLat, lon: testLon) let event = VehicleEventDto(lat: testLat, lon: testLon, addedBy: nil)
await #expect(throws: StorageError.vehicleNotFound) { await #expect(throws: StorageError.vehicleNotFound) {
_ = try await storageService.add(event: event, to: nonExistingVehicleNumber) _ = try await storageService.add(event: event, to: nonExistingVehicleNumber)
@ -37,7 +37,7 @@ extension StorageServiceTests {
@Test("Remove event") @Test("Remove event")
func removeEvent() async throws { func removeEvent() async throws {
let event = VehicleEventDto(lat: testLat, lon: testLon) let event = VehicleEventDto(lat: testLat, lon: testLon, addedBy: nil)
var vehicle = try await storageService.add(event: event, to: existingVehicleNumber) var vehicle = try await storageService.add(event: event, to: existingVehicleNumber)
let id = try #require(vehicle.events.first { $0.latitude == testLat && $0.longitude == testLon }?.id) let id = try #require(vehicle.events.first { $0.latitude == testLat && $0.longitude == testLon }?.id)
@ -66,10 +66,10 @@ extension StorageServiceTests {
@Test("Edit event") @Test("Edit event")
func editEvent() async throws { func editEvent() async throws {
let event = VehicleEventDto(lat: 0, lon: 0) let event = VehicleEventDto(lat: 0, lon: 0, addedBy: nil)
var vehicle = try await storageService.add(event: event, to: existingVehicleNumber) var vehicle = try await storageService.add(event: event, to: existingVehicleNumber)
var editedEvent = VehicleEventDto(lat: testLat, lon: testLon) var editedEvent = VehicleEventDto(lat: testLat, lon: testLon, addedBy: nil)
editedEvent.id = try #require(vehicle.events.first?.id) editedEvent.id = try #require(vehicle.events.first?.id)
vehicle = try await storageService.edit(event: editedEvent, for: existingVehicleNumber) vehicle = try await storageService.edit(event: editedEvent, for: existingVehicleNumber)
@ -83,7 +83,7 @@ extension StorageServiceTests {
@Test("Edit non-existent event") @Test("Edit non-existent event")
func editNonExistentEvent() async throws { func editNonExistentEvent() async throws {
let event = VehicleEventDto(lat: 0, lon: 0) let event = VehicleEventDto(lat: 0, lon: 0, addedBy: nil)
await #expect(throws: StorageError.eventNotFound) { await #expect(throws: StorageError.eventNotFound) {
_ = try await storageService.edit(event: event, for: existingVehicleNumber) _ = try await storageService.edit(event: event, for: existingVehicleNumber)
} }
@ -92,7 +92,7 @@ extension StorageServiceTests {
@Test("Edit event in non-existent vehicle") @Test("Edit event in non-existent vehicle")
func editEventInNonExistentVehicle() async throws { func editEventInNonExistentVehicle() async throws {
let event = VehicleEventDto(lat: 0, lon: 0) let event = VehicleEventDto(lat: 0, lon: 0, addedBy: nil)
await #expect(throws: StorageError.vehicleNotFound) { await #expect(throws: StorageError.vehicleNotFound) {
_ = try await storageService.edit(event: event, for: nonExistingVehicleNumber) _ = try await storageService.edit(event: event, for: nonExistingVehicleNumber)
} }

View File

@ -0,0 +1,69 @@
//
// EventsTests.swift
// AutoCatTests
//
// Created by Selim Mustafaev on 18.12.2024.
// Copyright © 2024 Selim Mustafaev. All rights reserved.
//
import Testing
import Mockable
import AutoCatCore
@testable import AutoCat
@MainActor
struct EventsTests {
var settingsServiceMock: MockSettingsServiceProtocol
var storageServiceMock: MockStorageServiceProtocol
var apiServiceMock: MockApiServiceProtocol
var viewModel: EventsViewModel
lazy var vehicleWithEvent: VehicleDto = .normal.addEvent(.valid)
init() {
settingsServiceMock = MockSettingsServiceProtocol()
storageServiceMock = MockStorageServiceProtocol()
apiServiceMock = MockApiServiceProtocol()
ServiceContainer.shared.register(SettingsServiceProtocol.self, instance: settingsServiceMock)
ServiceContainer.shared.register(StorageServiceProtocol.self, instance: storageServiceMock)
ServiceContainer.shared.register(ApiServiceProtocol.self, instance: apiServiceMock)
viewModel = EventsViewModel(vehicle: VehicleDto())
given(settingsServiceMock)
.user.willReturn(User())
}
@Test("Add event")
mutating func addEvent() async throws {
given(apiServiceMock)
.add(event: .value(.valid), to: .value(VehicleDto.validNumber))
.willReturn(vehicleWithEvent)
given(storageServiceMock)
.updateVehicleIfExists(dto: .value(vehicleWithEvent))
.willReturn()
viewModel = EventsViewModel(vehicle: .normal)
await viewModel.addEvent(.valid)
verify(apiServiceMock)
.add(event: .any, to: .any).called(.once)
verify(storageServiceMock)
.updateVehicleIfExists(dto: .any).called(.once)
#expect(viewModel.vehicle.events.count == 1)
#expect(viewModel.vehicle.events.first?.id == VehicleEventDto.validId)
#expect(viewModel.events.count == 1)
#expect(viewModel.events.first?.id == VehicleEventDto.validId)
#expect(viewModel.hud == nil)
}
}

View File

@ -10,16 +10,18 @@ import AutoCatCore
extension VehicleDto { extension VehicleDto {
static let validNumber: String = "А123АА761"
static var normal: VehicleDto { static var normal: VehicleDto {
var vehicle = VehicleDto() var vehicle = VehicleDto()
vehicle.number = "А123АА761" vehicle.number = validNumber
vehicle.brand = VehicleBrandDto() vehicle.brand = VehicleBrandDto()
return vehicle return vehicle
} }
static var unrecognized: VehicleDto { static var unrecognized: VehicleDto {
var vehicle = VehicleDto() var vehicle = VehicleDto()
vehicle.number = "А123АА761" vehicle.number = validNumber
return vehicle return vehicle
} }
} }
@ -31,17 +33,24 @@ extension VehicleDto {
func addNote(text: String) -> Self { func addNote(text: String) -> Self {
var vehicle = self var vehicle = self
vehicle.notes.append(VehicleNoteDto(text: text)) vehicle.notes.append(VehicleNoteDto(text: text, user: ""))
return vehicle return vehicle
} }
func addNote(text: String, id: String) -> Self { func addNote(text: String, id: String) -> Self {
var note = VehicleNoteDto(text: text) var note = VehicleNoteDto(text: text, user: "")
note.id = id note.id = id
var vehicle = self var vehicle = self
vehicle.notes.append(note) vehicle.notes.append(note)
return vehicle return vehicle
} }
func addEvent(_ event: VehicleEventDto) -> Self {
var vehicle = self
vehicle.events.append(event)
return vehicle
}
} }

View File

@ -0,0 +1,44 @@
//
// VehicleEventDto+Presets.swift
// AutoCatTests
//
// Created by Selim Mustafaev on 18.12.2024.
// Copyright © 2024 Selim Mustafaev. All rights reserved.
//
import CoreLocation
import AutoCatCore
@testable import AutoCat
extension VehicleEventDto {
static let validId = "0a41949b-0650-4155-a6d9-96cb4fcaad8b"
static let invalidId = "1930c803-a9b2-4ece-8e88-f27523bb7b5b"
static let validLatitude: Double = 42
static let validLongitude: Double = 24
static var valid: VehicleEventDto {
var event = VehicleEventDto(
lat: validLatitude,
lon: validLongitude,
addedBy: nil
)
event.id = validId
event.date = 0
return event
}
var viewModel: EventModel {
EventModel(
id: id,
date: "",
coordinate: CLLocationCoordinate2DMake(latitude, longitude),
address: "",
isMe: true
)
}
}

View File

@ -31,7 +31,7 @@ struct LocationPickerTests {
@Test("Set initial location (user)") @Test("Set initial location (user)")
func setInitialLocationUser() async throws { func setInitialLocationUser() async throws {
let viewModel = LocationPickerViewModel(event: .init(lat: 0, lon: 0)) let viewModel = LocationPickerViewModel(event: .init(lat: 0, lon: 0, addedBy: nil))
#expect(viewModel.position == .userLocation(fallback: .automatic)) #expect(viewModel.position == .userLocation(fallback: .automatic))
} }
@ -39,7 +39,7 @@ struct LocationPickerTests {
@Test("Set initial location (custom)") @Test("Set initial location (custom)")
func setInitialLocationCustom() async throws { func setInitialLocationCustom() async throws {
let viewModel = LocationPickerViewModel(event: .init(lat: latitude, lon: longitude)) let viewModel = LocationPickerViewModel(event: .init(lat: latitude, lon: longitude, addedBy: nil))
#expect(viewModel.position.region?.center.latitude == latitude) #expect(viewModel.position.region?.center.latitude == latitude)
#expect(viewModel.position.region?.center.longitude == longitude) #expect(viewModel.position.region?.center.longitude == longitude)
@ -48,7 +48,7 @@ struct LocationPickerTests {
@Test("Update event") @Test("Update event")
func updateEvent() async throws { func updateEvent() async throws {
let viewModel = LocationPickerViewModel(event: .init(lat: 0, lon: 0)) let viewModel = LocationPickerViewModel(event: .init(lat: 0, lon: 0, addedBy: nil))
geocoder.addLocation(latitude: latitude, geocoder.addLocation(latitude: latitude,
longitude: longitude, longitude: longitude,

View File

@ -37,8 +37,6 @@ final class NotesTests {
@Test("Add note (normal vehicle)") @Test("Add note (normal vehicle)")
func addNote() async { func addNote() async {
print(vehicleWithNote)
given(apiServiceMock) given(apiServiceMock)
.add(notes: .any, to: .any) .add(notes: .any, to: .any)
.willReturn(vehicleWithNote) .willReturn(vehicleWithNote)