create(); $workspace = Workspace::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspace->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', ]); $this->actingAs($user)->get('/admin/_test/workspace-context'); $log = AuditLog::query() ->where('action', AuditActionId::WorkspaceAutoSelected->value) ->where('workspace_id', $workspace->getKey()) ->first(); expect($log)->not->toBeNull(); expect($log->metadata)->toMatchArray([ 'method' => 'auto', 'reason' => 'single_membership', 'prev_workspace_id' => null, ]); expect($log->resource_type)->toBe('workspace'); expect($log->resource_id)->toBe((string) $workspace->getKey()); expect($log->actor_id)->toBe((int) $user->getKey()); }); it('records workspace.auto_selected audit with last_used reason', function (): void { $user = User::factory()->create(); $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspaceA->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', ]); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspaceB->getKey(), 'user_id' => $user->getKey(), 'role' => 'operator', ]); // Set last_workspace_id to workspaceA. $user->forceFill(['last_workspace_id' => (int) $workspaceA->getKey()])->save(); $this->actingAs($user)->get('/admin/_test/workspace-context'); $log = AuditLog::query() ->where('action', AuditActionId::WorkspaceAutoSelected->value) ->where('workspace_id', $workspaceA->getKey()) ->first(); expect($log)->not->toBeNull(); expect($log->metadata)->toMatchArray([ 'method' => 'auto', 'reason' => 'last_used', 'prev_workspace_id' => null, ]); expect($log->resource_type)->toBe('workspace'); expect($log->resource_id)->toBe((string) $workspaceA->getKey()); expect($log->actor_id)->toBe((int) $user->getKey()); }); it('records workspace.selected audit with chooser reason on manual selection', function (): void { $user = User::factory()->create(); $workspace = Workspace::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspace->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', ]); Livewire::actingAs($user) ->test(\App\Filament\Pages\ChooseWorkspace::class) ->call('selectWorkspace', (int) $workspace->getKey()); $log = AuditLog::query() ->where('action', AuditActionId::WorkspaceSelected->value) ->where('workspace_id', $workspace->getKey()) ->first(); expect($log)->not->toBeNull(); expect($log->metadata)->toMatchArray([ 'method' => 'manual', 'reason' => 'chooser', ]); expect($log->resource_type)->toBe('workspace'); expect($log->resource_id)->toBe((string) $workspace->getKey()); expect($log->actor_id)->toBe((int) $user->getKey()); }); it('records workspace.selected audit with context_bar reason on switch-workspace POST', function (): void { $user = User::factory()->create(); $workspace = Workspace::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspace->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', ]); $this->actingAs($user) ->post(route('admin.switch-workspace'), ['workspace_id' => (int) $workspace->getKey()]); $log = AuditLog::query() ->where('action', AuditActionId::WorkspaceSelected->value) ->where('workspace_id', $workspace->getKey()) ->first(); expect($log)->not->toBeNull(); expect($log->metadata)->toMatchArray([ 'method' => 'manual', 'reason' => 'context_bar', ]); expect($log->resource_type)->toBe('workspace'); expect($log->resource_id)->toBe((string) $workspace->getKey()); expect($log->actor_id)->toBe((int) $user->getKey()); }); // --- T035: it_includes_prev_workspace_id_when_switching_from_active_workspace --- it('includes prev_workspace_id when switching via chooser from active workspace', function (): void { $user = User::factory()->create(); $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspaceA->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', ]); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspaceB->getKey(), 'user_id' => $user->getKey(), 'role' => 'operator', ]); // Simulate having workspaceA as the current workspace. session()->put(WorkspaceContext::SESSION_KEY, (int) $workspaceA->getKey()); Livewire::actingAs($user) ->test(\App\Filament\Pages\ChooseWorkspace::class) ->call('selectWorkspace', (int) $workspaceB->getKey()); $log = AuditLog::query() ->where('action', AuditActionId::WorkspaceSelected->value) ->where('workspace_id', $workspaceB->getKey()) ->first(); expect($log)->not->toBeNull(); expect($log->metadata['prev_workspace_id'])->toBe((int) $workspaceA->getKey()); expect($log->metadata['method'])->toBe('manual'); expect($log->metadata['reason'])->toBe('chooser'); }); it('includes prev_workspace_id when switching via context bar from active workspace', function (): void { $user = User::factory()->create(); $workspaceA = Workspace::factory()->create(); $workspaceB = Workspace::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspaceA->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', ]); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspaceB->getKey(), 'user_id' => $user->getKey(), 'role' => 'operator', ]); $this->actingAs($user) ->withSession([ WorkspaceContext::SESSION_KEY => (int) $workspaceA->getKey(), ]) ->post(route('admin.switch-workspace'), ['workspace_id' => (int) $workspaceB->getKey()]); $log = AuditLog::query() ->where('action', AuditActionId::WorkspaceSelected->value) ->where('workspace_id', $workspaceB->getKey()) ->first(); expect($log)->not->toBeNull(); expect($log->metadata['prev_workspace_id'])->toBe((int) $workspaceA->getKey()); expect($log->metadata['method'])->toBe('manual'); expect($log->metadata['reason'])->toBe('context_bar'); });