Overview

Namespaces

  • Contrib
    • Bundle
      • CoverallsBundle
        • Console
        • Entity
      • CoverallsV1Bundle
        • Api
        • Collector
        • Command
        • Config
        • Entity
          • Git
    • Component
      • File
      • Log
      • System
        • Git
  • Guzzle
    • Batch
      • Exception
    • Cache
    • Common
      • Exception
    • Http
      • Curl
      • Exception
      • Message
      • QueryAggregator
    • Inflection
    • Iterator
    • Log
    • Parser
      • Cookie
      • Message
      • UriTemplate
      • Url
    • Plugin
      • Async
      • Backoff
      • Cache
      • Cookie
        • CookieJar
        • Exception
      • CurlAuth
      • ErrorResponse
        • Exception
      • History
      • Log
      • Md5
      • Mock
      • Oauth
    • Service
      • Builder
      • Command
        • Factory
        • LocationVisitor
          • Request
          • Response
      • Description
      • Exception
      • Resource
    • Stream
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Config
        • Definition
          • Builder
          • Exception
        • Exception
        • Loader
        • Resource
        • Util
      • Console
        • Command
        • Formatter
        • Helper
        • Input
        • Output
        • Tester
      • EventDispatcher
        • Debug
      • Finder
        • Adapter
        • Comparator
        • Exception
        • Expression
        • Iterator
        • Shell
      • Stopwatch
      • Yaml
        • Exception

