- Implement camera capture and plant identification workflow - Add Core Data persistence for plants, care schedules, and cached API data - Create collection view with grid/list layouts and filtering - Build plant detail views with care information display - Integrate Trefle botanical API for plant care data - Add local image storage for captured plant photos - Implement dependency injection container for testability - Include accessibility support throughout the app Bug fixes in this commit: - Fix Trefle API decoding by removing duplicate CodingKeys - Fix LocalCachedImage to load from correct PlantImages directory - Set dateAdded when saving plants for proper collection sorting Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
164 lines
6.2 KiB
Swift
164 lines
6.2 KiB
Swift
//
|
|
// PlantCareSchedule+TestFixtures.swift
|
|
// PlantGuideTests
|
|
//
|
|
// Test fixtures for PlantCareSchedule entity - provides factory methods for
|
|
// creating test instances with sensible defaults.
|
|
//
|
|
|
|
import Foundation
|
|
@testable import PlantGuide
|
|
|
|
// MARK: - PlantCareSchedule Test Fixtures
|
|
|
|
extension PlantCareSchedule {
|
|
|
|
// MARK: - Factory Methods
|
|
|
|
/// Creates a mock care schedule with default values for testing
|
|
/// - Parameters:
|
|
/// - id: The schedule's unique identifier. Defaults to a new UUID.
|
|
/// - plantID: ID of the plant this schedule belongs to. Defaults to a new UUID.
|
|
/// - lightRequirement: Light needs. Defaults to .partialShade.
|
|
/// - wateringSchedule: Watering description. Defaults to "Weekly".
|
|
/// - temperatureRange: Safe temp range. Defaults to 18...26.
|
|
/// - fertilizerSchedule: Fertilizer description. Defaults to "Monthly".
|
|
/// - tasks: Array of care tasks. Defaults to empty.
|
|
/// - Returns: A configured PlantCareSchedule instance for testing
|
|
static func mock(
|
|
id: UUID = UUID(),
|
|
plantID: UUID = UUID(),
|
|
lightRequirement: LightRequirement = .partialShade,
|
|
wateringSchedule: String = "Weekly",
|
|
temperatureRange: ClosedRange<Int> = 18...26,
|
|
fertilizerSchedule: String = "Monthly",
|
|
tasks: [CareTask] = []
|
|
) -> PlantCareSchedule {
|
|
PlantCareSchedule(
|
|
id: id,
|
|
plantID: plantID,
|
|
lightRequirement: lightRequirement,
|
|
wateringSchedule: wateringSchedule,
|
|
temperatureRange: temperatureRange,
|
|
fertilizerSchedule: fertilizerSchedule,
|
|
tasks: tasks
|
|
)
|
|
}
|
|
|
|
/// Creates a mock schedule with watering tasks
|
|
/// - Parameters:
|
|
/// - plantID: ID of the plant this schedule belongs to
|
|
/// - taskCount: Number of watering tasks to generate. Defaults to 4.
|
|
/// - startDate: Starting date for first task. Defaults to tomorrow.
|
|
/// - Returns: A schedule with generated watering tasks
|
|
static func mockWithWateringTasks(
|
|
plantID: UUID = UUID(),
|
|
taskCount: Int = 4,
|
|
startDate: Date = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
|
|
) -> PlantCareSchedule {
|
|
let tasks = (0..<taskCount).map { index in
|
|
CareTask.mockWatering(
|
|
plantID: plantID,
|
|
scheduledDate: Calendar.current.date(byAdding: .day, value: index * 7, to: startDate)!
|
|
)
|
|
}
|
|
return mock(
|
|
plantID: plantID,
|
|
wateringSchedule: "Every 7 days",
|
|
tasks: tasks
|
|
)
|
|
}
|
|
|
|
/// Creates a mock schedule with mixed care tasks
|
|
/// - Parameters:
|
|
/// - plantID: ID of the plant this schedule belongs to
|
|
/// - Returns: A schedule with watering and fertilizing tasks
|
|
static func mockWithMixedTasks(plantID: UUID = UUID()) -> PlantCareSchedule {
|
|
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
|
|
let nextWeek = Calendar.current.date(byAdding: .day, value: 7, to: Date())!
|
|
let nextMonth = Calendar.current.date(byAdding: .day, value: 30, to: Date())!
|
|
|
|
let tasks: [CareTask] = [
|
|
.mockWatering(plantID: plantID, scheduledDate: tomorrow),
|
|
.mockWatering(plantID: plantID, scheduledDate: nextWeek),
|
|
.mockFertilizing(plantID: plantID, scheduledDate: nextMonth)
|
|
]
|
|
|
|
return mock(
|
|
plantID: plantID,
|
|
wateringSchedule: "Weekly",
|
|
fertilizerSchedule: "Monthly during growing season",
|
|
tasks: tasks
|
|
)
|
|
}
|
|
|
|
/// Creates a mock schedule for a tropical plant (high humidity, frequent watering)
|
|
static func mockTropical(plantID: UUID = UUID()) -> PlantCareSchedule {
|
|
mock(
|
|
plantID: plantID,
|
|
lightRequirement: .partialShade,
|
|
wateringSchedule: "Every 3 days",
|
|
temperatureRange: 20...30,
|
|
fertilizerSchedule: "Biweekly during growing season"
|
|
)
|
|
}
|
|
|
|
/// Creates a mock schedule for a succulent (low water, full sun)
|
|
static func mockSucculent(plantID: UUID = UUID()) -> PlantCareSchedule {
|
|
mock(
|
|
plantID: plantID,
|
|
lightRequirement: .fullSun,
|
|
wateringSchedule: "Every 14 days",
|
|
temperatureRange: 15...35,
|
|
fertilizerSchedule: "Monthly during spring and summer"
|
|
)
|
|
}
|
|
|
|
/// Creates a mock schedule for a shade-loving plant
|
|
static func mockShadePlant(plantID: UUID = UUID()) -> PlantCareSchedule {
|
|
mock(
|
|
plantID: plantID,
|
|
lightRequirement: .lowLight,
|
|
wateringSchedule: "Weekly",
|
|
temperatureRange: 16...24,
|
|
fertilizerSchedule: "Every 6 weeks"
|
|
)
|
|
}
|
|
|
|
/// Creates a mock schedule with overdue tasks
|
|
static func mockWithOverdueTasks(plantID: UUID = UUID()) -> PlantCareSchedule {
|
|
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
|
|
let lastWeek = Calendar.current.date(byAdding: .day, value: -7, to: Date())!
|
|
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
|
|
|
|
let tasks: [CareTask] = [
|
|
.mockWatering(plantID: plantID, scheduledDate: lastWeek), // Overdue
|
|
.mockWatering(plantID: plantID, scheduledDate: yesterday), // Overdue
|
|
.mockWatering(plantID: plantID, scheduledDate: tomorrow) // Upcoming
|
|
]
|
|
|
|
return mock(
|
|
plantID: plantID,
|
|
tasks: tasks
|
|
)
|
|
}
|
|
|
|
/// Creates a mock schedule with completed tasks
|
|
static func mockWithCompletedTasks(plantID: UUID = UUID()) -> PlantCareSchedule {
|
|
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
|
|
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
|
|
let nextWeek = Calendar.current.date(byAdding: .day, value: 7, to: Date())!
|
|
|
|
let tasks: [CareTask] = [
|
|
.mockWatering(plantID: plantID, scheduledDate: yesterday, completedDate: yesterday),
|
|
.mockWatering(plantID: plantID, scheduledDate: tomorrow),
|
|
.mockWatering(plantID: plantID, scheduledDate: nextWeek)
|
|
]
|
|
|
|
return mock(
|
|
plantID: plantID,
|
|
tasks: tasks
|
|
)
|
|
}
|
|
}
|