instance(); $instance->cacheInteractsWithHeaderActions(); foreach ($instance->getCachedHeaderActions() as $action) { if ($action instanceof Action && $action->getName() === $name) { return $action; } } return null; } function getPlacementEmptyStateAction(Testable $component, string $name): ?Action { foreach ($component->instance()->getTable()->getEmptyStateActions() as $action) { if ($action instanceof Action && $action->getName() === $name) { return $action; } } return null; } it('shows create only in empty state when workspaces table is empty', function (): void { $workspace = Workspace::factory()->create([ 'archived_at' => now(), ]); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); $user->forceFill([ 'last_workspace_id' => (int) $workspace->getKey(), ])->save(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]); $component = Livewire::test(ListWorkspaces::class) ->assertTableEmptyStateActionsExistInOrder(['create']); expect($component->instance()->getTable()->getEmptyStateActions())->toHaveCount(1); $emptyStateCreate = getPlacementEmptyStateAction($component, 'create'); expect($emptyStateCreate)->not->toBeNull(); expect($emptyStateCreate?->getLabel())->toBe('New workspace'); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeFalse(); }); it('shows create only in header when workspaces table is not empty', function (): void { $workspace = Workspace::factory()->create([ 'archived_at' => null, ]); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); $user->forceFill([ 'last_workspace_id' => (int) $workspace->getKey(), ])->save(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]); $component = Livewire::test(ListWorkspaces::class) ->assertCountTableRecords(1); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeTrue(); }); it('shows create only in empty state when backup schedules table is empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); $component = Livewire::test(ListBackupSchedules::class) ->assertTableEmptyStateActionsExistInOrder(['create']); expect($component->instance()->getTable()->getEmptyStateActions())->toHaveCount(1); $emptyStateCreate = getPlacementEmptyStateAction($component, 'create'); expect($emptyStateCreate)->not->toBeNull(); expect($emptyStateCreate?->getLabel())->toBe('New backup schedule'); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeFalse(); }); it('shows create only in header when backup schedules table is not empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); BackupSchedule::query()->create([ 'tenant_id' => (int) $tenant->getKey(), 'name' => 'Daily schedule', 'is_enabled' => true, 'timezone' => 'UTC', 'frequency' => 'daily', 'time_of_day' => '00:00:00', 'days_of_week' => null, 'policy_types' => ['device_config'], 'include_foundations' => true, 'retention_keep_last' => 30, ]); $component = Livewire::test(ListBackupSchedules::class) ->assertCountTableRecords(1); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeTrue(); }); it('shows create only in empty state when restore runs table is empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); $component = Livewire::test(ListRestoreRuns::class) ->assertTableEmptyStateActionsExistInOrder(['create']); expect($component->instance()->getTable()->getEmptyStateActions())->toHaveCount(1); $emptyStateCreate = getPlacementEmptyStateAction($component, 'create'); expect($emptyStateCreate)->not->toBeNull(); expect($emptyStateCreate?->getLabel())->toBe('New restore run'); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeFalse(); }); it('shows create only in header when restore runs table is not empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); RestoreRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), ]); $component = Livewire::test(ListRestoreRuns::class) ->assertCountTableRecords(1); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeTrue(); }); it('shows create only in empty state when backup sets table is empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); $component = Livewire::test(ListBackupSets::class) ->assertTableEmptyStateActionsExistInOrder(['create']); expect($component->instance()->getTable()->getEmptyStateActions())->toHaveCount(1); $emptyStateCreate = getPlacementEmptyStateAction($component, 'create'); expect($emptyStateCreate)->not->toBeNull(); expect($emptyStateCreate?->getLabel())->toBe('Create backup set'); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeFalse(); }); it('shows create only in header when backup sets table is not empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); BackupSet::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), ]); $component = Livewire::test(ListBackupSets::class) ->assertCountTableRecords(1); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeTrue(); }); it('shows create only in empty state when tenants table is empty', function (): void { $workspace = Workspace::factory()->create([ 'archived_at' => now(), ]); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); $user->forceFill([ 'last_workspace_id' => (int) $workspace->getKey(), ])->save(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]); $component = Livewire::test(ListTenants::class) ->assertTableEmptyStateActionsExistInOrder(['add_tenant']); $emptyStateCreate = getPlacementEmptyStateAction($component, 'add_tenant'); expect($emptyStateCreate)->not->toBeNull(); expect($emptyStateCreate?->getLabel())->toBe('Add tenant'); $headerCreate = getHeaderAction($component, 'add_tenant'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeFalse(); }); it('shows create only in header when tenants table is not empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $component = Livewire::test(ListTenants::class) ->assertCountTableRecords(1); $headerCreate = getHeaderAction($component, 'add_tenant'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeTrue(); expect($headerCreate?->getLabel())->toBe('Add tenant'); }); it('labels the empty-state tenant action as continue onboarding when one draft exists', function (): void { $workspace = Workspace::factory()->create([ 'archived_at' => now(), ]); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'owner', ]); createOnboardingDraft([ 'workspace' => $workspace, 'started_by' => $user, 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'tenant_name' => 'Onboarding Tenant', ], ]); $user->forceFill([ 'last_workspace_id' => (int) $workspace->getKey(), ])->save(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]); $component = Livewire::test(ListTenants::class) ->assertTableEmptyStateActionsExistInOrder(['add_tenant']); $emptyStateCreate = getPlacementEmptyStateAction($component, 'add_tenant'); expect($emptyStateCreate)->not->toBeNull(); expect($emptyStateCreate?->getLabel())->toBe('Continue onboarding'); }); it('labels the tenant header action as continue onboarding when one draft exists', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); createOnboardingDraft([ 'workspace' => $tenant->workspace, 'started_by' => $user, 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'tenant_name' => 'Resumable Draft', ], ]); $this->actingAs($user); $component = Livewire::test(ListTenants::class) ->assertCountTableRecords(1); $headerCreate = getHeaderAction($component, 'add_tenant'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeTrue(); expect($headerCreate?->getLabel())->toBe('Continue onboarding'); }); it('labels the tenant header action as choose onboarding draft when multiple drafts exist', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); createOnboardingDraft([ 'workspace' => $tenant->workspace, 'started_by' => $user, 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => 'cccccccc-cccc-cccc-cccc-cccccccccccc', 'tenant_name' => 'Draft One', ], ]); createOnboardingDraft([ 'workspace' => $tenant->workspace, 'started_by' => $user, 'updated_by' => $user, 'state' => [ 'entra_tenant_id' => 'dddddddd-dddd-dddd-dddd-dddddddddddd', 'tenant_name' => 'Draft Two', ], ]); $this->actingAs($user); $component = Livewire::test(ListTenants::class) ->assertCountTableRecords(1); $headerCreate = getHeaderAction($component, 'add_tenant'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeTrue(); expect($headerCreate?->getLabel())->toBe('Choose onboarding draft'); }); it('shows create only in empty state when provider connections table is empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner', ensureDefaultMicrosoftProviderConnection: false); $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); $component = Livewire::test(ListProviderConnections::class) ->assertCountTableRecords(0) ->assertTableEmptyStateActionsExistInOrder(['create']); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeFalse(); }); it('shows create only in header when provider connections table is not empty', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); $tenant->makeCurrent(); Filament::setTenant($tenant, true); ProviderConnection::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); $component = Livewire::test(ListProviderConnections::class); $headerCreate = getHeaderAction($component, 'create'); expect($headerCreate)->not->toBeNull(); expect($headerCreate?->isVisible())->toBeTrue(); });