private function decorateWithMiddlewares(\Closure $rawControllerClosure, MiddlewareManager $middlewareManager) : \Closure { $controllerClosureWithMiddlewares = function (ServerRequestInterface $request, ResponseInterface $response) use($rawControllerClosure, $middlewareManager) : ResponseInterface { $originalRequestAndResponse = new RequestAndResponse($request, $response); $postMiddlewareRequestAndResponse = $middlewareManager->applyBeforeMiddlewares($originalRequestAndResponse); $controllerResponse = $rawControllerClosure($postMiddlewareRequestAndResponse->request(), $postMiddlewareRequestAndResponse->response()); $finalResponse = $middlewareManager->applyAfterMiddlewares($controllerResponse); return $finalResponse; }; return $controllerClosureWithMiddlewares; }
function it_can_build_a_controller_closure(ServerRequestInterface $initialRequest, ResponseInterface $initialResponse, RequestAndResponse $requestAndResponseBeforeUserController, ServerRequestInterface $requestPassedToUserController, ResponseInterface $responsePassedToUserController, ResponseInterface $responseReturnedByUserController, ResponseInterface $finalResponse, MiddlewareManager $middlewareManager, ContainerInterface $container, Route $route, ControllerClosureBuilder $thingBeingDecorated) { // ARRANGE $middlewareManager->applyBeforeMiddlewares(Argument::type('\\Sainsburys\\HttpService\\Components\\Middlewares\\Http\\RequestAndResponse'))->willReturn($requestAndResponseBeforeUserController); $requestAndResponseBeforeUserController->request()->willReturn($requestPassedToUserController); $requestAndResponseBeforeUserController->response()->willReturn($responsePassedToUserController); $controllerClosureBeingDecorated = function ($requestPassedIn, $responsePassedIn) use($responseReturnedByUserController) { return new JsonResponse([]); }; $middlewareManager->applyAfterMiddlewares(Argument::any())->willReturn($finalResponse); $thingBeingDecorated->buildControllerClosure($container, $route)->willReturn($controllerClosureBeingDecorated); // ACT $decoratedClosure = $this->buildControllerClosure($container, $route); $result = $decoratedClosure($initialRequest, $initialResponse); // ASSERT $result->shouldBe($finalResponse); }