testDir = sys_get_temp_dir() . '/controller_test_' . uniqid(); mkdir($this->testDir, 0777, true); // Create mock SymfonyStyle $this->io = $this->createMock(SymfonyStyle::class); $this->controllerGenerator = new ControllerGenerator(); } protected function tearDown(): void { if (is_dir($this->testDir)) { $this->removeDirectory($this->testDir); } } private function removeDirectory($dir) { if (!is_dir($dir)) { return; } $items = scandir($dir); foreach ($items as $item) { if ($item != '.' && $item != '..') { $path = $dir . DIRECTORY_SEPARATOR . $item; if (is_dir($path)) { $this->removeDirectory($path); } else { unlink($path); } } } rmdir($dir); } public function testGenerateApiController() { $tableName = 'users'; $tableComment = 'User management table'; $extensionInfo = [ 'namespace' => 'TestExtension', 'name' => 'test-extension' ]; $fields = [ ['name' => 'id', 'type' => 'integer'], ['name' => 'name', 'type' => 'string', 'length' => 255], ['name' => 'email', 'type' => 'string', 'length' => 255], ['name' => 'created_at', 'type' => 'datetime'] ]; $result = $this->controllerGenerator->generateControllers( $tableName, $tableComment, $fields, $extensionInfo, $this->testDir, $this->io ); $this->assertTrue($result); $controllerPath = $this->testDir . '/src/Controller/Api/UserController.php'; $this->assertFileExists($controllerPath); $content = file_get_contents($controllerPath); // Test namespace $this->assertStringContainsString('namespace TestExtension\Controller\Api;', $content); // Test class name $this->assertStringContainsString('class UserController', $content); // Test imports $this->assertStringContainsString('use SixShop\Core\Request;', $content); $this->assertStringContainsString('use TestExtension\Entity\UserEntity;', $content); // Test methods $this->assertStringContainsString('public function index(Request $request)', $content); $this->assertStringContainsString('public function show(Request $request)', $content); $this->assertStringContainsString('public function store(Request $request)', $content); $this->assertStringContainsString('public function update(Request $request)', $content); $this->assertStringContainsString('public function destroy(Request $request)', $content); // Test response helpers $this->assertStringContainsString('return page_response(', $content); $this->assertStringContainsString('return success_response(', $content); } public function testGenerateAdminController() { $tableName = 'products'; $tableComment = 'Product management table'; $extensionInfo = [ 'namespace' => 'TestExtension', 'name' => 'test-extension' ]; $fields = [ ['name' => 'id', 'type' => 'integer'], ['name' => 'title', 'type' => 'string', 'length' => 255], ['name' => 'price', 'type' => 'decimal'], ['name' => 'status', 'type' => 'integer'] ]; $result = $this->controllerGenerator->generateControllers( $tableName, $tableComment, $fields, $extensionInfo, $this->testDir, $this->io ); $this->assertTrue($result); $controllerPath = $this->testDir . '/src/Controller/Admin/ProductController.php'; $this->assertFileExists($controllerPath); $content = file_get_contents($controllerPath); // Test namespace $this->assertStringContainsString('namespace TestExtension\Controller\Admin;', $content); // Test class name $this->assertStringContainsString('class ProductController', $content); // Test middleware usage $this->assertStringContainsString('use SixShop\Core\MacroPageMiddleware;', $content); // Test entity usage $this->assertStringContainsString('use TestExtension\Entity\ProductEntity;', $content); // Test methods $this->assertStringContainsString('public function index(Request $request)', $content); $this->assertStringContainsString('public function show(Request $request)', $content); $this->assertStringContainsString('public function store(Request $request)', $content); $this->assertStringContainsString('public function update(Request $request)', $content); $this->assertStringContainsString('public function destroy(Request $request)', $content); } public function testDirectoryCreation() { $tableName = 'categories'; $tableComment = 'Category management table'; $extensionInfo = [ 'namespace' => 'TestExtension', 'name' => 'test-extension' ]; $fields = [ ['name' => 'id', 'type' => 'integer'], ['name' => 'name', 'type' => 'string'] ]; // Generate both controllers $result = $this->controllerGenerator->generateControllers( $tableName, $tableComment, $fields, $extensionInfo, $this->testDir, $this->io ); $this->assertTrue($result); // Test directory structure $this->assertDirectoryExists($this->testDir . '/src'); $this->assertDirectoryExists($this->testDir . '/src/Controller'); $this->assertDirectoryExists($this->testDir . '/src/Controller/Api'); $this->assertDirectoryExists($this->testDir . '/src/Controller/Admin'); } public function testControllerNaming() { $testCases = [ 'user_profiles' => 'UserProfileController', 'product_categories' => 'ProductCategoryController', 'orders' => 'OrderController', 'blog_posts' => 'BlogPostController' ]; foreach ($testCases as $tableName => $expectedClass) { $tableComment = 'Test table'; $extensionInfo = [ 'namespace' => 'TestExtension', 'name' => 'test-extension' ]; $fields = [['name' => 'id', 'type' => 'integer']]; $this->controllerGenerator->generateControllers( $tableName, $tableComment, $fields, $extensionInfo, $this->testDir, $this->io ); $controllerPath = $this->testDir . '/src/Controller/Api/' . $expectedClass . '.php'; $this->assertFileExists($controllerPath); $content = file_get_contents($controllerPath); $this->assertStringContainsString("class $expectedClass", $content); // Clean up for next iteration unlink($controllerPath); } } public function testValidationRulesGeneration() { $tableName = 'users'; $tableComment = 'User table'; $extensionInfo = [ 'namespace' => 'TestExtension', 'name' => 'test-extension' ]; $fields = [ ['name' => 'id', 'type' => 'integer'], ['name' => 'name', 'type' => 'string', 'length' => 255], ['name' => 'email', 'type' => 'string', 'length' => 255], ['name' => 'age', 'type' => 'integer'], ['name' => 'price', 'type' => 'decimal'], ['name' => 'is_active', 'type' => 'boolean'], ['name' => 'created_at', 'type' => 'datetime'] ]; $this->controllerGenerator->generateControllers( $tableName, $tableComment, $fields, $extensionInfo, $this->testDir, $this->io ); $controllerPath = $this->testDir . '/src/Controller/Api/UserController.php'; $content = file_get_contents($controllerPath); // Test validation rules are present $this->assertStringContainsString('$rules = [', $content); $this->assertStringContainsString("'name' => 'required|string|max:255'", $content); $this->assertStringContainsString("'email' => 'required|string|max:255'", $content); $this->assertStringContainsString("'age' => 'integer'", $content); $this->assertStringContainsString("'price' => 'numeric'", $content); $this->assertStringContainsString("'is_active' => 'boolean'", $content); } public function testEntityMethodCalls() { $tableName = 'posts'; $tableComment = 'Post table'; $extensionInfo = [ 'namespace' => 'TestExtension', 'name' => 'test-extension' ]; $fields = [ ['name' => 'id', 'type' => 'integer'], ['name' => 'title', 'type' => 'string'], ['name' => 'content', 'type' => 'text'] ]; $this->controllerGenerator->generateControllers( $tableName, $tableComment, $fields, $extensionInfo, $this->testDir, $this->io ); $controllerPath = $this->testDir . '/src/Controller/Api/PostController.php'; $content = file_get_contents($controllerPath); // Test entity method calls match expected patterns $this->assertStringContainsString('$entity->getList($page, $limit, $filters)', $content); $this->assertStringContainsString('$entity->getById($id)', $content); $this->assertStringContainsString('$entity->create($data)', $content); $this->assertStringContainsString('$entity->updateById($id, $data)', $content); $this->assertStringContainsString('$entity->deleteById($id)', $content); } public function testNamespaceHandling() { $tableName = 'users'; $tableComment = 'User table'; $fields = [ ['name' => 'id', 'type' => 'integer'], ['name' => 'name', 'type' => 'string'] ]; // Test different namespace formats $namespaces = [ 'SimpleExtension', 'Complex\\Nested\\Extension', 'CamelCase\\Extension' ]; foreach ($namespaces as $namespace) { $extensionInfo = [ 'namespace' => $namespace, 'name' => 'test-extension' ]; $this->controllerGenerator->generateControllers( $tableName, $tableComment, $fields, $extensionInfo, $this->testDir, $this->io ); $controllerPath = $this->testDir . '/src/Controller/Api/UserController.php'; $content = file_get_contents($controllerPath); $this->assertStringContainsString("namespace $namespace\\Controller\\Api;", $content); $this->assertStringContainsString("use $namespace\\Entity\\UserEntity;", $content); // Clean up for next iteration unlink($controllerPath); } } public function testTemplateErrorHandling() { $tableName = 'users'; $tableComment = 'User table'; $extensionInfo = [ 'namespace' => 'TestExtension', 'name' => 'test-extension' ]; $fields = [['name' => 'id', 'type' => 'integer']]; // Test with invalid directory (read-only) $readOnlyDir = '/tmp/readonly_test_' . uniqid(); mkdir($readOnlyDir, 0444, true); try { $result = $this->controllerGenerator->generateControllers( $tableName, $tableComment, $fields, $extensionInfo, $readOnlyDir, $this->io ); // Should return false due to permission issues $this->assertFalse($result); } catch (\Exception $e) { // This might throw an exception due to permission issues $this->assertInstanceOf(\Exception::class, $e); } finally { chmod($readOnlyDir, 0777); rmdir($readOnlyDir); } } }