Classes

  • MockPlugin
  • Overview
  • Namespace
  • Class
  • Tree
  • Todo
  1: <?php
  2: 
  3: namespace Guzzle\Plugin\Mock;
  4: 
  5: use Guzzle\Common\Event;
  6: use Guzzle\Common\Exception\InvalidArgumentException;
  7: use Guzzle\Common\AbstractHasDispatcher;
  8: use Guzzle\Http\Exception\CurlException;
  9: use Guzzle\Http\Message\RequestInterface;
 10: use Guzzle\Http\Message\EntityEnclosingRequestInterface;
 11: use Guzzle\Http\Message\Response;
 12: use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 13: 
 14: /**
 15:  * Queues mock responses or exceptions and delivers mock responses or exceptions in a fifo order.
 16:  */
 17: class MockPlugin extends AbstractHasDispatcher implements EventSubscriberInterface, \Countable
 18: {
 19:     /**
 20:      * @var array Array of mock responses / exceptions
 21:      */
 22:     protected $queue = array();
 23: 
 24:     /**
 25:      * @var bool Whether or not to remove the plugin when the queue is empty
 26:      */
 27:     protected $temporary = false;
 28: 
 29:     /**
 30:      * @var array Array of requests that were mocked
 31:      */
 32:     protected $received = array();
 33: 
 34:     /**
 35:      * @var bool Whether or not to consume an entity body when a mock response is served
 36:      */
 37:     protected $readBodies;
 38: 
 39:     /**
 40:      * Constructor
 41:      *
 42:      * @param array $items      Array of responses or exceptions to queue
 43:      * @param bool  $temporary  Set to TRUE to remove the plugin when the queue is empty
 44:      * @param bool  $readBodies Set to TRUE to consume the entity body when a mock is served
 45:      */
 46:     public function __construct(array $items = null, $temporary = false, $readBodies = false)
 47:     {
 48:         $this->readBodies = $readBodies;
 49:         $this->temporary = $temporary;
 50:         if ($items) {
 51:             foreach ($items as $item) {
 52:                 if ($item instanceof \Exception) {
 53:                     $this->addException($item);
 54:                 } else {
 55:                     $this->addResponse($item);
 56:                 }
 57:             }
 58:         }
 59:     }
 60: 
 61:     /**
 62:      * {@inheritdoc}
 63:      */
 64:     public static function getSubscribedEvents()
 65:     {
 66:         return array('client.create_request' => 'onRequestCreate');
 67:     }
 68: 
 69:     /**
 70:      * {@inheritdoc}
 71:      */
 72:     public static function getAllEvents()
 73:     {
 74:         return array('mock.request');
 75:     }
 76: 
 77:     /**
 78:      * Get a mock response from a file
 79:      *
 80:      * @param string $path File to retrieve a mock response from
 81:      *
 82:      * @return Response
 83:      * @throws InvalidArgumentException if the file is not found
 84:      */
 85:     public static function getMockFile($path)
 86:     {
 87:         if (!file_exists($path)) {
 88:             throw new InvalidArgumentException('Unable to open mock file: ' . $path);
 89:         }
 90: 
 91:         return Response::fromMessage(file_get_contents($path));
 92:     }
 93: 
 94:     /**
 95:      * Set whether or not to consume the entity body of a request when a mock
 96:      * response is used
 97:      *
 98:      * @param bool $readBodies Set to true to read and consume entity bodies
 99:      *
100:      * @return self
101:      */
102:     public function readBodies($readBodies)
103:     {
104:         $this->readBodies = $readBodies;
105: 
106:         return $this;
107:     }
108: 
109:     /**
110:      * Returns the number of remaining mock responses
111:      *
112:      * @return int
113:      */
114:     public function count()
115:     {
116:         return count($this->queue);
117:     }
118: 
119:     /**
120:      * Add a response to the end of the queue
121:      *
122:      * @param string|Response $response Response object or path to response file
123:      *
124:      * @return MockPlugin
125:      * @throws InvalidArgumentException if a string or Response is not passed
126:      */
127:     public function addResponse($response)
128:     {
129:         if (!($response instanceof Response)) {
130:             if (!is_string($response)) {
131:                 throw new InvalidArgumentException('Invalid response');
132:             }
133:             $response = self::getMockFile($response);
134:         }
135: 
136:         $this->queue[] = $response;
137: 
138:         return $this;
139:     }
140: 
141:     /**
142:      * Add an exception to the end of the queue
143:      *
144:      * @param CurlException $e Exception to throw when the request is executed
145:      *
146:      * @return MockPlugin
147:      */
148:     public function addException(CurlException $e)
149:     {
150:         $this->queue[] = $e;
151: 
152:         return $this;
153:     }
154: 
155:     /**
156:      * Clear the queue
157:      *
158:      * @return MockPlugin
159:      */
160:     public function clearQueue()
161:     {
162:         $this->queue = array();
163: 
164:         return $this;
165:     }
166: 
167:     /**
168:      * Returns an array of mock responses remaining in the queue
169:      *
170:      * @return array
171:      */
172:     public function getQueue()
173:     {
174:         return $this->queue;
175:     }
176: 
177:     /**
178:      * Check if this is a temporary plugin
179:      *
180:      * @return bool
181:      */
182:     public function isTemporary()
183:     {
184:         return $this->temporary;
185:     }
186: 
187:     /**
188:      * Get a response from the front of the list and add it to a request
189:      *
190:      * @param RequestInterface $request Request to mock
191:      *
192:      * @return self
193:      * @throws CurlException When request.send is called and an exception is queued
194:      */
195:     public function dequeue(RequestInterface $request)
196:     {
197:         $this->dispatch('mock.request', array(
198:             'plugin'  => $this,
199:             'request' => $request
200:         ));
201: 
202:         $item = array_shift($this->queue);
203:         if ($item instanceof Response) {
204:             if ($this->readBodies && $request instanceof EntityEnclosingRequestInterface) {
205:                 $request->getEventDispatcher()->addListener('request.sent', function (Event $event) {
206:                     while ($data = $event['request']->getBody()->read(8096));
207:                 });
208:             }
209:             $request->setResponse($item, true);
210:         } elseif ($item instanceof CurlException) {
211:             $request->getEventDispatcher()->addListener(
212:                 'request.before_send',
213:                 function (Event $event) use ($request, $item) {
214:                     // Emulates exceptions encountered while transferring requests
215:                     $item->setRequest($request);
216:                     $request->setState(RequestInterface::STATE_ERROR);
217:                     $request->dispatch('request.exception', array('request' => $request, 'exception' => $item));
218:                     // Only throw if the exception wasn't handled
219:                     if ($request->getState() == RequestInterface::STATE_ERROR) {
220:                         throw $item;
221:                     }
222:                 },
223:                 // Use a number lower than the CachePlugin
224:                 -999
225:             );
226:         }
227: 
228:         return $this;
229:     }
230: 
231:     /**
232:      * Clear the array of received requests
233:      */
234:     public function flush()
235:     {
236:         $this->received = array();
237:     }
238: 
239:     /**
240:      * Get an array of requests that were mocked by this plugin
241:      *
242:      * @return array
243:      */
244:     public function getReceivedRequests()
245:     {
246:         return $this->received;
247:     }
248: 
249:     /**
250:      * Called when a request completes
251:      *
252:      * @param Event $event
253:      */
254:     public function onRequestCreate(Event $event)
255:     {
256:         if (!empty($this->queue)) {
257:             $request = $event['request'];
258:             $this->dequeue($request);
259:             $this->received[] = $request;
260:             // Detach the filter from the client so it's a one-time use
261:             if ($this->temporary && empty($this->queue) && $request->getClient()) {
262:                 $request->getClient()->getEventDispatcher()->removeSubscriber($this);
263:             }
264:         }
265:     }
266: }
267: 
php-coveralls API documentation generated by ApiGen 2.8.0