move_detect/cloud/tests/AuthControllerTest.php

53 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests;
use App\Http\Request;
use App\Security\Password;
use App\Auth\{AuthController, ArraySessionStore};
use App\Tests\Support\{InMemoryUserRepository, InMemoryAuditRepository};
use PHPUnit\Framework\TestCase;
final class AuthControllerTest extends TestCase
{
private function users(): InMemoryUserRepository {
return new InMemoryUserRepository(['alice' => [
'id' => 1, 'username' => 'alice', 'password_hash' => Password::hash('pw'),
'role' => 'operator', 'site_scope' => null, 'failed_attempts' => 0, 'locked_until' => 0,
]]);
}
private function req(string $u, string $p): Request {
return new Request('POST', '/login', [], '', [], ['username' => $u, 'password' => $p]);
}
public function testLoginSuccessSetsSession(): void {
$c = new AuthController($this->users(), new InMemoryAuditRepository());
$sess = new ArraySessionStore();
$res = $c->login($this->req('alice', 'pw'), $sess, now: 1000);
$this->assertSame(200, $res->status());
$this->assertSame(1, $sess->get('user_id'));
$this->assertSame('operator', $sess->get('role'));
}
public function testBadPasswordIs401(): void {
$c = new AuthController($this->users(), new InMemoryAuditRepository());
$this->assertSame(401, $c->login($this->req('alice', 'nope'), new ArraySessionStore(), now: 1000)->status());
}
public function testLockoutAfterMaxAttempts(): void {
$repo = $this->users();
$c = new AuthController($repo, new InMemoryAuditRepository(), maxAttempts: 3, lockSeconds: 900);
for ($i = 0; $i < 3; $i++) $c->login($this->req('alice', 'bad'), new ArraySessionStore(), now: 1000);
// now locked, even correct password is 423
$this->assertSame(423, $c->login($this->req('alice', 'pw'), new ArraySessionStore(), now: 1000)->status());
}
public function testExpiredLockResetsAttempts(): void {
$repo = $this->users();
$c = new AuthController($repo, new InMemoryAuditRepository(), maxAttempts: 3, lockSeconds: 900);
// lock the account with 3 bad tries at now=1000
for ($i = 0; $i < 3; $i++) $c->login($this->req('alice', 'bad'), new ArraySessionStore(), now: 1000);
// locked_until is now 1000 + 900 = 1900, verify it's locked
$this->assertSame(423, $c->login($this->req('alice', 'pw'), new ArraySessionStore(), now: 1000)->status());
// now at now=2000 (after lock window expires at 1900), login with correct password should succeed
$sess = new ArraySessionStore();
$res = $c->login($this->req('alice', 'pw'), $sess, now: 2000);
$this->assertSame(200, $res->status());
$this->assertSame(1, $sess->get('user_id'));
}
}