aboutsummaryrefslogtreecommitdiffstats
path: root/public/system/storage/vendor/guzzlehttp/guzzle/src/Subscriber/Mock.php
blob: 2af4d3758dd91f13608f697585081016e14cae14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
namespace GuzzleHttp\Subscriber;

use GuzzleHttp\Event\RequestEvents;
use GuzzleHttp\Event\SubscriberInterface;
use GuzzleHttp\Event\BeforeEvent;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Message\MessageFactory;
use GuzzleHttp\Message\ResponseInterface;
use GuzzleHttp\Stream\StreamInterface;

/**
 * Queues mock responses or exceptions and delivers mock responses or
 * exceptions in a fifo order.
 */
class Mock implements SubscriberInterface, \Countable
{
    /** @var array Array of mock responses / exceptions */
    private $queue = [];

    /** @var bool Whether or not to consume an entity body when mocking */
    private $readBodies;

    /** @var MessageFactory */
    private $factory;

    /**
     * @param array $items      Array of responses or exceptions to queue
     * @param bool  $readBodies Set to false to not consume the entity body of
     *                          a request when a mock is served.
     */
    public function __construct(array $items = [], $readBodies = true)
    {
        $this->factory = new MessageFactory();
        $this->readBodies = $readBodies;
        $this->addMultiple($items);
    }

    public function getEvents()
    {
        // Fire the event last, after signing
        return ['before' => ['onBefore', RequestEvents::SIGN_REQUEST - 10]];
    }

    /**
     * @throws \OutOfBoundsException|\Exception
     */
    public function onBefore(BeforeEvent $event)
    {
        if (!$item = array_shift($this->queue)) {
            throw new \OutOfBoundsException('Mock queue is empty');
        } elseif ($item instanceof RequestException) {
            throw $item;
        }

        // Emulate reading a response body
        $request = $event->getRequest();
        if ($this->readBodies && $request->getBody()) {
            while (!$request->getBody()->eof()) {
                $request->getBody()->read(8096);
            }
        }

        $saveTo = $event->getRequest()->getConfig()->get('save_to');

        if (null !== $saveTo) {
            $body = $item->getBody();

            if (is_resource($saveTo)) {
                fwrite($saveTo, $body);
            } elseif (is_string($saveTo)) {
                file_put_contents($saveTo, $body);
            } elseif ($saveTo instanceof StreamInterface) {
                $saveTo->write($body);
            }
        }

        $event->intercept($item);
    }

    public function count()
    {
        return count($this->queue);
    }

    /**
     * Add a response to the end of the queue
     *
     * @param string|ResponseInterface $response Response or path to response file
     *
     * @return self
     * @throws \InvalidArgumentException if a string or Response is not passed
     */
    public function addResponse($response)
    {
        if (is_string($response)) {
            $response = file_exists($response)
                ? $this->factory->fromMessage(file_get_contents($response))
                : $this->factory->fromMessage($response);
        } elseif (!($response instanceof ResponseInterface)) {
            throw new \InvalidArgumentException('Response must a message '
                . 'string, response object, or path to a file');
        }

        $this->queue[] = $response;

        return $this;
    }

    /**
     * Add an exception to the end of the queue
     *
     * @param RequestException $e Exception to throw when the request is executed
     *
     * @return self
     */
    public function addException(RequestException $e)
    {
        $this->queue[] = $e;

        return $this;
    }

    /**
     * Add multiple items to the queue
     *
     * @param array $items Items to add
     */
    public function addMultiple(array $items)
    {
        foreach ($items as $item) {
            if ($item instanceof RequestException) {
                $this->addException($item);
            } else {
                $this->addResponse($item);
            }
        }
    }

    /**
     * Clear the queue
     */
    public function clearQueue()
    {
        $this->queue = [];
    }
}