feat(itinerary): add custom itinerary items with drag-to-reorder
- Add CustomItineraryItem domain model with sortOrder for ordering - Add CKCustomItineraryItem CloudKit wrapper for persistence - Create CustomItemService for CRUD operations - Create CustomItemSubscriptionService for real-time sync - Add AppDelegate for push notification handling - Add AddItemSheet for creating/editing items - Add CustomItemRow with drag handle - Update TripDetailView with continuous vertical timeline - Enable drag-to-reorder using .draggable/.dropDestination - Add inline "Add" buttons after games and travel segments Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
57
SportsTimeTests/Domain/CustomItineraryItemTests.swift
Normal file
57
SportsTimeTests/Domain/CustomItineraryItemTests.swift
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// CustomItineraryItemTests.swift
|
||||
// SportsTimeTests
|
||||
//
|
||||
|
||||
import Testing
|
||||
@testable import SportsTime
|
||||
import Foundation
|
||||
|
||||
struct CustomItineraryItemTests {
|
||||
|
||||
@Test("Item initializes with default values")
|
||||
func item_InitializesWithDefaults() {
|
||||
let tripId = UUID()
|
||||
let item = CustomItineraryItem(
|
||||
tripId: tripId,
|
||||
category: .restaurant,
|
||||
title: "Joe's BBQ",
|
||||
anchorDay: 1
|
||||
)
|
||||
|
||||
#expect(item.tripId == tripId)
|
||||
#expect(item.category == .restaurant)
|
||||
#expect(item.title == "Joe's BBQ")
|
||||
#expect(item.anchorType == .startOfDay)
|
||||
#expect(item.anchorId == nil)
|
||||
#expect(item.anchorDay == 1)
|
||||
}
|
||||
|
||||
@Test("Item category has correct icons")
|
||||
func category_HasCorrectIcons() {
|
||||
#expect(CustomItineraryItem.ItemCategory.restaurant.icon == "🍽️")
|
||||
#expect(CustomItineraryItem.ItemCategory.hotel.icon == "🏨")
|
||||
#expect(CustomItineraryItem.ItemCategory.activity.icon == "🎯")
|
||||
#expect(CustomItineraryItem.ItemCategory.note.icon == "📝")
|
||||
}
|
||||
|
||||
@Test("Item is Codable")
|
||||
func item_IsCodable() throws {
|
||||
let item = CustomItineraryItem(
|
||||
tripId: UUID(),
|
||||
category: .hotel,
|
||||
title: "Hilton Downtown",
|
||||
anchorType: .afterGame,
|
||||
anchorId: "game_123",
|
||||
anchorDay: 2
|
||||
)
|
||||
|
||||
let encoded = try JSONEncoder().encode(item)
|
||||
let decoded = try JSONDecoder().decode(CustomItineraryItem.self, from: encoded)
|
||||
|
||||
#expect(decoded.id == item.id)
|
||||
#expect(decoded.title == item.title)
|
||||
#expect(decoded.anchorType == .afterGame)
|
||||
#expect(decoded.anchorId == "game_123")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user