## Summary - keep `/admin/reviews/workspace` workspace-scoped in shell and sidebar context - treat `tenant` query hints on the customer review workspace as page-level filters only - update the customer review workspace tests and Spec 311 navigation contract to match the workspace-hub IA ## Testing - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Reviews/CustomerReviewWorkspacePageTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php tests/Feature/Filament/PanelNavigationSegregationTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `git diff --check` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #366
114 lines
4.3 KiB
Markdown
114 lines
4.3 KiB
Markdown
# TenantPilot Testing Guidelines
|
|
|
|
Status: 2026-05-15
|
|
Applies to: Pest 4.3+, PHPUnit 12, Laravel 12, Filament 5, Livewire 4.
|
|
|
|
## Test Philosophy
|
|
|
|
Tests protect business truth: workspace isolation, tenant isolation, RBAC, auditability, immutable snapshots, restore safety, queued operation correctness, and Graph contract safety.
|
|
|
|
Do not create broad tests for thin presentation helpers unless the helper encodes operator-critical behavior.
|
|
|
|
## Test Pyramid
|
|
|
|
| Layer | Use for | Default lane |
|
|
|---|---|---|
|
|
| Unit | Pure services, value objects, mappers, policy helpers | fast-feedback |
|
|
| Feature | HTTP, DB, policies, queued jobs, audit side effects | fast-feedback/confidence |
|
|
| Filament/Livewire | Pages, widgets, relation managers, actions | confidence |
|
|
| PostgreSQL | migrations, JSONB, partial indexes, locks, FK isolation | pgsql |
|
|
| Browser | critical multi-step UI, JS smoke, visual/user workflow checks | browser |
|
|
| Heavy governance | broad surface discovery and drift checks | heavy-governance |
|
|
|
|
## Minimum Standard for New Features
|
|
|
|
- Every new policy gets allowed and denied tests.
|
|
- Every new destructive/high-impact Filament action gets action tests.
|
|
- Every new tenant-owned model gets cross-tenant isolation tests.
|
|
- Every new migration touching constraints/indexes gets PostgreSQL lane coverage when SQLite cannot prove the behavior.
|
|
- Every job that calls Graph is tested for idempotency, terminal-state handling, retry/throttle classification, and safe logging.
|
|
- Every feature spec states test impact and lane classification.
|
|
|
|
## Critical User Journeys to Keep Covered
|
|
|
|
- Workspace selection and tenant selection.
|
|
- Provider connection create/verify/disable/health-check.
|
|
- Policy sync, snapshot capture, version history, diff navigation.
|
|
- Backup set creation, add policies, schedule run/retry.
|
|
- Restore preview, confirmation, execution, partial failure handling.
|
|
- Finding triage, assignment, exception, evidence review.
|
|
- Audit log visibility and tenant-scope enforcement.
|
|
- System panel login/session isolation and platform capability checks.
|
|
|
|
## Filament Action Test Pattern
|
|
|
|
```php
|
|
use App\Filament\Resources\BackupScheduleResource\Pages\ListBackupSchedules;
|
|
use App\Jobs\RunBackupScheduleJob;
|
|
use Illuminate\Support\Facades\Bus;
|
|
use function Pest\Livewire\livewire;
|
|
|
|
it('queues a backup schedule run for an authorized tenant member', function () {
|
|
Bus::fake();
|
|
|
|
[$user, $tenant, $schedule] = tenantUserWithBackupScheduleRunCapability();
|
|
|
|
actingAs($user);
|
|
Filament::setTenant($tenant);
|
|
|
|
livewire(ListBackupSchedules::class)
|
|
->assertTableActionVisible('runNow', $schedule)
|
|
->callTableAction('runNow', $schedule);
|
|
|
|
Bus::assertDispatched(RunBackupScheduleJob::class);
|
|
|
|
expectAuditLogged('backup_schedule.run_requested', $schedule);
|
|
});
|
|
```
|
|
|
|
## Policy Test Pattern
|
|
|
|
```php
|
|
it('hides another workspace backup set as not found', function () {
|
|
[$actor, $ownWorkspace] = workspaceMember();
|
|
$foreignBackupSet = BackupSet::factory()->forWorkspace()->create();
|
|
|
|
$response = Gate::forUser($actor)->inspect('view', $foreignBackupSet);
|
|
|
|
expect($response->denied())->toBeTrue()
|
|
->and($response->status())->toBe(404);
|
|
});
|
|
```
|
|
|
|
## PostgreSQL Lane Rule
|
|
|
|
Use `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml` or the equivalent CI PostgreSQL lane for:
|
|
|
|
- JSONB migrations and GIN indexes.
|
|
- Partial unique indexes.
|
|
- Composite foreign keys.
|
|
- `lockForUpdate()` behavior.
|
|
- Tenant/workspace constraint migrations.
|
|
- Query plans where performance depends on PostgreSQL-specific operators.
|
|
|
|
## CI Recommendation
|
|
|
|
Release/confidence CI should run:
|
|
|
|
1. `composer validate --strict`
|
|
2. `composer audit`
|
|
3. `corepack pnpm audit --audit-level moderate`
|
|
4. `./vendor/bin/pint --test`
|
|
5. `composer run test`
|
|
6. `composer run test:pgsql` when database paths changed
|
|
7. `composer run test:browser` for UI workflow changes
|
|
8. `corepack pnpm build:platform`
|
|
|
|
## Fragility Controls
|
|
|
|
- Prefer factories with explicit state over global seed assumptions.
|
|
- Keep full workspace/tenant/member setup opt-in.
|
|
- Assert outcomes, audit events, and authorization behavior, not implementation details.
|
|
- Use fake Graph clients that fail hard if UI rendering accidentally calls Graph.
|
|
- Avoid snapshot tests for volatile admin markup unless visual regression is the real goal.
|