Minor dependency updates
[yaffs-website] / vendor / guzzlehttp / guzzle / src / Handler / MockHandler.php
1 <?php
2 namespace GuzzleHttp\Handler;
3
4 use GuzzleHttp\Exception\RequestException;
5 use GuzzleHttp\HandlerStack;
6 use GuzzleHttp\Promise\PromiseInterface;
7 use GuzzleHttp\Promise\RejectedPromise;
8 use GuzzleHttp\TransferStats;
9 use Psr\Http\Message\RequestInterface;
10 use Psr\Http\Message\ResponseInterface;
11
12 /**
13  * Handler that returns responses or throw exceptions from a queue.
14  */
15 class MockHandler implements \Countable
16 {
17     private $queue = [];
18     private $lastRequest;
19     private $lastOptions;
20     private $onFulfilled;
21     private $onRejected;
22
23     /**
24      * Creates a new MockHandler that uses the default handler stack list of
25      * middlewares.
26      *
27      * @param array $queue Array of responses, callables, or exceptions.
28      * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
29      * @param callable $onRejected  Callback to invoke when the return value is rejected.
30      *
31      * @return HandlerStack
32      */
33     public static function createWithMiddleware(
34         array $queue = null,
35         callable $onFulfilled = null,
36         callable $onRejected = null
37     ) {
38         return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
39     }
40
41     /**
42      * The passed in value must be an array of
43      * {@see Psr7\Http\Message\ResponseInterface} objects, Exceptions,
44      * callables, or Promises.
45      *
46      * @param array $queue
47      * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
48      * @param callable $onRejected  Callback to invoke when the return value is rejected.
49      */
50     public function __construct(
51         array $queue = null,
52         callable $onFulfilled = null,
53         callable $onRejected = null
54     ) {
55         $this->onFulfilled = $onFulfilled;
56         $this->onRejected = $onRejected;
57
58         if ($queue) {
59             call_user_func_array([$this, 'append'], $queue);
60         }
61     }
62
63     public function __invoke(RequestInterface $request, array $options)
64     {
65         if (!$this->queue) {
66             throw new \OutOfBoundsException('Mock queue is empty');
67         }
68
69         if (isset($options['delay'])) {
70             usleep($options['delay'] * 1000);
71         }
72
73         $this->lastRequest = $request;
74         $this->lastOptions = $options;
75         $response = array_shift($this->queue);
76
77         if (isset($options['on_headers'])) {
78             if (!is_callable($options['on_headers'])) {
79                 throw new \InvalidArgumentException('on_headers must be callable');
80             }
81             try {
82                 $options['on_headers']($response);
83             } catch (\Exception $e) {
84                 $msg = 'An error was encountered during the on_headers event';
85                 $response = new RequestException($msg, $request, $response, $e);
86             }
87         }
88
89         if (is_callable($response)) {
90             $response = call_user_func($response, $request, $options);
91         }
92
93         $response = $response instanceof \Exception
94             ? \GuzzleHttp\Promise\rejection_for($response)
95             : \GuzzleHttp\Promise\promise_for($response);
96
97         return $response->then(
98             function ($value) use ($request, $options) {
99                 $this->invokeStats($request, $options, $value);
100                 if ($this->onFulfilled) {
101                     call_user_func($this->onFulfilled, $value);
102                 }
103                 if (isset($options['sink'])) {
104                     $contents = (string) $value->getBody();
105                     $sink = $options['sink'];
106
107                     if (is_resource($sink)) {
108                         fwrite($sink, $contents);
109                     } elseif (is_string($sink)) {
110                         file_put_contents($sink, $contents);
111                     } elseif ($sink instanceof \Psr\Http\Message\StreamInterface) {
112                         $sink->write($contents);
113                     }
114                 }
115
116                 return $value;
117             },
118             function ($reason) use ($request, $options) {
119                 $this->invokeStats($request, $options, null, $reason);
120                 if ($this->onRejected) {
121                     call_user_func($this->onRejected, $reason);
122                 }
123                 return \GuzzleHttp\Promise\rejection_for($reason);
124             }
125         );
126     }
127
128     /**
129      * Adds one or more variadic requests, exceptions, callables, or promises
130      * to the queue.
131      */
132     public function append()
133     {
134         foreach (func_get_args() as $value) {
135             if ($value instanceof ResponseInterface
136                 || $value instanceof \Exception
137                 || $value instanceof PromiseInterface
138                 || is_callable($value)
139             ) {
140                 $this->queue[] = $value;
141             } else {
142                 throw new \InvalidArgumentException('Expected a response or '
143                     . 'exception. Found ' . \GuzzleHttp\describe_type($value));
144             }
145         }
146     }
147
148     /**
149      * Get the last received request.
150      *
151      * @return RequestInterface
152      */
153     public function getLastRequest()
154     {
155         return $this->lastRequest;
156     }
157
158     /**
159      * Get the last received request options.
160      *
161      * @return array
162      */
163     public function getLastOptions()
164     {
165         return $this->lastOptions;
166     }
167
168     /**
169      * Returns the number of remaining items in the queue.
170      *
171      * @return int
172      */
173     public function count()
174     {
175         return count($this->queue);
176     }
177
178     private function invokeStats(
179         RequestInterface $request,
180         array $options,
181         ResponseInterface $response = null,
182         $reason = null
183     ) {
184         if (isset($options['on_stats'])) {
185             $stats = new TransferStats($request, $response, 0, $reason);
186             call_user_func($options['on_stats'], $stats);
187         }
188     }
189 }