callHtmlController('image', [ 'id' => 'upload-trigger', 'file' => 'images', 'type' => 'png,jpg', 'path' => 'system/example', 'size' => 4096, ], 9101); $this->assertStringContainsString('id="ImageDialog"', $html); $this->assertStringContainsString('var config = {"buttonSelector":"#upload-trigger"', $html); $this->assertStringContainsString('"multiple":true', $html); $this->assertStringContainsString('"imageUrl":"/api/system/upload/image"', $html); $this->assertStringContainsString('data-file="mul"', $html); $this->assertStringContainsString('data-path="system/example"', $html); $this->assertStringContainsString("$.form.load(config.imageUrl, this.params, 'get'", $html); $this->assertStringContainsString('centerLayer: function () {', $html); $this->assertStringContainsString("\$layer.css({left: left + 'px', top: top + 'px', marginLeft: 0, marginTop: 0});", $html); $this->assertStringContainsString('上传图片', $html); $this->assertStringNotContainsString('{$get', $html); $this->assertStringNotContainsString('{:url', $html); $this->assertStringNotContainsString('{if ', $html); } public function testIndexBuildsUploadScriptUsingTokenRestrictedExtensions(): void { $response = $this->callIndexController([ 'uptoken' => AuthService::withUploadToken(321, 'png,pdf,mp4'), ]); $contentType = strval($response->getHeader('Content-Type')); $content = strval($response->getContent()); $this->assertStringContainsString('application/x-javascript', $contentType); $this->assertStringContainsString('"png":"image\/png"', $content); $this->assertStringContainsString('"mp4":"video\/mp4"', $content); $this->assertStringNotContainsString('"jpg":"image\/jpeg"', $content); $this->assertStringNotContainsString('"pdf":"application\/pdf"', $content); $this->assertStringContainsString("indexOf('date') > -1", $content); } public function testDoneMarksOwnedFileAsUploaded(): void { $file = $this->createSystemFileFixture([ 'uuid' => 9101, 'status' => 1, 'hash' => 'upload-hash-owned', ]); $result = $this->callActionController('done', [ 'id' => $file->getAttr('id'), 'hash' => 'upload-hash-owned', ], 9101); $file = $file->refresh(); $this->assertSame(200, intval($result['code'] ?? 0)); $this->assertStringContainsString('文件记录状态更新成功!', $result['info'] ?? ''); $this->assertSame(2, intval($file->getAttr('status'))); } public function testDoneRejectsFileFromAnotherAdminUser(): void { $file = $this->createSystemFileFixture([ 'uuid' => 9201, 'status' => 1, 'hash' => 'upload-hash-foreign', ]); $result = $this->callActionController('done', [ 'id' => $file->getAttr('id'), 'hash' => 'upload-hash-foreign', ], 9101); $file = $file->refresh(); $this->assertSame(500, intval($result['code'] ?? 1)); $this->assertStringContainsString('文件记录不存在!', $result['info'] ?? ''); $this->assertSame(1, intval($file->getAttr('status'))); } protected function defineSchema(): void { $this->createSystemFileTable(); } protected function afterSchemaCreated(): void { $context = new PluginSystemContext(); Container::getInstance()->instance(SystemContextInterface::class, $context); $this->app->instance(SystemContextInterface::class, $context); $this->configureView(); } private function callIndexController(array $query = []) { $request = (new Request()) ->withGet($query) ->withServer(['HTTPS' => 'on']) ->setHost('admin.example.com') ->setMethod('GET') ->setController('upload') ->setAction('index'); $this->setRequestPayload($request, $query); $this->app->instance('request', $request); $controller = new UploadController($this->app); return $controller->index(); } private function callHtmlController(string $action, array $query = [], int $userId = 9101): string { $request = (new Request()) ->withGet($query) ->withPost($query) ->setMethod('GET') ->setController('upload') ->setAction($action); $this->bindAdminUser($userId); $this->setRequestPayload($request, $query); $this->app->instance('request', $request); try { $controller = new UploadController($this->app); $controller->{$action}(); self::fail("Expected UploadController::{$action} to throw HttpResponseException."); } catch (HttpResponseException $exception) { return strval($exception->getResponse()->getContent()); } } private function callActionController(string $action, array $payload, int $userId): array { $request = (new Request()) ->withGet($payload) ->withPost($payload) ->setMethod('POST') ->setController('upload') ->setAction($action); $this->bindAdminUser($userId); $this->setRequestPayload($request, $payload); $this->app->instance('request', $request); try { $controller = new UploadController($this->app); $controller->{$action}(); self::fail("Expected UploadController::{$action} to throw HttpResponseException."); } catch (HttpResponseException $exception) { return json_decode($exception->getResponse()->getContent(), true) ?: []; } } private function bindAdminUser(int $userId): void { RequestContext::instance()->setAuth([ 'id' => $userId, 'username' => "admin-{$userId}", 'password' => $this->hashSystemPassword('changed-password'), ], '', true); } private function setRequestPayload(Request $request, array $data): void { $property = new \ReflectionProperty(Request::class, 'request'); $property->setAccessible(true); $property->setValue($request, $data); } }