Completed
Pull Request — master (#3)
by Jonathan
05:00
created

VcrHandler::decodeResponses()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
crap 1
1
<?php
2
namespace Dshafik\GuzzleHttp;
3
4
/**
5
 * guzzlehttp-vcr middleware
6
 *
7
 * Records and automatically replays responses on subsequent requests
8
 * for unit testing
9
 * 
10
 * @package Dshafik\GuzzleHttp
11
 */
12
class VcrHandler
13
{
14
    /**
15
     * @var string
16
     */
17
    protected $cassette;
18
19
    /**
20
     * @param string $cassette fixture path 
21
     * @return \GuzzleHttp\HandlerStack
22
     */
23 5
    public static function turnOn($cassette)
24
    {
25 5
        if (!file_exists($cassette)) {
26 4
            $handler = \GuzzleHttp\HandlerStack::create();
27 4
            $handler->after('allow_redirects', new static($cassette), 'vcr_recorder');
28 4
            return $handler;
29
        } else {
30 5
            $responses = self::decodeResponses($cassette);
31
32 5
            $queue = [];
33 5
            $class = new \ReflectionClass(\GuzzleHttp\Psr7\Response::class);
34 5
            foreach ($responses as $response) {
35 5
                $queue[] = $class->newInstanceArgs($response);
36 5
            }
37
38 5
            return \GuzzleHttp\HandlerStack::create(new \GuzzleHttp\Handler\MockHandler($queue));
39
        }
40
    }
41
42
    /**
43
     * Constructor
44
     * 
45
     * @param string $cassette fixture path
46
     */
47 4
    protected function __construct($cassette)
48
    {
49 4
        $this->cassette = $cassette;
50 4
    }
51
52
    /**
53
     * Decodes every responses body from base64
54
     *
55
     * @param $cassette
56
     * @return array
57
     */
58 5
    protected static function decodeResponses($cassette)
59
    {
60 5
        $responses = json_decode(file_get_contents($cassette), true);
61
62
        array_walk($responses, function(&$response){
63 5
            $response['body'] = base64_decode($response['body']);
64 5
        });
65
66 5
        return $responses;
67
    }
68
69
    /**
70
     * Handle the request/response
71
     *
72
     * @param callable $handler
73
     * @return \Closure
74
     */
75 4
    public function __invoke(callable $handler)
76
    {
77
        return function (\Psr\Http\Message\RequestInterface $request, array $config) use ($handler) {
78 4
            return $handler($request, $config)->then(
79
                function (\Psr\Http\Message\ResponseInterface $response) use ($request) {
80 4
                    $responses = [];
81 4
                    if (file_exists($this->cassette)) {
82
                        //No need to base64 decode body of response here.
83 2
                        $responses = json_decode(file_get_contents($this->cassette), true);
84 2
                    }
85 4
                    $cassette = $response->withAddedHeader('X-VCR-Recording', time());
86 4
                    $responses[] = [
87 4
                        'status' =>  $cassette->getStatusCode(),
88 4
                        'headers' => $cassette->getHeaders(),
89 4
                        'body' => base64_encode((string) $cassette->getBody()),
90 4
                        'version' => $cassette->getProtocolVersion(),
91 4
                        'reason' => $cassette->getReasonPhrase()
92 4
                    ];
93
                    
94 4
                    file_put_contents($this->cassette, json_encode($responses, JSON_PRETTY_PRINT));
95 4
                    return $response;
96 4
                },
97
                function (\Exception $reason) {
98
                    return new \GuzzleHttp\Promise\RejectedPromise($reason);
99
                }
100 4
            );
101 4
        };
102
    }
103
}
104