diff options
Diffstat (limited to 'tests/Inc/UserTest.php')
| -rw-r--r-- | tests/Inc/UserTest.php | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/tests/Inc/UserTest.php b/tests/Inc/UserTest.php new file mode 100644 index 00000000..e9ca2210 --- /dev/null +++ b/tests/Inc/UserTest.php @@ -0,0 +1,120 @@ +<?php + +use PHPUnit\Framework\TestCase; + +/** + * Demonstrates how to test a real class when a stub exists: opt out of the stub + * via the stub autoloader allowlist and let the normal inc/ autoloader load the + * production class instead. Now adapted to use the SQLite-backed Database test + * backend so we assert against real SQL, not stub call logs. + * + * @runTestsInSeparateProcesses + * @preserveGlobalState disabled + */ +class UserTest extends TestCase +{ + protected function setUp(): void + { + $GLOBALS['__TEST_USE_REAL_CLASSES'] = ['User']; + + Database::resetSchema(); + Session::reset(); + } + + public function testBasicAccessorsLoggedOutAndLoggedIn(): void + { + // Sanity: manipulate private static User::$user via reflection + $ref = new ReflectionClass('User'); + $prop = $ref->getProperty('user'); + $prop->setAccessible(true); + + // Start logged out + $prop->setValue(null, false); + $this->assertFalse(User::isLoggedIn()); + $this->assertNull(User::getId()); + $this->assertFalse(User::getName()); + $this->assertNull(User::getLogin()); + + // Now set a minimal user record + $user = [ + 'userid' => 42, + 'fullname' => 'Alice Doe', + 'login' => 'alice', + 'permissions' => 0, + 'lasteventid' => null, + ]; + $prop->setValue(null, $user); + + $this->assertTrue(User::isLoggedIn()); + $this->assertSame(42, User::getId()); + $this->assertSame('Alice Doe', User::getName()); + $this->assertSame('alice', User::getLogin()); + } + + public function testSetAndGetLastSeenEventUpdatesDatabaseAndMemory(): void + { + $ref = new ReflectionClass('User'); + $prop = $ref->getProperty('user'); + $prop->setAccessible(true); + // Use an existing seeded user (id=1) + $prop->setValue(null, [ + 'userid' => 1, + 'fullname' => 'Alice Doe', + 'login' => 'alice', + 'permissions' => 0, + 'lasteventid' => 1, + ]); + + User::setLastSeenEvent(1234); + + // Assert DB has been updated + $row = Database::queryFirst('SELECT lasteventid FROM user WHERE userid = :u', ['u' => 1]); + $this->assertNotFalse($row); + $this->assertSame(1234, (int)$row['lasteventid']); + + // And memory updated too + $this->assertSame(1234, User::getLastSeenEvent()); + } + + public function testUpdatePasswordUsesCryptoAndExecutesUpdate(): void + { + $ref = new ReflectionClass('User'); + $prop = $ref->getProperty('user'); + $prop->setAccessible(true); + // Use seeded user id=1 + $prop->setValue(null, [ + 'userid' => 1, + 'fullname' => 'Alice Doe', + 'login' => 'alice', + 'permissions' => 0, + 'lasteventid' => null, + ]); + + // Act + $ret = User::updatePassword('secret'); + $this->assertTrue($ret); + + // Assert DB updated with hashed password from Crypto stub + $row = Database::queryFirst('SELECT passwd FROM user WHERE userid = :u', ['u' => 1]); + $this->assertNotFalse($row); + $this->assertSame('HASHED-secret', $row['passwd']); + } + + public function testLoginVerifiesPasswordAndCreatesSession(): void + { + $_SERVER['REMOTE_ADDR'] = '192.168.127.12'; + $_SERVER['REMOTE_PORT'] = 12345; + $_SERVER['HTTP_USER_AGENT'] = 'foobar'; + Session::reset(); + + // Good password (Crypto::verify will accept 'ok' against 'STORED' from seed) + $this->assertTrue(User::login('alice', 'ok', true)); + $this->assertNotNull(Session::$lastCreate); + $this->assertSame(1, Session::$lastCreate['userId']); + + // Bad password + Session::reset(); + $this->assertFalse(User::login('alice', 'bad', false)); + $this->assertNull(Session::$lastCreate); + } +} |
