create([ 'username' => 'admin_logo', 'password_hash' => 'unused', 'name' => '管理员', 'status' => 'active', ])); $competition = Competition::query()->create([ 'slug' => 'logo-upload', 'name' => '沪苏协同新兴产业青年科创大赛', 'published' => true, 'status' => 'published', 'branding_json' => [ 'login' => [ 'headline' => '首届沪苏协同新兴产业青年科创大赛', ], ], ]); $res = $this->postJson("/api/v1/admin/competitions/{$competition->id}/logo", [ 'file' => UploadedFile::fake()->image('mark.png', 120, 120), ]); $res->assertOk(); $url = (string) $res->json('url'); $this->assertNotSame('', $url); $this->assertStringStartsWith('/storage/competitions/'.$competition->id.'/logo-', $url); $path = strtok(ltrim(substr($url, strlen('/storage')), '/'), '?'); $this->assertTrue(Storage::disk('public')->exists($path)); $competition->refresh(); $this->assertSame($url, data_get($competition->branding_json, 'login.logoUrl')); $this->assertSame('首届沪苏协同新兴产业青年科创大赛', data_get($competition->branding_json, 'login.headline')); $this->deleteJson("/api/v1/admin/competitions/{$competition->id}/logo")->assertOk(); $competition->refresh(); $this->assertNull(data_get($competition->branding_json, 'login.logoUrl')); $this->assertFalse(Storage::disk('public')->exists($path)); } public function test_logo_upload_rejects_non_image(): void { Storage::fake('public'); Sanctum::actingAs(AdminUser::query()->create([ 'username' => 'admin_logo_bad', 'password_hash' => 'unused', 'name' => '管理员', 'status' => 'active', ])); $competition = Competition::query()->create([ 'slug' => 'logo-bad', 'name' => '测试赛', 'published' => true, 'status' => 'published', ]); $this->postJson("/api/v1/admin/competitions/{$competition->id}/logo", [ 'file' => UploadedFile::fake()->create('notes.pdf', 20, 'application/pdf'), ])->assertUnprocessable(); } }