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(substr_count($html, 'toBe(1); 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('~~s', $html, $main); expect($main[0])->not->toContain('data-flux-'); });