create(); $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $actor = User::factory()->create(); $member = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $actor->getKey(), 'role' => 'owner', ]); $memberMembership = WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $member->getKey(), 'role' => 'readonly', ]); $scope = ManagedEnvironmentMembership::query()->create([ 'managed_environment_id' => (int) $tenant->getKey(), 'user_id' => (int) $member->getKey(), 'role' => 'readonly', 'source' => 'manual', ]); app(WorkspaceMembershipManager::class)->changeRole($workspace, $actor, $memberMembership, 'manager'); app(CapabilityResolver::class)->clearCache(); expect(app(CapabilityResolver::class)->getRole($member, $tenant)?->value)->toBe('manager') ->and(app(CapabilityResolver::class)->can($member, $tenant, Capabilities::TENANT_MANAGE))->toBeTrue() ->and($scope->refresh()->role)->toBe('readonly'); }); it('keeps last-owner protection anchored at workspace scope', function (): void { $workspace = Workspace::factory()->create(); $owner = User::factory()->create(); $ownerMembership = WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $owner->getKey(), 'role' => 'owner', ]); expect(fn () => app(WorkspaceMembershipManager::class)->changeRole($workspace, $owner, $ownerMembership, 'manager')) ->toThrow(DomainException::class, 'You cannot demote the last remaining owner.'); expect($ownerMembership->refresh()->role)->toBe('owner'); }); it('keeps workspace role mutations confirmation protected in the relation manager', function (): void { $workspace = Workspace::factory()->create(); $owner = User::factory()->create(); $member = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $owner->getKey(), 'role' => 'owner', ]); $memberMembership = WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $member->getKey(), 'role' => 'readonly', ]); Livewire::actingAs($owner) ->test(WorkspaceMembershipsRelationManager::class, [ 'ownerRecord' => $workspace, 'pageClass' => ViewWorkspace::class, ]) ->assertTableActionExists('change_role', fn (Action $action): bool => $action->isConfirmationRequired(), $memberMembership) ->assertTableActionExists('remove', fn (Action $action): bool => $action->isConfirmationRequired(), $memberMembership); });