TenantAtlas/docs/testing-guidelines.md
ahmido bf43dad3d1 fix: enforce workspace surface scope for customer review workspace (#366)
## 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
2026-05-15 20:52:37 +00:00

4.3 KiB

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

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

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.