| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-20 08:41:14 +00:00
										 |  |  | require_once dirname(__DIR__, 3) . '/app/classes/database.php'; | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | use PHPUnit\Framework\TestCase; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  | /** | 
					
						
							|  |  |  |  * TestLogger class for testing log functionality | 
					
						
							|  |  |  |  * This is a simplified implementation that mimics the plugin's Log class | 
					
						
							|  |  |  |  * but with a different name to avoid conflicts | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class TestLogger { | 
					
						
							|  |  |  |     private $db; | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |     public function __construct($database) { | 
					
						
							|  |  |  |         $this->db = $database->getConnection(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |     public function insertLog($userId, $message, $scope = 'user') { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $sql = 'INSERT INTO log | 
					
						
							|  |  |  |                         (user_id, scope, message) | 
					
						
							|  |  |  |                     VALUES | 
					
						
							|  |  |  |                         (:user_id, :scope, :message)'; | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             $query = $this->db->prepare($sql); | 
					
						
							|  |  |  |             $query->execute([ | 
					
						
							|  |  |  |                 ':user_id' => $userId, | 
					
						
							|  |  |  |                 ':scope'   => $scope, | 
					
						
							|  |  |  |                 ':message' => $message, | 
					
						
							|  |  |  |             ]); | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             return true; | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         } catch (Exception $e) { | 
					
						
							|  |  |  |             return $e->getMessage(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |     public function readLog($userId, $scope, $offset = 0, $items_per_page = '', $filters = []) { | 
					
						
							|  |  |  |         $params = []; | 
					
						
							|  |  |  |         $where_clauses = []; | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Base query with user join
 | 
					
						
							|  |  |  |         $base_sql = 'SELECT l.*, u.username  | 
					
						
							|  |  |  |                     FROM log l  | 
					
						
							|  |  |  |                     LEFT JOIN user u ON l.user_id = u.id'; | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Add scope condition
 | 
					
						
							|  |  |  |         if ($scope === 'user') { | 
					
						
							|  |  |  |             $where_clauses[] = 'l.user_id = :user_id'; | 
					
						
							|  |  |  |             $params[':user_id'] = $userId; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Add time range filters if specified
 | 
					
						
							|  |  |  |         if (!empty($filters['from_time'])) { | 
					
						
							|  |  |  |             $where_clauses[] = 'l.time >= :from_time'; | 
					
						
							|  |  |  |             $params[':from_time'] = $filters['from_time'] . ' 00:00:00'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!empty($filters['until_time'])) { | 
					
						
							|  |  |  |             $where_clauses[] = 'l.time <= :until_time'; | 
					
						
							|  |  |  |             $params[':until_time'] = $filters['until_time'] . ' 23:59:59'; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Add message search if specified
 | 
					
						
							|  |  |  |         if (!empty($filters['message'])) { | 
					
						
							|  |  |  |             $where_clauses[] = 'l.message LIKE :message'; | 
					
						
							|  |  |  |             $params[':message'] = '%' . $filters['message'] . '%'; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Add user ID search if specified
 | 
					
						
							|  |  |  |         if (!empty($filters['id'])) { | 
					
						
							|  |  |  |             $where_clauses[] = 'l.user_id = :search_user_id'; | 
					
						
							|  |  |  |             $params[':search_user_id'] = $filters['id']; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Combine WHERE clauses
 | 
					
						
							|  |  |  |         $sql = $base_sql; | 
					
						
							|  |  |  |         if (!empty($where_clauses)) { | 
					
						
							|  |  |  |             $sql .= ' WHERE ' . implode(' AND ', $where_clauses); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Add ordering
 | 
					
						
							|  |  |  |         $sql .= ' ORDER BY l.time DESC'; | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Add pagination
 | 
					
						
							|  |  |  |         if ($items_per_page) { | 
					
						
							|  |  |  |             $items_per_page = (int)$items_per_page; | 
					
						
							|  |  |  |             $sql .= ' LIMIT ' . $offset . ',' . $items_per_page; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $query = $this->db->prepare($sql); | 
					
						
							|  |  |  |         $query->execute($params); | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         return $query->fetchAll(PDO::FETCH_ASSOC); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  | class LogTest extends TestCase | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     private $db; | 
					
						
							|  |  |  |     private $log; | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |     private $testUserId; | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     protected function setUp(): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         parent::setUp(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Prepare DB for Github CI
 | 
					
						
							|  |  |  |         $host = defined('CI_DB_HOST') ? CI_DB_HOST : '127.0.0.1'; | 
					
						
							|  |  |  |         $password = defined('CI_DB_PASSWORD') ? CI_DB_PASSWORD : ''; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         // Set up test database
 | 
					
						
							|  |  |  |         $this->db = new Database([ | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             'type' => 'mariadb', | 
					
						
							|  |  |  |             'host' => $host, | 
					
						
							|  |  |  |             'port' => '3306', | 
					
						
							| 
									
										
										
										
											2025-04-25 15:30:24 +00:00
										 |  |  |             'dbname' => 'jilo_test', | 
					
						
							|  |  |  |             'user' => 'test_jilo', | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             'password' => $password | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 13:16:38 +00:00
										 |  |  |         // Create user table
 | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             CREATE TABLE IF NOT EXISTS user ( | 
					
						
							|  |  |  |                 id INT AUTO_INCREMENT PRIMARY KEY, | 
					
						
							|  |  |  |                 username VARCHAR(255) NOT NULL, | 
					
						
							|  |  |  |                 password VARCHAR(255) NOT NULL, | 
					
						
							|  |  |  |                 email VARCHAR(255) NOT NULL, | 
					
						
							|  |  |  |                 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |             ) | 
					
						
							|  |  |  |         ");
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Create log table with the expected schema from Log class
 | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |             CREATE TABLE IF NOT EXISTS log ( | 
					
						
							|  |  |  |                 id INT AUTO_INCREMENT PRIMARY KEY, | 
					
						
							|  |  |  |                 user_id INT, | 
					
						
							|  |  |  |                 scope VARCHAR(50) NOT NULL DEFAULT 'user', | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |                 message TEXT NOT NULL, | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |                 time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | 
					
						
							| 
									
										
										
										
											2025-04-25 13:16:38 +00:00
										 |  |  |                 FOREIGN KEY (user_id) REFERENCES user(id) | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |             ) | 
					
						
							|  |  |  |         ");
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Create test users with all required fields
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("
 | 
					
						
							|  |  |  |             INSERT INTO user (username, password, email)  | 
					
						
							|  |  |  |             VALUES  | 
					
						
							|  |  |  |                 ('testuser', 'password123', 'testuser@example.com'), | 
					
						
							|  |  |  |                 ('testuser2', 'password123', 'testuser2@example.com') | 
					
						
							|  |  |  |         ");
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Store test user ID for later use
 | 
					
						
							|  |  |  |         $stmt = $this->db->getConnection()->query("SELECT id FROM user WHERE username = 'testuser' LIMIT 1"); | 
					
						
							|  |  |  |         $user = $stmt->fetch(PDO::FETCH_ASSOC); | 
					
						
							|  |  |  |         $this->testUserId = $user['id']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Create a TestLogger instance that will be used by the app's Log wrapper
 | 
					
						
							|  |  |  |         $this->log = new TestLogger($this->db); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function tearDown(): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Drop tables in correct order (respect foreign key constraints)
 | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("DROP TABLE IF EXISTS log"); | 
					
						
							|  |  |  |         $this->db->getConnection()->exec("DROP TABLE IF EXISTS user"); | 
					
						
							|  |  |  |         parent::tearDown(); | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testInsertLog() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $result = $this->log->insertLog($this->testUserId, 'Test message', 'test'); | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         $this->assertTrue($result); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Verify the log was inserted
 | 
					
						
							|  |  |  |         $stmt = $this->db->getConnection()->query("SELECT * FROM log WHERE user_id = {$this->testUserId} LIMIT 1"); | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         $log = $stmt->fetch(PDO::FETCH_ASSOC); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         $this->assertEquals('Test message', $log['message']); | 
					
						
							|  |  |  |         $this->assertEquals('test', $log['scope']); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testReadLog() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Insert some test logs with a delay to ensure order
 | 
					
						
							|  |  |  |         $this->log->insertLog($this->testUserId, 'Test message 1', 'user'); | 
					
						
							|  |  |  |         sleep(1); // Ensure different timestamps
 | 
					
						
							|  |  |  |         $this->log->insertLog($this->testUserId, 'Test message 2', 'user'); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $logs = $this->log->readLog($this->testUserId, 'user'); | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         $this->assertCount(2, $logs); | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $this->assertEquals('Test message 2', $logs[0]['message']); // Most recent first (by time)
 | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testReadLogWithTimeFilter() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // First message from yesterday
 | 
					
						
							|  |  |  |         $yesterday = date('Y-m-d', strtotime('-1 day')); | 
					
						
							|  |  |  |         $stmt = $this->db->getConnection()->prepare("
 | 
					
						
							|  |  |  |             INSERT INTO log (user_id, scope, message, time) | 
					
						
							|  |  |  |             VALUES (?, ?, ?, ?) | 
					
						
							|  |  |  |         ");
 | 
					
						
							|  |  |  |         $stmt->execute([$this->testUserId, 'user', 'Test message 1', $yesterday . ' 12:00:00']); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Second message from today
 | 
					
						
							|  |  |  |         $today = date('Y-m-d'); | 
					
						
							|  |  |  |         $stmt->execute([$this->testUserId, 'user', 'Test message 2', $today . ' 12:00:00']); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Should get only today's messages
 | 
					
						
							|  |  |  |         $logs = $this->log->readLog($this->testUserId, 'user', 0, '', [ | 
					
						
							|  |  |  |             'from_time' => $today | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         ]); | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $this->assertCount(1, $logs); | 
					
						
							|  |  |  |         $this->assertEquals('Test message 2', $logs[0]['message']); // Most recent first
 | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testReadLogWithPagination() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Insert multiple test logs with delays to ensure order
 | 
					
						
							|  |  |  |         for ($i = 1; $i <= 5; $i++) { | 
					
						
							|  |  |  |             $this->log->insertLog($this->testUserId, "Test message $i", 'user'); | 
					
						
							|  |  |  |             sleep(1); // Ensure different timestamps
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Get all logs to verify total
 | 
					
						
							|  |  |  |         $allLogs = $this->log->readLog($this->testUserId, 'user'); | 
					
						
							|  |  |  |         $this->assertCount(5, $allLogs); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Get first page (offset 0, limit 2)
 | 
					
						
							|  |  |  |         $logs = $this->log->readLog($this->testUserId, 'user', 0, 2); | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |         $this->assertCount(2, $logs); | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         $this->assertEquals('Test message 5', $logs[0]['message']); // Most recent first
 | 
					
						
							|  |  |  |         $this->assertEquals('Test message 4', $logs[1]['message']); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Get second page (offset 2, limit 2)
 | 
					
						
							|  |  |  |         $logs = $this->log->readLog($this->testUserId, 'user', 2, 2); | 
					
						
							|  |  |  |         $this->assertCount(2, $logs); | 
					
						
							|  |  |  |         $this->assertEquals('Test message 3', $logs[0]['message']); | 
					
						
							|  |  |  |         $this->assertEquals('Test message 2', $logs[1]['message']); | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function testReadLogWithMessageFilter() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Insert test logs with different messages and delays
 | 
					
						
							|  |  |  |         $this->log->insertLog($this->testUserId, 'Test message ABC', 'user'); | 
					
						
							|  |  |  |         sleep(1); // Ensure different timestamps
 | 
					
						
							|  |  |  |         $this->log->insertLog($this->testUserId, 'Test message XYZ', 'user'); | 
					
						
							|  |  |  |         sleep(1); // Ensure different timestamps
 | 
					
						
							|  |  |  |         $this->log->insertLog($this->testUserId, 'Different message', 'user'); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Filter by message content
 | 
					
						
							|  |  |  |         $logs = $this->log->readLog($this->testUserId, 'user', 0, '', ['message' => 'Test message']); | 
					
						
							|  |  |  |         $this->assertCount(2, $logs); | 
					
						
							| 
									
										
										
										
											2025-02-19 13:31:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 14:15:56 +00:00
										 |  |  |         // Verify filtered results
 | 
					
						
							|  |  |  |         foreach ($logs as $log) { | 
					
						
							|  |  |  |             $this->assertStringContainsString('Test message', $log['message']); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-18 14:36:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } |