|
| 1 | +<?php |
| 2 | + |
| 3 | +/* |
| 4 | + * This file is part of the Symfony package. |
| 5 | + * |
| 6 | + * (c) Fabien Potencier <fabien@symfony.com> |
| 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 | +namespace Symfony\Bridge\PsrHttpMessage\Tests\Functional; |
| 13 | + |
| 14 | +use Nyholm\Psr7\Factory\Psr17Factory; |
| 15 | +use Nyholm\Psr7\Response as Psr7Response; |
| 16 | +use Nyholm\Psr7\ServerRequest as Psr7Request; |
| 17 | +use Nyholm\Psr7\Stream as Psr7Stream; |
| 18 | +use PHPUnit\Framework\TestCase; |
| 19 | +use Psr\Http\Message\ResponseInterface; |
| 20 | +use Psr\Http\Message\ServerRequestInterface; |
| 21 | +use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory; |
| 22 | +use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; |
| 23 | +use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface; |
| 24 | +use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; |
| 25 | +use Symfony\Component\HttpFoundation\Cookie; |
| 26 | +use Symfony\Component\HttpFoundation\File\UploadedFile; |
| 27 | +use Symfony\Component\HttpFoundation\Request; |
| 28 | +use Symfony\Component\HttpFoundation\Response; |
| 29 | + |
| 30 | +/** |
| 31 | + * Test to convert a request/response back and forth to make sure we do not loose data. |
| 32 | + * |
| 33 | + * @author Tobias Nyholm <tobias.nyholm@gmail.com> |
| 34 | + */ |
| 35 | +class CovertTest extends TestCase |
| 36 | +{ |
| 37 | + private $tmpDir; |
| 38 | + |
| 39 | + public function setup() |
| 40 | + { |
| 41 | + if (!class_exists('Nyholm\Psr7\ServerRequest')) { |
| 42 | + $this->markTestSkipped('nyholm/psr7 is not installed.'); |
| 43 | + } |
| 44 | + |
| 45 | + $this->tmpDir = sys_get_temp_dir(); |
| 46 | + } |
| 47 | + |
| 48 | + /** |
| 49 | + * @dataProvider requestProvider |
| 50 | + * |
| 51 | + * @param Request|ServerRequestInterface $request |
| 52 | + * @param HttpFoundationFactoryInterface|HttpMessageFactoryInterface $firstFactory |
| 53 | + * @param HttpFoundationFactoryInterface|HttpMessageFactoryInterface $secondFactory |
| 54 | + */ |
| 55 | + public function testConvertRequestMultipleTimes($request, $firstFactory, $secondFactory) |
| 56 | + { |
| 57 | + $temporaryRequest = $firstFactory->createRequest($request); |
| 58 | + $finalRequest = $secondFactory->createRequest($temporaryRequest); |
| 59 | + |
| 60 | + if ($finalRequest instanceof Request) { |
| 61 | + $this->assertEquals($request->getBasePath(), $finalRequest->getBasePath()); |
| 62 | + $this->assertEquals($request->getBaseUrl(), $finalRequest->getBaseUrl()); |
| 63 | + $this->assertEquals($request->getContent(), $finalRequest->getContent()); |
| 64 | + $this->assertEquals($request->getEncodings(), $finalRequest->getEncodings()); |
| 65 | + $this->assertEquals($request->getETags(), $finalRequest->getETags()); |
| 66 | + $this->assertEquals($request->getHost(), $finalRequest->getHost()); |
| 67 | + $this->assertEquals($request->getHttpHost(), $finalRequest->getHttpHost()); |
| 68 | + $this->assertEquals($request->getMethod(), $finalRequest->getMethod()); |
| 69 | + $this->assertEquals($request->getPassword(), $finalRequest->getPassword()); |
| 70 | + $this->assertEquals($request->getPathInfo(), $finalRequest->getPathInfo()); |
| 71 | + $this->assertEquals($request->getPort(), $finalRequest->getPort()); |
| 72 | + $this->assertEquals($request->getProtocolVersion(), $finalRequest->getProtocolVersion()); |
| 73 | + $this->assertEquals($request->getQueryString(), $finalRequest->getQueryString()); |
| 74 | + $this->assertEquals($request->getRequestUri(), $finalRequest->getRequestUri()); |
| 75 | + $this->assertEquals($request->getScheme(), $finalRequest->getScheme()); |
| 76 | + $this->assertEquals($request->getSchemeAndHttpHost(), $finalRequest->getSchemeAndHttpHost()); |
| 77 | + $this->assertEquals($request->getScriptName(), $finalRequest->getScriptName()); |
| 78 | + $this->assertEquals($request->getUri(), $finalRequest->getUri()); |
| 79 | + $this->assertEquals($request->getUser(), $finalRequest->getUser()); |
| 80 | + $this->assertEquals($request->getUserInfo(), $finalRequest->getUserInfo()); |
| 81 | + } elseif ($finalRequest instanceof ServerRequestInterface) { |
| 82 | + $strToLower = function ($arr) { |
| 83 | + foreach ($arr as $key => $value) { |
| 84 | + yield strtolower($key) => $value; |
| 85 | + } |
| 86 | + }; |
| 87 | + $this->assertEquals($request->getAttributes(), $finalRequest->getAttributes()); |
| 88 | + $this->assertEquals($request->getCookieParams(), $finalRequest->getCookieParams()); |
| 89 | + $this->assertEquals((array) $request->getParsedBody(), (array) $finalRequest->getParsedBody()); |
| 90 | + $this->assertEquals($request->getQueryParams(), $finalRequest->getQueryParams()); |
| 91 | + // PSR7 does not define a "withServerParams" so this is impossible to implement without knowing the PSR7 implementation. |
| 92 | + //$this->assertEquals($request->getServerParams(), $finalRequest->getServerParams()); |
| 93 | + $this->assertEquals($request->getUploadedFiles(), $finalRequest->getUploadedFiles()); |
| 94 | + $this->assertEquals($request->getMethod(), $finalRequest->getMethod()); |
| 95 | + $this->assertEquals($request->getRequestTarget(), $finalRequest->getRequestTarget()); |
| 96 | + $this->assertEquals((string) $request->getUri(), (string) $finalRequest->getUri()); |
| 97 | + $this->assertEquals((string) $request->getBody(), (string) $finalRequest->getBody()); |
| 98 | + $this->assertEquals($strToLower($request->getHeaders()), $strToLower($finalRequest->getHeaders())); |
| 99 | + $this->assertEquals($request->getProtocolVersion(), $finalRequest->getProtocolVersion()); |
| 100 | + } else { |
| 101 | + $this->fail('$finalRequest must be an instance of PSR7 or a HTTPFoundation request'); |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + public function requestProvider() |
| 106 | + { |
| 107 | + $sfRequest = new Request( |
| 108 | + [ |
| 109 | + 'foo' => '1', |
| 110 | + 'bar' => ['baz' => '42'], |
| 111 | + ], |
| 112 | + [ |
| 113 | + 'twitter' => [ |
| 114 | + '@dunglas' => 'Kévin Dunglas', |
| 115 | + '@coopTilleuls' => 'Les-Tilleuls.coop', |
| 116 | + ], |
| 117 | + 'baz' => '2', |
| 118 | + ], |
| 119 | + [ |
| 120 | + 'a2' => ['foo' => 'bar'], |
| 121 | + ], |
| 122 | + [ |
| 123 | + 'c1' => 'foo', |
| 124 | + 'c2' => ['c3' => 'bar'], |
| 125 | + ], |
| 126 | + [ |
| 127 | + 'f1' => $this->createUploadedFile('F1', 'f1.txt', 'text/plain', UPLOAD_ERR_OK), |
| 128 | + 'foo' => ['f2' => $this->createUploadedFile('F2', 'f2.txt', 'text/plain', UPLOAD_ERR_OK)], |
| 129 | + ], |
| 130 | + [ |
| 131 | + 'REQUEST_METHOD' => 'POST', |
| 132 | + 'HTTP_HOST' => 'dunglas.fr', |
| 133 | + 'SERVER_NAME' => 'dunglas.fr', |
| 134 | + 'SERVER_PORT' => null, |
| 135 | + 'HTTP_X_SYMFONY' => '2.8', |
| 136 | + 'REQUEST_URI' => '/testCreateRequest?bar[baz]=42&foo=1', |
| 137 | + 'QUERY_STRING' => 'foo=1&bar[baz]=42', |
| 138 | + ], |
| 139 | + 'Content' |
| 140 | + ); |
| 141 | + |
| 142 | + $psr7Request = (new Psr7Request('POST', 'http://tnyholm.se/foo/?bar=biz')) |
| 143 | + ->withQueryParams(['bar' => 'biz']); |
| 144 | + |
| 145 | + $nyholmFactory = new Psr17Factory(); |
| 146 | + $psr17Factory = new PsrHttpFactory($nyholmFactory, $nyholmFactory, $nyholmFactory, $nyholmFactory); |
| 147 | + $symfonyFactory = new HttpFoundationFactory(); |
| 148 | + |
| 149 | + return [ |
| 150 | + [$sfRequest, $psr17Factory, $symfonyFactory], |
| 151 | + [$psr7Request, $symfonyFactory, $psr17Factory], |
| 152 | + ]; |
| 153 | + } |
| 154 | + |
| 155 | + /** |
| 156 | + * @dataProvider responseProvider |
| 157 | + * |
| 158 | + * @param Response|ResponseInterface $response |
| 159 | + * @param HttpFoundationFactoryInterface|HttpMessageFactoryInterface $firstFactory |
| 160 | + * @param HttpFoundationFactoryInterface|HttpMessageFactoryInterface $secondFactory |
| 161 | + */ |
| 162 | + public function testConvertResponseMultipleTimes($response, $firstFactory, $secondFactory) |
| 163 | + { |
| 164 | + $temporaryResponse = $firstFactory->createResponse($response); |
| 165 | + $finalResponse = $secondFactory->createResponse($temporaryResponse); |
| 166 | + |
| 167 | + if ($finalResponse instanceof Response) { |
| 168 | + $this->assertEquals($response->getAge(), $finalResponse->getAge()); |
| 169 | + $this->assertEquals($response->getCharset(), $finalResponse->getCharset()); |
| 170 | + $this->assertEquals($response->getContent(), $finalResponse->getContent()); |
| 171 | + $this->assertEquals($response->getDate(), $finalResponse->getDate()); |
| 172 | + $this->assertEquals($response->getEtag(), $finalResponse->getEtag()); |
| 173 | + $this->assertEquals($response->getExpires(), $finalResponse->getExpires()); |
| 174 | + $this->assertEquals($response->getLastModified(), $finalResponse->getLastModified()); |
| 175 | + $this->assertEquals($response->getMaxAge(), $finalResponse->getMaxAge()); |
| 176 | + $this->assertEquals($response->getProtocolVersion(), $finalResponse->getProtocolVersion()); |
| 177 | + $this->assertEquals($response->getStatusCode(), $finalResponse->getStatusCode()); |
| 178 | + $this->assertEquals($response->getTtl(), $finalResponse->getTtl()); |
| 179 | + } elseif ($finalResponse instanceof ResponseInterface) { |
| 180 | + $strToLower = function ($arr) { |
| 181 | + foreach ($arr as $key => $value) { |
| 182 | + yield strtolower($key) => $value; |
| 183 | + } |
| 184 | + }; |
| 185 | + $this->assertEquals($response->getStatusCode(), $finalResponse->getStatusCode()); |
| 186 | + $this->assertEquals($response->getReasonPhrase(), $finalResponse->getReasonPhrase()); |
| 187 | + $this->assertEquals((string) $response->getBody(), (string) $finalResponse->getBody()); |
| 188 | + $this->assertEquals($strToLower($response->getHeaders()), $strToLower($finalResponse->getHeaders())); |
| 189 | + $this->assertEquals($response->getProtocolVersion(), $finalResponse->getProtocolVersion()); |
| 190 | + } else { |
| 191 | + $this->fail('$finalResponse must be an instance of PSR7 or a HTTPFoundation response'); |
| 192 | + } |
| 193 | + } |
| 194 | + |
| 195 | + public function responseProvider() |
| 196 | + { |
| 197 | + $sfResponse = new Response( |
| 198 | + 'Response content.', |
| 199 | + 202, |
| 200 | + ['x-symfony' => ['3.4']] |
| 201 | + ); |
| 202 | + |
| 203 | + if (method_exists(Cookie::class, 'create')) { |
| 204 | + $cookie = Cookie::create('city', 'Lille', new \DateTime('Wed, 13 Jan 2021 22:23:01 GMT')); |
| 205 | + } else { |
| 206 | + $cookie = new Cookie('city', 'Lille', new \DateTime('Wed, 13 Jan 2021 22:23:01 GMT')); |
| 207 | + } |
| 208 | + |
| 209 | + $sfResponse->headers->setCookie($cookie); |
| 210 | + $body = Psr7Stream::create(); |
| 211 | + $status = 302; |
| 212 | + $headers = [ |
| 213 | + 'location' => ['http://example.com/'], |
| 214 | + ]; |
| 215 | + $zendResponse = new Psr7Response($status, $headers, $body); |
| 216 | + |
| 217 | + $nyholmFactory = new Psr17Factory(); |
| 218 | + $psr17Factory = new PsrHttpFactory($nyholmFactory, $nyholmFactory, $nyholmFactory, $nyholmFactory); |
| 219 | + $symfonyFactory = new HttpFoundationFactory(); |
| 220 | + |
| 221 | + return [ |
| 222 | + [$sfResponse, $psr17Factory, $symfonyFactory], |
| 223 | + [$zendResponse, $symfonyFactory, $psr17Factory], |
| 224 | + ]; |
| 225 | + } |
| 226 | + |
| 227 | + private function createUploadedFile($content, $originalName, $mimeType, $error) |
| 228 | + { |
| 229 | + $path = tempnam($this->tmpDir, uniqid()); |
| 230 | + file_put_contents($path, $content); |
| 231 | + |
| 232 | + if (class_exists('Symfony\Component\HttpFoundation\HeaderUtils')) { |
| 233 | + // Symfony 4.1+ |
| 234 | + return new UploadedFile($path, $originalName, $mimeType, $error, true); |
| 235 | + } |
| 236 | + |
| 237 | + return new UploadedFile($path, $originalName, $mimeType, filesize($path), $error, true); |
| 238 | + } |
| 239 | +} |
0 commit comments