createMock(\medoo::class); } protected function setUp(): void { \Shared\Cache\CacheHandler::reset(); } // --- find --- public function testFindReturnsUserArray(): void { $db = $this->mockDb(); $db->method('get')->willReturn(['id' => 1, 'login' => 'admin']); $repo = new UserRepository($db); $this->assertSame('admin', $repo->find(1)['login']); } public function testFindReturnsNullWhenNotFound(): void { $db = $this->mockDb(); $db->method('get')->willReturn(null); $repo = new UserRepository($db); $this->assertNull($repo->find(99)); } // --- findByLogin --- public function testFindByLoginReturnsUser(): void { $db = $this->mockDb(); $db->method('get')->willReturn(['id' => 1, 'login' => 'admin']); $repo = new UserRepository($db); $this->assertNotNull($repo->findByLogin('admin')); } // --- all --- public function testAllReturnsArray(): void { $db = $this->mockDb(); $db->method('select')->willReturn([['id' => 1], ['id' => 2]]); $repo = new UserRepository($db); $this->assertCount(2, $repo->all()); } public function testAllReturnsEmptyArrayWhenNull(): void { $db = $this->mockDb(); $db->method('select')->willReturn(null); $repo = new UserRepository($db); $this->assertSame([], $repo->all()); } // --- hasPrivilege --- public function testHasPrivilegeReturnsTrueForAdminUser(): void { $db = $this->mockDb(); $repo = new UserRepository($db); // userId === 1 zawsze ma uprawnienia, bez zapytania do DB $db->expects($this->never())->method('count'); $this->assertTrue($repo->hasPrivilege('articles', 1)); } public function testHasPrivilegeReturnsTrueWhenPrivilegeExists(): void { $db = $this->mockDb(); $db->method('count')->willReturn(1); $repo = new UserRepository($db); $this->assertTrue($repo->hasPrivilege('articles', 2)); } public function testHasPrivilegeReturnsFalseWhenPrivilegeMissing(): void { $db = $this->mockDb(); $db->method('count')->willReturn(0); $repo = new UserRepository($db); $this->assertFalse($repo->hasPrivilege('articles', 2)); } // --- logon --- public function testLogonReturnsZeroWhenUserNotFound(): void { $db = $this->mockDb(); // Pierwsze get() (sprawdź czy login istnieje) → null $db->method('get')->willReturn(null); $repo = new UserRepository($db); $this->assertSame(0, $repo->logon('unknown', 'pass')); } public function testLogonReturnsMinusOneWhenAccountBlocked(): void { $db = $this->mockDb(); // Pierwsze get() → użytkownik istnieje, drugie → konto zablokowane (null) $db->method('get')->willReturnOnConsecutiveCalls( ['id' => 2, 'login' => 'user'], null ); $repo = new UserRepository($db); $this->assertSame(-1, $repo->logon('user', 'pass')); } public function testLogonReturnsOneOnSuccess(): void { $db = $this->mockDb(); $db->method('get')->willReturnOnConsecutiveCalls( ['id' => 2, 'login' => 'user'], // login istnieje ['id' => 2, 'status' => 1, 'error_logged_count' => 0], // nie zablokowany ['id' => 2] // hasło poprawne ); $db->method('update')->willReturn(true); $repo = new UserRepository($db); $this->assertSame(1, $repo->logon('user', 'pass')); } // --- isLoginTaken --- public function testIsLoginTakenReturnsTrueWhenExists(): void { $db = $this->mockDb(); $db->method('get')->willReturn('user'); $repo = new UserRepository($db); $this->assertTrue($repo->isLoginTaken('user')); } public function testIsLoginTakenReturnsFalseWhenFree(): void { $db = $this->mockDb(); $db->method('get')->willReturn(null); $repo = new UserRepository($db); $this->assertFalse($repo->isLoginTaken('newuser')); } // --- verifyTwofaCode --- public function testVerifyTwofaCodeReturnsFalseWhenUserNotFound(): void { $db = $this->mockDb(); $db->method('get')->willReturn(null); $repo = new UserRepository($db); $this->assertFalse($repo->verifyTwofaCode(1, '123456')); } public function testVerifyTwofaCodeReturnsFalseWhenTooManyFailedAttempts(): void { $db = $this->mockDb(); $user = [ 'id' => 2, 'twofa_failed_attempts' => 5, 'twofa_expires_at' => date('Y-m-d H:i:s', time() + 600), 'twofa_code_hash' => password_hash('123456', PASSWORD_DEFAULT), ]; $db->method('get')->willReturn($user); $repo = new UserRepository($db); $this->assertFalse($repo->verifyTwofaCode(2, '123456')); } public function testVerifyTwofaCodeReturnsFalseWhenExpired(): void { $db = $this->mockDb(); $user = [ 'id' => 2, 'twofa_failed_attempts' => 0, 'twofa_expires_at' => date('Y-m-d H:i:s', time() - 1), 'twofa_code_hash' => password_hash('123456', PASSWORD_DEFAULT), ]; $db->method('get')->willReturn($user); $db->method('update')->willReturn(true); $repo = new UserRepository($db); $this->assertFalse($repo->verifyTwofaCode(2, '123456')); } public function testVerifyTwofaCodeReturnsTrueOnValidCode(): void { $code = '123456'; $db = $this->mockDb(); $user = [ 'id' => 2, 'twofa_failed_attempts' => 0, 'twofa_expires_at' => date('Y-m-d H:i:s', time() + 600), 'twofa_code_hash' => password_hash($code, PASSWORD_DEFAULT), ]; // find() wywołuje get() dwa razy (raz przez verifyTwofaCode, raz przez update) $db->method('get')->willReturn($user); $db->method('update')->willReturn(true); $repo = new UserRepository($db); $this->assertTrue($repo->verifyTwofaCode(2, $code)); } // --- delete --- public function testDeleteReturnsTrueOnSuccess(): void { $db = $this->mockDb(); $db->method('delete')->willReturn(1); $repo = new UserRepository($db); $this->assertTrue($repo->delete(2)); } // --- save — walidacja --- public function testSaveReturnsErrorWhenPasswordTooShort(): void { $db = $this->mockDb(); $db->method('delete')->willReturn(1); $repo = new UserRepository($db); $result = $repo->save(0, 'newuser', 'on', '', '123', '123', 0, []); $this->assertSame('error', $result['status']); } public function testSaveReturnsErrorWhenPasswordsMismatch(): void { $db = $this->mockDb(); $db->method('delete')->willReturn(1); $repo = new UserRepository($db); $result = $repo->save(0, 'newuser', 'on', '', 'password1', 'password2', 0, []); $this->assertSame('error', $result['status']); } }