complete story 3.2 with qa tests
This commit is contained in:
@@ -0,0 +1,518 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\ConsultationStatus;
|
||||
use App\Models\AdminLog;
|
||||
use App\Models\BlockedTime;
|
||||
use App\Models\Consultation;
|
||||
use App\Models\User;
|
||||
use Livewire\Volt\Volt;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->admin = User::factory()->admin()->create();
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Access Tests
|
||||
// ===========================================
|
||||
|
||||
test('admin can access blocked times page', function () {
|
||||
$this->actingAs($this->admin)
|
||||
->get(route('admin.settings.blocked-times'))
|
||||
->assertOk();
|
||||
});
|
||||
|
||||
test('non-admin cannot access blocked times page', function () {
|
||||
$client = User::factory()->individual()->create();
|
||||
|
||||
$this->actingAs($client)
|
||||
->get(route('admin.settings.blocked-times'))
|
||||
->assertForbidden();
|
||||
});
|
||||
|
||||
test('unauthenticated user cannot access blocked times page', function () {
|
||||
$this->get(route('admin.settings.blocked-times'))
|
||||
->assertRedirect(route('login'));
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Create All-Day Block Tests
|
||||
// ===========================================
|
||||
|
||||
test('admin can create an all-day block', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$blockDate = today()->addDays(5)->format('Y-m-d');
|
||||
|
||||
$initialCount = BlockedTime::count();
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', $blockDate)
|
||||
->set('is_all_day', true)
|
||||
->set('reason', 'Holiday')
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect(BlockedTime::count())->toBe($initialCount + 1);
|
||||
|
||||
$blocked = BlockedTime::latest()->first();
|
||||
|
||||
expect($blocked)->not->toBeNull()
|
||||
->and($blocked->isAllDay())->toBeTrue()
|
||||
->and($blocked->reason)->toBe('Holiday');
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Create Time-Range Block Tests
|
||||
// ===========================================
|
||||
|
||||
test('admin can create a time-range block', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$initialCount = BlockedTime::count();
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', today()->addDays(3)->format('Y-m-d'))
|
||||
->set('is_all_day', false)
|
||||
->set('start_time', '09:00')
|
||||
->set('end_time', '12:00')
|
||||
->set('reason', 'Morning meeting')
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect(BlockedTime::count())->toBe($initialCount + 1);
|
||||
|
||||
$blocked = BlockedTime::latest()->first();
|
||||
|
||||
expect($blocked)->not->toBeNull()
|
||||
->and($blocked->isAllDay())->toBeFalse()
|
||||
->and($blocked->start_time)->toContain('09:00')
|
||||
->and($blocked->end_time)->toContain('12:00')
|
||||
->and($blocked->reason)->toBe('Morning meeting');
|
||||
});
|
||||
|
||||
test('admin can create block without reason', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$initialCount = BlockedTime::count();
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', today()->addDays(2)->format('Y-m-d'))
|
||||
->set('is_all_day', true)
|
||||
->set('reason', '')
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect(BlockedTime::count())->toBe($initialCount + 1);
|
||||
|
||||
$blocked = BlockedTime::latest()->first();
|
||||
|
||||
expect($blocked)->not->toBeNull()
|
||||
->and($blocked->reason)->toBeNull();
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Edit Blocked Time Tests
|
||||
// ===========================================
|
||||
|
||||
test('admin can edit an existing blocked time', function () {
|
||||
$blocked = BlockedTime::factory()->allDay()->create([
|
||||
'block_date' => today()->addDays(5),
|
||||
'reason' => 'Original reason',
|
||||
]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openEditModal', $blocked->id)
|
||||
->set('reason', 'Updated reason')
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$blocked->refresh();
|
||||
|
||||
expect($blocked->reason)->toBe('Updated reason');
|
||||
});
|
||||
|
||||
test('admin can change block from all-day to time-range', function () {
|
||||
$blocked = BlockedTime::factory()->allDay()->create([
|
||||
'block_date' => today()->addDays(5),
|
||||
]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openEditModal', $blocked->id)
|
||||
->set('is_all_day', false)
|
||||
->set('start_time', '14:00')
|
||||
->set('end_time', '18:00')
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$blocked->refresh();
|
||||
|
||||
expect($blocked->isAllDay())->toBeFalse()
|
||||
->and($blocked->start_time)->toContain('14:00')
|
||||
->and($blocked->end_time)->toContain('18:00');
|
||||
});
|
||||
|
||||
test('admin can edit past blocked time date', function () {
|
||||
$blocked = BlockedTime::factory()->past()->create();
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->call('openEditModal', $blocked->id)
|
||||
->set('reason', 'Updated past block')
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
$blocked->refresh();
|
||||
|
||||
expect($blocked->reason)->toBe('Updated past block');
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Delete Blocked Time Tests
|
||||
// ===========================================
|
||||
|
||||
test('admin can delete a blocked time', function () {
|
||||
$blocked = BlockedTime::factory()->create();
|
||||
$blockedId = $blocked->id;
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('confirmDelete', $blockedId)
|
||||
->call('delete')
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect(BlockedTime::find($blockedId))->toBeNull();
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Validation Tests
|
||||
// ===========================================
|
||||
|
||||
test('cannot create block with end time before start time', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', today()->addDays(5)->format('Y-m-d'))
|
||||
->set('is_all_day', false)
|
||||
->set('start_time', '14:00')
|
||||
->set('end_time', '10:00')
|
||||
->call('save')
|
||||
->assertHasErrors(['end_time']);
|
||||
});
|
||||
|
||||
test('cannot create block for past dates', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', today()->subDays(5)->format('Y-m-d'))
|
||||
->set('is_all_day', true)
|
||||
->call('save')
|
||||
->assertHasErrors(['block_date']);
|
||||
});
|
||||
|
||||
test('can create block for today', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', today()->format('Y-m-d'))
|
||||
->set('is_all_day', true)
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect(BlockedTime::where('block_date', today())->exists())->toBeTrue();
|
||||
});
|
||||
|
||||
test('reason field respects 255 character max length', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$longReason = str_repeat('a', 256);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', today()->addDays(5)->format('Y-m-d'))
|
||||
->set('is_all_day', true)
|
||||
->set('reason', $longReason)
|
||||
->call('save')
|
||||
->assertHasErrors(['reason']);
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// List View Tests
|
||||
// ===========================================
|
||||
|
||||
test('list displays all blocked times sorted by date', function () {
|
||||
BlockedTime::factory()->create(['block_date' => today()->addDays(10)]);
|
||||
BlockedTime::factory()->create(['block_date' => today()->addDays(2)]);
|
||||
BlockedTime::factory()->create(['block_date' => today()->addDays(5)]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->set('filter', 'all');
|
||||
|
||||
$blockedTimes = $component->viewData('blockedTimes');
|
||||
|
||||
expect($blockedTimes)->toHaveCount(3);
|
||||
});
|
||||
|
||||
test('filter by upcoming shows only future blocks', function () {
|
||||
BlockedTime::factory()->upcoming()->create();
|
||||
BlockedTime::factory()->today()->create();
|
||||
BlockedTime::factory()->past()->create();
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->set('filter', 'upcoming');
|
||||
|
||||
$blockedTimes = $component->viewData('blockedTimes');
|
||||
|
||||
expect($blockedTimes)->toHaveCount(2)
|
||||
->and($blockedTimes->every(fn ($b) => $b->block_date->gte(today())))->toBeTrue();
|
||||
});
|
||||
|
||||
test('filter by past shows only past blocks', function () {
|
||||
BlockedTime::factory()->upcoming()->create();
|
||||
BlockedTime::factory()->today()->create();
|
||||
BlockedTime::factory()->past()->create();
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->set('filter', 'past');
|
||||
|
||||
$blockedTimes = $component->viewData('blockedTimes');
|
||||
|
||||
expect($blockedTimes)->toHaveCount(1)
|
||||
->and($blockedTimes->every(fn ($b) => $b->block_date->lt(today())))->toBeTrue();
|
||||
});
|
||||
|
||||
test('filter by all shows all blocks', function () {
|
||||
BlockedTime::factory()->upcoming()->create();
|
||||
BlockedTime::factory()->today()->create();
|
||||
BlockedTime::factory()->past()->create();
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->set('filter', 'all');
|
||||
|
||||
$blockedTimes = $component->viewData('blockedTimes');
|
||||
|
||||
expect($blockedTimes)->toHaveCount(3);
|
||||
});
|
||||
|
||||
test('list shows reason if provided', function () {
|
||||
BlockedTime::factory()->create([
|
||||
'block_date' => today()->addDays(5),
|
||||
'reason' => 'Personal vacation',
|
||||
]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->assertSee('Personal vacation');
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Audit Log Tests
|
||||
// ===========================================
|
||||
|
||||
test('audit log is created when blocked time is created', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', today()->addDays(5)->format('Y-m-d'))
|
||||
->set('is_all_day', true)
|
||||
->set('reason', 'Test')
|
||||
->call('save');
|
||||
|
||||
$log = AdminLog::where('target_type', 'blocked_time')->first();
|
||||
|
||||
expect($log)->not->toBeNull()
|
||||
->and($log->admin_id)->toBe($this->admin->id)
|
||||
->and($log->action)->toBe('create');
|
||||
});
|
||||
|
||||
test('audit log is created when blocked time is updated', function () {
|
||||
$blocked = BlockedTime::factory()->create([
|
||||
'block_date' => today()->addDays(5),
|
||||
]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openEditModal', $blocked->id)
|
||||
->set('reason', 'Updated')
|
||||
->call('save');
|
||||
|
||||
$log = AdminLog::where('target_type', 'blocked_time')
|
||||
->where('action', 'update')
|
||||
->first();
|
||||
|
||||
expect($log)->not->toBeNull()
|
||||
->and($log->target_id)->toBe($blocked->id);
|
||||
});
|
||||
|
||||
test('audit log is created when blocked time is deleted', function () {
|
||||
$blocked = BlockedTime::factory()->create();
|
||||
$blockedId = $blocked->id;
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('confirmDelete', $blockedId)
|
||||
->call('delete');
|
||||
|
||||
$log = AdminLog::where('target_type', 'blocked_time')
|
||||
->where('action', 'delete')
|
||||
->first();
|
||||
|
||||
expect($log)->not->toBeNull()
|
||||
->and($log->target_id)->toBe($blockedId);
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Pending Booking Warning Tests
|
||||
// ===========================================
|
||||
|
||||
test('warning displayed when blocking date with pending consultations', function () {
|
||||
$client = User::factory()->individual()->create();
|
||||
$blockDate = today()->addDays(5);
|
||||
|
||||
Consultation::factory()->create([
|
||||
'user_id' => $client->id,
|
||||
'booking_date' => $blockDate,
|
||||
'booking_time' => '10:00:00',
|
||||
'status' => ConsultationStatus::Pending,
|
||||
]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', $blockDate->format('Y-m-d'))
|
||||
->set('is_all_day', true)
|
||||
->call('checkPendingBookings');
|
||||
|
||||
expect($component->get('pendingBookings'))->toHaveCount(1)
|
||||
->and($component->get('pendingBookings')[0]['client'])->toBe($client->full_name);
|
||||
});
|
||||
|
||||
test('warning shows pending bookings within time range', function () {
|
||||
$client = User::factory()->individual()->create();
|
||||
$blockDate = today()->addDays(5);
|
||||
|
||||
// Consultation within blocked range (10:00 is between 09:00 and 12:00)
|
||||
Consultation::factory()->create([
|
||||
'user_id' => $client->id,
|
||||
'booking_date' => $blockDate,
|
||||
'booking_time' => '10:00:00',
|
||||
'status' => ConsultationStatus::Pending,
|
||||
]);
|
||||
|
||||
// Consultation outside blocked range (15:00 is not between 09:00 and 12:00)
|
||||
Consultation::factory()->create([
|
||||
'user_id' => $client->id,
|
||||
'booking_date' => $blockDate,
|
||||
'booking_time' => '15:00:00',
|
||||
'status' => ConsultationStatus::Pending,
|
||||
]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', $blockDate->format('Y-m-d'))
|
||||
->set('is_all_day', false)
|
||||
->set('start_time', '09:00')
|
||||
->set('end_time', '12:00')
|
||||
->call('checkPendingBookings');
|
||||
|
||||
expect($component->get('pendingBookings'))->toHaveCount(1);
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Modal Tests
|
||||
// ===========================================
|
||||
|
||||
test('create modal opens with default values', function () {
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal');
|
||||
|
||||
expect($component->get('showModal'))->toBeTrue()
|
||||
->and($component->get('editingId'))->toBeNull()
|
||||
->and($component->get('is_all_day'))->toBeTrue()
|
||||
->and($component->get('block_date'))->toBe(today()->format('Y-m-d'));
|
||||
});
|
||||
|
||||
test('edit modal opens with existing values', function () {
|
||||
$blocked = BlockedTime::factory()->timeRange('10:00', '14:00')->create([
|
||||
'block_date' => today()->addDays(5),
|
||||
'reason' => 'Test reason',
|
||||
]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->call('openEditModal', $blocked->id);
|
||||
|
||||
expect($component->get('showModal'))->toBeTrue()
|
||||
->and($component->get('editingId'))->toBe($blocked->id)
|
||||
->and($component->get('is_all_day'))->toBeFalse()
|
||||
->and($component->get('start_time'))->toBe('10:00')
|
||||
->and($component->get('end_time'))->toBe('14:00')
|
||||
->and($component->get('reason'))->toBe('Test reason');
|
||||
});
|
||||
|
||||
test('modal closes and resets on close', function () {
|
||||
$blocked = BlockedTime::factory()->create();
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
$component = Volt::test('admin.settings.blocked-times')
|
||||
->call('openEditModal', $blocked->id)
|
||||
->call('closeModal');
|
||||
|
||||
expect($component->get('showModal'))->toBeFalse()
|
||||
->and($component->get('editingId'))->toBeNull();
|
||||
});
|
||||
|
||||
// ===========================================
|
||||
// Multiple Blocks on Same Date Tests
|
||||
// ===========================================
|
||||
|
||||
test('multiple time-range blocks on same date handled correctly', function () {
|
||||
$blockDate = today()->addDays(5);
|
||||
|
||||
BlockedTime::factory()->timeRange('09:00', '12:00')->create([
|
||||
'block_date' => $blockDate,
|
||||
]);
|
||||
|
||||
$this->actingAs($this->admin);
|
||||
|
||||
Volt::test('admin.settings.blocked-times')
|
||||
->call('openCreateModal')
|
||||
->set('block_date', $blockDate->format('Y-m-d'))
|
||||
->set('is_all_day', false)
|
||||
->set('start_time', '14:00')
|
||||
->set('end_time', '17:00')
|
||||
->call('save')
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect(BlockedTime::where('block_date', $blockDate)->count())->toBe(2);
|
||||
});
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
use App\Models\BlockedTime;
|
||||
|
||||
test('isAllDay returns true when start_time and end_time are null', function () {
|
||||
$blocked = BlockedTime::factory()->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());
|
||||
});
|
||||
Reference in New Issue
Block a user