5a5f43f2de
- 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>
179 lines
7.1 KiB
PHP
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);
|
|
}
|
|
}
|