1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the doyo/behat-coverage-extension project. |
||
5 | * |
||
6 | * (c) Anthonius Munthi <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | declare(strict_types=1); |
||
13 | |||
14 | namespace Doyo\Behat\Coverage\Listener; |
||
15 | |||
16 | use Doyo\Behat\Coverage\Bridge\CodeCoverage\Exception\SessionException; |
||
17 | use Doyo\Behat\Coverage\Bridge\CodeCoverage\Session\RemoteSession; |
||
18 | use Doyo\Behat\Coverage\Bridge\CodeCoverage\Session\SessionInterface; |
||
19 | use Doyo\Behat\Coverage\Event\CoverageEvent; |
||
20 | use GuzzleHttp\Client; |
||
21 | use GuzzleHttp\ClientInterface; |
||
22 | use GuzzleHttp\Exception\GuzzleException; |
||
23 | use GuzzleHttp\Exception\RequestException; |
||
24 | use Psr\Http\Message\ResponseInterface; |
||
25 | use spec\Doyo\Behat\Coverage\Listener\AbstractSessionCoverageListener; |
||
26 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
||
27 | use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface; |
||
28 | use Symfony\Component\HttpFoundation\Response; |
||
29 | |||
30 | class RemoteCoverageListener extends AbstractSessionCoverageListener implements EventSubscriberInterface |
||
31 | { |
||
32 | /** |
||
33 | * @var \Behat\Mink\Mink |
||
34 | */ |
||
35 | private $mink; |
||
36 | |||
37 | /** |
||
38 | * @var ClientInterface |
||
39 | */ |
||
40 | private $httpClient; |
||
41 | |||
42 | private $minkSessionName; |
||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
43 | |||
44 | private $remoteUrl; |
||
45 | |||
46 | /** |
||
47 | * @var bool |
||
48 | */ |
||
49 | private $initialized = false; |
||
50 | |||
51 | /** |
||
52 | * @var SessionException |
||
53 | */ |
||
54 | private $refreshException; |
||
55 | |||
56 | 5 | public static function getSubscribedEvents() |
|
57 | { |
||
58 | return [ |
||
59 | 5 | CoverageEvent::BEFORE_START => 'beforeCoverageStart', |
|
60 | CoverageEvent::REFRESH => 'coverageRefresh', |
||
61 | CoverageEvent::COMPLETED => 'coverageCompleted', |
||
62 | ]; |
||
63 | } |
||
64 | |||
65 | 5 | public function setMink($mink) |
|
66 | { |
||
67 | 5 | $this->mink = $mink; |
|
68 | } |
||
69 | |||
70 | 12 | public function setRemoteUrl($url) |
|
71 | { |
||
72 | 12 | $this->remoteUrl = $url; |
|
73 | } |
||
74 | |||
75 | 12 | public function setHttpClient(ClientInterface $httpClient) |
|
76 | { |
||
77 | 12 | $this->httpClient = $httpClient; |
|
78 | } |
||
79 | |||
80 | 9 | public function coverageRefresh() |
|
81 | { |
||
82 | 9 | $client = $this->httpClient; |
|
83 | 9 | $session = $this->session; |
|
84 | 9 | $processor = $session->getProcessor(); |
|
85 | 9 | $filter = $processor->getCodeCoverageFilter(); |
|
86 | 9 | $coverageOptions = $processor->getCodeCoverageOptions(); |
|
87 | 9 | $url = $this->remoteUrl; |
|
88 | |||
89 | $data = [ |
||
90 | 'filterOptions' => [ |
||
91 | 9 | 'whitelistedFiles' => $filter->getWhitelistedFiles(), |
|
92 | ], |
||
93 | 9 | 'codeCoverageOptions' => $coverageOptions, |
|
94 | ]; |
||
95 | 9 | $body = json_encode($data); |
|
96 | $options = [ |
||
97 | 9 | 'body' => $body, |
|
98 | 'query' => [ |
||
99 | 9 | 'action' => 'init', |
|
100 | 9 | 'session' => $this->session->getName(), |
|
101 | ], |
||
102 | ]; |
||
103 | |||
104 | try { |
||
105 | 9 | $this->initialized = false; |
|
106 | 9 | $client->request('POST', $url, $options); |
|
107 | 8 | $this->initialized = true; |
|
108 | 1 | } catch (\Exception $e) { |
|
109 | 1 | $message = $this->getExceptionMessage($e); |
|
110 | 1 | $this->initialized = false; |
|
111 | 1 | $this->refreshException = new SessionException($message); |
|
112 | } |
||
113 | } |
||
114 | |||
115 | 4 | public function beforeCoverageStart(CoverageEvent $event) |
|
116 | { |
||
117 | 4 | if($this->initialized){ |
|
118 | 4 | $this->doBeforeCoverageStart($event); |
|
119 | } |
||
120 | } |
||
121 | |||
122 | 6 | public function coverageCompleted(CoverageEvent $event) |
|
123 | { |
||
124 | 6 | if($this->initialized){ |
|
125 | 6 | $this->doCoverageComplete($event); |
|
126 | } |
||
127 | } |
||
128 | |||
129 | 4 | private function doBeforeCoverageStart(CoverageEvent $event) |
|
130 | { |
||
131 | 4 | $sessionName = $this->session->getName(); |
|
132 | 4 | $testCaseName = $event->getTestCase()->getName(); |
|
133 | |||
134 | 4 | $mink = $this->mink; |
|
135 | |||
136 | /** @var \Behat\Mink\Driver\Goutte\Client $client */ |
||
137 | 4 | $driver = $mink->getSession()->getDriver(); |
|
138 | 4 | $driver->setRequestHeader(RemoteSession::HEADER_SESSION_KEY, $sessionName); |
|
139 | 4 | $driver->setRequestHeader(RemoteSession::HEADER_TEST_CASE_KEY, $testCaseName); |
|
140 | |||
141 | /* patch for browserkit driver */ |
||
142 | 4 | if (method_exists($driver, 'getClient')) { |
|
143 | 4 | $client = $driver->getClient(); |
|
144 | 4 | $client->setServerParameters([ |
|
145 | 4 | RemoteSession::HEADER_SESSION_KEY => $sessionName, |
|
146 | 4 | RemoteSession::HEADER_TEST_CASE_KEY => $testCaseName, |
|
147 | ]); |
||
148 | } |
||
149 | } |
||
150 | |||
151 | 6 | private function doCoverageComplete(CoverageEvent $event) |
|
152 | { |
||
153 | 6 | $session = $this->session; |
|
154 | 6 | $client = $this->httpClient; |
|
155 | 6 | $uri = $this->remoteUrl; |
|
156 | |||
157 | $options = [ |
||
158 | 'query' => [ |
||
159 | 6 | 'action' => 'read', |
|
160 | 6 | 'session' => $session->getName(), |
|
161 | ], |
||
162 | ]; |
||
163 | |||
164 | try { |
||
165 | 6 | $response = $client->request('GET', $uri, $options); |
|
166 | 4 | $data = $response->getBody()->getContents(); |
|
167 | 4 | $session = unserialize($data); |
|
168 | 4 | $processor = $session->getProcessor(); |
|
169 | 4 | $event->getProcessor()->merge($processor); |
|
170 | 2 | } catch (\Exception $exception) { |
|
171 | 2 | $message = $this->getExceptionMessage($exception); |
|
172 | 2 | $event->getConsoleIO()->sessionError($session->getName(), $message); |
|
173 | } |
||
174 | } |
||
175 | |||
176 | 3 | private function getExceptionMessage(\Exception $exception): string |
|
177 | { |
||
178 | 3 | $message = $exception->getMessage(); |
|
179 | |||
180 | 3 | if(!$exception instanceof RequestException){ |
|
181 | 1 | return $message; |
|
182 | } |
||
183 | |||
184 | 2 | $response = $exception->getResponse(); |
|
185 | 2 | if(!$response instanceof ResponseInterface){ |
|
0 ignored issues
–
show
|
|||
186 | return $message; |
||
187 | } |
||
188 | |||
189 | 2 | $contentType = $response->getHeader('Content-Type'); |
|
190 | 2 | if(in_array('application/json',$contentType)){ |
|
191 | 2 | $data = json_decode($response->getBody()->getContents(), true); |
|
192 | 2 | $message = $data['message']; |
|
193 | } |
||
194 | |||
195 | 2 | return $message; |
|
196 | } |
||
197 | } |
||
198 |