provider(Role::ADMIN, 100, new DashboardWidget('Nur für Admins', [])); $registry = new DashboardWidgetRegistry([$provider], $this->securityGranting([])); $this->assertSame([], $registry->build()); } public function testKeepsProvidersWhoseRoleIsGranted(): void { $widget = new DashboardWidget('Gruppenbuchungen', []); $provider = $this->provider(Role::GROUPS_MANAGER, 100, $widget); $registry = new DashboardWidgetRegistry([$provider], $this->securityGranting([Role::GROUPS_MANAGER])); $this->assertSame([$widget], $registry->build()); } /** * The hierarchy is security.yaml's business, not the registry's: whatever isGranted() says * about ROLE_GROUPS_MANAGER is what an admin gets, without the registry knowing why. */ public function testRoleIsResolvedByTheSecurityCheckerAlone(): void { $widget = new DashboardWidget('Gruppenbuchungen', []); $provider = $this->provider(Role::GROUPS_MANAGER, 100, $widget); $security = $this->createMock(Security::class); $security->expects($this->once()) ->method('isGranted') ->with(Role::GROUPS_MANAGER) ->willReturn(true) ; $registry = new DashboardWidgetRegistry([$provider], $security); $this->assertSame([$widget], $registry->build()); } public function testDropsProvidersReturningNullButKeepsEmptyWidgets(): void { $empty = new DashboardWidget('Leer, aber da', []); $registry = new DashboardWidgetRegistry([ $this->provider(Role::ADMIN, 100, null), $this->provider(Role::ADMIN, 90, $empty), ], $this->securityGranting([Role::ADMIN])); $this->assertSame([$empty], $registry->build()); } public function testReturnsWidgetsInPriorityOrder(): void { $low = new DashboardWidget('Zuletzt', []); $high = new DashboardWidget('Zuerst', []); $registry = new DashboardWidgetRegistry([ $this->provider(Role::ADMIN, 10, $low), $this->provider(Role::ADMIN, 100, $high), ], $this->securityGranting([Role::ADMIN])); $this->assertSame([$high, $low], $registry->build()); } private function provider(string $role, int $priority, ?DashboardWidget $widget): DashboardWidgetProviderInterface { $provider = $this->createMock(DashboardWidgetProviderInterface::class); $provider->method('getRequiredRole')->willReturn($role); $provider->method('getPriority')->willReturn($priority); $provider->method('build')->willReturn($widget); return $provider; } /** * @param string[] $grantedRoles */ private function securityGranting(array $grantedRoles): Security { $security = $this->createMock(Security::class); $security->method('isGranted')->willReturnCallback( static fn (mixed $role): bool => \in_array($role, $grantedRoles, true), ); return $security; } }