create(); $this->actingAs($user); expect(TenantResource::canCreate())->toBeFalse(); }); it('cannot be created via CRUD (onboarding wizard is the only path)', function () { [$user] = createUserWithTenant(role: 'manager'); $this->actingAs($user); expect(TenantResource::canCreate())->toBeFalse(); }); it('can be edited by managers (TENANT_MANAGE)', function () { [$user, $tenant] = createUserWithTenant(role: 'manager'); $this->actingAs($user); expect(TenantResource::canEdit($tenant))->toBeTrue(); }); it('cannot be deleted by managers (TENANT_DELETE)', function () { [$user, $tenant] = createUserWithTenant(role: 'manager'); $this->actingAs($user); expect(TenantResource::canDelete($tenant))->toBeFalse(); }); it('can be deleted by owners (TENANT_DELETE)', function () { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); expect(TenantResource::canDelete($tenant))->toBeTrue(); }); it('cannot edit tenants it cannot access', function () { [$user] = createUserWithTenant(role: 'manager'); $otherTenant = Tenant::factory()->create(); $this->actingAs($user); expect(TenantResource::canEdit($otherTenant))->toBeFalse(); }); it('keeps onboarding and archived tenants manageable when the actor is entitled', function () { $onboardingTenant = Tenant::factory()->onboarding()->create(); [$user, $onboardingTenant] = createUserWithTenant( tenant: $onboardingTenant, role: 'manager', ensureDefaultMicrosoftProviderConnection: false, ); $archivedTenant = Tenant::factory()->archived()->create([ 'workspace_id' => (int) $onboardingTenant->workspace_id, ]); createUserWithTenant( tenant: $archivedTenant, user: $user, role: 'manager', workspaceRole: 'manager', ensureDefaultMicrosoftProviderConnection: false, ); $archivedTenant = Tenant::withTrashed()->findOrFail((int) $archivedTenant->getKey()); $this->actingAs($user); expect(TenantResource::canEdit($onboardingTenant))->toBeTrue() ->and(TenantResource::canEdit($archivedTenant))->toBeTrue() ->and(TenantResource::canDelete($onboardingTenant))->toBeFalse() ->and(TenantResource::canDelete($archivedTenant))->toBeFalse(); }); });