create(); $workspace = Workspace::factory()->create(); $workspace->users()->attach($user->id, [ 'role' => $role, 'permissions' => $permissions, ]); session(['current_workspace_id' => $workspace->id]); return [$user, $workspace]; } function createWorkspaceMember(Workspace $workspace, string $role, array $permissions = []): User { $member = User::factory()->create(); $workspace->users()->attach($member->id, [ 'role' => $role, 'permissions' => $permissions, ]); return $member; } function getWorkspaceUserId(Workspace $workspace, User $user): int { return WorkspaceUser::where('workspace_id', $workspace->id) ->where('user_id', $user->id) ->firstOrFail() ->id; } // ── Owner can change roles ────────────────────────────────── test('owner can change a member role from worker to manager', function () { [$owner, $workspace] = setupRoleTestUser(WorkspaceUserRole::Owner); $worker = createWorkspaceMember($workspace, WorkspaceUserRole::Worker); $pivotId = getWorkspaceUserId($workspace, $worker); $response = $this->actingAs($owner)->patch(route('team.updateRole', $pivotId), [ 'role' => 'manager', ]); $response->assertRedirect(); $response->assertSessionHas('success', 'Rôle mis à jour'); $updatedPivot = WorkspaceUser::find($pivotId); expect($updatedPivot->role->is(WorkspaceUserRole::Manager))->toBeTrue(); }); test('owner can change a member role from manager to worker', function () { [$owner, $workspace] = setupRoleTestUser(WorkspaceUserRole::Owner); $manager = createWorkspaceMember($workspace, WorkspaceUserRole::Manager, [ Permission::CanManageTeam => true, Permission::CanViewActivityLogs => true, ]); $pivotId = getWorkspaceUserId($workspace, $manager); $response = $this->actingAs($owner)->patch(route('team.updateRole', $pivotId), [ 'role' => 'worker', ]); $response->assertRedirect(); $response->assertSessionHas('success', 'Rôle mis à jour'); $updatedPivot = WorkspaceUser::find($pivotId); expect($updatedPivot->role->is(WorkspaceUserRole::Worker))->toBeTrue(); }); // ── Role change resets permissions ────────────────────────── test('role change resets permissions to defaults for new role', function () { [$owner, $workspace] = setupRoleTestUser(WorkspaceUserRole::Owner); $worker = createWorkspaceMember($workspace, WorkspaceUserRole::Worker); $pivotId = getWorkspaceUserId($workspace, $worker); $this->actingAs($owner)->patch(route('team.updateRole', $pivotId), [ 'role' => 'manager', ]); $updatedPivot = WorkspaceUser::find($pivotId); $managerDefaults = config('permissions.defaults.manager'); expect($updatedPivot->permissions)->toBe($managerDefaults); // Now change back to worker — permissions should be empty $this->actingAs($owner)->patch(route('team.updateRole', $pivotId), [ 'role' => 'worker', ]); $updatedPivot->refresh(); expect($updatedPivot->permissions)->toBe([]); }); // ── Owner cannot change own role ──────────────────────────── test('owner cannot change own role', function () { [$owner, $workspace] = setupRoleTestUser(WorkspaceUserRole::Owner); $pivotId = getWorkspaceUserId($workspace, $owner); $response = $this->actingAs($owner)->patch(route('team.updateRole', $pivotId), [ 'role' => 'manager', ]); $response->assertNotFound(); }); // ── Manager with can_manage_team can change worker role ───── test('manager with can_manage_team can change worker role', function () { [$manager, $workspace] = setupRoleTestUser(WorkspaceUserRole::Manager, [ Permission::CanManageTeam => true, ]); $worker = createWorkspaceMember($workspace, WorkspaceUserRole::Worker); $pivotId = getWorkspaceUserId($workspace, $worker); $response = $this->actingAs($manager)->patch(route('team.updateRole', $pivotId), [ 'role' => 'manager', ]); $response->assertRedirect(); $response->assertSessionHas('success', 'Rôle mis à jour'); }); // ── Manager with can_manage_team can change another manager role ─ test('manager with can_manage_team can change another manager role', function () { [$manager, $workspace] = setupRoleTestUser(WorkspaceUserRole::Manager, [ Permission::CanManageTeam => true, ]); $otherManager = createWorkspaceMember($workspace, WorkspaceUserRole::Manager, [ Permission::CanManageTeam => false, ]); $pivotId = getWorkspaceUserId($workspace, $otherManager); $response = $this->actingAs($manager)->patch(route('team.updateRole', $pivotId), [ 'role' => 'worker', ]); $response->assertRedirect(); $response->assertSessionHas('success', 'Rôle mis à jour'); $updatedPivot = WorkspaceUser::find($pivotId); expect($updatedPivot->role->is(WorkspaceUserRole::Worker))->toBeTrue(); }); // ── Manager with can_manage_team cannot change owner role ─── test('manager with can_manage_team cannot change owner role', function () { [$manager, $workspace] = setupRoleTestUser(WorkspaceUserRole::Manager, [ Permission::CanManageTeam => true, ]); $owner = createWorkspaceMember($workspace, WorkspaceUserRole::Owner); $pivotId = getWorkspaceUserId($workspace, $owner); $response = $this->actingAs($manager)->patch(route('team.updateRole', $pivotId), [ 'role' => 'worker', ]); $response->assertNotFound(); }); // ── Manager without can_manage_team gets 404 ─────────────── test('manager without can_manage_team gets 404 on role change', function () { [$manager, $workspace] = setupRoleTestUser(WorkspaceUserRole::Manager, [ Permission::CanManageTeam => false, ]); $worker = createWorkspaceMember($workspace, WorkspaceUserRole::Worker); $pivotId = getWorkspaceUserId($workspace, $worker); $response = $this->actingAs($manager)->patch(route('team.updateRole', $pivotId), [ 'role' => 'manager', ]); $response->assertNotFound(); }); // ── Worker gets 404 on role change attempt ────────────────── test('worker gets 404 on role change attempt', function () { [$worker, $workspace] = setupRoleTestUser(WorkspaceUserRole::Worker); $otherWorker = createWorkspaceMember($workspace, WorkspaceUserRole::Worker); $pivotId = getWorkspaceUserId($workspace, $otherWorker); $response = $this->actingAs($worker)->patch(route('team.updateRole', $pivotId), [ 'role' => 'manager', ]); $response->assertNotFound(); }); // ── Activity log ──────────────────────────────────────────── test('role change is logged in activity log', function () { [$owner, $workspace] = setupRoleTestUser(WorkspaceUserRole::Owner); $worker = createWorkspaceMember($workspace, WorkspaceUserRole::Worker); $pivotId = getWorkspaceUserId($workspace, $worker); $this->actingAs($owner)->patch(route('team.updateRole', $pivotId), [ 'role' => 'manager', ]); $log = Activity::latest('id')->first(); expect($log->description)->toBe('role_changed') ->and($log->properties['target_user'])->toBe($worker->name) ->and($log->properties['old_role'])->toBe('worker') ->and($log->properties['new_role'])->toBe('manager'); });