98 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /*
 | |
|  * This file is part of the Symfony package.
 | |
|  *
 | |
|  * (c) Fabien Potencier <fabien@symfony.com>
 | |
|  *
 | |
|  * For the full copyright and license information, please view the LICENSE
 | |
|  * file that was distributed with this source code.
 | |
|  */
 | |
| 
 | |
| namespace Symfony\Component\HttpClient\Test;
 | |
| 
 | |
| use Symfony\Component\HttpClient\Exception\TransportException;
 | |
| use Symfony\Component\HttpClient\Response\MockResponse;
 | |
| use Symfony\Contracts\HttpClient\ResponseInterface;
 | |
| 
 | |
| /**
 | |
|  * See: https://w3c.github.io/web-performance/specs/HAR/Overview.html.
 | |
|  *
 | |
|  * @author Gary PEGEOT <garypegeot@gmail.com>
 | |
|  */
 | |
| class HarFileResponseFactory
 | |
| {
 | |
|     public function __construct(private string $archiveFile)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     public function setArchiveFile(string $archiveFile): void
 | |
|     {
 | |
|         $this->archiveFile = $archiveFile;
 | |
|     }
 | |
| 
 | |
|     public function __invoke(string $method, string $url, array $options): ResponseInterface
 | |
|     {
 | |
|         if (!is_file($this->archiveFile)) {
 | |
|             throw new \InvalidArgumentException(sprintf('Invalid file path provided: "%s".', $this->archiveFile));
 | |
|         }
 | |
| 
 | |
|         $json = json_decode(json: file_get_contents($this->archiveFile), associative: true, flags: \JSON_THROW_ON_ERROR);
 | |
| 
 | |
|         foreach ($json['log']['entries'] as $entry) {
 | |
|             /**
 | |
|              * @var array{status: int, headers: array, content: array}  $response
 | |
|              * @var array{method: string, url: string, postData: array} $request
 | |
|              */
 | |
|             ['response' => $response, 'request' => $request, 'startedDateTime' => $startedDateTime] = $entry;
 | |
| 
 | |
|             $body = $this->getContent($response['content']);
 | |
|             $entryMethod = $request['method'];
 | |
|             $entryUrl = $request['url'];
 | |
|             $requestBody = $options['body'] ?? null;
 | |
| 
 | |
|             if ($method !== $entryMethod || $url !== $entryUrl) {
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             if (null !== $requestBody && $requestBody !== $this->getContent($request['postData'] ?? [])) {
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             $info = [
 | |
|                 'http_code' => $response['status'],
 | |
|                 'http_method' => $entryMethod,
 | |
|                 'response_headers' => [],
 | |
|                 'start_time' => strtotime($startedDateTime),
 | |
|                 'url' => $entryUrl,
 | |
|             ];
 | |
| 
 | |
|             /** @var array{name: string, value: string} $header */
 | |
|             foreach ($response['headers'] as $header) {
 | |
|                 ['name' => $name, 'value' => $value] = $header;
 | |
| 
 | |
|                 $info['response_headers'][$name][] = $value;
 | |
|             }
 | |
| 
 | |
|             return new MockResponse($body, $info);
 | |
|         }
 | |
| 
 | |
|         throw new TransportException(sprintf('File "%s" does not contain a response for HTTP request "%s" "%s".', $this->archiveFile, $method, $url));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @param array{text: string, encoding: string} $content
 | |
|      */
 | |
|     private function getContent(array $content): string
 | |
|     {
 | |
|         $text = $content['text'] ?? '';
 | |
|         $encoding = $content['encoding'] ?? null;
 | |
| 
 | |
|         return match ($encoding) {
 | |
|             'base64' => base64_decode($text),
 | |
|             null => $text,
 | |
|             default => throw new \InvalidArgumentException(sprintf('Unsupported encoding "%s", currently only base64 is supported.', $encoding)),
 | |
|         };
 | |
|     }
 | |
| }
 |