/module/ExCodeception/src/Connector/ZF3.php

https://github.com/bupy7/zf-app-blank · PHP · 183 lines · 135 code · 22 blank · 26 comment · 9 complexity · 3751a939168f453324519768d030115c MD5 · raw file

  1. <?php
  2. namespace ExCodeception\Connector;
  3. use Exception;
  4. use PHPUnit_Framework_AssertionFailedError;
  5. use Symfony\Component\BrowserKit\Client;
  6. use Symfony\Component\BrowserKit\Request;
  7. use Symfony\Component\BrowserKit\Request as BrowserKitRequest;
  8. use Symfony\Component\BrowserKit\Response;
  9. use Zend\Http\Headers as HttpHeaders;
  10. use Zend\Http\Request as HttpRequest;
  11. use Zend\Mvc\Application;
  12. use Zend\Stdlib\Parameters;
  13. use Zend\Uri\Http as HttpUri;
  14. use PHPUnit_Framework_Exception;
  15. class ZF3 extends Client
  16. {
  17. /**
  18. * @var array
  19. */
  20. protected $appConfig;
  21. /**
  22. * @var Application
  23. */
  24. protected $app;
  25. /**
  26. * @var array
  27. */
  28. protected $authData;
  29. public function setAuthData(array $authData): void
  30. {
  31. $this->authData = $authData;
  32. }
  33. public function setAppConfig(array $appConfig): void
  34. {
  35. $this->appConfig = $appConfig;
  36. }
  37. /**
  38. * @param Request $request
  39. *
  40. * @return Response
  41. * @throws Exception
  42. */
  43. public function doRequest($request): Response
  44. {
  45. $this->destroyApp();
  46. /** @var \Zend\Http\PhpEnvironment\Request $zendRequest */
  47. $zendRequest = $this->getApp()->getRequest();
  48. $uri = new HttpUri($request->getUri());
  49. $queryString = $uri->getQuery();
  50. $query = [];
  51. if ($queryString) {
  52. parse_str($queryString, $query);
  53. }
  54. $post = [];
  55. $method = strtoupper($request->getMethod());
  56. if ($method !== HttpRequest::METHOD_GET) {
  57. $post = $request->getParameters();
  58. }
  59. $zendRequest->setQuery(new Parameters($query));
  60. $zendRequest->setPost(new Parameters($post));
  61. $zendRequest->setFiles(new Parameters($request->getFiles()));
  62. $zendRequest->setCookies(new Parameters($request->getCookies()));
  63. $zendRequest->setContent($request->getContent());
  64. $zendRequest->setMethod($method);
  65. $zendRequest->setUri($uri);
  66. $requestUri = $uri->getPath();
  67. if (!empty($queryString)) {
  68. $requestUri .= '?' . $queryString;
  69. }
  70. $zendRequest->setRequestUri($requestUri);
  71. $zendRequest->getHeaders()->addHeaders($this->extractHeaders($request));
  72. $this->getApp()->run();
  73. /** @var \Zend\Http\PhpEnvironment\Response $zendResponse */
  74. $zendResponse = $this->getApp()->getResponse();
  75. $exception = $this->getApp()->getMvcEvent()->getParam('exception');
  76. if ($exception instanceof Exception) {
  77. throw $exception;
  78. }
  79. $response = new Response(
  80. $zendResponse->getBody(),
  81. $zendResponse->getStatusCode(),
  82. $zendResponse->getHeaders()->toArray()
  83. );
  84. return $response;
  85. }
  86. /**
  87. * @param string $service
  88. * @return mixed
  89. */
  90. public function grabService(string $service)
  91. {
  92. $serviceManager = $this->getApp()->getServiceManager();
  93. if (!$serviceManager->has($service)) {
  94. throw new PHPUnit_Framework_AssertionFailedError("Service {$service} is not available in container");
  95. }
  96. return $serviceManager->get($service);
  97. }
  98. /**
  99. * @param string $name
  100. * @param array|object $service
  101. */
  102. public function addService(string $name, $service): void
  103. {
  104. $sm = $this->getApp()->getServiceManager();
  105. $sm->setAllowOverride(true);
  106. $sm->setService($name, $service);
  107. $sm->setAllowOverride(false);
  108. }
  109. public function getApp(): Application
  110. {
  111. if ($this->app === null) {
  112. $this->createApp();
  113. }
  114. return $this->app;
  115. }
  116. public function createApp(): void
  117. {
  118. $this->app = Application::init($this->appConfig);
  119. $sendResponseListener = $this->app->getServiceManager()->get('SendResponseListener');
  120. $events = $this->app->getEventManager();
  121. $events->detach([$sendResponseListener, 'sendResponse']);
  122. $this->authentication();
  123. }
  124. public function authentication(): void
  125. {
  126. if (empty($this->authData)) {
  127. return;
  128. }
  129. /** @var \Zend\Authentication\AuthenticationService $auth */
  130. $auth = $this->grabService('Zend\Authentication\AuthenticationService');
  131. $auth->clearIdentity();
  132. $auth->getAdapter()
  133. ->setIdentity($this->authData['identity'])
  134. ->setCredential($this->authData['credential']);
  135. $result = $auth->authenticate();
  136. if (!$result->isValid()) {
  137. throw new PHPUnit_Framework_Exception(sprintf('User "%s" is not authorized', $this->authData['identity']));
  138. }
  139. }
  140. protected function destroyApp(): void
  141. {
  142. $this->app = null;
  143. }
  144. private function extractHeaders(BrowserKitRequest $request): HttpHeaders
  145. {
  146. $headers = [];
  147. $server = $request->getServer();
  148. $contentHeaders = ['Content-Length' => true, 'Content-Md5' => true, 'Content-Type' => true];
  149. foreach ($server as $header => $val) {
  150. $header = implode('-', array_map('ucfirst', explode('-', strtolower(str_replace('_', '-', $header)))));
  151. if (strpos($header, 'Http-') === 0) {
  152. $headers[substr($header, 5)] = $val;
  153. } elseif (isset($contentHeaders[$header])) {
  154. $headers[$header] = $val;
  155. }
  156. }
  157. $zendHeaders = new HttpHeaders();
  158. $zendHeaders->addHeaders($headers);
  159. return $zendHeaders;
  160. }
  161. }