import XCTest @testable import MealMood final class AutocompleteEngineTests: XCTestCase { func testValidateDropRejectsConsecutiveTag() { let tag = Tag( name: "Carne", nameEN: "Meat", color: "#E74C3C", maxPerWeek: nil, noConsecutive: true, noDuplicateInDay: false ) let dishA = Dish(name: "Pollo", tagIds: [tag.id]) let dishB = Dish(name: "Ternera", tagIds: [tag.id]) let plan = WeekPlan(weekStartDate: Date().startOfWeek()) let mondayDinner = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: dishA.id) let tuesdayDinner = MealSlot(dayOfWeek: 1, mealType: MealType.dinner.rawValue, dishId: nil) plan.slots = [mondayDinner, tuesdayDinner] let isValid = AutocompleteEngine.validateDrop( dish: dishB, slot: tuesdayDinner, plan: plan, allTags: [tag], allDishes: [dishA, dishB] ) XCTAssertFalse(isValid) } func testAutocompleteLeavesSlotEmptyWhenMaxPerWeekReached() { let tag = Tag( name: "Pescado", nameEN: "Fish", color: "#3498DB", maxPerWeek: 1, noConsecutive: false, noDuplicateInDay: false ) let fishDish = Dish(name: "Salmon", tagIds: [tag.id]) let plan = WeekPlan(weekStartDate: Date().startOfWeek()) let mondayDinner = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: fishDish.id) let tuesdayDinner = MealSlot(dayOfWeek: 1, mealType: MealType.dinner.rawValue, dishId: nil) plan.slots = [mondayDinner, tuesdayDinner] let result = AutocompleteEngine.autocomplete( emptySlots: [tuesdayDinner], currentPlan: plan, allDishes: [fishDish], allTags: [tag] ) XCTAssertEqual(result.unfilledCount, 1) XCTAssertNil(tuesdayDinner.dishId) } func testDishStableSortRemainsConsistentAfterDeletion() { let base = Date() let oldest = Dish(id: UUID(uuidString: "00000000-0000-0000-0000-000000000001")!, name: "Old", createdAt: base.addingTimeInterval(-60)) let newest = Dish(id: UUID(uuidString: "00000000-0000-0000-0000-000000000002")!, name: "New", createdAt: base) let middle = Dish(id: UUID(uuidString: "00000000-0000-0000-0000-000000000003")!, name: "Middle", createdAt: base.addingTimeInterval(-30)) let initial = Dish.stableSortedForDisplay([oldest, newest, middle]).map(\.id) XCTAssertEqual(initial, [newest.id, middle.id, oldest.id]) let afterDeletion = Dish.stableSortedForDisplay([newest, oldest]).map(\.id) XCTAssertEqual(afterDeletion, [newest.id, oldest.id]) } func testPreferredDuplicateSlotKeepsAssignedDish() { let duplicateWithDish = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: UUID()) let duplicateWithoutDish = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: nil) let preferred = MealSlot.preferredForDuplicateResolution([duplicateWithoutDish, duplicateWithDish]) XCTAssertEqual(preferred.id, duplicateWithDish.id) } }