allDay()->create(); expect($blocked->isAllDay())->toBeTrue(); }); test('isAllDay returns false when times are set', function () { $blocked = BlockedTime::factory()->timeRange('09:00', '12:00')->create(); expect($blocked->isAllDay())->toBeFalse(); }); test('scopeUpcoming filters to today and future dates', function () { BlockedTime::factory()->create(['block_date' => today()]); BlockedTime::factory()->create(['block_date' => today()->addDays(5)]); BlockedTime::factory()->create(['block_date' => today()->subDays(5)]); $upcoming = BlockedTime::upcoming()->get(); expect($upcoming)->toHaveCount(2) ->and($upcoming->pluck('block_date')->every(fn ($date) => $date->gte(today())))->toBeTrue(); }); test('scopePast filters to past dates only', function () { BlockedTime::factory()->create(['block_date' => today()]); BlockedTime::factory()->create(['block_date' => today()->addDays(5)]); BlockedTime::factory()->create(['block_date' => today()->subDays(5)]); $past = BlockedTime::past()->get(); expect($past)->toHaveCount(1) ->and($past->first()->block_date->lt(today()))->toBeTrue(); }); test('scopeForDate filters by exact date', function () { $targetDate = today()->addDays(3); BlockedTime::factory()->create(['block_date' => $targetDate]); BlockedTime::factory()->create(['block_date' => today()]); BlockedTime::factory()->create(['block_date' => today()->addDays(10)]); $result = BlockedTime::forDate($targetDate)->get(); expect($result)->toHaveCount(1) ->and($result->first()->block_date->toDateString())->toBe($targetDate->toDateString()); }); test('blocksSlot returns true for all times when all-day block', function () { $blocked = BlockedTime::factory()->allDay()->create(); expect($blocked->blocksSlot('09:00'))->toBeTrue() ->and($blocked->blocksSlot('12:00'))->toBeTrue() ->and($blocked->blocksSlot('17:00'))->toBeTrue() ->and($blocked->blocksSlot('23:59'))->toBeTrue(); }); test('blocksSlot returns true for times within blocked range', function () { $blocked = BlockedTime::factory()->timeRange('09:00', '12:00')->create(); expect($blocked->blocksSlot('09:00'))->toBeTrue() ->and($blocked->blocksSlot('10:00'))->toBeTrue() ->and($blocked->blocksSlot('11:00'))->toBeTrue() ->and($blocked->blocksSlot('11:30'))->toBeTrue(); }); test('blocksSlot returns false for times outside blocked range', function () { $blocked = BlockedTime::factory()->timeRange('09:00', '12:00')->create(); expect($blocked->blocksSlot('08:00'))->toBeFalse() ->and($blocked->blocksSlot('08:59'))->toBeFalse() ->and($blocked->blocksSlot('12:00'))->toBeFalse() ->and($blocked->blocksSlot('13:00'))->toBeFalse(); }); test('blocksSlot returns true at start time boundary', function () { $blocked = BlockedTime::factory()->timeRange('09:00', '12:00')->create(); expect($blocked->blocksSlot('09:00'))->toBeTrue(); }); test('blocksSlot returns false at end time boundary', function () { $blocked = BlockedTime::factory()->timeRange('09:00', '12:00')->create(); expect($blocked->blocksSlot('12:00'))->toBeFalse(); }); test('block_date is cast to date', function () { $blocked = BlockedTime::factory()->create([ 'block_date' => '2025-12-26', ]); expect($blocked->block_date)->toBeInstanceOf(Carbon\Carbon::class); }); test('reason can be null', function () { $blocked = BlockedTime::factory()->create([ 'reason' => null, ]); expect($blocked->reason)->toBeNull(); }); test('reason can be set', function () { $blocked = BlockedTime::factory()->withReason('Holiday vacation')->create(); expect($blocked->reason)->toBe('Holiday vacation'); }); test('factory allDay state creates full day block', function () { $blocked = BlockedTime::factory()->allDay()->create(); expect($blocked->start_time)->toBeNull() ->and($blocked->end_time)->toBeNull() ->and($blocked->isAllDay())->toBeTrue(); }); test('factory timeRange state creates partial day block', function () { $blocked = BlockedTime::factory()->timeRange('10:00', '14:00')->create(); expect($blocked->start_time)->toContain('10:00') ->and($blocked->end_time)->toContain('14:00') ->and($blocked->isAllDay())->toBeFalse(); }); test('factory upcoming state creates future date', function () { $blocked = BlockedTime::factory()->upcoming()->create(); expect($blocked->block_date->gt(today()))->toBeTrue(); }); test('factory past state creates past date', function () { $blocked = BlockedTime::factory()->past()->create(); expect($blocked->block_date->lt(today()))->toBeTrue(); }); test('factory today state creates today date', function () { $blocked = BlockedTime::factory()->today()->create(); expect($blocked->block_date->toDateString())->toBe(today()->toDateString()); });