TenantAtlas/apps/platform/tests/Feature/TenantConfiguration/Spec415CoverageCaptureAuthorizationTest.php
Ahmed Darrazi 736e61c73e
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m37s
feat: add generic content-backed coverage capture
2026-06-25 21:55:27 +02:00

107 lines
3.9 KiB
PHP

<?php
declare(strict_types=1);
use App\Jobs\TenantConfiguration\CaptureTenantConfigurationEvidenceJob;
use App\Models\AuditLog;
use App\Models\ManagedEnvironment;
use App\Models\ProviderConnection;
use App\Models\User;
use App\Services\TenantConfiguration\StartTenantConfigurationCapture;
use App\Support\OperationRunStatus;
use Illuminate\Support\Facades\DB;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
it('starts an authorized capture run and queues remote execution', function (): void {
Queue::fake();
[$user, $tenant] = createStandardUserWithTenant(role: 'owner');
$connection = ProviderConnection::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
]);
$run = app(StartTenantConfigurationCapture::class)->start(
tenant: $tenant,
providerConnection: $connection,
actor: $user,
canonicalTypes: ['deviceAndAppManagementAssignmentFilter'],
);
expect($run->type)->toBe('tenant_configuration.capture')
->and($run->status)->toBe(OperationRunStatus::Queued->value)
->and(data_get($run->context, 'required_capability'))->toBe('evidence.manage')
->and(data_get($run->context, 'target_scope.provider_connection_id'))->toBe((int) $connection->getKey());
Queue::assertPushed(CaptureTenantConfigurationEvidenceJob::class);
expect(AuditLog::query()->where('action', 'tenant_configuration.capture.started')->exists())->toBeTrue();
});
it('returns forbidden when the user lacks the evidence manage capability', function (): void {
Queue::fake();
[$user, $tenant] = createStandardUserWithTenant(role: 'readonly', workspaceRole: 'readonly');
$connection = ProviderConnection::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
]);
expect(fn () => app(StartTenantConfigurationCapture::class)->start($tenant, $connection, $user))
->toThrow(AuthorizationException::class);
Queue::assertNothingPushed();
});
it('hides managed environments outside the user workspace scope', function (): void {
Queue::fake();
$user = User::factory()->create();
[, $tenant] = createStandardUserWithTenant(role: 'owner');
$connection = ProviderConnection::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
]);
expect(fn () => app(StartTenantConfigurationCapture::class)->start($tenant, $connection, $user))
->toThrow(NotFoundHttpException::class);
Queue::assertNothingPushed();
});
it('hides managed environments excluded by explicit environment entitlement scope', function (): void {
Queue::fake();
[$user, $tenant] = createMinimalUserWithTenant(role: 'owner');
$allowedTenant = ManagedEnvironment::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
]);
$connection = ProviderConnection::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
]);
DB::table('managed_environment_memberships')
->where('managed_environment_id', (int) $tenant->getKey())
->where('user_id', (int) $user->getKey())
->delete();
DB::table('managed_environment_memberships')->insert([
'id' => (string) Str::uuid(),
'managed_environment_id' => (int) $allowedTenant->getKey(),
'user_id' => (int) $user->getKey(),
'role' => 'owner',
'source' => 'manual',
'created_at' => now(),
'updated_at' => now(),
]);
expect(fn () => app(StartTenantConfigurationCapture::class)->start($tenant, $connection, $user))
->toThrow(NotFoundHttpException::class);
Queue::assertNothingPushed();
});