app/tests/Unit/Schedule/Actions/GenerateScheduleForMonthActionTest.php

135 lines
4.6 KiB
PHP

<?php
namespace Tests\Unit\Schedule\Actions;
use App\Models\Dish;
use App\Models\Schedule;
use App\Models\ScheduledUserDish;
use App\Models\User;
use Carbon\Carbon;
use DishPlanner\Schedule\Actions\GenerateScheduleForMonthAction;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use Tests\Traits\HasPlanner;
class GenerateScheduleForMonthActionTest extends TestCase
{
use HasPlanner;
use RefreshDatabase;
private GenerateScheduleForMonthAction $action;
protected function setUp(): void
{
parent::setUp();
$this->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]);
}
}