2016-10-24 20:01:32 +03:00
|
|
|
<?php
|
|
|
|
|
2019-01-09 22:32:09 +03:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2016-11-24 01:02:12 +03:00
|
|
|
/*
|
2017-11-22 11:37:04 +03:00
|
|
|
* Copyright (C) 2013 Mailgun
|
2016-11-24 01:02:12 +03:00
|
|
|
*
|
|
|
|
* This software may be modified and distributed under the terms
|
2016-12-06 21:12:52 +03:00
|
|
|
* of the MIT license. See the LICENSE file for details.
|
2016-11-24 01:02:12 +03:00
|
|
|
*/
|
|
|
|
|
2016-10-24 20:01:32 +03:00
|
|
|
namespace Mailgun\Tests\Api;
|
|
|
|
|
2018-08-05 01:45:03 +03:00
|
|
|
use GuzzleHttp\Psr7\Request;
|
|
|
|
use GuzzleHttp\Psr7\Response;
|
2018-08-05 10:54:41 +03:00
|
|
|
use Mailgun\Hydrator\ModelHydrator;
|
2018-08-05 01:45:03 +03:00
|
|
|
use Psr\Http\Message\ResponseInterface;
|
2017-04-08 11:34:57 +03:00
|
|
|
|
2016-10-24 20:01:32 +03:00
|
|
|
/**
|
|
|
|
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
|
|
|
* @author Contributors of https://github.com/KnpLabs/php-github-api
|
|
|
|
*/
|
2019-01-09 22:18:58 +03:00
|
|
|
abstract class TestCase extends \PHPUnit\Framework\TestCase
|
2016-10-24 20:01:32 +03:00
|
|
|
{
|
2018-08-05 01:45:03 +03:00
|
|
|
private $requestMethod;
|
2018-08-05 10:55:49 +03:00
|
|
|
|
2018-08-05 01:45:03 +03:00
|
|
|
private $requestUri;
|
2018-08-05 10:55:49 +03:00
|
|
|
|
2018-08-05 01:45:03 +03:00
|
|
|
private $requestHeaders;
|
2018-08-05 10:55:49 +03:00
|
|
|
|
2018-08-05 01:45:03 +03:00
|
|
|
private $requestBody;
|
|
|
|
|
|
|
|
private $httpResponse;
|
2018-08-05 10:55:49 +03:00
|
|
|
|
2018-08-05 01:45:03 +03:00
|
|
|
private $hydratedResponse;
|
2018-08-05 10:55:49 +03:00
|
|
|
|
2018-08-05 01:45:03 +03:00
|
|
|
private $hydrateClass;
|
|
|
|
|
2017-12-01 23:10:21 +03:00
|
|
|
protected function setUp()
|
2016-10-27 09:34:27 +03:00
|
|
|
{
|
2018-08-05 01:45:03 +03:00
|
|
|
$this->reset();
|
2016-10-27 09:34:27 +03:00
|
|
|
}
|
|
|
|
|
2016-10-24 20:01:32 +03:00
|
|
|
abstract protected function getApiClass();
|
|
|
|
|
2018-08-05 11:34:38 +03:00
|
|
|
/**
|
|
|
|
* This will give you a mocked API. Optionally you can provide mocked dependencies.
|
|
|
|
*/
|
2017-12-01 23:10:21 +03:00
|
|
|
protected function getApiMock($httpClient = null, $requestClient = null, $hydrator = null)
|
2016-10-24 20:01:32 +03:00
|
|
|
{
|
2017-12-01 23:10:21 +03:00
|
|
|
if (null === $httpClient) {
|
|
|
|
$httpClient = $this->getMockBuilder('Http\Client\HttpClient')
|
|
|
|
->setMethods(['sendRequest'])
|
|
|
|
->getMock();
|
|
|
|
$httpClient
|
2018-08-05 11:34:38 +03:00
|
|
|
->expects($this->any())
|
|
|
|
->method('sendRequest');
|
2017-12-01 23:10:21 +03:00
|
|
|
}
|
|
|
|
if (null === $requestClient) {
|
2019-01-09 22:18:58 +03:00
|
|
|
$requestClient = $this->getMockBuilder('Mailgun\HttpClient\RequestBuilder')
|
2017-12-01 23:10:21 +03:00
|
|
|
->setMethods(['create'])
|
|
|
|
->getMock();
|
|
|
|
}
|
2018-08-05 11:34:38 +03:00
|
|
|
if (null === $hydrator) {
|
|
|
|
$hydrator = $this->getMockBuilder('Mailgun\Hydrator\Hydrator')
|
|
|
|
->setMethods(['hydrate'])
|
|
|
|
->getMock();
|
|
|
|
}
|
2018-08-05 12:00:43 +03:00
|
|
|
|
2018-08-05 11:34:38 +03:00
|
|
|
return $this->getMockBuilder($this->getApiClass())
|
|
|
|
->setMethods(['httpGet', 'httpPost', 'httpPostRaw', 'httpDelete', 'httpPut'])
|
|
|
|
->setConstructorArgs([$httpClient, $requestClient, $hydrator])
|
|
|
|
->getMock();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This will return you a real API instance with mocked dependencies.
|
|
|
|
* This will make use of the "setHydratedResponse" and "setRequestMethod" etc..
|
|
|
|
*/
|
2018-08-05 12:59:29 +03:00
|
|
|
protected function getApiInstance($apiKey = null)
|
2018-08-05 11:34:38 +03:00
|
|
|
{
|
|
|
|
$httpClient = $this->getMockBuilder('Http\Client\HttpClient')
|
|
|
|
->setMethods(['sendRequest'])
|
|
|
|
->getMock();
|
|
|
|
$httpClient
|
|
|
|
->method('sendRequest')
|
|
|
|
->willReturn(null === $this->httpResponse ? new Response() : $this->httpResponse);
|
|
|
|
|
2019-01-09 22:18:58 +03:00
|
|
|
$requestClient = $this->getMockBuilder('Mailgun\HttpClient\RequestBuilder')
|
2018-08-05 11:34:38 +03:00
|
|
|
->setMethods(['create'])
|
|
|
|
->getMock();
|
|
|
|
$requestClient->method('create')
|
|
|
|
->with(
|
|
|
|
$this->callback([$this, 'validateRequestMethod']),
|
|
|
|
$this->callback([$this, 'validateRequestUri']),
|
|
|
|
$this->callback([$this, 'validateRequestHeaders']),
|
|
|
|
$this->callback([$this, 'validateRequestBody'])
|
|
|
|
)
|
|
|
|
->willReturn(new Request('GET', '/'));
|
|
|
|
|
2018-08-05 10:54:41 +03:00
|
|
|
$hydrator = new ModelHydrator();
|
2018-08-05 11:34:38 +03:00
|
|
|
if (null === $this->httpResponse) {
|
2017-12-01 23:10:21 +03:00
|
|
|
$hydrator = $this->getMockBuilder('Mailgun\Hydrator\Hydrator')
|
|
|
|
->setMethods(['hydrate'])
|
|
|
|
->getMock();
|
2018-08-05 01:45:03 +03:00
|
|
|
|
|
|
|
$hydratorModelClass = $this->hydrateClass;
|
|
|
|
$hydrateMethod = $hydrator->method('hydrate')
|
|
|
|
->with(
|
|
|
|
$this->callback(function ($response) {
|
|
|
|
return $response instanceof ResponseInterface;
|
|
|
|
}),
|
|
|
|
$this->callback(function ($class) use ($hydratorModelClass) {
|
2018-08-05 10:55:49 +03:00
|
|
|
return null === $hydratorModelClass || $class === $hydratorModelClass;
|
2018-08-05 01:45:03 +03:00
|
|
|
}));
|
|
|
|
|
|
|
|
if (null !== $this->hydratedResponse) {
|
|
|
|
$hydrateMethod->willReturn($this->hydratedResponse);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$class = $this->getApiClass();
|
2018-08-05 10:55:49 +03:00
|
|
|
|
2018-08-05 13:00:05 +03:00
|
|
|
if (null !== $apiKey) {
|
2018-08-05 12:59:29 +03:00
|
|
|
return new $class($httpClient, $requestClient, $hydrator, $apiKey);
|
|
|
|
}
|
|
|
|
|
2018-08-05 01:45:03 +03:00
|
|
|
return new $class($httpClient, $requestClient, $hydrator);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function validateRequestMethod($method)
|
|
|
|
{
|
2018-08-05 12:00:43 +03:00
|
|
|
return $this->verifyProperty($this->requestMethod, $method);
|
2018-08-05 01:45:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function validateRequestUri($uri)
|
|
|
|
{
|
2018-08-05 12:00:43 +03:00
|
|
|
return $this->verifyProperty($this->requestUri, $uri);
|
2018-08-05 01:45:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function validateRequestHeaders($headers)
|
|
|
|
{
|
2018-08-05 12:00:43 +03:00
|
|
|
return $this->verifyProperty($this->requestHeaders, $headers);
|
2018-08-05 01:45:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
public function validateRequestBody($body)
|
|
|
|
{
|
2018-08-05 12:00:43 +03:00
|
|
|
if ($this->verifyProperty($this->requestBody, $body)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assert: $body is prepared for a "multipart stream".
|
|
|
|
|
|
|
|
// Check length
|
|
|
|
if (count($this->requestBody) !== count($body)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check every item in body.
|
|
|
|
foreach ($body as $item) {
|
2018-08-05 13:00:05 +03:00
|
|
|
if ('resource' === $this->requestBody[$item['name']] && is_resource($item['content'])) {
|
2018-08-05 12:33:47 +03:00
|
|
|
continue;
|
|
|
|
}
|
2018-08-05 12:00:43 +03:00
|
|
|
if ($this->requestBody[$item['name']] !== $item['content']) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2016-10-24 20:01:32 +03:00
|
|
|
}
|
2016-10-27 09:34:27 +03:00
|
|
|
|
2018-08-05 01:45:03 +03:00
|
|
|
protected function reset()
|
|
|
|
{
|
|
|
|
$this->httpResponse = null;
|
|
|
|
$this->hydratedResponse = null;
|
|
|
|
$this->requestMethod = null;
|
|
|
|
$this->requestUri = null;
|
|
|
|
$this->requestHeaders = null;
|
|
|
|
$this->requestBody = null;
|
|
|
|
$this->hydrateClass = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a response that you want to client to respond with.
|
|
|
|
*/
|
|
|
|
public function setHttpResponse(ResponseInterface $httpResponse)
|
|
|
|
{
|
|
|
|
$this->httpResponse = $httpResponse;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The data you want the hydrator to return.
|
|
|
|
*/
|
|
|
|
public function setHydratedResponse($hydratedResponse)
|
|
|
|
{
|
|
|
|
$this->hydratedResponse = $hydratedResponse;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-08-05 10:55:49 +03:00
|
|
|
* Set request http method.
|
|
|
|
*
|
2018-08-05 01:45:03 +03:00
|
|
|
* @param string $httpMethod
|
|
|
|
*/
|
|
|
|
public function setRequestMethod($httpMethod)
|
|
|
|
{
|
|
|
|
$this->requestMethod = $httpMethod;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $requestUri
|
|
|
|
*/
|
|
|
|
public function setRequestUri($requestUri)
|
|
|
|
{
|
|
|
|
$this->requestUri = $requestUri;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setRequestHeaders(array $requestHeaders)
|
|
|
|
{
|
|
|
|
$this->requestHeaders = $requestHeaders;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setRequestBody($requestBody)
|
|
|
|
{
|
|
|
|
$this->requestBody = $requestBody;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-08-05 10:55:49 +03:00
|
|
|
* The class we should hydrate to.
|
|
|
|
*
|
2018-08-05 01:45:03 +03:00
|
|
|
* @param string $hydrateClass
|
|
|
|
*/
|
|
|
|
public function setHydrateClass($hydrateClass)
|
|
|
|
{
|
|
|
|
$this->hydrateClass = $hydrateClass;
|
|
|
|
}
|
|
|
|
|
2018-08-05 10:54:41 +03:00
|
|
|
/**
|
|
|
|
* @param mixed|callable $property Example $this->requestMethod
|
2019-01-07 08:12:53 +03:00
|
|
|
* @param mixed $value the actual value from the user
|
2018-08-05 10:55:49 +03:00
|
|
|
*
|
2018-08-05 10:54:41 +03:00
|
|
|
* @return bool
|
|
|
|
*/
|
2018-08-05 12:00:43 +03:00
|
|
|
private function verifyProperty($property, $value)
|
2018-08-05 10:54:41 +03:00
|
|
|
{
|
2018-08-05 10:55:49 +03:00
|
|
|
if (null === $property) {
|
2018-08-05 10:54:41 +03:00
|
|
|
return true;
|
|
|
|
}
|
2018-08-05 01:45:03 +03:00
|
|
|
|
2018-08-05 11:34:38 +03:00
|
|
|
return is_callable($property) ? call_user_func($property, $value) : $value === $property;
|
2018-08-05 10:54:41 +03:00
|
|
|
}
|
2016-10-24 20:01:32 +03:00
|
|
|
}
|