create(); foreach (WorkspaceRole::cases() as $role) { $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => $role->value, ]); expect(Gate::forUser($user)->allows(Capabilities::WORKSPACE_MEMBERSHIP_VIEW, $workspace))->toBe($role !== WorkspaceRole::Readonly); expect(Gate::forUser($user)->allows(Capabilities::WORKSPACE_MEMBERSHIP_MANAGE, $workspace))->toBe($role === WorkspaceRole::Owner); } }); it('denies non-owner workspace membership service mutations', function (string $role): void { $workspace = Workspace::factory()->create(); $actor = User::factory()->create(); $member = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $actor->getKey(), 'role' => $role, ]); app(WorkspaceMembershipManager::class)->addMember( workspace: $workspace, actor: $actor, member: $member, role: WorkspaceRole::Readonly->value, ); })->throws(\DomainException::class, 'Forbidden.')->with([ 'manager' => [WorkspaceRole::Manager->value], 'operator' => [WorkspaceRole::Operator->value], 'readonly' => [WorkspaceRole::Readonly->value], ]); it('allows owner workspace membership service mutations', 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' => WorkspaceRole::Owner->value, ]); $membership = app(WorkspaceMembershipManager::class)->addMember( workspace: $workspace, actor: $owner, member: $member, role: WorkspaceRole::Readonly->value, ); expect($membership->workspace_id)->toBe((int) $workspace->getKey()) ->and($membership->user_id)->toBe((int) $member->getKey()) ->and($membership->role)->toBe(WorkspaceRole::Readonly->value); }); it('denies manager managed-environment access-scope management', function (): void { $workspace = Workspace::factory()->create(); $tenant = ManagedEnvironment::factory()->active()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $manager = User::factory()->create(); $member = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $manager->getKey(), 'role' => WorkspaceRole::Manager->value, ]); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $member->getKey(), 'role' => WorkspaceRole::Readonly->value, ]); app(ManagedEnvironmentMembershipManager::class)->grantScope( tenant: $tenant, actor: $manager, member: $member, ); })->throws(\DomainException::class, 'Forbidden.');