7637294593
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
89 lines
3.6 KiB
PHP
89 lines
3.6 KiB
PHP
<?php
|
|
|
|
use App\Models\Consultation;
|
|
use App\Models\User;
|
|
use App\Models\WorkingHour;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
use Livewire\Volt\Volt;
|
|
|
|
beforeEach(function () {
|
|
Mail::fake();
|
|
RateLimiter::clear('guest-booking:127.0.0.1');
|
|
foreach (range(0, 6) as $dow) {
|
|
WorkingHour::factory()->create(['day_of_week' => $dow, 'is_active' => true, 'start_time' => '09:00', 'end_time' => '13:00']);
|
|
}
|
|
});
|
|
|
|
test('booking page shows the section head, the forest card and the month calendar', function () {
|
|
$html = $this->get('/booking')->assertOk()->getContent();
|
|
|
|
expect($html)
|
|
->toContain('class="sec-head"')
|
|
->toContain('class="book"')
|
|
->toContain('book-l on-dark')
|
|
->toContain('data-balance="static"')
|
|
->toContain('tel:+970599353502')
|
|
->toContain('book-r')
|
|
->toContain('calendar-grid')
|
|
->not->toContain('class="days"');
|
|
|
|
expect(strpos($html, 'book-r'))->toBeLessThan(strpos($html, 'calendar-grid'));
|
|
});
|
|
|
|
test('selecting a slot reveals the fields and the full flow books once', function () {
|
|
$date = now()->addDay()->format('Y-m-d');
|
|
|
|
$c = Volt::test('pages.booking')
|
|
->call('selectSlot', $date, '09:00')
|
|
->assertSee('wire:model="guestName"', false)
|
|
->assertSee('wire:model="guestEmail"', false)
|
|
->assertSee('wire:model="guestPhone"', false)
|
|
->assertSee('wire:model="problemSummary"', false)
|
|
->assertSee('wire:model="captchaAnswer"', false)
|
|
->set('guestName', 'Test Guest')->set('guestEmail', 'g@example.com')->set('guestPhone', '+970599000000')
|
|
->set('problemSummary', 'A sufficiently long description of my case.')
|
|
->set('captchaAnswer', session('captcha_answer'))
|
|
->call('showConfirm')->assertSet('showConfirmation', true)
|
|
->call('submit')->assertRedirect(route('booking.success'));
|
|
|
|
expect(Consultation::count())->toBe(1);
|
|
});
|
|
|
|
test('validation errors render under their fields', function () {
|
|
$date = now()->addDay()->format('Y-m-d');
|
|
|
|
Volt::test('pages.booking')->call('selectSlot', $date, '09:00')
|
|
->call('showConfirm')
|
|
->assertHasErrors(['guestName', 'guestEmail', 'guestPhone', 'problemSummary', 'captchaAnswer'])
|
|
->assertSeeHtml('class="err"');
|
|
});
|
|
|
|
test('logged in clients see the message and no form on the booking page', function () {
|
|
$html = $this->actingAs(User::factory()->client()->create())->get('/booking')->assertOk()->getContent();
|
|
|
|
expect($html)->toContain(__('booking.logged_in_title'))->toContain(route('client.consultations.book'))
|
|
->not->toContain('wire:model="guestName"');
|
|
});
|
|
|
|
test('month calendar days carry hook classes without changing behaviour', function () {
|
|
$html = Volt::test('availability-calendar')->html();
|
|
|
|
expect($html)->toContain('site-cal-day')->toContain('is-available')->toContain('site-cal-nav')->toContain('wire:click="selectDate(');
|
|
});
|
|
|
|
test('calendar css is scoped to the public site', function () {
|
|
$css = file_get_contents(resource_path('css/public.css'));
|
|
expect($css)->toContain('body.site .book-r .site-cal-day')->toContain('body.site .book-r .site-cal-day.is-selected');
|
|
});
|
|
|
|
test('success page shows the balance, title, message and home button without flux output', function () {
|
|
$html = $this->get('/booking/success')->assertOk()->getContent();
|
|
|
|
expect($html)->toContain('data-balance="static"')->toContain(__('booking.success_title'))->toContain(__('booking.success_message'))
|
|
->toContain(__('site.nav_home'));
|
|
|
|
preg_match('~<main.*?</main>~s', $html, $main);
|
|
expect($main[0])->not->toContain('data-flux-');
|
|
});
|