mockPdo = $this->createMock(PDO::class); // Create real config and user objects with mocked PDO $this->config = new ConfigModel($this->mockPdo); $this->config->siteTitle = 'Test Site'; $this->config->siteDescription = 'Test Description'; $this->config->baseUrl = 'https://example.com'; $this->config->basePath = '/tkr'; $this->config->itemsPerPage = 10; $this->user = new UserModel($this->mockPdo); $this->user->username = 'testuser'; $this->user->displayName = 'Test User'; $this->user->website = 'https://example.com'; // Set up global $app for simplified dependency access global $app; $app = [ 'db' => $this->mockPdo, 'config' => $this->config, 'user' => $this->user, ]; } public function testGetAdminDataRegularMode(): void { $controller = new AdminController(); $data = $controller->getAdminData(false); // Should return proper structure $this->assertArrayHasKey('config', $data); $this->assertArrayHasKey('user', $data); $this->assertArrayHasKey('isSetup', $data); // Should be the injected instances $this->assertSame($this->config, $data['config']); $this->assertSame($this->user, $data['user']); $this->assertFalse($data['isSetup']); } public function testGetAdminDataSetupMode(): void { $controller = new AdminController(); $data = $controller->getAdminData(true); // Should return proper structure $this->assertArrayHasKey('config', $data); $this->assertArrayHasKey('user', $data); $this->assertArrayHasKey('isSetup', $data); // Should be the injected instances $this->assertSame($this->config, $data['config']); $this->assertSame($this->user, $data['user']); $this->assertTrue($data['isSetup']); } public function testProcessSettingsSaveWithEmptyData(): void { $controller = new AdminController(); $result = $controller->saveSettings([], false); $this->assertFalse($result['success']); $this->assertContains('No data provided', $result['errors']); } public function testProcessSettingsSaveValidationErrors(): void { $controller = new AdminController(); // Test data with multiple validation errors $postData = [ 'username' => '', // Missing username 'display_name' => '', // Missing display name 'website' => 'invalid-url', // Invalid URL 'site_title' => '', // Missing site title 'base_url' => '', // Missing base URL 'base_path' => 'invalid', // Invalid base path 'items_per_page' => 100, // Too high 'password' => 'test123', 'confirm_password' => 'different' // Passwords don't match ]; $result = $controller->saveSettings($postData, false); $this->assertFalse($result['success']); $this->assertNotEmpty($result['errors']); // Should have multiple validation errors $this->assertGreaterThan(5, count($result['errors'])); } public function testProcessSettingsSaveValidData(): void { // Mock PDO to simulate successful database operations $mockStatement = $this->createMock(PDOStatement::class); $mockStatement->method('execute')->willReturn(true); $mockStatement->method('fetchColumn')->willReturn(1); // Existing record count $mockStatement->method('fetch')->willReturnOnConsecutiveCalls( [ 'site_title' => 'Updated Site', 'site_description' => 'Updated Description', 'base_url' => 'https://updated.com', 'base_path' => '/updated', 'items_per_page' => 15, 'css_id' => null, 'strict_accessibility' => true, 'log_level' => 2 ], [ 'username' => 'newuser', 'display_name' => 'New User', 'website' => 'https://example.com', 'mood' => '' ] ); $this->mockPdo->method('prepare')->willReturn($mockStatement); $this->mockPdo->method('query')->willReturn($mockStatement); // Create models with mocked PDO $config = new ConfigModel($this->mockPdo); $user = new UserModel($this->mockPdo); // Update global $app with test models global $app; $app['config'] = $config; $app['user'] = $user; $controller = new AdminController(); $postData = [ 'username' => 'newuser', 'display_name' => 'New User', 'website' => 'https://example.com', 'site_title' => 'Updated Site', 'site_description' => 'Updated Description', 'base_url' => 'https://updated.com', 'base_path' => '/updated', 'items_per_page' => 15, 'strict_accessibility' => 'on', 'log_level' => 2 ]; $result = $controller->saveSettings($postData, false); $this->assertTrue($result['success']); $this->assertEmpty($result['errors']); } public function testProcessSettingsSaveWithPassword(): void { // Mock PDO for successful save operations $mockStatement = $this->createMock(PDOStatement::class); $mockStatement->method('execute')->willReturn(true); $mockStatement->method('fetchColumn')->willReturn(1); $mockStatement->method('fetch')->willReturnOnConsecutiveCalls( [ 'site_title' => 'Test Site', 'site_description' => 'Test Description', 'base_url' => 'https://example.com', 'base_path' => '/tkr', 'items_per_page' => 10, 'css_id' => null, 'strict_accessibility' => true, 'log_level' => 2 ], [ 'username' => 'testuser', 'display_name' => 'Test User', 'website' => '', 'mood' => '' ] ); // Verify password hash is called $this->mockPdo->expects($this->atLeastOnce()) ->method('prepare') ->willReturn($mockStatement); $this->mockPdo->method('query')->willReturn($mockStatement); // Create models with mocked PDO $config = new ConfigModel($this->mockPdo); $user = new UserModel($this->mockPdo); // Update global $app with test models global $app; $app['config'] = $config; $app['user'] = $user; $controller = new AdminController(); $postData = [ 'username' => 'testuser', 'display_name' => 'Test User', 'site_title' => 'Test Site', 'site_description' => 'Test Description', 'base_url' => 'https://example.com', 'base_path' => '/tkr', 'items_per_page' => 10, 'password' => 'newpassword', 'confirm_password' => 'newpassword' ]; $result = $controller->saveSettings($postData, false); $this->assertTrue($result['success']); } public function testProcessSettingsSaveDatabaseError(): void { // Mock PDO to throw exception on save $this->mockPdo->method('query') ->willThrowException(new PDOException("Database error")); $config = new ConfigModel($this->mockPdo); $user = new UserModel($this->mockPdo); // Update global $app with test models global $app; $app['config'] = $config; $app['user'] = $user; $controller = new AdminController(); $postData = [ 'username' => 'testuser', 'display_name' => 'Test User', 'site_title' => 'Test Site', 'site_description' => 'Test Description', 'base_url' => 'https://example.com', 'base_path' => '/tkr', 'items_per_page' => 10 ]; $result = $controller->saveSettings($postData, false); $this->assertFalse($result['success']); $this->assertContains('Failed to save settings', $result['errors']); } }