Files
autocrm/tests/Feature/CalendarEnhancementsTest.php
T
Vasyka 5a5f43f2de feat(pdf): inline preview by default with ?download=1 override + vehicle photo fallback
- WorkOrder and InjectorProtocol PDF routes now respond with
  Content-Disposition: inline (opens in browser tab so the user can
  read/print/save from the built-in PDF viewer). ?download=1 forces
  the classic attachment download.
- CalendarBoard exportPdf() switched to the same inline default.
- WO edit action + WO table row action + injector protocol actions
  now use ->url(...)->openUrlInNewTab() instead of streaming the PDF
  inline into the current tab.
- Dashboard Docs tab has both a preview link and a "Descarcă" link.
- Vehicle card photo falls back to WO's first uploaded photo when
  Vehicle model has no MediaLibrary integration of its own.

Test CalendarEnhancementsTest updated to assert the new inline
response headers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-08-05 20:56:24 +00:00

179 lines
7.1 KiB
PHP

<?php
namespace Tests\Feature;
use App\Filament\Tenant\Pages\CalendarBoard;
use App\Models\Central\Company;
use App\Models\Central\Plan;
use App\Models\Tenant\Appointment;
use App\Models\Tenant\Client;
use App\Models\Tenant\Post;
use App\Models\Tenant\User;
use App\Models\Tenant\Vehicle;
use App\Tenancy\TenantManager;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Livewire\Livewire;
use Tests\TestCase;
class CalendarEnhancementsTest extends TestCase
{
use RefreshDatabase;
private Company $company;
protected function setUp(): void
{
parent::setUp();
$plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
$this->company = Company::create(['plan_id' => $plan->id, 'slug' => 'ce-' . uniqid(), 'name' => 'CE', 'status' => 'active']);
app(TenantManager::class)->setCurrent($this->company);
}
public function test_view_mode_day_returns_one_day(): void
{
Carbon::setTestNow('2026-06-10 10:00:00');
$page = new CalendarBoard;
$page->weekStart = '2026-06-10';
$page->viewMode = 'day';
$days = $page->getDays();
$this->assertCount(1, $days);
$this->assertEquals('2026-06-10', $days[0]['date']);
Carbon::setTestNow();
}
public function test_view_mode_month_returns_30_or_31_days(): void
{
$page = new CalendarBoard;
$page->weekStart = '2026-06-01';
$page->viewMode = 'month';
$days = $page->getDays();
$this->assertCount(30, $days); // June has 30 days
$this->assertEquals('2026-06-01', $days[0]['date']);
$this->assertEquals('2026-06-30', $days[29]['date']);
}
public function test_view_mode_custom_uses_range(): void
{
$page = new CalendarBoard;
$page->weekStart = '2026-06-10';
$page->viewMode = 'custom';
$page->customStart = '2026-06-10';
$page->customEnd = '2026-06-13';
$days = $page->getDays();
$this->assertCount(4, $days);
$this->assertEquals('2026-06-10', $days[0]['date']);
$this->assertEquals('2026-06-13', $days[3]['date']);
}
public function test_create_post_inline_adds_to_calendar(): void
{
$admin = User::create(['name' => 'A', 'email' => 'a@e.com', 'password' => bcrypt('x'), 'role' => 'admin', 'status' => 'active']);
$this->actingAs($admin);
Livewire::test(CalendarBoard::class)
->call('openNewPostForm')
->set('newPost.name', 'Curte 1')
->set('newPost.color', '#ff0000')
->set('newPost.hours_per_day', 8)
->set('newPost.description', 'fără lift')
->call('createPost')
->assertSet('showNewPostForm', false);
$post = Post::where('name', 'Curte 1')->first();
$this->assertNotNull($post);
$this->assertEquals(8.0, (float) $post->hours_per_day);
$this->assertEquals('fără lift', $post->description);
}
public function test_rename_post_updates_name_and_default_master(): void
{
$admin = User::create(['name' => 'A', 'email' => 'a@e.com', 'password' => bcrypt('x'), 'role' => 'admin', 'status' => 'active']);
$master = User::create(['name' => 'Vasile', 'email' => 'v@e.com', 'password' => bcrypt('x'), 'role' => 'mechanic', 'status' => 'active']);
$post = Post::create(['name' => 'Pod 1', 'color' => '#3b82f6', 'is_active' => true]);
$this->actingAs($admin);
Livewire::test(CalendarBoard::class)
->call('openRenamePost', $post->id)
->set('renamingPostName', 'Pod electric')
->set('renamingPostMasterId', $master->id)
->call('saveRenamePost')
->assertSet('renamingPostId', null);
$post->refresh();
$this->assertEquals('Pod electric', $post->name);
$this->assertEquals($master->id, $post->default_master_id);
}
public function test_new_appointment_autofills_master_from_post_default(): void
{
$master = User::create(['name' => 'Vasile', 'email' => 'v@e.com', 'password' => bcrypt('x'), 'role' => 'mechanic', 'status' => 'active']);
$post = Post::create(['name' => 'Pod 1', 'color' => '#3b82f6', 'is_active' => true, 'default_master_id' => $master->id]);
Livewire::test(CalendarBoard::class)
->set('groupBy', 'post')
->call('openNewForm', $post->id, '2026-06-10');
$component = Livewire::test(CalendarBoard::class);
$component->set('groupBy', 'post')->call('openNewForm', $post->id, '2026-06-10');
// The newAppt.master_id should have been auto-set from post.default_master_id
$page = new CalendarBoard;
$page->groupBy = 'post';
$page->openNewForm($post->id, '2026-06-10');
$this->assertEquals($master->id, $page->newAppt['master_id']);
$this->assertEquals($post->id, $page->newAppt['post_id']);
}
public function test_list_view_returns_flat_appointments(): void
{
$client = Client::create(['name' => 'C', 'phone' => '+37399000000', 'type' => 'individual', 'status' => 'active']);
$vehicle = Vehicle::create(['client_id' => $client->id, 'make' => 'BMW', 'model' => 'X5', 'plate' => 'L-1']);
$post = Post::create(['name' => 'Pod 1', 'color' => '#3b82f6', 'is_active' => true]);
Appointment::create([
'post_id' => $post->id, 'client_id' => $client->id, 'vehicle_id' => $vehicle->id,
'date' => '2026-06-10', 'time_start' => '10:00', 'time_end' => '11:00',
'title' => 'Schimb ulei', 'status' => 'scheduled',
]);
$page = new CalendarBoard;
$page->weekStart = '2026-06-08';
$page->viewMode = 'week';
$list = $page->getListAppointments();
$this->assertCount(1, $list);
$this->assertEquals('Schimb ulei', $list[0]['title']);
$this->assertEquals('C', $list[0]['client_name']);
$this->assertEquals('+37399000000', $list[0]['client_phone']);
$this->assertEquals('Pod 1', $list[0]['post_name']);
}
public function test_export_pdf_returns_streamed_pdf_response(): void
{
$client = Client::create(['name' => 'C', 'phone' => '+37399000000', 'type' => 'individual', 'status' => 'active']);
$post = Post::create(['name' => 'Pod 1', 'color' => '#3b82f6', 'is_active' => true]);
Appointment::create([
'post_id' => $post->id, 'client_id' => $client->id,
'date' => Carbon::now()->startOfWeek()->toDateString(),
'time_start' => '09:00', 'time_end' => '10:00',
'title' => 'Test PDF', 'status' => 'scheduled',
]);
$page = new CalendarBoard;
$page->mount();
$page->viewMode = 'week';
$response = $page->exportPdf();
// Inline PDF response (was StreamedResponse before we switched to preview-by-default).
$this->assertSame('application/pdf', $response->headers->get('content-type'));
$cd = $response->headers->get('content-disposition');
$this->assertStringStartsWith('inline;', $cd);
$this->assertStringContainsString('programari_', $cd);
$this->assertStringContainsString('.pdf', $cd);
}
}