TenantAtlas/apps/platform/tests/Feature/PortfolioCompare/CrossEnvironmentCompareAuthorizationTest.php
ahmido 292d555eac refactor: consolidate internal tenant model naming (#355)
## Summary
- consolidate internal platform naming from `Tenant` to `Environment` / `ManagedEnvironment` across models, controllers, services, and Filament resources
- rename environment-scoped UI surfaces such as dashboards, chooser flows, navigation, and related widgets to match the updated environment-first domain language
- align middleware, onboarding/review lifecycle services, jobs, and route/context controllers with the new environment-scoped architecture

## Validation
- not rerun as part of this commit/push/PR request

## Notes
- branch is 1 commit ahead of `platform-dev`
- main commit: `refactor: consolidate internal tenant model naming`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #355
2026-05-14 11:13:28 +00:00

97 lines
3.9 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\CrossEnvironmentComparePage;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Services\Auth\WorkspaceCapabilityResolver;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Actions\Action;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Tests\Feature\Concerns\BuildsPortfolioCompareFixtures;
uses(RefreshDatabase::class, BuildsPortfolioCompareFixtures::class);
it('returns 404 for non-members on the cross-environment compare route', function (): void {
$workspace = Workspace::factory()->create();
$user = User::factory()->create();
$this->actingAs($user)
->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
->get(CrossEnvironmentComparePage::getUrl(panel: 'admin'))
->assertNotFound();
});
it('returns 403 for workspace members missing baseline view capability on the compare route', function (): void {
$workspace = Workspace::factory()->create();
$viewer = User::factory()->create();
WorkspaceMembership::factory()->create([
'workspace_id' => (int) $workspace->getKey(),
'user_id' => (int) $viewer->getKey(),
'role' => 'readonly',
]);
$resolver = \Mockery::mock(WorkspaceCapabilityResolver::class);
$resolver->shouldReceive('isMember')->andReturnTrue();
$resolver->shouldReceive('can')->andReturnFalse();
app()->instance(WorkspaceCapabilityResolver::class, $resolver);
$this->actingAs($viewer)
->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
->get(CrossEnvironmentComparePage::getUrl(panel: 'admin'))
->assertForbidden();
});
it('returns 404 when the requested target environment is outside the actor scope', function (): void {
$fixture = $this->makeCrossEnvironmentCompareFixture();
$hiddenTarget = ManagedEnvironment::factory()->create([
'workspace_id' => (int) $fixture['workspace']->getKey(),
'name' => 'Hidden Target',
]);
$session = $this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace']);
$this->withSession($session)
->get(CrossEnvironmentComparePage::getUrl(parameters: [
'source_environment_id' => (int) $fixture['sourceEnvironment']->getKey(),
'target_environment_id' => (int) $hiddenTarget->getKey(),
], panel: 'admin'))
->assertNotFound();
});
it('keeps promotion preflight visible but disabled for readonly members and forbids forced execution', function (): void {
$fixture = $this->makeCrossEnvironmentCompareFixture(workspaceRole: 'readonly', tenantRole: 'readonly');
$this->createPortfolioCompareSubject(
tenant: $fixture['sourceEnvironment'],
displayName: 'Readonly Policy',
snapshot: ['settings' => [['key' => 'readonly', 'value' => 1]]],
);
$this->createPortfolioCompareSubject(
tenant: $fixture['targetEnvironment'],
displayName: 'Readonly Policy',
snapshot: ['settings' => [['key' => 'readonly', 'value' => 1]]],
);
$this->setAdminWorkspaceContext($fixture['user'], $fixture['workspace']);
$query = [
'source_environment_id' => (int) $fixture['sourceEnvironment']->getKey(),
'target_environment_id' => (int) $fixture['targetEnvironment']->getKey(),
'policy_type' => ['deviceConfiguration'],
];
Livewire::withQueryParams($query)
->actingAs($fixture['user'])
->test(CrossEnvironmentComparePage::class)
->assertActionVisible('generatePromotionPreflight')
->assertActionDisabled('generatePromotionPreflight')
->assertActionExists('generatePromotionPreflight', fn (Action $action): bool => $action->getTooltip() === 'You need workspace baseline manage access to generate a promotion preflight.')
->call('generatePromotionPreflight')
->assertForbidden();
});