Shockingly, this didn't require any code changes. But PHP is more forgiving with "strict typing" than I'd expected. I may go back and clean up function declarations later, but that's not urgent. Reviewed-on: https://gitea.subcultureofone.org/greg/tkr/pulls/60 Co-authored-by: Greg Sarjeant <greg@subcultureofone.org> Co-committed-by: Greg Sarjeant <greg@subcultureofone.org>
		
			
				
	
	
		
			257 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| declare(strict_types=1);
 | |
| 
 | |
| require_once dirname(dirname(dirname(__DIR__))) . "/config/bootstrap.php";
 | |
| use PHPUnit\Framework\TestCase;
 | |
| 
 | |
| class AdminControllerTest extends TestCase
 | |
| {
 | |
|     private PDO $mockPdo;
 | |
|     private ConfigModel $config;
 | |
|     private UserModel $user;
 | |
| 
 | |
|     protected function setUp(): void
 | |
|     {
 | |
|         // Create mock PDO
 | |
|         $this->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']);
 | |
|     }
 | |
| 
 | |
| } |