196 lines
7.1 KiB
PHP
196 lines
7.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Resources\BackupScheduleResource;
|
|
use App\Filament\Resources\BackupScheduleResource\Pages\ListBackupSchedules;
|
|
use App\Filament\Resources\BackupSetResource;
|
|
use App\Filament\Resources\BackupSetResource\Pages\ListBackupSets;
|
|
use App\Filament\Resources\PolicyResource\Pages\ListPolicies;
|
|
use App\Filament\Resources\RestoreRunResource;
|
|
use App\Filament\Resources\RestoreRunResource\Pages\ListRestoreRuns;
|
|
use App\Filament\Resources\Workspaces\Pages\ListWorkspaces;
|
|
use App\Filament\Resources\Workspaces\WorkspaceResource;
|
|
use App\Jobs\SyncPoliciesJob;
|
|
use App\Models\User;
|
|
use App\Models\Workspace;
|
|
use App\Models\WorkspaceMembership;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Filament\Actions\Action;
|
|
use Filament\Facades\Filament;
|
|
use Filament\Tables\Table;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Livewire\Features\SupportTesting\Testable;
|
|
use Livewire\Livewire;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
function getFeature122EmptyStateTable(Testable $component): Table
|
|
{
|
|
return $component->instance()->getTable();
|
|
}
|
|
|
|
function getFeature122EmptyStateAction(Testable $component, string $name): ?Action
|
|
{
|
|
foreach (getFeature122EmptyStateTable($component)->getEmptyStateActions() as $action) {
|
|
if ($action instanceof Action && $action->getName() === $name) {
|
|
return $action;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function makeWorkspaceListComponent(string $role = 'owner'): Testable
|
|
{
|
|
$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' => $role,
|
|
]);
|
|
|
|
$user->forceFill([
|
|
'last_workspace_id' => (int) $workspace->getKey(),
|
|
])->save();
|
|
|
|
test()->actingAs($user)
|
|
->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()]);
|
|
|
|
return Livewire::test(ListWorkspaces::class);
|
|
}
|
|
|
|
it('defines the policies empty state contract and keeps the sync CTA outcome intact', function (): void {
|
|
Queue::fake();
|
|
bindFailHardGraphClient();
|
|
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$this->actingAs($user);
|
|
$tenant->makeCurrent();
|
|
Filament::setTenant($tenant, true);
|
|
|
|
$component = Livewire::test(ListPolicies::class)
|
|
->assertTableEmptyStateActionsExistInOrder(['sync'])
|
|
->assertSee('No policies synced yet')
|
|
->assertSee('Sync your first tenant to see Intune policies here.');
|
|
|
|
$table = getFeature122EmptyStateTable($component);
|
|
|
|
expect($table->getEmptyStateHeading())->toBe('No policies synced yet');
|
|
expect($table->getEmptyStateDescription())->toBe('Sync your first tenant to see Intune policies here.');
|
|
expect($table->getEmptyStateIcon())->toBe('heroicon-o-arrow-path');
|
|
|
|
$action = getFeature122EmptyStateAction($component, 'sync');
|
|
|
|
expect($action)->not->toBeNull();
|
|
expect($action?->getLabel())->toBe('Sync from Intune');
|
|
|
|
$component
|
|
->mountAction('sync')
|
|
->callMountedAction()
|
|
->assertHasNoActionErrors();
|
|
|
|
Queue::assertPushed(SyncPoliciesJob::class);
|
|
});
|
|
|
|
it('defines the backup sets empty state contract and links its CTA to create', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$this->actingAs($user);
|
|
$tenant->makeCurrent();
|
|
Filament::setTenant($tenant, true);
|
|
|
|
$component = Livewire::test(ListBackupSets::class)
|
|
->assertTableEmptyStateActionsExistInOrder(['create'])
|
|
->assertSee('No backup sets')
|
|
->assertSee('Create a backup set to start protecting your configurations.');
|
|
|
|
$table = getFeature122EmptyStateTable($component);
|
|
|
|
expect($table->getEmptyStateHeading())->toBe('No backup sets');
|
|
expect($table->getEmptyStateDescription())->toBe('Create a backup set to start protecting your configurations.');
|
|
expect($table->getEmptyStateIcon())->toBe('heroicon-o-archive-box');
|
|
|
|
$action = getFeature122EmptyStateAction($component, 'create');
|
|
|
|
expect($action)->not->toBeNull();
|
|
expect($action?->getLabel())->toBe('Create backup set');
|
|
expect($action?->getUrl())->toBe(BackupSetResource::getUrl('create', tenant: $tenant));
|
|
});
|
|
|
|
it('defines the restore runs empty state contract and links its CTA to create', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$this->actingAs($user);
|
|
$tenant->makeCurrent();
|
|
Filament::setTenant($tenant, true);
|
|
|
|
$component = Livewire::test(ListRestoreRuns::class)
|
|
->assertTableEmptyStateActionsExistInOrder(['create'])
|
|
->assertSee('No restore runs')
|
|
->assertSee('Start a restoration from a backup set.');
|
|
|
|
$table = getFeature122EmptyStateTable($component);
|
|
|
|
expect($table->getEmptyStateHeading())->toBe('No restore runs');
|
|
expect($table->getEmptyStateDescription())->toBe('Start a restoration from a backup set.');
|
|
expect($table->getEmptyStateIcon())->toBe('heroicon-o-arrow-path-rounded-square');
|
|
|
|
$action = getFeature122EmptyStateAction($component, 'create');
|
|
|
|
expect($action)->not->toBeNull();
|
|
expect($action?->getLabel())->toBe('New restore run');
|
|
expect($action?->getUrl())->toBe(RestoreRunResource::getUrl('create', tenant: $tenant));
|
|
});
|
|
|
|
it('defines the backup schedules empty state contract and links its CTA to create', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$this->actingAs($user);
|
|
$tenant->makeCurrent();
|
|
Filament::setTenant($tenant, true);
|
|
|
|
$component = Livewire::test(ListBackupSchedules::class)
|
|
->assertTableEmptyStateActionsExistInOrder(['create'])
|
|
->assertSee('No schedules configured')
|
|
->assertSee('Set up automated backups.');
|
|
|
|
$table = getFeature122EmptyStateTable($component);
|
|
|
|
expect($table->getEmptyStateHeading())->toBe('No schedules configured');
|
|
expect($table->getEmptyStateDescription())->toBe('Set up automated backups.');
|
|
expect($table->getEmptyStateIcon())->toBe('heroicon-o-clock');
|
|
|
|
$action = getFeature122EmptyStateAction($component, 'create');
|
|
|
|
expect($action)->not->toBeNull();
|
|
expect($action?->getLabel())->toBe('New backup schedule');
|
|
expect($action?->getUrl())->toBe(BackupScheduleResource::getUrl('create', tenant: $tenant));
|
|
});
|
|
|
|
it('defines the workspaces empty state contract and links its CTA to create', function (): void {
|
|
$component = makeWorkspaceListComponent()
|
|
->assertTableEmptyStateActionsExistInOrder(['create'])
|
|
->assertSee('No workspaces')
|
|
->assertSee('Create your first workspace.');
|
|
|
|
$table = getFeature122EmptyStateTable($component);
|
|
|
|
expect($table->getEmptyStateHeading())->toBe('No workspaces');
|
|
expect($table->getEmptyStateDescription())->toBe('Create your first workspace.');
|
|
expect($table->getEmptyStateIcon())->toBe('heroicon-o-squares-2x2');
|
|
|
|
$action = getFeature122EmptyStateAction($component, 'create');
|
|
|
|
expect($action)->not->toBeNull();
|
|
expect($action?->getLabel())->toBe('New workspace');
|
|
expect($action?->getUrl())->toBe(WorkspaceResource::getUrl('create'));
|
|
});
|