create(); $workspace = Workspace::factory()->create(); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); $response = $this->actingAs($user) ->get(BaselineProfileResource::getUrl(panel: 'admin')); expect($response->status())->toBeIn([403, 404, 302], 'Non-members should not get HTTP 200'); }); it('returns 404 for members accessing a profile from another workspace', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $otherWorkspace = Workspace::factory()->create(); $profile = BaselineProfile::factory()->create([ 'workspace_id' => (int) $otherWorkspace->getKey(), ]); $this->actingAs($user) ->get(BaselineProfileResource::getUrl('view', ['record' => $profile], panel: 'admin')) ->assertNotFound(); }); it('returns 200 for readonly members accessing list page', function (): void { [$user] = createUserWithTenant(role: 'readonly'); $this->actingAs($user) ->get(BaselineProfileResource::getUrl(panel: 'admin')) ->assertOk(); }); it('returns 403 for members with mocked missing capability on list page', function (): void { $workspace = Workspace::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'role' => 'readonly', ]); $resolver = \Mockery::mock(WorkspaceCapabilityResolver::class); $resolver->shouldReceive('isMember')->andReturnTrue(); $resolver->shouldReceive('can')->andReturnFalse(); app()->instance(WorkspaceCapabilityResolver::class, $resolver); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); $this->actingAs($user) ->get(BaselineProfileResource::getUrl(panel: 'admin')) ->assertForbidden(); }); it('returns 403 for readonly members accessing create page', function (): void { [$user] = createUserWithTenant(role: 'readonly'); $this->actingAs($user) ->get(BaselineProfileResource::getUrl('create', panel: 'admin')) ->assertForbidden(); }); it('returns 200 for owner members accessing create page', function (): void { [$user] = createUserWithTenant(role: 'owner'); $this->actingAs($user) ->get(BaselineProfileResource::getUrl('create', panel: 'admin')) ->assertOk(); }); it('returns 404 for members accessing profile from another workspace', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $otherWorkspace = Workspace::factory()->create(); $profile = BaselineProfile::factory()->create([ 'workspace_id' => (int) $otherWorkspace->getKey(), ]); $this->actingAs($user) ->get(BaselineProfileResource::getUrl('view', ['record' => $profile], panel: 'admin')) ->assertNotFound(); }); it('returns 403 for readonly members accessing edit page', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); $workspace = Workspace::query()->whereKey($tenant->workspace_id)->first(); $profile = BaselineProfile::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $this->actingAs($user) ->get(BaselineProfileResource::getUrl('edit', ['record' => $profile], panel: 'admin')) ->assertForbidden(); }); it('returns 200 for owner members accessing edit page', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $workspace = Workspace::query()->whereKey($tenant->workspace_id)->first(); $profile = BaselineProfile::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), ]); $this->actingAs($user) ->get(BaselineProfileResource::getUrl('edit', ['record' => $profile], panel: 'admin')) ->assertOk(); }); it('keeps edit-page authorization stable for legacy-scope profiles', function (): void { [$owner, $tenant] = createUserWithTenant(role: 'owner'); [$readonly] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $profile = BaselineProfile::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); DB::table('baseline_profiles') ->where('id', (int) $profile->getKey()) ->update([ 'scope_jsonb' => json_encode([ 'policy_types' => ['deviceConfiguration'], 'foundation_types' => [], ], JSON_THROW_ON_ERROR), 'updated_at' => now(), ]); $this->actingAs($owner) ->get(BaselineProfileResource::getUrl('edit', ['record' => $profile], panel: 'admin')) ->assertOk(); $this->actingAs($readonly) ->get(BaselineProfileResource::getUrl('edit', ['record' => $profile], panel: 'admin')) ->assertForbidden(); }); }); describe('BaselineProfile static authorization methods', function () { it('canViewAny returns false for non-members', function (): void { $user = User::factory()->create(); $workspace = Workspace::factory()->create(); $this->actingAs($user); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); expect(BaselineProfileResource::canViewAny())->toBeFalse(); }); it('canViewAny returns true for members', function (): void { [$user] = createUserWithTenant(role: 'readonly'); $this->actingAs($user); expect(BaselineProfileResource::canViewAny())->toBeTrue(); }); it('canCreate returns true for managers and false for readonly', function (): void { [$owner] = createUserWithTenant(role: 'owner'); $this->actingAs($owner); expect(BaselineProfileResource::canCreate())->toBeTrue(); [$readonly] = createUserWithTenant(role: 'readonly'); $this->actingAs($readonly); expect(BaselineProfileResource::canCreate())->toBeFalse(); }); });