Files
Tstore/tests/Feature/VersionPublishServiceTest.php
T
浪子 04a2034975 前端极简黑白重设计,并纳入客户端注册、站点设置与后台相关改动
- storefront 全站改为极简黑白配色:直角、细线分隔、卡片 hover 浅底、深色模式(跟随系统+手动切换)
- 抽出 storefront/partials/card 复用卡片
- 一并提交此前暂存的客户端注册 API、站点设置、后台页面与测试

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-22 08:35:49 +08:00

190 lines
5.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Package;
use App\Services\VersionPublishService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\File;
use RuntimeException;
use Tests\TestCase;
use ZipArchive;
class VersionPublishServiceTest extends TestCase
{
use RefreshDatabase;
/**
* @var array<int, string>
*/
private array $temporaryZipPaths = [];
public function test_it_can_publish_zip_without_manifest_using_manual_metadata(): void
{
$package = Package::query()->create([
'type' => 'plugin',
'slug' => 'DemoPlugin',
'name' => 'Demo Plugin',
'summary' => '',
'description' => '',
'author' => '',
'homepage' => '',
'icon_url' => '',
'license' => '',
'status' => 'draft',
'is_featured' => false,
'sort_order' => 0,
'download_count' => 0,
'latest_version' => '',
]);
$uploadedFile = $this->makeZipUpload($package->slug, [
'Plugin.php' => '<?php echo "ok";',
]);
$version = app(VersionPublishService::class)->publishFromZip($package, $uploadedFile, [
'version' => '1.2.3',
'typecho_min' => '1.2.0',
'typecho_max' => '1.3.*',
'php_min' => '8.0',
'php_max' => '8.3',
'php_extensions' => ['curl', 'json'],
'is_stable' => true,
'mark_as_latest' => true,
]);
$this->assertSame('1.2.3', $version->version);
$this->assertSame('1.2.0', $version->typecho_min);
$this->assertSame('1.3.*', $version->typecho_max);
$this->assertSame('8.0', $version->php_min);
$this->assertSame('8.3', $version->php_max);
$this->assertSame(['curl', 'json'], $version->php_extensions_array);
$this->assertTrue($version->is_stable);
$this->assertTrue($version->is_latest);
$this->assertFileExists(storage_path('app/packages/plugin/DemoPlugin/1.2.3.zip'));
$this->assertSame('1.2.3', $package->fresh()->latest_version);
}
public function test_it_requires_manual_version_when_manifest_is_missing(): void
{
$package = Package::query()->create([
'type' => 'plugin',
'slug' => 'DemoPlugin',
'name' => 'Demo Plugin',
'summary' => '',
'description' => '',
'author' => '',
'homepage' => '',
'icon_url' => '',
'license' => '',
'status' => 'draft',
'is_featured' => false,
'sort_order' => 0,
'download_count' => 0,
'latest_version' => '',
]);
$uploadedFile = $this->makeZipUpload($package->slug, [
'Plugin.php' => '<?php echo "ok";',
]);
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('manifest.json not found at zip root; version is required for zip publish');
app(VersionPublishService::class)->publishFromZip($package, $uploadedFile, []);
}
public function test_manifest_validation_allows_lowercase_theme_slug(): void
{
$package = Package::query()->create([
'type' => 'theme',
'slug' => 'clarity',
'name' => 'Clarity',
'summary' => '',
'description' => '',
'author' => '',
'homepage' => '',
'icon_url' => '',
'license' => '',
'status' => 'draft',
'is_featured' => false,
'sort_order' => 0,
'download_count' => 0,
'latest_version' => '',
]);
$manifest = [
'schema_version' => '1.0',
'type' => 'theme',
'slug' => 'clarity',
'name' => 'Clarity',
'author' => 'Author',
'version' => '1.5.0',
'compatibility' => [
'typecho_min' => '1.2.0',
'php_min' => '8.0',
],
'install' => [
'root_dir' => 'clarity',
'target_dir' => 'usr/themes/clarity',
],
'package' => [
'sha256' => str_repeat('a', 64),
],
];
$method = new \ReflectionMethod(VersionPublishService::class, 'validateManifest');
$method->setAccessible(true);
$method->invoke(app(VersionPublishService::class), $manifest, $package, str_repeat('a', 64));
$this->assertTrue(true);
}
protected function tearDown(): void
{
foreach ($this->temporaryZipPaths as $path) {
if (is_file($path)) {
@unlink($path);
}
}
$storedZip = storage_path('app/packages/plugin/DemoPlugin/1.2.3.zip');
if (is_file($storedZip)) {
@unlink($storedZip);
}
$storedDir = storage_path('app/packages/plugin/DemoPlugin');
if (is_dir($storedDir)) {
@rmdir($storedDir);
}
parent::tearDown();
}
private function makeZipUpload(string $slug, array $files): UploadedFile
{
$directory = storage_path('framework/testing');
File::ensureDirectoryExists($directory);
$path = tempnam($directory, 'zip');
$this->temporaryZipPaths[] = $path;
$zip = new ZipArchive();
$opened = $zip->open($path, ZipArchive::CREATE | ZipArchive::OVERWRITE);
if ($opened !== true) {
throw new RuntimeException('failed to create test zip');
}
foreach ($files as $name => $contents) {
$zip->addFromString($slug . '/' . $name, $contents);
}
$zip->close();
return new UploadedFile($path, $slug . '.zip', 'application/zip', null, true);
}
}