iptv-stream-web/tests/unit/UserModelTest.php
Vincent 41cd7a4fd8 Add comprehensive unit tests for Security, UserModel, and Validation utilities
- Implemented SecurityTest to validate token generation, CSRF protection, input sanitization, and rate limiting.
- Created UserModelTest to ensure correct database operations for user management, including creation, updating, banning, and fetching active users.
- Developed ValidationTest to verify input validation and sanitization for user IDs, nicknames, messages, and API requests.
- Introduced Security and Validation utility classes with methods for secure token generation, input sanitization, and comprehensive validation rules.
2025-09-30 21:22:28 -04:00

215 lines
7.7 KiB
PHP

<?php
use PHPUnit\Framework\TestCase;
/**
* Test UserModel database operations
*/
class UserModelTest extends TestCase
{
private $userModel;
private $testUserId;
protected function setUp(): void
{
// Set up in-memory database for testing
TestDatabaseHelper::setupTestSchema();
$this->userModel = new UserModel();
$this->testUserId = 'test_user_' . bin2hex(random_bytes(8));
}
protected function tearDown(): void
{
// Clean up after each test
$pdo = TestDatabaseHelper::getTestPdo();
$pdo->exec('DELETE FROM users');
$pdo->exec('DELETE FROM chat_messages');
$pdo->exec('DELETE FROM active_viewers');
$pdo->exec('DELETE FROM banned_users');
}
public function testCreateOrUpdateNewUser()
{
$userData = [
'nickname' => 'TestUser',
'ip_address' => '192.168.1.100',
'session_id' => 'session_123456'
];
$result = $this->userModel->createOrUpdate($this->testUserId, $userData);
$this->assertNotFalse($result);
// Verify user was created
$user = $this->userModel->getByUserId($this->testUserId);
$this->assertNotFalse($user);
$this->assertEquals($this->testUserId, $user['user_id']);
$this->assertEquals('TestUser', $user['nickname']);
$this->assertEquals('192.168.1.100', $user['ip_address']);
}
public function testCreateOrUpdateExistingUser()
{
// First create user
$this->userModel->createOrUpdate($this->testUserId, ['nickname' => 'OriginalName']);
// Update existing user
$this->userModel->createOrUpdate($this->testUserId, ['nickname' => 'UpdatedName']);
$user = $this->userModel->getByUserId($this->testUserId);
$this->assertEquals('UpdatedName', $user['nickname']);
}
public function testGetActiveUsers()
{
// Create test users
$userId1 = 'active_user_1';
$userId2 = 'active_user_2';
$userId3 = 'inactive_user';
// Add active users
$this->userModel->createOrUpdate($userId1, ['nickname' => 'Active1']);
$this->userModel->createOrUpdate($userId2, ['nickname' => 'Active2']);
$this->userModel->createOrUpdate($userId3, ['nickname' => 'Inactive']);
// Simulate inactive user (old timestamp)
$pdo = TestDatabaseHelper::getTestPdo();
$pdo->exec("UPDATE users SET last_seen = datetime('now', '-40 seconds') WHERE user_id = '$userId3'");
$activeUsers = $this->userModel->getActiveUsers(30);
$this->assertCount(2, $activeUsers);
// Verify active users are returned
$userIds = array_column($activeUsers, 'user_id');
$this->assertContains($userId1, $userIds);
$this->assertContains($userId2, $userIds);
$this->assertNotContains($userId3, $userIds);
}
public function testUpdateLastSeen()
{
// Create user
$this->userModel->createOrUpdate($this->testUserId, ['nickname' => 'TestUser']);
// Get initial last_seen
$user = $this->userModel->getByUserId($this->testUserId);
$initialLastSeen = $user['last_seen'];
// Wait a moment to ensure different timestamp
sleep(1);
// Update last seen
$result = $this->userModel->updateLastSeen($this->testUserId);
$this->assertNotFalse($result);
// Verify last seen was updated
$updatedUser = $this->userModel->getByUserId($this->testUserId);
$this->assertNotEquals($initialLastSeen, $updatedUser['last_seen']);
}
public function testBanAndUnbanUser()
{
// Create user first
$this->userModel->createOrUpdate($this->testUserId, ['nickname' => 'TestUser']);
// Test initial state - not banned
$this->assertFalse($this->userModel->isBanned($this->testUserId));
// Ban user
$result = $this->userModel->banUser($this->testUserId, 'admin_user', 'Test ban reason');
$this->assertNotFalse($result);
// Verify user is banned
$this->assertTrue($this->userModel->isBanned($this->testUserId));
// Get banned users list
$bannedUsers = $this->userModel->getBannedUsers();
$this->assertCount(1, $bannedUsers);
$this->assertEquals($this->testUserId, $bannedUsers[0]['user_id']);
$this->assertEquals('Test ban reason', $bannedUsers[0]['reason']);
// Unban user
$result = $this->userModel->unbanUser($this->testUserId);
$this->assertNotFalse($result);
// Verify user is no longer banned
$this->assertFalse($this->userModel->isBanned($this->testUserId));
// Verify banned users list is empty
$bannedUsers = $this->userModel->getBannedUsers();
$this->assertCount(0, $bannedUsers);
}
public function testUpdateNickname()
{
// Create user
$this->userModel->createOrUpdate($this->testUserId, ['nickname' => 'OldName']);
// Update nickname
$result = $this->userModel->updateNickname($this->testUserId, 'NewName');
$this->assertNotFalse($result);
// Verify nickname was updated
$user = $this->userModel->getByUserId($this->testUserId);
$this->assertEquals('NewName', $user['nickname']);
}
public function testCleanupOldRecords()
{
// Create user
$this->userModel->createOrUpdate($this->testUserId, ['nickname' => 'TestUser']);
// Set last_seen to be very old
$pdo = TestDatabaseHelper::getTestPdo();
$pdo->exec("UPDATE users SET last_seen = datetime('now', '-40 days') WHERE user_id = '$this->testUserId'");
// Cleanup records older than 30 days
$result = $this->userModel->cleanupOldRecords(30);
$this->assertGreaterThan(0, $result); // Should have deleted at least one record
// Verify user was cleaned up
$user = $this->userModel->getByUserId($this->testUserId);
$this->assertFalse($user);
}
public function testNonExistentUser()
{
$user = $this->userModel->getByUserId('nonexistent_user');
$this->assertFalse($user);
// Test update on non-existent user
$result = $this->userModel->updateLastSeen('nonexistent_user');
$this->assertEquals(0, $result); // No rows affected
}
public function testGetActiveUsersWithinTimeframe()
{
// Create users with different activity times
$userId1 = 'recent_user';
$userId2 = 'old_user';
$this->userModel->createOrUpdate($userId1, ['nickname' => 'Recent']);
$this->userModel->createOrUpdate($userId2, ['nickname' => 'Old']);
// Make one user appear old
$pdo = TestDatabaseHelper::getTestPdo();
$pdo->exec("UPDATE users SET last_seen = datetime('now', '-1 hour') WHERE user_id = '$userId2'");
// Get users active within 30 minutes
$activeUsers = $this->userModel->getActiveUsers(30); // 30 seconds for testing
$this->assertCount(1, $activeUsers);
$this->assertEquals($userId1, $activeUsers[0]['user_id']);
}
public function testDatabaseConnectionFailure()
{
// This test would verify error handling in a real scenario
// For now, we test that the model handles database operations gracefully
$this->assertIsObject($this->userModel);
// Test that methods return false/null on failure rather than throwing exceptions
$result = $this->userModel->getByUserId('invalid_id_format_x');
$this->assertFalse($result);
}
}