2025-10-13 14:57:11 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Tests\Unit\Schedule;
|
|
|
|
|
|
|
|
|
|
use App\Models\Dish;
|
|
|
|
|
use App\Models\MinimumRecurrence;
|
|
|
|
|
use App\Models\Planner;
|
|
|
|
|
use App\Models\Schedule;
|
|
|
|
|
use App\Models\User;
|
|
|
|
|
use App\Models\UserDish;
|
|
|
|
|
use App\Models\UserDishRecurrence;
|
|
|
|
|
use App\Models\WeeklyRecurrence;
|
|
|
|
|
use App\WeekdaysEnum;
|
|
|
|
|
use DishPlanner\Schedule\Services\ScheduleGenerator;
|
|
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
|
use Illuminate\Support\Carbon;
|
|
|
|
|
use Tests\TestCase;
|
|
|
|
|
use Tests\Traits\HasPlanner;
|
|
|
|
|
|
|
|
|
|
class ScheduleGeneratorTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
use HasPlanner;
|
|
|
|
|
use RefreshDatabase;
|
|
|
|
|
|
2025-12-29 23:36:15 +01:00
|
|
|
protected function setUp(): void
|
|
|
|
|
{
|
|
|
|
|
parent::setUp();
|
|
|
|
|
$this->setUpHasPlanner();
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-13 14:57:11 +02:00
|
|
|
public function test_it_fills_up_the_next_2_weeks(): void
|
|
|
|
|
{
|
|
|
|
|
$planner = $this->planner;
|
|
|
|
|
$user = User::factory()->planner($this->planner)->create();
|
|
|
|
|
|
|
|
|
|
$dishOne = Dish::factory()->planner($planner)->create();
|
|
|
|
|
$dishTwo = Dish::factory()->planner($planner)->create();
|
|
|
|
|
UserDish::factory()->user($user)->dish($dishOne)->create();
|
|
|
|
|
UserDish::factory()->user($user)->dish($dishTwo)->create();
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseEmpty(Schedule::class);
|
|
|
|
|
|
|
|
|
|
(new ScheduleGenerator())->generate($planner);
|
|
|
|
|
|
|
|
|
|
$schedules = Schedule::all();
|
|
|
|
|
$this->assertTrue($schedules->isNotEmpty());
|
|
|
|
|
$this->assertCount(14, $schedules);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_it_takes_weekly_recurrences_into_account(): void
|
|
|
|
|
{
|
|
|
|
|
$recurringDay = now()->addDays(2);
|
|
|
|
|
|
|
|
|
|
$planner = $this->planner;
|
|
|
|
|
$user = User::factory()->planner($this->planner)->create();
|
|
|
|
|
$dishesPlain = Dish::factory()->planner($planner)->count(20)->create();
|
|
|
|
|
$dishRecurring = Dish::factory()->planner($planner)->create();
|
|
|
|
|
$weeklyRecurrence = WeeklyRecurrence::factory()
|
|
|
|
|
->weekday(WeekdaysEnum::from($recurringDay->dayOfWeek()))
|
|
|
|
|
->create();
|
|
|
|
|
|
|
|
|
|
$dishesPlain->each(fn (Dish $dish) => UserDish::factory()
|
|
|
|
|
->user($user)
|
|
|
|
|
->dish($dish)
|
|
|
|
|
->create()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$userDishRecurring = UserDish::factory()
|
|
|
|
|
->user($user)
|
|
|
|
|
->dish($dishRecurring)
|
|
|
|
|
->create();
|
|
|
|
|
|
|
|
|
|
UserDishRecurrence::factory()->create([
|
|
|
|
|
'user_dish_id' => $userDishRecurring->id,
|
|
|
|
|
'recurrence_id' => $weeklyRecurrence->id,
|
|
|
|
|
'recurrence_type' => WeeklyRecurrence::class,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$userDishRecurring->refresh();
|
|
|
|
|
$this->assertNotEmpty($userDishRecurring->recurrences);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseEmpty(Schedule::class);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(new ScheduleGenerator())->generate($planner);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$this->assertTrue(Schedule::all()->isNotEmpty());
|
|
|
|
|
|
|
|
|
|
$schedule = Schedule::query()->where('date', $recurringDay->format('Y-m-d'))->first();
|
|
|
|
|
$this->assertNotNull($schedule);
|
|
|
|
|
$this->assertNotEmpty($schedule->scheduledUserDishes);
|
|
|
|
|
$this->assertEquals($schedule->scheduledUserDishes->first()->userDish->id, $userDishRecurring->id);
|
|
|
|
|
|
|
|
|
|
$schedule = Schedule::query()->where('date', $recurringDay->addWeek()->format('Y-m-d'))->first();
|
|
|
|
|
$this->assertNotNull($schedule);
|
|
|
|
|
$this->assertNotEmpty($schedule->scheduledUserDishes);
|
|
|
|
|
$this->assertEquals($schedule->scheduledUserDishes->first()->userDish->id, $userDishRecurring->id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function test_it_takes_minimum_recurrences_into_account(): void
|
|
|
|
|
{
|
|
|
|
|
$recurringMinimum = 3;
|
|
|
|
|
|
|
|
|
|
$planner = $this->planner;
|
|
|
|
|
$user = User::factory()->planner($this->planner)->create();
|
|
|
|
|
$dishPlain = Dish::factory()->planner($planner)->create();
|
|
|
|
|
$dishRecurring = Dish::factory()->planner($planner)->create();
|
|
|
|
|
$minimumRecurrence = MinimumRecurrence::factory()->days($recurringMinimum)->create();
|
|
|
|
|
UserDish::factory()
|
|
|
|
|
->user($user)
|
|
|
|
|
->dish($dishPlain)
|
|
|
|
|
->create();
|
|
|
|
|
$userDishRecurring = UserDish::factory()
|
|
|
|
|
->user($user)
|
|
|
|
|
->dish($dishRecurring)
|
|
|
|
|
->create();
|
|
|
|
|
|
|
|
|
|
UserDishRecurrence::factory()->create([
|
|
|
|
|
'user_dish_id' => $userDishRecurring->id,
|
|
|
|
|
'recurrence_id' => $minimumRecurrence->id,
|
|
|
|
|
'recurrence_type' => MinimumRecurrence::class,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$userDishRecurring->refresh();
|
|
|
|
|
$this->assertNotEmpty($userDishRecurring->recurrences);
|
|
|
|
|
|
|
|
|
|
$this->assertDatabaseEmpty(Schedule::class);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(new ScheduleGenerator())->generate($planner);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$this->assertTrue(Schedule::all()->isNotEmpty());
|
|
|
|
|
|
|
|
|
|
Schedule::all()
|
|
|
|
|
->filter(fn (Schedule $schedule) => $schedule->scheduledUserDishes()->first()->userDish->dish->id === $dishRecurring->id)
|
|
|
|
|
->map(fn (Schedule $schedule) => $schedule->date)
|
|
|
|
|
->reduce(function (?Carbon $previousDate, Carbon $currentDate) use ($recurringMinimum) {
|
|
|
|
|
if (! is_null($previousDate)) {
|
|
|
|
|
$this->assertGreaterThanOrEqual(
|
|
|
|
|
$recurringMinimum,
|
|
|
|
|
$previousDate->diffInDays($currentDate),
|
|
|
|
|
'Dates are not spaced properly'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $currentDate;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|