apiClient = $this->createMock(ApiClient::class); $this->userDataHandler = $this->createMock(UserDataHandler::class); } public function testUnknownUserWithoutClaimedRolesIsNeverCreated(): void { $this->stubApiClient($this->createCrmAttributes()); $this->userDataHandler->method('collectRoles')->willReturn([]); $this->userDataHandler->method('findLocalUser')->willReturn(null); $this->userDataHandler->expects($this->never())->method('createLocalUser'); $this->userDataHandler->expects($this->never())->method('disableForRevokedCrmRoles'); $this->expectException(UserNotFoundException::class); $this->loadUser(); } public function testExistingUserWithoutClaimedRolesIsBlockedAndReturned(): void { $user = (new User())->setRoles(['ROLE_ADMIN']); $this->stubApiClient($this->createCrmAttributes()); $this->userDataHandler->method('collectRoles')->willReturn([]); $this->userDataHandler->method('findLocalUser')->willReturn($user); $this->userDataHandler->expects($this->never())->method('updateLocalUser'); $this->userDataHandler ->expects($this->once()) ->method('disableForRevokedCrmRoles') ->with($user) ; // returned rather than refused, so the UserChecker can explain the block $this->assertSame($user, $this->loadUser()); } public function testResponseWithoutAttributeGroupsRefusesTheLoginWithoutBlocking(): void { $user = (new User())->setRoles(['ROLE_ADMIN']); // an empty payload carries no roles either and must not read as a revocation $this->stubApiClient(new CrmAttributesResponse()); $this->userDataHandler->method('collectRoles')->willReturn([]); $this->userDataHandler->method('findLocalUser')->willReturn($user); $this->userDataHandler->expects($this->never())->method('disableForRevokedCrmRoles'); $this->expectException(UserNotFoundException::class); $this->loadUser(); } private function createCrmAttributes(): CrmAttributesResponse { return (new CrmAttributesResponse())->setAttributeGroups([new CrmAttributeGroup()]); } private function stubApiClient(CrmAttributesResponse $crmAttributes): void { $this->apiClient->method('getProfile')->willReturn(new ProfileResponse()); $this->apiClient->method('getCrmAttributes')->willReturn($crmAttributes); } private function loadUser(): ?User { $authenticator = new BpnAuthenticator( $this->createMock(UrlGeneratorInterface::class), $this->createMock(EntityManagerInterface::class), $this->apiClient, $this->createMock(LoggerInterface::class), $this->userDataHandler, $this->createMock(RequiredTeamerCheckRegistry::class), ); $request = new Request(request: [ '_username' => 'user@example.com', '_password' => 'secret', '_csrf_token' => 'token', ]); $request->setSession(new Session(new MockArraySessionStorage())); $passport = $authenticator->authenticate($request); /** @var UserBadge $badge */ $badge = $passport->getBadge(UserBadge::class); /* @var User $user */ return $badge->getUser(); } }