auditRecords = new TestHandler(); } public function testAnOrdinaryAccountPasses(): void { $this->expectNotToPerformAssertions(); $this->checker()->checkPreAuth(new User('anna@ep-reisen.de', 'Anna')); } public function testALockedOutAccountIsRefusedWithItsReason(): void { $user = new User('anna@ep-reisen.de', 'Anna'); $user->disable('Auf eigenen Wunsch'); $this->expectException(CustomUserMessageAccountStatusException::class); $this->expectExceptionMessage('Auf eigenen Wunsch'); $this->checker()->checkPreAuth($user); } public function testALockoutWithoutAReasonStillSaysWhatHappened(): void { $user = new User('anna@ep-reisen.de', 'Anna'); $user->disable(); $this->expectException(CustomUserMessageAccountStatusException::class); $this->expectExceptionMessage('gesperrt'); $this->checker()->checkPreAuth($user); } /** * The authenticator audits the refusals it can see; this one happens after it has handed the * passport over, so the trail would otherwise show a sign-in that simply never completed. */ public function testTheRefusalIsAudited(): void { $user = new User('anna@ep-reisen.de', 'Anna'); $user->disable('Auf eigenen Wunsch'); try { $this->checker()->checkPreAuth($user); } catch (CustomUserMessageAccountStatusException) { } $records = $this->auditRecords->getRecords(); self::assertCount(1, $records); self::assertSame('Sign-in refused.', $records[0]->message); self::assertSame('account_disabled', $records[0]->context['reason']); self::assertSame('anna@ep-reisen.de', $records[0]->context['account']); } private function checker(): UserChecker { return new UserChecker(new AuditLogger(new Logger('audit', [$this->auditRecords]))); } }