seed(\Database\Seeders\PermissionSeeder::class); $this->seed(\Database\Seeders\RoleSeeder::class); $this->admin = User::factory()->create(); $adminRole = Role::where('slug', 'admin')->first(); $this->admin->roles()->attach($adminRole); $this->themesPath = base_path('themes'); if (!File::exists($this->themesPath)) { File::makeDirectory($this->themesPath); } } public function test_admin_can_upload_valid_theme_zip(): void { $themeName = 'test-upload-theme'; $zipPath = storage_path('app/test_theme.zip'); $this->createTestThemeZip($zipPath, $themeName); $file = new UploadedFile($zipPath, 'test_theme.zip', 'application/zip', null, true); $response = $this->actingAs($this->admin)->postJson('/loom/themes/upload', [ 'theme_zip' => $file, ]); $response->assertStatus(200); $response->assertJsonPath('message', 'Theme uploaded successfully.'); $this->assertTrue(File::exists(base_path("themes/{$themeName}/theme.md"))); // Cleanup File::delete($zipPath); if (File::exists(base_path("themes/{$themeName}"))) { File::deleteDirectory(base_path("themes/{$themeName}")); } } public function test_upload_fails_if_theme_md_is_missing(): void { $zipPath = storage_path('app/invalid_theme.zip'); $tempDir = storage_path('app/temp_invalid_' . uniqid()); File::makeDirectory($tempDir); File::put($tempDir . '/somefile.txt', 'content'); shell_exec("cd {$tempDir} && zip -r {$zipPath} ."); File::deleteDirectory($tempDir); $file = new UploadedFile($zipPath, 'invalid_theme.zip', 'application/zip', null, true); $response = $this->actingAs($this->admin)->postJson('/loom/themes/upload', [ 'theme_zip' => $file, ]); $response->assertStatus(422); $response->assertJsonPath('message', 'Invalid theme: theme.md is missing.'); // Cleanup File::delete($zipPath); } public function test_non_admin_cannot_upload_themes(): void { $user = User::factory()->create(); // Regular user role doesn't have upload-themes permission $user->roles()->attach(Role::where('slug', 'user')->first()); $response = $this->actingAs($user)->postJson('/loom/themes/upload', [ 'theme_zip' => UploadedFile::fake()->create('theme.zip', 100, 'application/zip'), ]); $response->assertStatus(403); } protected function createTestThemeZip(string $path, string $themeName): void { $tempDir = storage_path('app/temp_' . $themeName); File::makeDirectory($tempDir . '/' . $themeName, 0755, true); File::put($tempDir . '/' . $themeName . '/theme.md', "Title: Test Upload Theme\nAuthor: Junie\nDescription: A test theme."); File::put($tempDir . '/' . $themeName . '/index.blade.php', "