setUpHasPlanner(); $this->action = new GenerateScheduleForMonthAction(); } public function test_generates_schedule_for_entire_month(): void { $planner = $this->planner; $user = User::factory()->planner($planner)->create(); $dish = Dish::factory()->planner($planner)->create(); $dish->users()->attach($user); $month = 1; $year = 2026; $daysInMonth = Carbon::createFromDate($year, $month, 1)->daysInMonth; $this->action->execute($planner, $month, $year, [$user->id]); $this->assertDatabaseCount(Schedule::class, $daysInMonth); $this->assertDatabaseCount(ScheduledUserDish::class, $daysInMonth); } public function test_generates_schedule_for_multiple_users(): void { $planner = $this->planner; $users = User::factory()->planner($planner)->count(3)->create(); $dish = Dish::factory()->planner($planner)->create(); $dish->users()->attach($users); $month = 2; $year = 2026; $daysInMonth = Carbon::createFromDate($year, $month, 1)->daysInMonth; $this->action->execute($planner, $month, $year, $users->pluck('id')->toArray()); $this->assertDatabaseCount(Schedule::class, $daysInMonth); $this->assertDatabaseCount(ScheduledUserDish::class, $daysInMonth * 3); } public function test_clears_existing_schedules_when_flag_is_true(): void { $planner = $this->planner; $user = User::factory()->planner($planner)->create(); $dish = Dish::factory()->planner($planner)->create(); $dish->users()->attach($user); $month = 3; $year = 2026; $this->action->execute($planner, $month, $year, [$user->id]); $firstRunDishId = ScheduledUserDish::first()->user_dish_id; $this->action->execute($planner, $month, $year, [$user->id], true); $daysInMonth = Carbon::createFromDate($year, $month, 1)->daysInMonth; $this->assertDatabaseCount(ScheduledUserDish::class, $daysInMonth); } public function test_preserves_existing_schedules_when_flag_is_false(): void { $planner = $this->planner; $user = User::factory()->planner($planner)->create(); $dish = Dish::factory()->planner($planner)->create(); $dish->users()->attach($user); $month = 4; $year = 2026; $this->action->execute($planner, $month, $year, [$user->id]); $originalCount = ScheduledUserDish::count(); $this->action->execute($planner, $month, $year, [$user->id], false); $this->assertDatabaseCount(ScheduledUserDish::class, $originalCount); } public function test_skips_users_without_dishes(): void { $planner = $this->planner; $userWithDish = User::factory()->planner($planner)->create(); $userWithoutDish = User::factory()->planner($planner)->create(); $dish = Dish::factory()->planner($planner)->create(); $dish->users()->attach($userWithDish); $month = 5; $year = 2026; $daysInMonth = Carbon::createFromDate($year, $month, 1)->daysInMonth; $this->action->execute($planner, $month, $year, [$userWithDish->id, $userWithoutDish->id]); $this->assertDatabaseCount(ScheduledUserDish::class, $daysInMonth); $this->assertDatabaseMissing(ScheduledUserDish::class, ['user_id' => $userWithoutDish->id]); } public function test_only_generates_for_specified_users(): void { $planner = $this->planner; $user1 = User::factory()->planner($planner)->create(); $user2 = User::factory()->planner($planner)->create(); $dish = Dish::factory()->planner($planner)->create(); $dish->users()->attach([$user1->id, $user2->id]); $month = 6; $year = 2026; $daysInMonth = Carbon::createFromDate($year, $month, 1)->daysInMonth; $this->action->execute($planner, $month, $year, [$user1->id]); $this->assertDatabaseCount(ScheduledUserDish::class, $daysInMonth); $this->assertDatabaseMissing(ScheduledUserDish::class, ['user_id' => $user2->id]); } }