## Summary - replace the legacy Tenant and TenantMembership core models with ManagedEnvironment and ManagedEnvironmentMembership - propagate the managed environment naming and key changes across Filament resources, pages, controllers, jobs, models, and supporting runtime paths - add feature 279 spec artifacts and focused managed-environment test coverage for model behavior, route binding, panel context, authorization, and legacy guardrails ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` ## Notes - branch pushed from commit `1123b122` - browser smoke test file was added but not run in this pass Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #335
127 lines
4.3 KiB
PHP
127 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Pages\TenantRequiredPermissions;
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\TenantPermission;
|
|
use App\Models\User;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Livewire\Livewire;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
function seedTenantRequiredPermissionsFixture(ManagedEnvironment $tenant): void
|
|
{
|
|
config()->set('intune_permissions.permissions', [
|
|
[
|
|
'key' => 'DeviceManagementApps.Read.All',
|
|
'type' => 'application',
|
|
'description' => 'Backup application permission',
|
|
'features' => ['backup'],
|
|
],
|
|
[
|
|
'key' => 'Group.Read.All',
|
|
'type' => 'delegated',
|
|
'description' => 'Backup delegated permission',
|
|
'features' => ['backup'],
|
|
],
|
|
[
|
|
'key' => 'Reports.Read.All',
|
|
'type' => 'application',
|
|
'description' => 'Reporting permission',
|
|
'features' => ['reporting'],
|
|
],
|
|
]);
|
|
config()->set('entra_permissions.permissions', []);
|
|
|
|
TenantPermission::query()->create([
|
|
'managed_environment_id' => (int) $tenant->getKey(),
|
|
'permission_key' => 'Group.Read.All',
|
|
'status' => 'missing',
|
|
'details' => ['source' => 'fixture'],
|
|
'last_checked_at' => now(),
|
|
]);
|
|
|
|
TenantPermission::query()->create([
|
|
'managed_environment_id' => (int) $tenant->getKey(),
|
|
'permission_key' => 'Reports.Read.All',
|
|
'status' => 'granted',
|
|
'details' => ['source' => 'fixture'],
|
|
'last_checked_at' => now(),
|
|
]);
|
|
}
|
|
|
|
function tenantRequiredPermissionsComponent(User $user, ManagedEnvironment $tenant, array $query = [])
|
|
{
|
|
test()->actingAs($user);
|
|
setAdminPanelContext();
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
|
|
|
|
$query = array_merge([
|
|
'tenant' => (string) $tenant->external_id,
|
|
], $query);
|
|
|
|
return Livewire::withQueryParams($query)->test(TenantRequiredPermissions::class);
|
|
}
|
|
|
|
it('uses native table filters and search while keeping summary state aligned with visible rows', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'readonly');
|
|
seedTenantRequiredPermissionsFixture($tenant);
|
|
|
|
$component = tenantRequiredPermissionsComponent($user, $tenant)
|
|
->assertTableFilterExists('status')
|
|
->assertTableFilterExists('type')
|
|
->assertTableFilterExists('features')
|
|
->assertCanSeeTableRecords([
|
|
'DeviceManagementApps.Read.All',
|
|
'Group.Read.All',
|
|
])
|
|
->assertCanNotSeeTableRecords(['Reports.Read.All'])
|
|
->assertSee('Missing application permissions')
|
|
->assertSee('Guidance');
|
|
|
|
$component
|
|
->filterTable('status', 'present')
|
|
->filterTable('type', 'application')
|
|
->searchTable('Reports')
|
|
->assertCountTableRecords(1)
|
|
->assertCanSeeTableRecords(['Reports.Read.All'])
|
|
->assertCanNotSeeTableRecords([
|
|
'DeviceManagementApps.Read.All',
|
|
'Group.Read.All',
|
|
]);
|
|
|
|
$viewModel = $component->instance()->viewModel();
|
|
|
|
expect($viewModel['overview']['counts'])->toBe([
|
|
'missing_application' => 0,
|
|
'missing_delegated' => 0,
|
|
'present' => 1,
|
|
'error' => 0,
|
|
])
|
|
->and(array_column($viewModel['permissions'], 'key'))->toBe(['Reports.Read.All'])
|
|
->and($viewModel['copy']['application'])->toBe('DeviceManagementApps.Read.All');
|
|
});
|
|
|
|
it('keeps copy payloads feature-scoped and shows the native no-matches state', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'readonly');
|
|
seedTenantRequiredPermissionsFixture($tenant);
|
|
|
|
$component = tenantRequiredPermissionsComponent($user, $tenant)
|
|
->set('tableFilters.features.values', ['backup'])
|
|
->assertSet('tableFilters.features.values', ['backup']);
|
|
|
|
$viewModel = $component->instance()->viewModel();
|
|
|
|
expect($viewModel['copy']['application'])->toBe('DeviceManagementApps.Read.All')
|
|
->and($viewModel['copy']['delegated'])->toBe('Group.Read.All');
|
|
|
|
$component
|
|
->searchTable('no-such-permission')
|
|
->assertCountTableRecords(0)
|
|
->assertSee('No matches')
|
|
->assertTableEmptyStateActionsExistInOrder(['clear_filters']);
|
|
});
|