false); $response = $this->callMiddleware(); $payload = json_decode($response->getContent(), true) ?: []; $this->assertSame(200, $response->getCode()); $this->assertSame(AuthResponse::STATUS_UNAUTHORIZED, intval($payload['code'] ?? 0)); $this->assertSame(AuthResponse::ERROR_UNAUTHORIZED, $payload['error'] ?? ''); $this->assertSame('请重新登录!', $payload['info'] ?? ''); $this->assertNotEmpty($payload['url'] ?? ''); } public function testHandleReturnsForbiddenResponseWhenLoginHasNoPermission(): void { RequestContext::instance()->setAuth([ 'id' => 1, 'username' => 'tester', 'nodes' => [], ], 'system-token', true); AuthService::registerCheckCallable(static fn ($current, $methods, $userNodes): bool => false); $response = $this->callMiddleware(); $payload = json_decode($response->getContent(), true) ?: []; $this->assertSame(200, $response->getCode()); $this->assertSame(AuthResponse::STATUS_FORBIDDEN, intval($payload['code'] ?? 0)); $this->assertSame(AuthResponse::ERROR_FORBIDDEN, $payload['error'] ?? ''); $this->assertSame('禁用访问!', $payload['info'] ?? ''); $this->assertArrayNotHasKey('url', $payload); } public function testHandleUsesRecordedAuthFailureStatus(): void { AuthService::registerCheckCallable(static fn ($current, $methods, $userNodes): bool => false); $response = $this->callMiddleware(function (): void { RequestContext::instance()->clearAuth(true); RequestContext::instance()->setAuthFailure( AuthResponse::STATUS_FORBIDDEN, '账号已经被禁用,请联系管理员!', AuthResponse::ERROR_FORBIDDEN ); }); $payload = json_decode($response->getContent(), true) ?: []; $this->assertSame(200, $response->getCode()); $this->assertSame(AuthResponse::STATUS_FORBIDDEN, intval($payload['code'] ?? 0)); $this->assertSame(AuthResponse::ERROR_FORBIDDEN, $payload['error'] ?? ''); $this->assertSame('账号已经被禁用,请联系管理员!', $payload['info'] ?? ''); $this->assertArrayNotHasKey('url', $payload); } private function callMiddleware(?callable $beforeHandle = null): Response { $request = (new Request()) ->setController('index') ->setAction('index'); $this->activateApplicationContext($request); $this->app->config->set([ 'rbac_ignore' => [], 'rbac_login' => 'system/login/index', ], 'app'); sysvar('think.admin.methods', []); is_callable($beforeHandle) && $beforeHandle(); $middleware = new RbacAccess($this->app); try { return $middleware->handle($request, static fn (Request $current): Response => Response::create($current->pathinfo() ?: 'ok')); } catch (HttpResponseException $exception) { return $exception->getResponse(); } } }