summaryrefslogtreecommitdiff
path: root/vendor/guzzle/guzzle/tests/Guzzle/Tests/GuzzleTestCase.php
blob: d89c5f0a28ac6d0847d8cec81a5bf0880b4a23b1 (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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
<?php

namespace Guzzle\Tests;

use Guzzle\Common\HasDispatcherInterface;
use Guzzle\Common\Event;
use Guzzle\Http\Message\Response;
use Guzzle\Http\Message\RequestInterface;
use Guzzle\Tests\Http\Message\HeaderComparison;
use Guzzle\Plugin\Mock\MockPlugin;
use Guzzle\Http\Client;
use Guzzle\Service\Builder\ServiceBuilderInterface;
use Guzzle\Service\Builder\ServiceBuilder;
use Guzzle\Tests\Mock\MockObserver;
use Guzzle\Tests\Http\Server;
use RuntimeException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Base testcase class for all Guzzle testcases.
 */
abstract class GuzzleTestCase extends \PHPUnit_Framework_TestCase
{
    protected static $mockBasePath;
    public static $serviceBuilder;
    public static $server;

    private $requests = array();
    public $mockObserver;

    /**
     * Get the global server object used throughout the unit tests of Guzzle
     *
     * @return Server
     */
    public static function getServer()
    {
        if (!self::$server) {
            self::$server = new Server();
            if (self::$server->isRunning()) {
                self::$server->flush();
            } else {
                self::$server->start();
            }
        }

        return self::$server;
    }

    /**
     * Set the service builder to use for tests
     *
     * @param ServiceBuilderInterface $builder Service builder
     */
    public static function setServiceBuilder(ServiceBuilderInterface $builder)
    {
        self::$serviceBuilder = $builder;
    }

    /**
     * Get a service builder object that can be used throughout the service tests
     *
     * @return ServiceBuilder
     */
    public static function getServiceBuilder()
    {
        if (!self::$serviceBuilder) {
            throw new RuntimeException('No service builder has been set via setServiceBuilder()');
        }

        return self::$serviceBuilder;
    }

    /**
     * Check if an event dispatcher has a subscriber
     *
     * @param HasDispatcherInterface $dispatcher
     * @param EventSubscriberInterface $subscriber
     *
     * @return bool
     */
    protected function hasSubscriber(HasDispatcherInterface $dispatcher, EventSubscriberInterface $subscriber)
    {
        $class = get_class($subscriber);
        $all = array_keys(call_user_func(array($class, 'getSubscribedEvents')));

        foreach ($all as $i => $event) {
            foreach ($dispatcher->getEventDispatcher()->getListeners($event) as $e) {
                if ($e[0] === $subscriber) {
                    unset($all[$i]);
                    break;
                }
            }
        }

        return count($all) == 0;
    }

    /**
     * Get a wildcard observer for an event dispatcher
     *
     * @param HasDispatcherInterface $hasDispatcher
     *
     * @return MockObserver
     */
    public function getWildcardObserver(HasDispatcherInterface $hasDispatcher)
    {
        $class = get_class($hasDispatcher);
        $o = new MockObserver();
        $events = call_user_func(array($class, 'getAllEvents'));
        foreach ($events as $event) {
            $hasDispatcher->getEventDispatcher()->addListener($event, array($o, 'update'));
        }

        return $o;
    }

    /**
     * Set the mock response base path
     *
     * @param string $path Path to mock response folder
     *
     * @return GuzzleTestCase
     */
    public static function setMockBasePath($path)
    {
        self::$mockBasePath = $path;
    }

    /**
     * Mark a request as being mocked
     *
     * @param RequestInterface $request
     *
     * @return self
     */
    public function addMockedRequest(RequestInterface $request)
    {
        $this->requests[] = $request;

        return $this;
    }

    /**
     * Get all of the mocked requests
     *
     * @return array
     */
    public function getMockedRequests()
    {
        return $this->requests;
    }

    /**
     * Get a mock response for a client by mock file name
     *
     * @param string $path Relative path to the mock response file
     *
     * @return Response
     */
    public function getMockResponse($path)
    {
        return $path instanceof Response
            ? $path
            : MockPlugin::getMockFile(self::$mockBasePath . DIRECTORY_SEPARATOR . $path);
    }

    /**
     * Set a mock response from a mock file on the next client request.
     *
     * This method assumes that mock response files are located under the
     * Command/Mock/ directory of the Service being tested
     * (e.g. Unfuddle/Command/Mock/).  A mock response is added to the next
     * request sent by the client.
     *
     * @param Client $client Client object to modify
     * @param string $paths  Path to files within the Mock folder of the service
     *
     * @return MockPlugin returns the created mock plugin
     */
    public function setMockResponse(Client $client, $paths)
    {
        $this->requests = array();
        $that = $this;
        $mock = new MockPlugin(null, true);
        $client->getEventDispatcher()->removeSubscriber($mock);
        $mock->getEventDispatcher()->addListener('mock.request', function(Event $event) use ($that) {
            $that->addMockedRequest($event['request']);
        });

        if ($paths instanceof Response) {
            // A single response instance has been specified, create an array with that instance
            // as the only element for the following loop to work as expected
            $paths = array($paths);
        }

        foreach ((array) $paths as $path) {
            $mock->addResponse($this->getMockResponse($path));
        }

        $client->getEventDispatcher()->addSubscriber($mock);

        return $mock;
    }

    /**
     * Compare HTTP headers and use special markup to filter values
     * A header prefixed with '!' means it must not exist
     * A header prefixed with '_' means it must be ignored
     * A header value of '*' means anything after the * will be ignored
     *
     * @param array $filteredHeaders Array of special headers
     * @param array $actualHeaders Array of headers to check against
     *
     * @return array|bool Returns an array of the differences or FALSE if none
     */
    public function compareHeaders($filteredHeaders, $actualHeaders)
    {
        $comparison = new HeaderComparison();

        return $comparison->compare($filteredHeaders, $actualHeaders);
    }

    /**
     * Case insensitive assertContains
     *
     * @param string $needle Search string
     * @param string $haystack Search this
     * @param string $message Optional failure message
     */
    public function assertContainsIns($needle, $haystack, $message = null)
    {
        $this->assertContains(strtolower($needle), strtolower($haystack), $message);
    }
}