Add Plant Rooms/Zones feature for organizing plants by location

Implements Phase 3 of the feature roadmap:
- Room entity with 7 default rooms (Kitchen, Living Room, Bedroom, etc.)
- RoomRepositoryProtocol and CoreDataRoomRepository for persistence
- CreateDefaultRoomsUseCase and ManageRoomsUseCase for CRUD operations
- RoomsListView with swipe-to-delete and drag-to-reorder
- RoomEditorView with SF Symbol icon picker
- RoomPickerView for assigning plants to rooms
- Updated Plant entity (location → roomID) and PlantDetailView
- Added "Manage Rooms" section in SettingsView

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-23 14:44:14 -06:00
parent d125216a95
commit 7786a40ae0
22 changed files with 2245 additions and 21 deletions

View File

@@ -277,10 +277,11 @@ final class UpdatePlantUseCaseTests: XCTestCase {
let originalPlant = createTestPlant(id: plantID, notes: "Original notes")
mockRepository.addPlant(originalPlant)
let roomID = UUID()
var updatedPlant = originalPlant
updatedPlant.notes = "Updated notes"
updatedPlant.customName = "My Monstera"
updatedPlant.location = "Living Room"
updatedPlant.roomID = roomID
// When
let result = try await sut.execute(plant: updatedPlant)
@@ -289,7 +290,7 @@ final class UpdatePlantUseCaseTests: XCTestCase {
XCTAssertEqual(result.id, plantID)
XCTAssertEqual(result.notes, "Updated notes")
XCTAssertEqual(result.customName, "My Monstera")
XCTAssertEqual(result.location, "Living Room")
XCTAssertEqual(result.roomID, roomID)
XCTAssertEqual(mockRepository.existsCallCount, 1)
XCTAssertEqual(mockRepository.updatePlantCallCount, 1)
@@ -345,20 +346,21 @@ final class UpdatePlantUseCaseTests: XCTestCase {
XCTAssertEqual(result.customName, "Bob the Plant")
}
func testExecute_WhenUpdatingOnlyLocation_SuccessfullyUpdates() async throws {
func testExecute_WhenUpdatingOnlyRoomID_SuccessfullyUpdates() async throws {
// Given
let plantID = UUID()
let originalPlant = createTestPlant(id: plantID)
mockRepository.addPlant(originalPlant)
let kitchenRoomID = UUID()
var updatedPlant = originalPlant
updatedPlant.location = "Kitchen windowsill"
updatedPlant.roomID = kitchenRoomID
// When
let result = try await sut.execute(plant: updatedPlant)
// Then
XCTAssertEqual(result.location, "Kitchen windowsill")
XCTAssertEqual(result.roomID, kitchenRoomID)
}
func testExecute_PreservesImmutableProperties() async throws {