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); } }