diff --git a/.travis.yml b/.travis.yml index 83e3d82..8e6fe14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - 5.5 - 5.6 - 7.0 - hhvm diff --git a/CHANGELOG.md b/CHANGELOG.md index cbf0180..78f11f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All Notable changes to `gigya-client` will be documented in this file +## 1.0 - 2016-11-28 + +### Changed +- Upgrade Guzzle from v5 to v6 +- All Subscribers are now Guzzle Middleware +- Renamed `->addSubscriber` to `->addHandler` +- Renamed `->removeSubscriber` to `->removeHandler` + +## 0.3 - 2016-04-02 + +### Added +- OAuth2 authentication + ## 0.2 - 2015-10-20 ### Changed diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 70036c8..0000000 --- a/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM graze/php-alpine - -RUN apk add --no-cache --repository "http://dl-cdn.alpinelinux.org/alpine/edge/testing" \ - php7-xdebug - -ADD . /srv - -WORKDIR /srv - -CMD /bin/bash diff --git a/Makefile b/Makefile index b68324d..4785733 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ SHELL = /bin/sh DOCKER ?= $(shell which docker) -DOCKER_REPOSITORY := graze/gigya-client +DOCKER_REPOSITORY := graze/php-alpine VOLUME := /srv VOLUME_MAP := -v $$(pwd):${VOLUME} DOCKER_RUN_BASE := ${DOCKER} run --rm -t ${VOLUME_MAP} -w ${VOLUME} -DOCKER_RUN := ${DOCKER_RUN_BASE} ${DOCKER_REPOSITORY}:latest +DOCKER_RUN := ${DOCKER_RUN_BASE} ${DOCKER_REPOSITORY}:test .PHONY: install composer clean help .PHONY: test lint lint-fix test-unit test-integration test-matrix test-coverage test-coverage-html test-coverage-clover @@ -16,14 +16,13 @@ DOCKER_RUN := ${DOCKER_RUN_BASE} ${DOCKER_REPOSITORY}:latest install: ## Download the dependencies then build the image :rocket:. make 'composer-install --optimize-autoloader --ignore-platform-reqs' - $(DOCKER) build --tag ${DOCKER_REPOSITORY}:latest . composer-%: ## Run a composer command, `make "composer- [...]"`. ${DOCKER} run -t --rm \ - -v $$(pwd):/usr/src/app \ + -v $$(pwd):/app \ -v ~/.composer:/root/composer \ -v ~/.ssh:/root/.ssh:ro \ - graze/composer --ansi --no-interaction $* $(filter-out $@,$(MAKECMDGOALS)) + composer/composer:alpine --ansi --no-interaction $* $(filter-out $@,$(MAKECMDGOALS)) clean: ## Clean up any images. $(DOCKER) rmi ${DOCKER_REPOSITORY}:latest @@ -54,13 +53,13 @@ test-performance: ## Run the performance testsuite. $(DOCKER_RUN) vendor/bin/phpunit --colors=always --testsuite performance test-coverage: ## Run all tests and output coverage to the console. - $(DOCKER_RUN) vendor/bin/phpunit --coverage-text --testsuite coverage + $(DOCKER_RUN) phpdbg7 -qrr vendor/bin/phpunit --coverage-text --testsuite coverage test-coverage-html: ## Run all tests and output html results - $(DOCKER_RUN) vendor/bin/phpunit --coverage-html ./tests/report/html --testsuite coverage + $(DOCKER_RUN) phpdbg7 -qrr vendor/bin/phpunit --coverage-html ./tests/report/html --testsuite coverage test-coverage-clover: ## Run all tests and output clover coverage to file. - $(DOCKER_RUN) vendor/bin/phpunit --coverage-clover=./tests/report/coverage.clover --testsuite coverage + $(DOCKER_RUN) phpdbg7 -qrr vendor/bin/phpunit --coverage-clover=./tests/report/coverage.clover --testsuite coverage # Help diff --git a/README.md b/README.md index 972fcbf..13d0a45 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ $account = $response->getData(); ```php $grant = new ManualGrant(); $gigya = new Gigya($key, $secret, $region, null, ['auth' => 'oauth2-custom']); -$gigya->addSubscriber(new OAuth2Subscriber($grant)); +$gigya->addHandler(OAuth2Subscriber::middleware($grant)); $tokenResponse = $gigya->socialize()->getToken([ 'grant_type' => 'code', diff --git a/composer.json b/composer.json index 028d40b..f5182da 100644 --- a/composer.json +++ b/composer.json @@ -22,12 +22,12 @@ ], "require": { "php": ">=5.5.0", - "guzzlehttp/guzzle": "^5.3", + "guzzlehttp/guzzle": "^6.2", "illuminate/support": "^5.0", "graze/standards": "^1.0" }, "require-dev": { - "phpunit/phpunit" : "^4", + "phpunit/phpunit" : "^5", "mockery/mockery": "^0.9.4", "squizlabs/php_codesniffer": "^2.3" }, diff --git a/src/Auth/CredentialsAuth.php b/src/Auth/CredentialsAuth.php deleted file mode 100644 index 86709ff..0000000 --- a/src/Auth/CredentialsAuth.php +++ /dev/null @@ -1,99 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md - * @link https://github.com/graze/gigya-client - */ - -namespace Graze\Gigya\Auth; - -use GuzzleHttp\Event\BeforeEvent; -use GuzzleHttp\Event\RequestEvents; -use GuzzleHttp\Event\SubscriberInterface; - -class CredentialsAuth implements SubscriberInterface -{ - const AUTH_NAME = 'credentials'; - - /** - * @var string - */ - private $apiKey; - - /** - * @var string - */ - private $secret; - - /** - * @var null|string - */ - private $userKey; - - /** - * @param string $apiKey - * @param string $secret - * @param string|null $userKey - */ - public function __construct($apiKey, $secret, $userKey = null) - { - $this->apiKey = $apiKey; - $this->secret = $secret; - $this->userKey = $userKey; - } - - /** - * Returns an array of event names this subscriber wants to listen to. - * - * @return array - */ - public function getEvents() - { - return ['before' => ['sign', RequestEvents::SIGN_REQUEST]]; - } - - /** - * Add the authentication params to the request. - * - * @param BeforeEvent $event - */ - public function sign(BeforeEvent $event) - { - $request = $event->getRequest(); - if ($request->getScheme() == 'https' && $request->getConfig()->get('auth') == static::AUTH_NAME) { - $query = $request->getQuery(); - $query['client_id'] = $this->userKey ?: $this->apiKey; - $query['client_secret'] = $this->secret; - } - } - - /** - * @return string - */ - public function getApiKey() - { - return $this->apiKey; - } - - /** - * @return string - */ - public function getSecret() - { - return $this->secret; - } - - /** - * @return string|null - */ - public function getUserKey() - { - return $this->userKey; - } -} diff --git a/src/Auth/CredentialsAuthMiddleware.php b/src/Auth/CredentialsAuthMiddleware.php new file mode 100644 index 0000000..9ebcae2 --- /dev/null +++ b/src/Auth/CredentialsAuthMiddleware.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md + * @link https://github.com/graze/gigya-client + */ + +namespace Graze\Gigya\Auth; + +use Closure; +use GuzzleHttp\Psr7\Uri; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; + +class CredentialsAuthMiddleware +{ + const AUTH_NAME = 'credentials'; + + /** + * @var string + */ + private $apiKey; + + /** + * @var string + */ + private $secret; + + /** + * @var null|string + */ + private $userKey; + /** + * @var callable + */ + private $nextHandler; + + /** + * @param callable $nextHandler + * @param string $apiKey + * @param string $secret + * @param string|null $userKey + */ + public function __construct(callable $nextHandler, $apiKey, $secret, $userKey = null) + { + $this->nextHandler = $nextHandler; + $this->apiKey = $apiKey; + $this->secret = $secret; + $this->userKey = $userKey; + } + + /** + * Inject credentials information into the query parameters + * + * @param RequestInterface $request + * @param array $options + * + * @return GuzzleResponseInterface + */ + public function __invoke(RequestInterface $request, array $options) + { + if ($request->getUri()->getScheme() == 'https' && $options['auth'] == static::AUTH_NAME) { + $uri = Uri::withQueryValue($request->getUri(), 'client_id', $this->userKey ?: $this->apiKey); + $uri = Uri::withQueryValue($uri, 'client_secret', $this->secret); + $request = $request->withUri($uri); + } + $fn = $this->nextHandler; + return $fn($request, $options); + } + + /** + * @return string + */ + public function getApiKey() + { + return $this->apiKey; + } + + /** + * @return string + */ + public function getSecret() + { + return $this->secret; + } + + /** + * @return string|null + */ + public function getUserKey() + { + return $this->userKey; + } + + /** + * Return a middleware handler function for this Authentication + * + * @param string $apiKey + * @param string $secret + * @param string|null $userKey + * + * @return Closure + */ + public static function middleware($apiKey, $secret, $userKey = null) + { + return function (callable $handler) use ($apiKey, $secret, $userKey) { + return new static($handler, $apiKey, $secret, $userKey); + }; + } +} diff --git a/src/Auth/HttpsAuth.php b/src/Auth/HttpsAuth.php deleted file mode 100644 index 10226ed..0000000 --- a/src/Auth/HttpsAuth.php +++ /dev/null @@ -1,102 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md - * @link https://github.com/graze/gigya-client - */ - -namespace Graze\Gigya\Auth; - -use GuzzleHttp\Event\BeforeEvent; -use GuzzleHttp\Event\RequestEvents; -use GuzzleHttp\Event\SubscriberInterface; - -class HttpsAuth implements SubscriberInterface -{ - const AUTH_NAME = 'gigya'; - - /** - * @var string - */ - private $apiKey; - - /** - * @var string - */ - private $secret; - - /** - * @var null|string - */ - private $userKey; - - /** - * @param string $apiKey - * @param string $secret - * @param string|null $userKey - */ - public function __construct($apiKey, $secret, $userKey = null) - { - $this->apiKey = $apiKey; - $this->secret = $secret; - $this->userKey = $userKey; - } - - /** - * Returns an array of event names this subscriber wants to listen to. - * - * @return array - */ - public function getEvents() - { - return ['before' => ['sign', RequestEvents::SIGN_REQUEST]]; - } - - /** - * Add the authentication params to the request. - * - * @param BeforeEvent $event - */ - public function sign(BeforeEvent $event) - { - $request = $event->getRequest(); - if ($request->getScheme() == 'https' && $request->getConfig()->get('auth') == static::AUTH_NAME) { - $query = $request->getQuery(); - $query['apiKey'] = $this->apiKey; - $query['secret'] = $this->secret; - if ((bool) $this->userKey) { - $query['userKey'] = $this->userKey; - } - } - } - - /** - * @return string - */ - public function getApiKey() - { - return $this->apiKey; - } - - /** - * @return string - */ - public function getSecret() - { - return $this->secret; - } - - /** - * @return string|null - */ - public function getUserKey() - { - return $this->userKey; - } -} diff --git a/src/Auth/HttpsAuthMiddleware.php b/src/Auth/HttpsAuthMiddleware.php new file mode 100644 index 0000000..2371964 --- /dev/null +++ b/src/Auth/HttpsAuthMiddleware.php @@ -0,0 +1,118 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md + * @link https://github.com/graze/gigya-client + */ + +namespace Graze\Gigya\Auth; + +use Closure; +use GuzzleHttp\Psr7\Uri; +use Psr\Http\Message\RequestInterface; + +class HttpsAuthMiddleware +{ + const AUTH_NAME = 'gigya'; + + /** + * @var string + */ + private $apiKey; + + /** + * @var string + */ + private $secret; + + /** + * @var null|string + */ + private $userKey; + /** + * @var callable + */ + private $nextHandler; + + /** + * @param callable $nextHandler + * @param string $apiKey + * @param string $secret + * @param string|null $userKey + */ + public function __construct(callable $nextHandler, $apiKey, $secret, $userKey = null) + { + $this->nextHandler = $nextHandler; + $this->apiKey = $apiKey; + $this->secret = $secret; + $this->userKey = $userKey; + } + + /** + * Inject the https auth into the query string + * + * @param RequestInterface $request + * @param array $options + * + * @return Closure + */ + public function __invoke(RequestInterface $request, array $options) + { + if ($request->getUri()->getScheme() == 'https' && $options['auth'] == static::AUTH_NAME) { + $uri = Uri::withQueryValue($request->getUri(), 'apiKey', $this->apiKey); + $uri = Uri::withQueryValue($uri, 'secret', $this->secret); + if ((bool) $this->userKey) { + $uri = Uri::withQueryValue($uri, 'userKey', $this->userKey); + } + $request = $request->withUri($uri); + } + $fn = $this->nextHandler; + return $fn($request, $options); + } + + /** + * @return string + */ + public function getApiKey() + { + return $this->apiKey; + } + + /** + * @return string + */ + public function getSecret() + { + return $this->secret; + } + + /** + * @return string|null + */ + public function getUserKey() + { + return $this->userKey; + } + + /** + * Return a middleware handler function for https Authentication + * + * @param string $apiKey + * @param string $secret + * @param string|null $userKey + * + * @return Closure + */ + public static function middleware($apiKey, $secret, $userKey = null) + { + return function (callable $handler) use ($apiKey, $secret, $userKey) { + return new static($handler, $apiKey, $secret, $userKey); + }; + } +} diff --git a/src/Auth/OAuth2/OAuth2Middleware.php b/src/Auth/OAuth2/OAuth2Middleware.php new file mode 100644 index 0000000..eb817d1 --- /dev/null +++ b/src/Auth/OAuth2/OAuth2Middleware.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md + * @link https://github.com/graze/gigya-client + */ + +namespace Graze\Gigya\Auth\OAuth2; + +use Closure; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; + +class OAuth2Middleware +{ + const AUTH_NAME = 'gigya-oauth2'; + + /** @var GrantInterface */ + private $grant; + /** @var string|null */ + private $name; + /** + * @var callable + */ + private $nextHandler; + + /** + * @param callable $nextHandler + * @param GrantInterface $grant + * @param string|null $name + */ + public function __construct(callable $nextHandler, GrantInterface $grant, $name = null) + { + $this->nextHandler = $nextHandler; + $this->grant = $grant; + $this->name = $name ?: static::AUTH_NAME; + } + + /** + * @param RequestInterface $request + * @param array $options + * + * @return mixed + */ + public function __invoke(RequestInterface $request, array $options) + { + if ($request->getUri()->getScheme() == 'https' && $options['auth'] == $this->name) { + $token = $this->grant->getToken(); + + if (!is_null($token)) { + $request = $request->withHeader('Authorization', sprintf('OAuth %s', $token->getToken())); + } + } + + $fn = $this->nextHandler; + + return $fn($request, $options) + ->then($this->refreshToken($request, $options)); + } + + /** + * @param RequestInterface $request + * @param array $options + * + * @return Closure A function taking a response and returning a new response|future + */ + private function refreshToken(RequestInterface $request, array $options) + { + /** + * Take a response and if it requires authentication, retry the request. Otherwise pass through the response + * + * @param GuzzleResponseInterface $response + * + * @return GuzzleResponseInterface + */ + return function (GuzzleResponseInterface $response) use ($request, $options) { + if ($response->getStatusCode() == 401 + && $this->canRetry($request, $options)) { + if (!is_null($this->grant->getToken())) { + $options['retries'] = (isset($options['retries'])) ? $options['retries'] + 1 : 1; + return $this($request, $options); + } + } + return $response; + }; + } + + /** + * @param RequestInterface $request + * @param array $options + * + * @return bool + */ + private function canRetry(RequestInterface $request, array $options) + { + return ($request->getUri()->getScheme() == 'https' + && $options['auth'] == $this->name + && (!isset($options['retries']) || $options['retries'] === 0)); + } + + /** + * Return a middleware handler function for OAuth2 Authentication + * + * @param GrantInterface $grant + * @param string|null $name + * + * @return Closure + */ + public static function middleware(GrantInterface $grant, $name = null) + { + return function (callable $handler) use ($grant, $name) { + return new static($handler, $grant, $name); + }; + } +} diff --git a/src/Auth/OAuth2/OAuth2Subscriber.php b/src/Auth/OAuth2/OAuth2Subscriber.php deleted file mode 100644 index d6099fa..0000000 --- a/src/Auth/OAuth2/OAuth2Subscriber.php +++ /dev/null @@ -1,92 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md - * @link https://github.com/graze/gigya-client - */ - -namespace Graze\Gigya\Auth\OAuth2; - -use GuzzleHttp\Event\BeforeEvent; -use GuzzleHttp\Event\ErrorEvent; -use GuzzleHttp\Event\RequestEvents; -use GuzzleHttp\Event\SubscriberInterface; - -class OAuth2Subscriber implements SubscriberInterface -{ - const AUTH_NAME = 'gigya-oauth2'; - - /** @var GrantInterface */ - private $grant; - /** @var string|null */ - private $name; - - /** - * @param GrantInterface $grant - * @param string|null $name - */ - public function __construct(GrantInterface $grant, $name = null) - { - $this->grant = $grant; - $this->name = $name ?: static::AUTH_NAME; - } - - /** - * Returns an array of event names this subscriber wants to listen to. - * - * @return array - */ - public function getEvents() - { - return [ - 'before' => ['sign', RequestEvents::SIGN_REQUEST], - 'error' => ['error', RequestEvents::EARLY], - ]; - } - - /** - * Add the authentication params to the request. - * - * @param BeforeEvent $event - */ - public function sign(BeforeEvent $event) - { - $request = $event->getRequest(); - if ($request->getScheme() == 'https' - && $request->getConfig()->get('auth') == $this->name - ) { - $token = $this->grant->getToken(); - - if (!is_null($token)) { - $request->addHeader('Authorization', sprintf('OAuth %s', $token->getToken())); - } - } - } - - /** - * @param ErrorEvent $event - */ - public function error(ErrorEvent $event) - { - $response = $event->getResponse(); - if ($response && $response->getStatusCode() == 401) { - $request = $event->getRequest(); - if ($request->getScheme() == 'https' - && $request->getConfig()->get('auth') == $this->name - && !$request->getConfig()->get('retried') - ) { - $token = $this->grant->getToken(); - if (!is_null($token)) { - $request->getConfig()->set('retried', true); - $event->intercept($event->getClient()->send($request)); - } - } - } - } -} diff --git a/src/Exception/UnknownResponseException.php b/src/Exception/UnknownResponseException.php index 8a506e4..1f58b76 100644 --- a/src/Exception/UnknownResponseException.php +++ b/src/Exception/UnknownResponseException.php @@ -14,9 +14,7 @@ namespace Graze\Gigya\Exception; use Exception; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface; - -// use Psr\Http\Message\ResponseInterface; Guzzle v6 +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; class UnknownResponseException extends Exception { @@ -33,7 +31,7 @@ class UnknownResponseException extends Exception public function __construct(GuzzleResponseInterface $response = null, $message = '', Exception $previous = null) { $message = "The contents of the response could not be determined. {$message}" . - ($response ? "\n Body:\n" . $response->getBody() : ''); + ($response ? "\n Body:\n" . $response->getBody()->getContents() : ''); $this->response = $response; diff --git a/src/Gigya.php b/src/Gigya.php index 47255b0..d254e87 100644 --- a/src/Gigya.php +++ b/src/Gigya.php @@ -14,10 +14,10 @@ namespace Graze\Gigya; use BadMethodCallException; -use Graze\Gigya\Auth\CredentialsAuth; -use Graze\Gigya\Auth\HttpsAuth; +use Graze\Gigya\Auth\CredentialsAuthMiddleware; +use Graze\Gigya\Auth\HttpsAuthMiddleware; use Graze\Gigya\Auth\OAuth2\GigyaGrant; -use Graze\Gigya\Auth\OAuth2\OAuth2Subscriber; +use Graze\Gigya\Auth\OAuth2\OAuth2Middleware; use Graze\Gigya\Endpoint\Accounts; use Graze\Gigya\Endpoint\Audit; use Graze\Gigya\Endpoint\Client; @@ -34,7 +34,8 @@ use Graze\Gigya\Validation\UidSignatureValidator; use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\ClientInterface; -use GuzzleHttp\Event\SubscriberInterface; +use GuzzleHttp\Handler\CurlHandler; +use GuzzleHttp\HandlerStack; class Gigya { @@ -89,11 +90,6 @@ class Gigya */ protected $validators = []; - /** - * @var SubscriberInterface[] - */ - protected $subscribers = []; - /** * @var ResponseFactoryInterface */ @@ -104,15 +100,20 @@ class Gigya */ private $guzzle; + /** + * @var HandlerStack + */ + private $handlerStack; + /** * @param string $apiKey * @param string $secretKey * @param string|null $dataCenter * @param string|null $userKey * @param array $config Gigya configuration: - * - auth (Default: gigya) Type of authentication, gigya (HttpsAuth) is the - * default. 'credentials' provides `client_id,client_secret` params, 'gigya-oauth2' - * uses an oauth2 access token + * - auth (Default: gigya) Type of authentication, gigya + * (HttpsAuthMiddleware) is the default. 'credentials' provides + * `client_id,client_secret` params, 'gigya-oauth2' uses an oauth2 access token * - uidValidator (Default: true) Include Uid Signature Validation * - factory (Default: null) A ResponseFactoryInterface to use, if none is * provided ResponseFactory will be used @@ -122,6 +123,12 @@ class Gigya public function __construct($apiKey, $secretKey, $dataCenter = null, $userKey = null, array $config = []) { $guzzleConfig = (isset($config['guzzle'])) ? $config['guzzle'] : []; + + if (!isset($guzzleConfig['handler'])) { + $guzzleConfig['handler'] = new HandlerStack(new CurlHandler()); + } + $this->handlerStack = $guzzleConfig['handler']; + $this->guzzle = new GuzzleClient($guzzleConfig); if (isset($config['options'])) { @@ -129,14 +136,14 @@ public function __construct($apiKey, $secretKey, $dataCenter = null, $userKey = } $this->addOption('verify', __DIR__ . '/' . static::CERTIFICATE_FILE); - $this->addSubscriber(new HttpsAuth($apiKey, $secretKey, $userKey)); - $this->addSubscriber(new CredentialsAuth($apiKey, $secretKey, $userKey)); + $this->addHandler(HttpsAuthMiddleware::middleware($apiKey, $secretKey, $userKey)); + $this->addHandler(CredentialsAuthMiddleware::middleware($apiKey, $secretKey, $userKey)); $auth = isset($config['auth']) ? $config['auth'] : 'gigya'; switch ($auth) { case 'gigya-oauth2': $this->addOption('auth', 'gigya-oauth2'); - $this->addSubscriber(new OAuth2Subscriber(new GigyaGrant($this))); + $this->addHandler(OAuth2Middleware::middleware(new GigyaGrant($this))); break; default: $this->addOption('auth', $auth); @@ -201,25 +208,25 @@ public function addValidator(ResponseValidatorInterface $validator) } /** - * @param SubscriberInterface $subscriber + * @param callable $handler * * @return $this */ - public function addSubscriber(SubscriberInterface $subscriber) + public function addHandler(callable $handler) { - $this->guzzle->getEmitter()->attach($subscriber); + $this->handlerStack->push($handler); return $this; } /** - * @param SubscriberInterface $subscriber + * @param callable $handler * * @return $this */ - public function removeSubscriber(SubscriberInterface $subscriber) + public function removeHandler(callable $handler) { - $this->guzzle->getEmitter()->detach($subscriber); + $this->handlerStack->remove($handler); return $this; } diff --git a/src/Response/Response.php b/src/Response/Response.php index 5870001..1a3eae5 100644 --- a/src/Response/Response.php +++ b/src/Response/Response.php @@ -16,10 +16,8 @@ use DateTimeImmutable; use DateTimeInterface; use Graze\Gigya\Gigya; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface; use Illuminate\Support\Collection; - -// use Psr\Http\Message\ResponseInterface; Guzzle v6 +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; class Response implements ResponseInterface { @@ -79,7 +77,7 @@ class Response implements ResponseInterface public function __construct(GuzzleResponseInterface $response) { $this->response = $response; - $this->body = (object) $response->json(['object' => true]); + $this->body = json_decode($response->getBody()); $this->errorCode = (int) $this->popField('errorCode'); $this->errorMessage = $this->popField('errorMessage'); $this->errorDetails = $this->popField('errorDetails'); diff --git a/src/Response/ResponseCollection.php b/src/Response/ResponseCollection.php index b8f4b88..ed0c760 100644 --- a/src/Response/ResponseCollection.php +++ b/src/Response/ResponseCollection.php @@ -13,10 +13,8 @@ namespace Graze\Gigya\Response; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface; use Illuminate\Support\Collection; - -// use Psr\Http\Message\ResponseInterface; Guzzle v6 +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; class ResponseCollection extends Response implements ResponseCollectionInterface { diff --git a/src/Response/ResponseFactory.php b/src/Response/ResponseFactory.php index 86fe1fa..8f9a00f 100644 --- a/src/Response/ResponseFactory.php +++ b/src/Response/ResponseFactory.php @@ -13,9 +13,7 @@ namespace Graze\Gigya\Response; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface; - -// use Psr\Http\Message\ResponseInterface; Guzzle v6 +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; class ResponseFactory implements ResponseFactoryInterface { @@ -28,7 +26,7 @@ class ResponseFactory implements ResponseFactoryInterface */ public function getResponse(GuzzleResponseInterface $response) { - $body = $response->json(); + $body = json_decode($response->getBody(), true); if (array_key_exists('results', $body)) { $result = new ResponseCollection($response); } else { diff --git a/src/Response/ResponseFactoryInterface.php b/src/Response/ResponseFactoryInterface.php index c01e8a2..cdc5053 100644 --- a/src/Response/ResponseFactoryInterface.php +++ b/src/Response/ResponseFactoryInterface.php @@ -13,7 +13,7 @@ namespace Graze\Gigya\Response; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface; +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; interface ResponseFactoryInterface { diff --git a/src/Response/ResponseInterface.php b/src/Response/ResponseInterface.php index 0a9ccd4..b815e8c 100644 --- a/src/Response/ResponseInterface.php +++ b/src/Response/ResponseInterface.php @@ -14,10 +14,8 @@ namespace Graze\Gigya\Response; use DateTimeInterface; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface; use Illuminate\Support\Collection; - -// use Psr\Http\Message\ResponseInterface; Guzzle v6 +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; interface ResponseInterface { diff --git a/src/Validation/ValidGigyaResponseSubscriber.php b/src/Validation/ValidGigyaResponseMiddleware.php similarity index 55% rename from src/Validation/ValidGigyaResponseSubscriber.php rename to src/Validation/ValidGigyaResponseMiddleware.php index db0e612..fd4fbe7 100644 --- a/src/Validation/ValidGigyaResponseSubscriber.php +++ b/src/Validation/ValidGigyaResponseMiddleware.php @@ -13,16 +13,13 @@ namespace Graze\Gigya\Validation; +use Closure; use Graze\Gigya\Exception\InvalidTimestampException; use Graze\Gigya\Exception\UnknownResponseException; -use GuzzleHttp\Event\CompleteEvent; -use GuzzleHttp\Event\RequestEvents; -use GuzzleHttp\Event\SubscriberInterface; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; -// use Psr\Http\Message\ResponseInterface; Guzzle v6 - -class ValidGigyaResponseSubscriber implements SubscriberInterface +class ValidGigyaResponseMiddleware { /** * @var string[] @@ -35,6 +32,41 @@ class ValidGigyaResponseSubscriber implements SubscriberInterface 'time', ]; + /** + * @var callable + */ + private $handler; + + /** + * ValidGigyaResponseMiddleware constructor. + * + * @param callable $handler + */ + public function __construct(callable $handler) + { + $this->handler = $handler; + } + + /** + * Return the handler to assert that the response returned is valid + * + * @param RequestInterface $request + * @param array $options + * + * @return Closure + */ + public function __invoke(RequestInterface $request, array $options) + { + $fn = $this->handler; + return $fn($request, $options) + ->then( + function (GuzzleResponseInterface $response) { + $this->assert($response); + return $response; + } + ); + } + /** * @param GuzzleResponseInterface $response * @@ -58,32 +90,14 @@ private function assert(GuzzleResponseInterface $response) } /** - * List of events to listen for - * - * @return array - */ - public function getEvents() - { - return ['complete' => ['onComplete', RequestEvents::VERIFY_RESPONSE]]; - } - - /** - * When the response is complete, validate it against our current knowledge of what a gigya response shoud look - * like. - * - * @param CompleteEvent $event + * Returns a Middleware handler functions for this class * - * @throws InvalidTimestampException - * @throws UnknownResponseException + * @return Closure */ - public function onComplete(CompleteEvent $event) + public static function middleware() { - $response = $event->getResponse(); - - if (is_null($response)) { - throw new UnknownResponseException($response, 'No response provided'); - } - - $this->assert($response); + return function (callable $handler) { + return new static($handler); + }; } } diff --git a/tests/integration/GigyaTest.php b/tests/integration/GigyaTest.php index 8e0de7b..ed0eeb5 100644 --- a/tests/integration/GigyaTest.php +++ b/tests/integration/GigyaTest.php @@ -19,83 +19,74 @@ use Graze\Gigya\Test\TestCase; use Graze\Gigya\Test\TestFixtures; use Graze\Gigya\Validation\Signature; -use GuzzleHttp\Event\SubscriberInterface; -use GuzzleHttp\Message\Response; -use GuzzleHttp\Stream\Stream; -use GuzzleHttp\Subscriber\History; -use GuzzleHttp\Subscriber\Mock; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Middleware; +use GuzzleHttp\Psr7\Response; +use Illuminate\Support\Collection; use Mockery as m; +use Psr\Http\Message\RequestInterface; class GigyaTest extends TestCase { /** - * @param Gigya $gigya * @param string|null $body Optional body text * - * @return History + * @return HandlerStack */ - public function setUpGigyaHistory(Gigya $gigya, $body = null) + public function setupHandler($body = null) { - $history = new History(); - $mock = new Mock(array_pad( + $mockHandler = new MockHandler(array_pad( [], 3, new Response( '200', [], - Stream::factory( - $body ?: TestFixtures::getFixture('basic') - ) + $body ?: TestFixtures::getFixture('basic') ) )); - $gigya->addSubscriber($history); - $gigya->addSubscriber($mock); - return $history; + return new HandlerStack($mockHandler); } public function testAuthInjectsKeyAndSecretIntoParams() { - $client = new Gigya('key', 'secret'); - $history = $this->setUpGigyaHistory($client); + $handler = $this->setupHandler(); + $client = new Gigya('key', 'secret', null, null, ['guzzle' => ['handler' => $handler]]); + $store = []; + $handler->push(Middleware::history($store)); $response = $client->accounts()->getAccountInfo(); static::assertEquals(0, $response->getErrorCode()); - static::assertEquals(1, $history->count()); - $request = $history->getLastRequest(); + static::assertCount(1, $store); + $log = array_pop($store); static::assertEquals( 'https://accounts.eu1.gigya.com/accounts.getAccountInfo?apiKey=key&secret=secret', - $request->getUrl() + $log['request']->getUri()->__toString() ); - $query = $request->getQuery(); - static::assertArrayHasKey('apiKey', $query); - static::assertArrayHasKey('secret', $query); - static::assertEquals('key', $query['apiKey']); - static::assertEquals('secret', $query['secret']); } public function testAuthInjectsKeySecretAndUserKeyIntoParams() { - $client = new Gigya('key', 'secret', null, 'userKey'); - $history = $this->setUpGigyaHistory($client); + $handler = $this->setupHandler(); + $client = new Gigya('key', 'secret', null, 'userKey', ['guzzle' => ['handler' => $handler]]); + $store = []; + $handler->push(Middleware::history($store)); $response = $client->accounts()->getAccountInfo(); static::assertEquals(0, $response->getErrorCode()); - static::assertEquals(1, $history->count()); - $request = $history->getLastRequest(); + static::assertCount(1, $store); + $log = array_pop($store); + static::assertArrayHasKey('request', $log); + /** @var RequestInterface $request */ + $request = $log['request']; + static::assertInstanceOf(RequestInterface::class, $request); static::assertEquals( 'https://accounts.eu1.gigya.com/accounts.getAccountInfo?apiKey=key&secret=secret&userKey=userKey', - $request->getUrl() + $request->getUri()->__toString() ); - $query = $request->getQuery(); - static::assertArrayHasKey('apiKey', $query); - static::assertArrayHasKey('secret', $query); - static::assertArrayHasKey('userKey', $query); - static::assertEquals('key', $query['apiKey']); - static::assertEquals('secret', $query['secret']); - static::assertEquals('userKey', $query['userKey']); } public function testUidSignatureWhenValidDoesNotThrowException() @@ -122,24 +113,19 @@ public function testUidSignatureWhenValidDoesNotThrowException() $timestamp ); - $client = new Gigya('key', 'secret'); - $history = $this->setUpGigyaHistory($client, $body); + $handler = $this->setupHandler($body); + $client = new Gigya('key', 'secret', null, null, ['guzzle' => ['handler' => $handler]]); + $store = []; + $handler->push(Middleware::history($store)); $response = $client->accounts()->getAccountInfo(['uid' => $uid]); static::assertEquals(0, $response->getErrorCode()); - static::assertEquals(1, $history->count()); - $request = $history->getLastRequest(); + static::assertCount(1, $store); + $log = array_pop($store); static::assertEquals( "https://accounts.eu1.gigya.com/accounts.getAccountInfo?uid=$uid&apiKey=key&secret=secret", - $request->getUrl() + $log['request']->getUri()->__toString() ); - $query = $request->getQuery(); - static::assertArrayHasKey('apiKey', $query); - static::assertArrayHasKey('secret', $query); - static::assertArrayHasKey('uid', $query); - static::assertEquals('key', $query['apiKey']); - static::assertEquals('secret', $query['secret']); - static::assertEquals($uid, $query['uid']); $data = $response->getData(); static::assertEquals($uid, $data->get('UID')); @@ -171,12 +157,10 @@ public function testUidSignatureWhenIncorrectTimestampThrowsAnException() $timestamp ); - $client = new Gigya('key', 'secret'); - $this->setUpGigyaHistory($client, $body); + $handler = $this->setupHandler($body); + $client = new Gigya('key', 'secret', null, null, ['guzzle' => ['handler' => $handler]]); - static::setExpectedException( - InvalidTimestampException::class - ); + static::expectException(InvalidTimestampException::class); $client->accounts()->getAccountInfo(['uid' => $uid]); } @@ -202,12 +186,10 @@ public function testUidSignatureWhenInvalidSignatureThrowsAnException() $timestamp ); - $client = new Gigya('key', 'secret'); - $this->setUpGigyaHistory($client, $body); + $handler = $this->setupHandler($body); + $client = new Gigya('key', 'secret', null, null, ['guzzle' => ['handler' => $handler]]); - static::setExpectedException( - InvalidUidSignatureException::class - ); + static::expectException(InvalidUidSignatureException::class); $client->accounts()->getAccountInfo(['uid' => $uid]); } @@ -233,38 +215,40 @@ public function testRequestWillThrowTimestampExceptionWhenBothTimestampAndSignat $timestamp ); - $client = new Gigya('key', 'secret'); - $this->setUpGigyaHistory($client, $body); + $handler = $this->setupHandler($body); + $client = new Gigya('key', 'secret', null, null, ['guzzle' => ['handler' => $handler]]); - static::setExpectedException( - InvalidTimestampException::class - ); + static::expectException(InvalidTimestampException::class); $client->accounts()->getAccountInfo(['uid' => $uid]); } public function testGigyaWillTriggerSubscriberOnlyWhenItIsAddedInARequest() { - $client = new Gigya('key', 'secret'); - $this->setUpGigyaHistory($client); + $handler = $this->setupHandler(); + $client = new Gigya('key', 'secret', null, null, ['guzzle' => ['handler' => $handler]]); $client->accounts()->getAccountInfo(); - $subscriber = m::mock(SubscriberInterface::class); - $subscriber->shouldReceive('getEvents') - ->andReturn([ - 'complete' => ['someMethod'], - ]); + $called = 0; - $client->addSubscriber($subscriber); + $fn = function (callable $handler) use (&$called) { + return function (RequestInterface $request, $options) use ($handler, &$called) { + $called++; + return $handler($request, $options); + }; + }; - $subscriber->shouldReceive('someMethod') - ->once(); + $client->addHandler($fn); $client->accounts()->getAccountInfo(); - $client->removeSubscriber($subscriber); + $this->assertEquals(1, $called); + + $client->removeHandler($fn); $client->accounts()->getAccountInfo(); + + $this->assertEquals(1, $called); } } diff --git a/tests/performance/GigyaTest.php b/tests/performance/GigyaTest.php index e08e0a6..0258b7f 100644 --- a/tests/performance/GigyaTest.php +++ b/tests/performance/GigyaTest.php @@ -17,7 +17,9 @@ use Graze\Gigya\Test\TestCase; use Graze\Gigya\Test\TestFixtures; use Graze\Gigya\Validation\Signature; -use GuzzleHttp\Ring\Client\MockHandler; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Psr7\Response; /** * @group performance @@ -41,49 +43,50 @@ class GigyaTest extends TestCase public function createBasicHandler() { - $handler = new MockHandler([ - 'status' => 200, - 'body' => TestFixtures::getFixture('basic'), - ]); + $handler = new MockHandler(array_pad([], 1000, new Response(200, [], TestFixtures::getFixture('basic')))); $this->gigya = new Gigya('key', 'secret', null, null, [ 'guzzle' => [ - 'handler' => $handler, + 'handler' => new HandlerStack($handler), ], ]); } public function createAccountInfoHandler() { - $handler = new MockHandler(function () { - $uid = 'diofu90ifgdf'; - $timestamp = time(); - - $signatureValidator = new Signature(); - $signature = $signatureValidator->calculateSignature($timestamp . '_' . $uid, 'secret'); - - return [ - 'status' => 200, - 'body' => sprintf( - '{ - "UID": "%s", - "UIDSignature": "%s", - "signatureTimestamp": "%d", - "statusCode": 200, - "errorCode": 0, - "statusReason": "OK", - "callId": "123456", - "time": "2015-03-22T11:42:25.943Z" - }', - $uid, - $signature, - $timestamp - ), - ]; - }); + $handler = new MockHandler(); + for ($i = 0; $i < 1000; $i++) { + $handler->append(function () { + $uid = 'diofu90ifgdf'; + $timestamp = time(); + + $signatureValidator = new Signature(); + $signature = $signatureValidator->calculateSignature($timestamp . '_' . $uid, 'secret'); + + return new Response( + 200, + [], + sprintf( + '{ + "UID": "%s", + "UIDSignature": "%s", + "signatureTimestamp": "%d", + "statusCode": 200, + "errorCode": 0, + "statusReason": "OK", + "callId": "123456", + "time": "2015-03-22T11:42:25.943Z" + }', + $uid, + $signature, + $timestamp + ) + ); + }); + } $this->gigya = new Gigya('key', 'secret', null, null, [ 'guzzle' => [ - 'handler' => $handler, + 'handler' => new HandlerStack($handler), ], ]); } diff --git a/tests/src/TestCase.php b/tests/src/TestCase.php index fe46f62..5543e64 100644 --- a/tests/src/TestCase.php +++ b/tests/src/TestCase.php @@ -13,6 +13,20 @@ namespace Graze\Gigya\Test; +use GuzzleHttp\Psr7\Stream; + class TestCase extends \PHPUnit_Framework_TestCase { + /** + * @param string $text + * + * @return Stream + */ + protected function toStream($text) + { + $stream = fopen('php://temp', 'a+'); + fwrite($stream, $text); + rewind($stream); + return new Stream($stream); + } } diff --git a/tests/unit/Auth/CredentialsAuthMiddlewareTest.php b/tests/unit/Auth/CredentialsAuthMiddlewareTest.php new file mode 100644 index 0000000..8df6d33 --- /dev/null +++ b/tests/unit/Auth/CredentialsAuthMiddlewareTest.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md + * @link https://github.com/graze/gigya-client + */ + +namespace Graze\Gigya\Test\Unit\Auth; + +use Graze\Gigya\Auth\CredentialsAuthMiddleware; +use Graze\Gigya\Test\TestCase; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Promise\PromiseInterface; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; +use Mockery as m; +use Psr\Http\Message\RequestInterface; + +class CredentialsAuthMiddlewareTest extends TestCase +{ + public function testKeyAndSecretIsPassedToParams() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $query = $request->getUri()->getQuery(); + $this->assertRegExp('/client_id=key/', $query); + $this->assertRegExp('/client_secret=client_secret/', $query); + return new Response(200); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(CredentialsAuthMiddleware::middleware('key', 'client_secret')); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'credentials']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } + + public function testKeySecretAndUserKeyIsPassedToParams() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $query = $request->getUri()->getQuery(); + $this->assertRegExp('/client_id=user/', $query); + $this->assertRegExp('/client_secret=client_secret/', $query); + return new Response(200); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(CredentialsAuthMiddleware::middleware('key', 'client_secret', 'user')); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'credentials']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } + + public function testAccessors() + { + $auth = new CredentialsAuthMiddleware(function () { + }, 'key', 'client_secret', 'user'); + static::assertEquals('key', $auth->getApiKey()); + static::assertEquals('client_secret', $auth->getSecret()); + static::assertEquals('user', $auth->getUserKey()); + } + + public function testSubscriberDoesNotDoAnythingForNonHttpsRequests() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $query = $request->getUri()->getQuery(); + $this->assertNotRegExp('/client_id=/', $query); + $this->assertNotRegExp('/client_secret=/', $query); + return new Response(200); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(CredentialsAuthMiddleware::middleware('key', 'secret', 'user')); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'http://example.com'), ['auth' => 'credentials']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } + + public function testSubscriberDoesNotDoAnythingForNonGigyaAuthRequests() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $query = $request->getUri()->getQuery(); + $this->assertNotRegExp('/client_id=/', $query); + $this->assertNotRegExp('/client_secret=/', $query); + return new Response(200); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(CredentialsAuthMiddleware::middleware('key', 'secret', 'user')); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'oauth']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } +} diff --git a/tests/unit/Auth/CredentialsAuthTest.php b/tests/unit/Auth/CredentialsAuthTest.php deleted file mode 100644 index 14c8ee8..0000000 --- a/tests/unit/Auth/CredentialsAuthTest.php +++ /dev/null @@ -1,144 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md - * @link https://github.com/graze/gigya-client - */ - -namespace Graze\Gigya\Test\Unit\Auth; - -use Graze\Gigya\Auth\CredentialsAuth; -use Graze\Gigya\Auth\GigyaAuthInterface; -use Graze\Gigya\Test\TestCase; -use GuzzleHttp\Collection; -use GuzzleHttp\Event\BeforeEvent; -use GuzzleHttp\Event\RequestEvents; -use GuzzleHttp\Event\SubscriberInterface; -use GuzzleHttp\Message\RequestInterface; -use GuzzleHttp\Query; -use Mockery as m; - -class CredentialsAuthTest extends TestCase -{ - public function testInstanceOf() - { - $auth = new CredentialsAuth('key', 'client_secret'); - static::assertInstanceOf(SubscriberInterface::class, $auth); - } - - public function testGetEventsHandlesBeforeAndSignsRequest() - { - $auth = new CredentialsAuth('key', 'client_secret'); - static::assertEquals( - ['before' => ['sign', RequestEvents::SIGN_REQUEST]], - $auth->getEvents() - ); - } - - public function testKeyAndSecretIsPassedToParams() - { - $request = m::mock(RequestInterface::class); - $event = m::mock(BeforeEvent::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - - $query = m::mock(Query::class); - $config = m::mock(Collection::class); - - $request->shouldReceive('getScheme') - ->andReturn('https'); - $request->shouldReceive('getConfig') - ->andReturn($config); - $request->shouldReceive('getQuery') - ->andReturn($query); - - $query->shouldReceive('offsetSet') - ->with('client_id', 'key'); - $query->shouldReceive('offsetSet') - ->with('client_secret', 'client_secret'); - $config->shouldReceive('get') - ->with('auth') - ->andReturn('credentials'); - - $auth = new CredentialsAuth('key', 'client_secret'); - $auth->sign($event); - } - - public function testKeySecretAndUserKeyIsPassedToParams() - { - $request = m::mock(RequestInterface::class); - $event = m::mock(BeforeEvent::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - - $query = m::mock(Query::class); - $config = m::mock(Collection::class); - - $request->shouldReceive('getScheme') - ->andReturn('https'); - $request->shouldReceive('getConfig') - ->andReturn($config); - $request->shouldReceive('getQuery') - ->andReturn($query); - - $query->shouldReceive('offsetSet') - ->with('client_id', 'user'); - $query->shouldReceive('offsetSet') - ->with('client_secret', 'client_secret'); - $config->shouldReceive('get') - ->with('auth') - ->andReturn('credentials'); - - $auth = new CredentialsAuth('key', 'client_secret', 'user'); - $auth->sign($event); - } - - public function testAccessors() - { - $auth = new CredentialsAuth('key', 'client_secret', 'user'); - static::assertEquals('key', $auth->getApiKey()); - static::assertEquals('client_secret', $auth->getSecret()); - static::assertEquals('user', $auth->getUserKey()); - } - - public function testSubscriberDoesNotDoAnythingForNonHttpsRequests() - { - $request = m::mock(RequestInterface::class); - $event = m::mock(BeforeEvent::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - - $request->shouldReceive('getScheme') - ->andReturn('http'); - - $auth = new CredentialsAuth('key', 'client_secret', 'user'); - $auth->sign($event); - } - - public function testSubscriberDoesNotDoAnythingForNonGigyaAuthRequests() - { - $request = m::mock(RequestInterface::class); - $event = m::mock(BeforeEvent::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - - $config = m::mock(Collection::class); - $request->shouldReceive('getScheme') - ->andReturn('https'); - $request->shouldReceive('getConfig') - ->andReturn($config); - - $config->shouldReceive('get') - ->with('auth') - ->andReturn('oauth'); - - $auth = new CredentialsAuth('key', 'client_secret', 'user'); - $auth->sign($event); - } -} diff --git a/tests/unit/Auth/HttpsAuthMiddlewareTest.php b/tests/unit/Auth/HttpsAuthMiddlewareTest.php new file mode 100644 index 0000000..52618f1 --- /dev/null +++ b/tests/unit/Auth/HttpsAuthMiddlewareTest.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md + * @link https://github.com/graze/gigya-client + */ + +namespace Graze\Gigya\Test\Unit\Auth; + +use Graze\Gigya\Auth\HttpsAuthMiddleware; +use Graze\Gigya\Test\TestCase; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Promise\PromiseInterface; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; +use Mockery as m; +use Psr\Http\Message\RequestInterface; + +class HttpsAuthMiddlewareTest extends TestCase +{ + public function testKeyAndSecretIsPassedToParams() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $query = $request->getUri()->getQuery(); + $this->assertRegExp('/apiKey=key/', $query); + $this->assertRegExp('/secret=secret/', $query); + return new Response(200); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(HttpsAuthMiddleware::middleware('key', 'secret')); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'gigya']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } + + public function testKeySecretAndUserKeyIsPassedToParams() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $query = $request->getUri()->getQuery(); + $this->assertRegExp('/apiKey=key/', $query); + $this->assertRegExp('/secret=secret/', $query); + $this->assertRegExp('/userKey=user/', $query); + return new Response(200); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(HttpsAuthMiddleware::middleware('key', 'secret', 'user')); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'gigya']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } + + public function testAccessors() + { + $auth = new HttpsAuthMiddleware(function () { + }, 'key', 'secret', 'user'); + static::assertEquals('key', $auth->getApiKey()); + static::assertEquals('secret', $auth->getSecret()); + static::assertEquals('user', $auth->getUserKey()); + } + + public function testSubscriberDoesNotDoAnythingForNonHttpsRequests() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $query = $request->getUri()->getQuery(); + $this->assertNotRegExp('/apiKey=/', $query); + $this->assertNotRegExp('/secret=/', $query); + $this->assertNotRegExp('/userKey=/', $query); + return new Response(200); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(HttpsAuthMiddleware::middleware('key', 'secret', 'user')); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'http://example.com'), ['auth' => 'gigya']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } + + public function testSubscriberDoesNotDoAnythingForNonGigyaAuthRequests() + { + $handler = new MockHandler([ + function (RequestInterface $request, array $options) { + $query = $request->getUri()->getQuery(); + $this->assertNotRegExp('/apiKey=/', $query); + $this->assertNotRegExp('/secret=/', $query); + $this->assertNotRegExp('/userKey=/', $query); + return new Response(200); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(HttpsAuthMiddleware::middleware('key', 'secret', 'user')); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'http://example.com'), ['auth' => 'oauth']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } +} diff --git a/tests/unit/Auth/HttpsAuthTest.php b/tests/unit/Auth/HttpsAuthTest.php deleted file mode 100644 index 8f7eb8f..0000000 --- a/tests/unit/Auth/HttpsAuthTest.php +++ /dev/null @@ -1,146 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md - * @link https://github.com/graze/gigya-client - */ - -namespace Graze\Gigya\Test\Unit\Auth; - -use Graze\Gigya\Auth\GigyaAuthInterface; -use Graze\Gigya\Auth\HttpsAuth; -use Graze\Gigya\Test\TestCase; -use GuzzleHttp\Collection; -use GuzzleHttp\Event\BeforeEvent; -use GuzzleHttp\Event\RequestEvents; -use GuzzleHttp\Event\SubscriberInterface; -use GuzzleHttp\Message\RequestInterface; -use GuzzleHttp\Query; -use Mockery as m; - -class HttpsAuthTest extends TestCase -{ - public function testInstanceOf() - { - $auth = new HttpsAuth('key', 'secret'); - static::assertInstanceOf(SubscriberInterface::class, $auth); - } - - public function testGetEventsHandlesBeforeAndSignsRequest() - { - $auth = new HttpsAuth('key', 'secret'); - static::assertEquals( - ['before' => ['sign', RequestEvents::SIGN_REQUEST]], - $auth->getEvents() - ); - } - - public function testKeyAndSecretIsPassedToParams() - { - $request = m::mock(RequestInterface::class); - $event = m::mock(BeforeEvent::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - - $query = m::mock(Query::class); - $config = m::mock(Collection::class); - - $request->shouldReceive('getScheme') - ->andReturn('https'); - $request->shouldReceive('getConfig') - ->andReturn($config); - $request->shouldReceive('getQuery') - ->andReturn($query); - - $query->shouldReceive('offsetSet') - ->with('apiKey', 'key'); - $query->shouldReceive('offsetSet') - ->with('secret', 'secret'); - $config->shouldReceive('get') - ->with('auth') - ->andReturn('gigya'); - - $auth = new HttpsAuth('key', 'secret'); - $auth->sign($event); - } - - public function testKeySecretAndUserKeyIsPassedToParams() - { - $request = m::mock(RequestInterface::class); - $event = m::mock(BeforeEvent::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - - $query = m::mock(Query::class); - $config = m::mock(Collection::class); - - $request->shouldReceive('getScheme') - ->andReturn('https'); - $request->shouldReceive('getConfig') - ->andReturn($config); - $request->shouldReceive('getQuery') - ->andReturn($query); - - $query->shouldReceive('offsetSet') - ->with('apiKey', 'key'); - $query->shouldReceive('offsetSet') - ->with('secret', 'secret'); - $query->shouldReceive('offsetSet') - ->with('userKey', 'user'); - $config->shouldReceive('get') - ->with('auth') - ->andReturn('gigya'); - - $auth = new HttpsAuth('key', 'secret', 'user'); - $auth->sign($event); - } - - public function testAccessors() - { - $auth = new HttpsAuth('key', 'secret', 'user'); - static::assertEquals('key', $auth->getApiKey()); - static::assertEquals('secret', $auth->getSecret()); - static::assertEquals('user', $auth->getUserKey()); - } - - public function testSubscriberDoesNotDoAnythingForNonHttpsRequests() - { - $request = m::mock(RequestInterface::class); - $event = m::mock(BeforeEvent::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - - $request->shouldReceive('getScheme') - ->andReturn('http'); - - $auth = new HttpsAuth('key', 'secret', 'user'); - $auth->sign($event); - } - - public function testSubscriberDoesNotDoAnythingForNonGigyaAuthRequests() - { - $request = m::mock(RequestInterface::class); - $event = m::mock(BeforeEvent::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - - $config = m::mock(Collection::class); - $request->shouldReceive('getScheme') - ->andReturn('https'); - $request->shouldReceive('getConfig') - ->andReturn($config); - - $config->shouldReceive('get') - ->with('auth') - ->andReturn('oauth'); - - $auth = new HttpsAuth('key', 'secret', 'user'); - $auth->sign($event); - } -} diff --git a/tests/unit/Auth/OAuth2/OAuth2MiddlewareTest.php b/tests/unit/Auth/OAuth2/OAuth2MiddlewareTest.php new file mode 100644 index 0000000..0f1b202 --- /dev/null +++ b/tests/unit/Auth/OAuth2/OAuth2MiddlewareTest.php @@ -0,0 +1,193 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md + * @link https://github.com/graze/gigya-client + */ + +namespace Graze\Gigya\Test\Unit\Auth\OAuth2; + +use Graze\Gigya\Auth\OAuth2\AccessToken; +use Graze\Gigya\Auth\OAuth2\GrantInterface; +use Graze\Gigya\Auth\OAuth2\OAuth2Middleware; +use Graze\Gigya\Test\TestCase; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Promise\PromiseInterface; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; +use Mockery as m; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + +class OAuth2MiddlewareTest extends TestCase +{ + /** @var mixed */ + private $grant; + + public function setUp() + { + $this->grant = m::mock(GrantInterface::class); + } + + public function testSign() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $this->assertEquals('OAuth test', $request->getHeaderLine('Authorization')); + return new Response(200); + }, + ]); + + $token = new AccessToken('test'); + $this->grant->shouldReceive('getToken') + ->andReturn($token); + + $stack = new HandlerStack($handler); + $stack->push(OAuth2Middleware::middleware($this->grant)); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'gigya-oauth2']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } + + public function testErrorThatIsNot401() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $this->assertEquals('OAuth test', $request->getHeaderLine('Authorization')); + return new Response(503); + }, + ]); + + $token = new AccessToken('test'); + $this->grant->shouldReceive('getToken') + ->andReturn($token); + + $stack = new HandlerStack($handler); + $stack->push(OAuth2Middleware::middleware($this->grant)); + + $comp = $stack->resolve(); + + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'gigya-oauth2']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + } + + public function testErrorThatIsNotRetried() + { + $handler = new MockHandler([ + function (RequestInterface $request, array $options) { + $this->assertEquals('OAuth test', $request->getHeaderLine('Authorization')); + $this->assertEquals(1, $options['retries']); + return new Response(401); + }, + ]); + + $token = new AccessToken('test'); + $this->grant->shouldReceive('getToken') + ->andReturn($token); + + $stack = new HandlerStack($handler); + $stack->push(OAuth2Middleware::middleware($this->grant)); + + $comp = $stack->resolve(); + + /** @var PromiseInterface $promise */ + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'gigya-oauth2', 'retries' => 1]); + $this->assertInstanceOf(PromiseInterface::class, $promise); + /** @var ResponseInterface $response */ + $response = $promise->wait(); + $this->assertEquals(401, $response->getStatusCode()); + } + + public function testErrorThatIsRetried() + { + $handler = new MockHandler([ + function (RequestInterface $request, array $options) { + $this->assertEquals('OAuth test', $request->getHeaderLine('Authorization')); + if (isset($options['retries'])) { + $this->assertEquals(0, $options['retries']); + } + return new Response(401); + }, + function (RequestInterface $request, array $options) { + $this->assertEquals('OAuth test2', $request->getHeaderLine('Authorization')); + $this->assertEquals(1, $options['retries']); + return new Response(200); + }, + ]); + + $token1 = new AccessToken('test'); + $token2 = new AccessToken('test2'); + $this->grant->shouldReceive('getToken') + ->andReturn($token1, $token2); + + $stack = new HandlerStack($handler); + $stack->push(OAuth2Middleware::middleware($this->grant)); + + $comp = $stack->resolve(); + + /** @var PromiseInterface $promise */ + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'gigya-oauth2']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + /** @var ResponseInterface $response */ + $response = $promise->wait(); + $this->assertEquals(200, $response->getStatusCode()); + } + + public function testErrorThatIsNotOauthAuth() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $this->assertEquals('', $request->getHeaderLine('Authorization')); + return new Response(401); + }, + ]); + + $stack = new HandlerStack($handler); + $stack->push(OAuth2Middleware::middleware($this->grant)); + + $comp = $stack->resolve(); + + /** @var PromiseInterface $promise */ + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'none']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + /** @var ResponseInterface $response */ + $response = $promise->wait(true); + $this->assertEquals(401, $response->getStatusCode()); + } + + public function testErrorWhenNoTokenIsReturnedWillNotIntercept() + { + $handler = new MockHandler([ + function (RequestInterface $request) { + $this->assertEquals('', $request->getHeaderLine('Authorization')); + return new Response(401); + }, + ]); + + $this->grant->shouldReceive('getToken') + ->atLeast() + ->once() + ->andReturn(null); + + $stack = new HandlerStack($handler); + $stack->push(OAuth2Middleware::middleware($this->grant)); + + $comp = $stack->resolve(); + + /** @var PromiseInterface $promise */ + $promise = $comp(new Request('GET', 'https://example.com'), ['auth' => 'gigya-oauth2']); + $this->assertInstanceOf(PromiseInterface::class, $promise); + /** @var ResponseInterface $response */ + $response = $promise->wait(true); + $this->assertEquals(401, $response->getStatusCode()); + } +} diff --git a/tests/unit/Auth/OAuth2/OAuth2SubscriberTest.php b/tests/unit/Auth/OAuth2/OAuth2SubscriberTest.php deleted file mode 100644 index 9c5bea1..0000000 --- a/tests/unit/Auth/OAuth2/OAuth2SubscriberTest.php +++ /dev/null @@ -1,229 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md - * @link https://github.com/graze/gigya-client - */ - -namespace Graze\Gigya\Test\Unit\Auth\OAuth2; - -use Graze\Gigya\Auth\OAuth2\AccessToken; -use Graze\Gigya\Auth\OAuth2\GrantInterface; -use Graze\Gigya\Auth\OAuth2\OAuth2Subscriber; -use Graze\Gigya\Test\TestCase; -use GuzzleHttp\Collection; -use GuzzleHttp\Event\BeforeEvent; -use GuzzleHttp\Event\ErrorEvent; -use GuzzleHttp\Event\RequestEvents; -use GuzzleHttp\Event\SubscriberInterface; -use GuzzleHttp\Message\RequestInterface; -use GuzzleHttp\Message\ResponseInterface; -use Mockery as m; - -class OAuth2SubscriberTest extends TestCase -{ - /** @var mixed */ - private $grant; - /** @var OAuth2Subscriber */ - private $subscriber; - - public function setUp() - { - $this->grant = m::mock(GrantInterface::class); - $this->subscriber = new OAuth2Subscriber($this->grant); - } - - public function testInstanceOf() - { - static::assertInstanceOf(SubscriberInterface::class, $this->subscriber); - } - - public function testGetEvents() - { - static::assertEquals([ - 'before' => ['sign', RequestEvents::SIGN_REQUEST], - 'error' => ['error', RequestEvents::EARLY], - ], $this->subscriber->getEvents()); - } - - public function testSign() - { - $event = m::mock(BeforeEvent::class); - $request = m::mock(RequestInterface::class); - $event->shouldReceive('getRequest') - ->andReturn($request); - $request->shouldReceive('getScheme') - ->andReturn('https'); - $request->shouldReceive('getConfig->get') - ->with('auth') - ->andReturn('gigya-oauth2'); - - $token = new AccessToken('test'); - - $this->grant->shouldReceive('getToken') - ->andReturn($token); - - $request->shouldReceive('addHeader') - ->with('Authorization', 'OAuth test') - ->once(); - - $this->subscriber->sign($event); - } - - public function testErrorThatIsNot401() - { - $event = m::mock(ErrorEvent::class); - $response = m::mock(ResponseInterface::class); - $event->shouldReceive('getResponse') - ->andReturn($response); - $response->shouldReceive('getStatusCode') - ->andReturn(503); - $this->subscriber->error($event); - } - - public function testErrorThatIsNotRetried() - { - $event = m::mock(ErrorEvent::class); - - $response = m::mock(ResponseInterface::class); - $event->shouldReceive('getResponse') - ->atLeast() - ->once() - ->andReturn($response); - $response->shouldReceive('getStatusCode') - ->atLeast() - ->once() - ->andReturn(401); - - $request = m::mock(RequestInterface::class); - $event->shouldReceive('getRequest') - ->atLeast() - ->once() - ->andReturn($request); - $request->shouldReceive('getScheme') - ->atLeast() - ->once() - ->andReturn('https'); - $config = m::mock(Collection::class); - $request->shouldReceive('getConfig') - ->atLeast() - ->once() - ->andReturn($config); - $config->shouldReceive('get') - ->with('auth') - ->atLeast() - ->once() - ->andReturn('gigya-oauth2'); - $config->shouldReceive('get') - ->with('retried') - ->atLeast() - ->once() - ->andReturn(false); - - $token = new AccessToken('test2'); - $this->grant->shouldReceive('getToken') - ->andReturn($token); - - $config->shouldReceive('set') - ->with('retried', true) - ->atLeast() - ->once(); - - $newResponse = m::mock(ResponseInterface::class); - - $event->shouldReceive('getClient->send') - ->with($request) - ->atLeast() - ->once() - ->andReturn($newResponse); - $event->shouldReceive('intercept') - ->atLeast() - ->once() - ->with($newResponse); - - $this->subscriber->error($event); - } - - public function testErrorThatIsNotOauthAuth() - { - $event = m::mock(ErrorEvent::class); - - $response = m::mock(ResponseInterface::class); - $event->shouldReceive('getResponse') - ->atLeast() - ->once() - ->andReturn($response); - $response->shouldReceive('getStatusCode') - ->atLeast() - ->once() - ->andReturn(401); - - $request = m::mock(RequestInterface::class); - $event->shouldReceive('getRequest') - ->atLeast() - ->once() - ->andReturn($request); - $request->shouldReceive('getScheme') - ->atLeast() - ->once() - ->andReturn('https'); - $request->shouldReceive('getConfig->get') - ->with('auth') - ->atLeast() - ->once() - ->andReturn('none'); - - $this->subscriber->error($event); - } - - public function testErrorWhenNoTokenIsReturnedWillNotIntercept() - { - $event = m::mock(ErrorEvent::class); - - $response = m::mock(ResponseInterface::class); - $event->shouldReceive('getResponse') - ->atLeast() - ->once() - ->andReturn($response); - $response->shouldReceive('getStatusCode') - ->atLeast() - ->once() - ->andReturn(401); - - $request = m::mock(RequestInterface::class); - $event->shouldReceive('getRequest') - ->atLeast() - ->once() - ->andReturn($request); - $request->shouldReceive('getScheme') - ->atLeast() - ->once() - ->andReturn('https'); - $config = m::mock(Collection::class); - $request->shouldReceive('getConfig') - ->atLeast() - ->once() - ->andReturn($config); - $config->shouldReceive('get') - ->with('auth') - ->atLeast() - ->once() - ->andReturn('gigya-oauth2'); - $config->shouldReceive('get') - ->with('retried') - ->atLeast() - ->once() - ->andReturn(false); - - $this->grant->shouldReceive('getToken') - ->andReturn(null); - - $this->subscriber->error($event); - } -} diff --git a/tests/unit/Exception/ResponseExceptionTest.php b/tests/unit/Exception/ResponseExceptionTest.php index 52bd0f6..8aea56d 100644 --- a/tests/unit/Exception/ResponseExceptionTest.php +++ b/tests/unit/Exception/ResponseExceptionTest.php @@ -39,11 +39,9 @@ public function testExceptionIncludeResponseStringAndCode() ->andReturn('some description from the response'); $exception = new ResponseException($response); - static::setExpectedException( - ResponseException::class, - 'some description from the response', - 100001 - ); + static::expectException(ResponseException::class); + static::expectExceptionMessage('some description from the response'); + static::expectExceptionCode(100001); throw $exception; } diff --git a/tests/unit/GigyaTest.php b/tests/unit/GigyaTest.php index 7dbfe48..e82e1df 100644 --- a/tests/unit/GigyaTest.php +++ b/tests/unit/GigyaTest.php @@ -14,16 +14,13 @@ namespace Graze\Gigya\Test\Unit; use Exception; -use Graze\Gigya\Auth\CredentialsAuth; -use Graze\Gigya\Auth\HttpsAuth; -use Graze\Gigya\Auth\OAuth2\OAuth2Subscriber; use Graze\Gigya\Gigya; +use Graze\Gigya\Response\ResponseFactoryInterface; use Graze\Gigya\Test\TestCase; use Graze\Gigya\Test\TestFixtures; use Graze\Gigya\Validation\ResponseValidatorInterface; -use Graze\Gigya\Validation\ValidGigyaResponseSubscriber; -use GuzzleHttp\Event\EmitterInterface; -use GuzzleHttp\Event\SubscriberInterface; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Psr7\Response; use Mockery as m; /** @@ -32,30 +29,23 @@ */ class GigyaTest extends TestCase { - /** @var mixed */ - private $guzzleClient; /** @var mixed */ private $factory; /** @var string */ private $certPath; /** @var mixed */ - private $emitter; + private $handlerStack; + /** @var mixed */ + private $guzzleClient; public function setUp() { $this->guzzleClient = m::mock('overload:GuzzleHttp\Client'); - $this->emitter = m::mock(EmitterInterface::class); - $this->guzzleClient->shouldReceive('getEmitter') - ->andReturn($this->emitter); - $this->factory = m::mock('Graze\Gigya\Response\ResponseFactoryInterface'); + $this->handlerStack = m::mock(new HandlerStack())->makePartial(); + $this->factory = m::mock(ResponseFactoryInterface::class); $this->certPath = realpath(__DIR__ . '/../../src/' . Gigya::CERTIFICATE_FILE); } - public function tearDown() - { - $this->guzzleClient = $this->factory = null; - } - /** * @param string $key * @param string $secret @@ -69,53 +59,22 @@ public function createClient($key = 'key', $secret = 'secret', $dc = Gigya::DC_E $options = [ 'uidValidator' => false, 'factory' => $this->factory, + 'guzzle' => ['handler' => $this->handlerStack], ]; return new Gigya($key, $secret, $dc, $userKey, $options); } /** - * Setup the subscribers - * - * @param string $key - * @param string $secret - * @param string|null $userKey - */ - private function setupSubscribers($key, $secret, $userKey = null) - { - $subscriber = function (SubscriberInterface $subscriber) use ($key, $secret, $userKey) { - if ($subscriber instanceof HttpsAuth) { - static::assertEquals($key, $subscriber->getApiKey()); - static::assertEquals($secret, $subscriber->getSecret()); - static::assertEquals($userKey, $subscriber->getUserKey()); - } - - return true; - }; - $this->emitter->shouldReceive('attach') - ->with(m::type(ValidGigyaResponseSubscriber::class)) - ->once(); - $this->emitter->shouldReceive('attach') - ->with(m::on($subscriber)) - ->once(); - } - - /** - * @param string $fixtureName - * @param string $uri - * @param array $getOptions - * @param string $key - * @param string $secret - * @param string|null $userKey + * @param string $fixtureName + * @param string $uri + * @param array $getOptions * * @return mixed MockInterface and ResponseInterface */ - private function setupCall($fixtureName, $uri, array $getOptions, $key, $secret, $userKey = null) + private function setupCall($fixtureName, $uri, array $getOptions) { - $this->setupSubscribers($key, $secret, $userKey); - - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $response->shouldReceive('getBody')->andReturn(TestFixtures::getFixture($fixtureName)); + $response = new Response(200, [], TestFixtures::getFixture($fixtureName)); $this->guzzleClient->shouldReceive('get') ->with( @@ -133,28 +92,22 @@ private function setupCall($fixtureName, $uri, array $getOptions, $key, $secret, return $gigyaResponse; } + public function testDefaultConstructor() + { + $client = new Gigya('key', 'secret'); + static::assertInstanceOf(Gigya::class, $client); + } + public function testConstructorConfig() { $this->guzzleClient->shouldReceive('__construct') ->once() ->with([ - 'emitter' => $this->emitter, + 'handler' => $this->handlerStack, ]) ->andReturn($this->guzzleClient); - $this->emitter->shouldReceive('attach') - ->with(m::type(HttpsAuth::class)) - ->once(); - $this->emitter->shouldReceive('attach') - ->with(m::type(CredentialsAuth::class)) - ->once(); - - $this->emitter->shouldReceive('attach') - ->with(m::type(ValidGigyaResponseSubscriber::class)) - ->once(); - - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $response->shouldReceive('getBody')->andReturn(TestFixtures::getFixture('account.getAccountInfo')); + $response = new Response(200, [], TestFixtures::getFixture('account.getAccountInfo')); $this->guzzleClient->shouldReceive('get') ->with( @@ -179,7 +132,7 @@ public function testConstructorConfig() 'uidValidator' => false, 'factory' => $this->factory, 'guzzle' => [ - 'emitter' => $this->emitter, + 'handler' => $this->handlerStack, ], 'options' => [ 'cert' => 'some_cert.pem', @@ -195,22 +148,11 @@ public function testOAuth2AuthConstructor() $this->guzzleClient->shouldReceive('__construct') ->once() ->with([ - 'emitter' => $this->emitter, + 'handler' => $this->handlerStack, ]) ->andReturn($this->guzzleClient); - $this->emitter->shouldReceive('attach') - ->with(m::type(HttpsAuth::class)) - ->once(); - $this->emitter->shouldReceive('attach') - ->with(m::type(CredentialsAuth::class)) - ->once(); - $this->emitter->shouldReceive('attach') - ->with(m::type(OAuth2Subscriber::class)) - ->once(); - - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $response->shouldReceive('getBody')->andReturn(TestFixtures::getFixture('account.getAccountInfo')); + $response = new Response(200, [], TestFixtures::getFixture('account.getAccountInfo')); $this->guzzleClient->shouldReceive('get') ->with( @@ -235,7 +177,7 @@ public function testOAuth2AuthConstructor() 'uidValidator' => false, 'factory' => $this->factory, 'guzzle' => [ - 'emitter' => $this->emitter, + 'handler' => $this->handlerStack, ], 'options' => [ 'cert' => 'some_cert.pem', @@ -250,20 +192,12 @@ public function testCredentialsAuthConstructor() { $this->guzzleClient->shouldReceive('__construct') ->with([ - 'emitter' => $this->emitter, + 'handler' => $this->handlerStack, ]) ->once() ->andReturn($this->guzzleClient); - $this->emitter->shouldReceive('attach') - ->with(m::type(HttpsAuth::class)) - ->once(); - $this->emitter->shouldReceive('attach') - ->with(m::type(CredentialsAuth::class)) - ->once(); - - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $response->shouldReceive('getBody')->andReturn(TestFixtures::getFixture('account.getAccountInfo')); + $response = new Response(200, [], TestFixtures::getFixture('account.getAccountInfo')); $this->guzzleClient->shouldReceive('get') ->with( @@ -290,7 +224,7 @@ public function testCredentialsAuthConstructor() 'uidValidator' => false, 'factory' => $this->factory, 'guzzle' => [ - 'emitter' => $this->emitter, + 'handler' => $this->handlerStack, ], 'options' => [ 'cert' => 'some_cert.pem', @@ -313,9 +247,7 @@ public function testSettingKeyAndSecretWillPassToGuzzleClient() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - $key, - $secret + ] ); $client = $this->createClient($key, $secret, Gigya::DC_EU, null); $client->setFactory($this->factory); @@ -334,9 +266,7 @@ public function testSettingDataCenterToAuWillCallAuUri() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - 'key', - 'secret' + ] ); $client = $this->createClient('key', 'secret', Gigya::DC_AU); @@ -354,9 +284,7 @@ public function testSettingDataCenterToUsWillCallUsUri() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - 'key', - 'secret' + ] ); $client = $this->createClient('key', 'secret', Gigya::DC_US); @@ -374,10 +302,7 @@ public function testSettingTheUserKeyWillPassItThroughToGuzzle() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - 'key', - 'userSecret', - 'userKey' + ] ); $client = $this->createClient('key', 'userSecret', Gigya::DC_EU, 'userKey'); $client->setFactory($this->factory); @@ -398,9 +323,7 @@ public function testPassingParamsThroughToTheMethodWillPassThroughToGuzzle() 'query' => [ 'param' => 'passedThrough', ], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -420,9 +343,7 @@ public function testCallingChildMethodsCallTheCorrectUri() 'query' => [ 'params' => 'passedThrough', ], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -442,9 +363,7 @@ public function testTfaCallingChildMethodsCallTheCorrectUri() 'query' => [ 'params' => 'passedThrough', ], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -471,9 +390,7 @@ public function testClientCalls($namespace, $method, $expectedUri) 'query' => [ 'params' => 'passedThrough', ], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -484,12 +401,9 @@ public function testClientCalls($namespace, $method, $expectedUri) public function testCallingMagicMethodWithArgumentsThrowsAnException() { - static::setExpectedException( - 'BadMethodCallException', - 'No Arguments should be supplied for Gigya call' - ); + static::expectException('BadMethodCallException'); + static::expectExceptionMessage('No Arguments should be supplied for Gigya call'); - $this->setupSubscribers('key', 'secret'); $client = $this->createClient(); $client->custom('params'); } @@ -507,9 +421,7 @@ public function testAddingOptionsPassesThroughTheOptionsToGuzzle() ], 'option1' => 'value1', 'option2' => false, - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -534,9 +446,7 @@ public function testAddingOptionsWithASingleCallPassesThroughTheOptionsToGuzzle( ], 'option1' => 'value1', 'option2' => true, - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -562,9 +472,7 @@ public function testAddingTheSameOptionAgainWillTakeTheLastValueSet() 'params' => 'passedThrough', ], 'option1' => false, - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -588,9 +496,7 @@ public function testAddingTheSameOptionAgainWithAddOptionsWillTakeTheLastValueSe 'params' => 'passedThrough', ], 'option1' => true, - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -613,9 +519,7 @@ public function testAddingQueryOptionsWillBeIgnored() 'query' => [ 'params' => 'passedThrough', ], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -639,9 +543,7 @@ public function testSettingOptionsAsPartOfTheQuery() 'params' => 'passedThrough', ], 'custom' => 'value', - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -662,9 +564,7 @@ public function testSettingGlobalAndRequestOptionsTheRequestOptionsOverrideGloba 'params' => 'passedThrough', ], 'custom' => 'value', - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -686,9 +586,7 @@ public function testSettingRequestOptionsDoOverrideTheParams() 'query' => [ 'params' => 'passedThrough', ], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -711,9 +609,7 @@ public function testSettingParamsWillNotOverwriteTheDefaultParams() 'query' => [ 'secret' => 'newSecret', ], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -735,9 +631,7 @@ public function testCallingAChainWillCallThatChain() 'query' => [ 'secret' => 'newSecret', ], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -757,9 +651,7 @@ public function testWillCallAValidator() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -784,9 +676,7 @@ public function tesWillCallMultipleValidators() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -819,9 +709,7 @@ public function testTheValidatorThrowingAnExceptionWillPassthrough() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -837,7 +725,7 @@ public function testTheValidatorThrowingAnExceptionWillPassthrough() ->with($response) ->andThrow($exception); - static::setExpectedException(Exception::class); + static::expectException(Exception::class); $client->accounts()->getAccountInfo(); } @@ -851,9 +739,7 @@ public function testTheValidatorWillOnlyCallAssertWhenItCanValidate() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); @@ -883,26 +769,26 @@ public function testRemoveSubscriberWillDetachFromEmitter() 'auth' => 'gigya', 'verify' => $this->certPath, 'query' => [], - ], - 'key', - 'secret' + ] ); $client = $this->createClient(); static::assertSame($response, $client->accounts()->getAccountInfo()); - $subscriber = m::mock(SubscriberInterface::class); - $this->emitter->shouldReceive('attach') - ->with($subscriber) - ->once(); + $fn = function (callable $handler) { + return $handler; + }; + $this->handlerStack->shouldReceive('push') + ->with($fn) + ->once(); - $client->addSubscriber($subscriber); + $client->addHandler($fn); - $this->emitter->shouldReceive('detach') - ->with($subscriber) - ->once(); + $this->handlerStack->shouldReceive('remove') + ->with($fn) + ->once(); - $client->removeSubscriber($subscriber); + $client->removeHandler($fn); } /** diff --git a/tests/unit/Response/ResponseFactoryTest.php b/tests/unit/Response/ResponseFactoryTest.php index e7ba165..5b6a056 100644 --- a/tests/unit/Response/ResponseFactoryTest.php +++ b/tests/unit/Response/ResponseFactoryTest.php @@ -20,8 +20,7 @@ use Graze\Gigya\Test\TestCase; use Graze\Gigya\Test\TestFixtures; use Mockery as m; - -// use Psr\Http\Message\ResponseInterface; Guzzle v6 +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; class ResponseFactoryTest extends TestCase { @@ -47,9 +46,9 @@ public function tearDown() public function testAccountModel() { - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $response->shouldReceive('json') - ->andReturn(json_decode(TestFixtures::getFixture('accounts.getAccountInfo'))); + $response = m::mock(GuzzleResponseInterface::class); + $response->shouldReceive('getBody') + ->andReturn($this->tostream(TestFixtures::getFixture('accounts.getAccountInfo'))); $gigyaResponse = $this->factory->getResponse($response); @@ -70,9 +69,9 @@ public function testAccountModel() public function testCollectionModel() { - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $response->shouldReceive('json') - ->andReturn(json_decode(TestFixtures::getFixture('accounts.search_simple'))); + $response = m::mock(GuzzleResponseInterface::class); + $response->shouldReceive('getBody') + ->andReturn($this->tostream(TestFixtures::getFixture('accounts.search_simple'))); /** @var ResponseCollectionInterface $gigyaResponse */ $gigyaResponse = $this->factory->getResponse($response); @@ -91,9 +90,9 @@ public function testCollectionModel() public function testError403() { - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $response->shouldReceive('json') - ->andReturn(json_decode(TestFixtures::getFixture('failure_403'))); + $response = m::mock(GuzzleResponseInterface::class); + $response->shouldReceive('getBody') + ->andReturn($this->tostream(TestFixtures::getFixture('failure_403'))); $gigyaResponse = $this->factory->getResponse($response); diff --git a/tests/unit/Response/ResponseTest.php b/tests/unit/Response/ResponseTest.php index 06c45d3..b950d37 100644 --- a/tests/unit/Response/ResponseTest.php +++ b/tests/unit/Response/ResponseTest.php @@ -18,8 +18,8 @@ use Graze\Gigya\Response\Response; use Graze\Gigya\Test\TestCase; use Graze\Gigya\Test\TestFixtures; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponseInterface; use Mockery as m; +use Psr\Http\Message\ResponseInterface as GuzzleResponseInterface; class ResponseTest extends TestCase { @@ -61,7 +61,7 @@ public function testOtherTimeZoneFormat() public function testToString() { $guzzleResponse = m::mock(GuzzleResponseInterface::class); - $guzzleResponse->shouldReceive('json')->andReturn(json_decode(TestFixtures::getFixture('accounts.getAccountInfo'))); + $guzzleResponse->shouldReceive('getBody')->andReturn($this->toStream(TestFixtures::getFixture('accounts.getAccountInfo'))); $response = new Response($guzzleResponse); static::assertRegExp('/Response: \d+: \w+ - \d+: .+\n.+/s', $response->__toString()); @@ -70,7 +70,7 @@ public function testToString() public function testToStringForFailure() { $guzzleResponse = m::mock(GuzzleResponseInterface::class); - $guzzleResponse->shouldReceive('json')->andReturn(json_decode(TestFixtures::getFixture('failure_403'))); + $guzzleResponse->shouldReceive('getBody')->andReturn($this->toStream(TestFixtures::getFixture('failure_403'))); $response = new Response($guzzleResponse); static::assertRegExp('/Response: \d+: \w+ - \d+: .+\n.+\n.+\n.+/s', $response->__toString()); diff --git a/tests/unit/Validation/UidSignatureValidatorTest.php b/tests/unit/Validation/UidSignatureValidatorTest.php index d210795..9b18e98 100644 --- a/tests/unit/Validation/UidSignatureValidatorTest.php +++ b/tests/unit/Validation/UidSignatureValidatorTest.php @@ -120,7 +120,7 @@ public function testInvalidUidSignature() $response->shouldReceive('getErrorCode') ->andReturn(0); - static::setExpectedException(InvalidUidSignatureException::class); + static::expectException(InvalidUidSignatureException::class); $this->validator->assert($response); } @@ -158,7 +158,7 @@ public function testInvalidTimestamp() $response->shouldReceive('getErrorCode') ->andReturn(0); - static::setExpectedException(InvalidTimestampException::class); + static::expectException(InvalidTimestampException::class); $this->validator->assert($response); } diff --git a/tests/unit/Validation/ValidGigyaResponseMiddlewareTest.php b/tests/unit/Validation/ValidGigyaResponseMiddlewareTest.php new file mode 100644 index 0000000..20020e2 --- /dev/null +++ b/tests/unit/Validation/ValidGigyaResponseMiddlewareTest.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md + * @link https://github.com/graze/gigya-client + */ + +namespace Graze\Gigya\Test\Unit\Validation; + +use Graze\Gigya\Exception\UnknownResponseException; +use Graze\Gigya\Test\TestCase; +use Graze\Gigya\Test\TestFixtures; +use Graze\Gigya\Validation\ValidGigyaResponseMiddleware; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; +use Mockery as m; + +class ValidGigyaResponseMiddlewareTest extends TestCase +{ + public function testValidResponse() + { + $handler = new MockHandler([ + new Response(200, [], TestFixtures::getFixture('accounts.search_simple')), + ]); + + $middleware = ValidGigyaResponseMiddleware::middleware(); + + $func = $middleware($handler); + $func(new Request('GET', 'https://foo.com'), [])->wait(); + } + + public function testMissingFieldWillThrowAnException() + { + $handler = new MockHandler([ + new Response(200, [], TestFixtures::getFixture('missing_field')), + ]); + + $this->expectException(UnknownResponseException::class); + $this->expectExceptionMessage("The contents of the response could not be determined. Missing required field: 'statusReason'"); + + $middleware = ValidGigyaResponseMiddleware::middleware(); + + $func = $middleware($handler); + $func(new Request('GET', 'https://foo.com'), [])->wait(); + } + + public function testNoBodyWillFail() + { + $handler = new MockHandler([ + new Response(200), + ]); + + $this->expectException(UnknownResponseException::class); + $this->expectExceptionMessage('The contents of the response could not be determined'); + + $middleware = ValidGigyaResponseMiddleware::middleware(); + + $func = $middleware($handler); + $func(new Request('GET', 'https://foo.com'), [])->wait(); + } + + public function testInvalidBody() + { + $handler = new MockHandler([ + new Response(200, [], TestFixtures::getFixture('invalid_json')), + ]); + + $this->expectException(UnknownResponseException::class); + $this->expectExceptionMessage('The contents of the response could not be determined. Could not decode the body'); + + $middleware = ValidGigyaResponseMiddleware::middleware(); + + $func = $middleware($handler); + $func(new Request('GET', 'https://foo.com'), [])->wait(); + } + + public function testUnknownResponseContainsTheOriginalResponse() + { + $response = new Response(200, [], TestFixtures::getFixture('invalid_json')); + $handler = new MockHandler([$response]); + + $middleware = ValidGigyaResponseMiddleware::middleware(); + + $func = $middleware($handler); + try { + $func(new Request('GET', 'https://foo.com'), [])->wait(); + } catch (UnknownResponseException $e) { + $this->assertSame($response, $e->getResponse()); + } + } +} diff --git a/tests/unit/Validation/ValidGigyaResponseSubscriberTest.php b/tests/unit/Validation/ValidGigyaResponseSubscriberTest.php deleted file mode 100644 index 23374e9..0000000 --- a/tests/unit/Validation/ValidGigyaResponseSubscriberTest.php +++ /dev/null @@ -1,145 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - * - * @license https://github.com/graze/gigya-client/blob/master/LICENSE.md - * @link https://github.com/graze/gigya-client - */ - -namespace Graze\Gigya\Test\Unit\Validation; - -use Graze\Gigya\Exception\UnknownResponseException; -use Graze\Gigya\Test\TestCase; -use Graze\Gigya\Test\TestFixtures; -use Graze\Gigya\Validation\ValidGigyaResponseSubscriber; -use GuzzleHttp\Event\CompleteEvent; -use GuzzleHttp\Event\RequestEvents; -use GuzzleHttp\Event\SubscriberInterface; -use Mockery as m; - -class ValidGigyaResponseSubscriberTest extends TestCase -{ - /** - * @var ValidGigyaResponseSubscriber - */ - private $validator; - - public function setUp() - { - $this->validator = new ValidGigyaResponseSubscriber(); - } - - public function tearDown() - { - $this->validator = null; - } - - public function testInstanceOf() - { - static::assertInstanceOf(SubscriberInterface::class, $this->validator); - } - - public function testGetEvents() - { - static::assertEquals( - ['complete' => ['onComplete', RequestEvents::VERIFY_RESPONSE]], - $this->validator->getEvents() - ); - } - - /** - * @throws \Graze\Gigya\Exception\UnknownResponseException - */ - public function testValidResponse() - { - $completeEvent = m::mock(CompleteEvent::class); - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $completeEvent->shouldReceive('getResponse') - ->andReturn($response); - $response->shouldReceive('getBody')->andReturn(TestFixtures::getFixture('accounts.search_simple')); - - $this->validator->onComplete($completeEvent, 'name'); - } - - public function testNullResponseWillThrowAnException() - { - $completeEvent = m::mock(CompleteEvent::class); - $completeEvent->shouldReceive('getResponse') - ->andReturn(null); - - static::setExpectedException( - 'Graze\Gigya\Exception\UnknownResponseException', - 'The contents of the response could not be determined. No response provided' - ); - - $this->validator->onComplete($completeEvent, 'name'); - } - - public function testMissingFieldWillThrowAnException() - { - $completeEvent = m::mock(CompleteEvent::class); - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $completeEvent->shouldReceive('getResponse') - ->andReturn($response); - $response->shouldReceive('getBody')->andReturn(TestFixtures::getFixture('missing_field')); - - static::setExpectedException( - 'Graze\Gigya\Exception\UnknownResponseException', - "The contents of the response could not be determined. Missing required field: 'statusReason'" - ); - - $this->validator->onComplete($completeEvent, 'name'); - } - - public function testNoBodyWillFail() - { - $completeEvent = m::mock(CompleteEvent::class); - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $completeEvent->shouldReceive('getResponse') - ->andReturn($response); - $response->shouldReceive('getBody')->andReturn(''); - - static::setExpectedException( - 'Graze\Gigya\Exception\UnknownResponseException', - 'The contents of the response could not be determined' - ); - - $this->validator->onComplete($completeEvent, 'name'); - } - - public function testInvalidBody() - { - $completeEvent = m::mock(CompleteEvent::class); - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $completeEvent->shouldReceive('getResponse') - ->andReturn($response); - $response->shouldReceive('getBody')->andReturn(TestFixtures::getFixture('invalid_json')); - - static::setExpectedException( - 'Graze\Gigya\Exception\UnknownResponseException', - 'The contents of the response could not be determined. Could not decode the body' - ); - - $this->validator->onComplete($completeEvent, 'name'); - } - - public function testUnknownResponseContainsTheOriginalResponse() - { - $completeEvent = m::mock(CompleteEvent::class); - $response = m::mock('GuzzleHttp\Message\ResponseInterface'); - $completeEvent->shouldReceive('getResponse') - ->andReturn($response); - $response->shouldReceive('getBody')->andReturn(TestFixtures::getFixture('invalid_json')); - - try { - $this->validator->onComplete($completeEvent, 'name'); - } catch (UnknownResponseException $e) { - static::assertSame($response, $e->getResponse()); - } - } -}