adminUser()); $file = UploadedFile::fake()->image('cover.png', 16, 16); $response = $this->post('/api/upload', ['file' => $file], ['Accept' => 'application/json']); $response->assertOk(); $url = (string) $response->json('url'); $path = (string) $response->json('path'); $this->assertMatchesRegularExpression('#^uploads/[0-9a-f-]{36}\.png$#', $path); $this->assertStringEndsWith('/storage/'.$path, $url); Storage::disk('public')->assertExists($path); } /** * @dataProvider rejectedUploadNamesProvider */ public function test_admin_upload_rejects_unsafe_names_without_leaving_files(string $clientName): void { Storage::fake('public'); Sanctum::actingAs($this->adminUser()); $file = UploadedFile::fake()->create($clientName, 8, 'text/plain'); $response = $this->post('/api/upload', ['file' => $file], ['Accept' => 'application/json']); $response->assertStatus(422); $this->assertSame([], Storage::disk('public')->allFiles('uploads')); } public function test_h5_upload_uses_same_constraints(): void { Storage::fake('public'); Sanctum::actingAs($this->wechatUser()); $ok = UploadedFile::fake()->image('avatar.png', 16, 16); $okResponse = $this->post('/api/h5/upload', ['file' => $ok], ['Accept' => 'application/json']); $okResponse->assertOk(); $path = (string) $okResponse->json('path'); $this->assertMatchesRegularExpression('#^uploads/h5/[0-9a-f-]{36}\.png$#', $path); Storage::disk('public')->assertExists($path); $denied = UploadedFile::fake()->create('avatar.php', 8, 'text/plain'); $deniedResponse = $this->post('/api/h5/upload', ['file' => $denied], ['Accept' => 'application/json']); $deniedResponse->assertStatus(422); $this->assertCount(1, Storage::disk('public')->allFiles('uploads/h5')); } /** * @return array */ public static function rejectedUploadNamesProvider(): array { return [ 'php' => ['note.php'], 'phtml' => ['note.phtml'], 'phar' => ['note.phar'], 'php_jpg' => ['1.php.jpg'], 'php_png' => ['xxx.php.png'], ]; } private function adminUser(): User { $user = new User([ 'username' => 'upload_admin', 'name' => '上传测试', 'role' => 'super_admin', 'is_active' => true, ]); $user->id = 1; return $user; } private function wechatUser(): WechatUser { $user = new AuthenticatableWechatUserStub([ 'openid' => 'otest_upload_user', 'nickname' => 'tester', ]); $user->id = 1; return $user; } }