libra/tests/Unit/Services/CalendarServiceTest.php

179 lines
5.7 KiB
PHP

<?php
use App\Enums\ConsultationType;
use App\Models\Consultation;
use App\Models\User;
use App\Services\CalendarService;
beforeEach(function () {
$this->service = new CalendarService;
});
it('generates valid ics file', function () {
$consultation = Consultation::factory()->approved()->create([
'booking_date' => '2024-03-15',
'booking_time' => '10:00:00',
]);
$ics = $this->service->generateIcs($consultation);
expect($ics)
->toContain('BEGIN:VCALENDAR')
->toContain('BEGIN:VEVENT')
->toContain('DTSTART')
->toContain('DTEND')
->toContain('END:VCALENDAR');
});
it('includes correct duration of 45 minutes', function () {
$consultation = Consultation::factory()->approved()->create([
'booking_date' => '2024-03-15',
'booking_time' => '10:00:00',
]);
$ics = $this->service->generateIcs($consultation);
// Start at 10:00, end at 10:45 (45 min default)
expect($ics)
->toContain('DTSTART;TZID=Asia/Jerusalem:20240315T100000')
->toContain('DTEND;TZID=Asia/Jerusalem:20240315T104500');
});
it('generates Arabic content for Arabic-preferring users', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->for($user)->create();
$ics = $this->service->generateIcs($consultation);
expect($ics)
->toContain('استشارة مع مكتب ليبرا للمحاماة')
->toContain('رقم الحجز');
});
it('generates English content for English-preferring users', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->for($user)->create();
$ics = $this->service->generateIcs($consultation);
expect($ics)
->toContain('Consultation with Libra Law Firm')
->toContain('Booking Reference');
});
it('defaults to Arabic when user has default language setting', function () {
// The database defaults preferred_language to 'ar', so we test with the default
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->for($user)->create();
$ics = $this->service->generateIcs($consultation);
expect($ics)
->toContain('استشارة مع مكتب ليبرا للمحاماة');
});
it('includes payment info for paid consultations', function () {
$consultation = Consultation::factory()->approved()->create([
'consultation_type' => ConsultationType::Paid,
'payment_amount' => 150.00,
]);
$ics = $this->service->generateIcs($consultation);
expect($ics)->toContain('150.00');
});
it('does not include payment info for free consultations', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->free()->for($user)->create();
$ics = $this->service->generateIcs($consultation);
expect($ics)
->toContain('Consultation Type: Free')
->not->toContain('Amount:');
});
it('includes 1-hour reminder alarm', function () {
$consultation = Consultation::factory()->approved()->create();
$ics = $this->service->generateIcs($consultation);
expect($ics)
->toContain('BEGIN:VALARM')
->toContain('TRIGGER:-PT1H')
->toContain('ACTION:DISPLAY')
->toContain('END:VALARM');
});
it('includes proper timezone definition', function () {
$consultation = Consultation::factory()->approved()->create();
$ics = $this->service->generateIcs($consultation);
expect($ics)
->toContain('BEGIN:VTIMEZONE')
->toContain('TZID:Asia/Jerusalem')
->toContain('END:VTIMEZONE');
});
it('includes unique identifier', function () {
$consultation = Consultation::factory()->approved()->create();
$ics = $this->service->generateIcs($consultation);
expect($ics)->toContain('UID:consultation-'.$consultation->id.'@libra.ps');
});
it('includes location from config', function () {
$consultation = Consultation::factory()->approved()->create();
$ics = $this->service->generateIcs($consultation);
expect($ics)->toContain('LOCATION:');
});
it('uses CRLF line endings per RFC 5545', function () {
$consultation = Consultation::factory()->approved()->create();
$ics = $this->service->generateIcs($consultation);
// Check for CRLF line endings
expect($ics)->toContain("\r\n");
});
it('escapes special characters in content', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->for($user)->create();
$ics = $this->service->generateIcs($consultation);
// The location should have escaped commas if present
// Location is: "Libra Law Firm, Palestine" which has a comma
expect($ics)->toContain('Libra Law Firm\, Palestine');
});
it('returns download response with correct headers', function () {
$consultation = Consultation::factory()->approved()->create([
'booking_date' => '2024-03-15',
]);
$response = $this->service->generateDownloadResponse($consultation);
expect($response->headers->get('Content-Type'))
->toBe('text/calendar; charset=utf-8');
expect($response->headers->get('Content-Disposition'))
->toContain('consultation-2024-03-15.ics');
});
it('generates correct filename based on booking date', function () {
$consultation = Consultation::factory()->approved()->create([
'booking_date' => '2025-06-20',
]);
$response = $this->service->generateDownloadResponse($consultation);
expect($response->headers->get('Content-Disposition'))
->toContain('consultation-2025-06-20.ics');
});