TenantAtlas/apps/platform/tests/Feature/Filament/PolicyCaptureSnapshotOptionsTest.php
ahmido ce0615a9c1 Spec 182: relocate Laravel platform to apps/platform (#213)
## Summary
- move the Laravel application into `apps/platform` and keep the repository root for orchestration, docs, and tooling
- update the local command model, Sail/Docker wiring, runtime paths, and ignore rules around the new platform location
- add relocation quickstart/contracts plus focused smoke coverage for bootstrap, command model, routes, and runtime behavior

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/PlatformRelocation`
- integrated browser smoke validated `/up`, `/`, `/admin`, `/admin/choose-workspace`, and tenant route semantics for `200`, `403`, and `404`

## Remaining Rollout Checks
- validate Dokploy build context and working-directory assumptions against the new `apps/platform` layout
- confirm web, queue, and scheduler processes all start from the expected working directory in staging/production
- verify no legacy volume mounts or asset-publish paths still point at the old root-level `public/` or `storage/` locations

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #213
2026-04-08 08:40:47 +00:00

134 lines
3.5 KiB
PHP

<?php
use App\Filament\Resources\PolicyResource\Pages\ViewPolicy;
use App\Jobs\CapturePolicySnapshotJob;
use App\Jobs\Operations\CapturePolicySnapshotWorkerJob;
use App\Models\Policy;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Graph\AssignmentFetcher;
use App\Services\Graph\ScopeTagResolver;
use App\Services\Intune\PolicySnapshotService;
use Filament\Facades\Filament;
use Illuminate\Contracts\Cache\Lock;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Queue;
use Livewire\Livewire;
use Mockery\MockInterface;
uses(RefreshDatabase::class);
it('captures a policy snapshot with scope tags when requested', function () {
Queue::fake();
$tenant = Tenant::factory()->create();
$tenant->makeCurrent();
ensureDefaultProviderConnection($tenant, 'microsoft');
$policy = Policy::factory()->for($tenant)->create([
'external_id' => 'policy-123',
]);
$user = User::factory()->create();
$this->actingAs($user);
$user->tenants()->syncWithoutDetaching([
$tenant->getKey() => ['role' => 'owner'],
]);
Filament::setTenant($tenant, true);
$this->mock(PolicySnapshotService::class, function (MockInterface $mock) use ($policy) {
$mock->shouldReceive('fetch')
->once()
->andReturn([
'payload' => [
'id' => $policy->external_id,
'name' => $policy->display_name,
'roleScopeTagIds' => ['0'],
],
]);
});
$this->mock(AssignmentFetcher::class, function (MockInterface $mock) {
$mock->shouldReceive('fetch')->never();
});
$this->mock(ScopeTagResolver::class, function (MockInterface $mock) {
$mock->shouldReceive('resolve')
->once()
->andReturn([
['id' => '0', 'displayName' => 'Default'],
]);
});
Livewire::test(ViewPolicy::class, ['record' => $policy->getRouteKey()])
->callAction('capture_snapshot', data: [
'include_assignments' => false,
'include_scope_tags' => true,
]);
$job = null;
$lock = new class implements Lock
{
public function get($callback = null): bool
{
return true;
}
public function block($seconds, $callback = null): bool
{
return true;
}
public function release(): bool
{
return true;
}
public function owner(): string
{
return 'test';
}
public function forceRelease(): void
{
// no-op
}
};
Cache::partialMock()
->shouldReceive('lock')
->andReturn($lock);
Queue::assertPushed(CapturePolicySnapshotJob::class, function (CapturePolicySnapshotJob $queuedJob) use (&$job): bool {
$job = $queuedJob;
return true;
});
expect($job)->not->toBeNull();
app()->call([$job, 'handle']);
$worker = null;
Queue::assertPushed(CapturePolicySnapshotWorkerJob::class, function (CapturePolicySnapshotWorkerJob $queuedWorker) use (&$worker): bool {
$worker = $queuedWorker;
return true;
});
expect($worker)->not->toBeNull();
app()->call([$worker, 'handle']);
$version = $policy->versions()->first();
expect($version)->not->toBeNull();
expect($version->assignments)->toBeNull();
expect($version->scope_tags)->toBe([
'ids' => ['0'],
'names' => ['Default'],
]);
});