diff --git a/CalenTask/Support/WidgetBridge.swift b/CalenTask/Support/WidgetBridge.swift index 80de1b1..3985ca7 100644 --- a/CalenTask/Support/WidgetBridge.swift +++ b/CalenTask/Support/WidgetBridge.swift @@ -62,7 +62,7 @@ enum WidgetBridge { static func refresh(in context: ModelContext) { guard let url = snapshotURL else { return } do { - let snapshot = try makeSnapshot(in: context) + let snapshot = try makeSnapshot(in: context, now: .now) let encoder = JSONEncoder() encoder.dateEncodingStrategy = .iso8601 try encoder.encode(snapshot).write(to: url, options: .atomic) @@ -73,9 +73,10 @@ enum WidgetBridge { } } - private static func makeSnapshot(in context: ModelContext) throws -> WidgetSnapshot { + /// Internal (non private) per i test (#19): `now` è iniettabile. + static func makeSnapshot(in context: ModelContext, now: Date) throws -> WidgetSnapshot { let calendar = Calendar.app - let today = Date.now.startOfDay + let today = now.startOfDay let open = try context.fetch(FetchDescriptor(predicate: TodoTask.openPredicate)) let inbox = try context.fetchCount(FetchDescriptor(predicate: TodoTask.inboxPredicate)) @@ -104,7 +105,7 @@ enum WidgetBridge { } return WidgetSnapshot( - generatedAt: .now, + generatedAt: now, dayLabel: today.formatted(.dateTime.weekday(.wide).day().month(.wide)), items: Array(items), overdueCount: overdue.count, diff --git a/CalenTaskTests/WidgetSnapshotTests.swift b/CalenTaskTests/WidgetSnapshotTests.swift new file mode 100644 index 0000000..16bb422 --- /dev/null +++ b/CalenTaskTests/WidgetSnapshotTests.swift @@ -0,0 +1,43 @@ +import Foundation +import SwiftData +import Testing +@testable import CalenTask + +/// #19 — snapshot del widget: cosa finisce in "oggi", arretrati e Inbox. +@MainActor +struct WidgetSnapshotTests { + + private func makeContainer() throws -> ModelContainer { + let schema = Schema([ + Workspace.self, Membership.self, UserProfile.self, + Project.self, TodoTask.self, TaskDependency.self, Tag.self, + CustomFieldDefinition.self, CustomFieldValue.self, SavedView.self, WorkflowStage.self, AutomationRule.self, Attachment.self, + Contact.self, CrewAssignment.self, ProductionScene.self, + ]) + let config = ModelConfiguration(schema: schema, isStoredInMemoryOnly: true) + return try ModelContainer(for: schema, configurations: [config]) + } + + @Test func snapshotCountsTodayOverdueAndInbox() throws { + let container = try makeContainer() // va tenuto vivo: il contesto non lo trattiene + let context = container.mainContext + let ws = UUID(), me = UUID() + let now = try #require(Calendar.app.date( + bySettingHour: 10, minute: 0, second: 0, of: Date(timeIntervalSince1970: 1_790_000_000) + )) + let today = now.startOfDay + + let todayTask = TodoTask(workspaceID: ws, title: "Oggi", dueAt: today.addingTimeInterval(14 * 3600), createdByID: me) + let overdue = TodoTask(workspaceID: ws, title: "Arretrato", dueAt: today.addingTimeInterval(-86_400), createdByID: me) + let deleted = TodoTask(workspaceID: ws, title: "Eliminata", dueAt: today.addingTimeInterval(14 * 3600), createdByID: me) + deleted.deletedAt = now + for task in [todayTask, overdue, deleted] { context.insert(task) } + + let snapshot = try WidgetBridge.makeSnapshot(in: context, now: now) + #expect(snapshot.generatedAt == now) + #expect(snapshot.items.map(\.title) == ["Oggi"]) + #expect(snapshot.overdueCount == 1) + #expect(snapshot.inboxCount == 2) + withExtendedLifetime(container) {} + } +}