POC - Better api (#192)

* Added base for the new API

* code style

* Added response classes

* Added support for serializer

* The abstract API should not know of Mailgun

* Minor

* minor

* Using a client configrator

* code style

* Put HTTPClient in the configurator

* Do not use the api() function

* Use stable version of Assert

* style

* Fixed tests

* make the httpClient private

* Renamed ResponseSerializer to ResponseDeserializer

* Disabled tests that are testing error messages with Assert

* style fixes

* Refactoring fix
This commit is contained in:
Tobias Nyholm 2016-10-24 19:01:32 +02:00 committed by Sean Johnson
parent 043658f996
commit 738e6e32e2
31 changed files with 1082 additions and 18 deletions

View File

@ -6,7 +6,9 @@
"php-http/httplug": "^1.0", "php-http/httplug": "^1.0",
"php-http/multipart-stream-builder": "^0.1", "php-http/multipart-stream-builder": "^0.1",
"php-http/message": "^1.0", "php-http/message": "^1.0",
"php-http/discovery": "^1.0" "php-http/client-common": "^1.0",
"php-http/discovery": "^1.0",
"webmozart/assert": "^1.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~4.6", "phpunit/phpunit": "~4.6",

View File

@ -0,0 +1,150 @@
<?php
namespace Mailgun\Api;
use Http\Client\Common\HttpMethodsClient;
use Http\Client\HttpClient;
use Http\Message\RequestFactory;
use Mailgun\Exception\HttpServerException;
use Http\Client\Exception as HttplugException;
use Mailgun\Serializer\ResponseDeserializer;
use Psr\Http\Message\ResponseInterface;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
abstract class AbstractApi
{
/**
* The HTTP client.
*
* @var HttpMethodsClient
*/
private $httpClient;
/**
* @var ResponseDeserializer
*/
protected $serializer;
/**
* @param HttpClient $httpClient
* @param RequestFactory $requestFactory
* @param ResponseDeserializer $serializer
*/
public function __construct(HttpClient $httpClient, RequestFactory $requestFactory, ResponseDeserializer $serializer)
{
$this->httpClient = new HttpMethodsClient($httpClient, $requestFactory);
$this->serializer = $serializer;
}
/**
* Send a GET request with query parameters.
*
* @param string $path Request path.
* @param array $parameters GET parameters.
* @param array $requestHeaders Request Headers.
*
* @return ResponseInterface
*/
protected function get($path, array $parameters = [], array $requestHeaders = [])
{
if (count($parameters) > 0) {
$path .= '?'.http_build_query($parameters);
}
try {
$response = $this->httpClient->get($path, $requestHeaders);
} catch (HttplugException\NetworkException $e) {
throw HttpServerException::networkError($e);
}
return $response;
}
/**
* Send a POST request with JSON-encoded parameters.
*
* @param string $path Request path.
* @param array $parameters POST parameters to be JSON encoded.
* @param array $requestHeaders Request headers.
*
* @return ResponseInterface
*/
protected function post($path, array $parameters = [], array $requestHeaders = [])
{
return $this->postRaw($path, $this->createJsonBody($parameters), $requestHeaders);
}
/**
* Send a POST request with raw data.
*
* @param string $path Request path.
* @param string $body Request body.
* @param array $requestHeaders Request headers.
*
* @return ResponseInterface
*/
protected function postRaw($path, $body, array $requestHeaders = [])
{
try {
$response = $this->httpClient->post($path, $requestHeaders, $body);
} catch (HttplugException\NetworkException $e) {
throw HttpServerException::networkError($e);
}
return $response;
}
/**
* Send a PUT request with JSON-encoded parameters.
*
* @param string $path Request path.
* @param array $parameters POST parameters to be JSON encoded.
* @param array $requestHeaders Request headers.
*
* @return ResponseInterface
*/
protected function put($path, array $parameters = [], array $requestHeaders = [])
{
try {
$response = $this->httpClient->put($path, $requestHeaders, $this->createJsonBody($parameters));
} catch (HttplugException\NetworkException $e) {
throw HttpServerException::networkError($e);
}
return $response;
}
/**
* Send a DELETE request with JSON-encoded parameters.
*
* @param string $path Request path.
* @param array $parameters POST parameters to be JSON encoded.
* @param array $requestHeaders Request headers.
*
* @return ResponseInterface
*/
protected function delete($path, array $parameters = [], array $requestHeaders = [])
{
try {
$response = $this->httpClient->delete($path, $requestHeaders, $this->createJsonBody($parameters));
} catch (HttplugException\NetworkException $e) {
throw HttpServerException::networkError($e);
}
return $response;
}
/**
* Create a JSON encoded version of an array of parameters.
*
* @param array $parameters Request parameters
*
* @return null|string
*/
protected function createJsonBody(array $parameters)
{
return (count($parameters) === 0) ? null : json_encode($parameters, empty($parameters) ? JSON_FORCE_OBJECT : 0);
}
}

45
src/Mailgun/Api/Stats.php Normal file
View File

@ -0,0 +1,45 @@
<?php
namespace Mailgun\Api;
use Mailgun\Assert;
use Mailgun\Resource\Api\Stats\AllResponse;
use Mailgun\Resource\Api\Stats\TotalResponse;
/**
* {@link https://documentation.mailgun.com/api-stats.html}.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class Stats extends AbstractApi
{
/**
* @param string $domain
* @param array $params
*
* @return TotalResponse|array
*/
public function total($domain, array $params = [])
{
Assert::stringNotEmpty($domain);
$response = $this->get(sprintf('/v3/%s/stats/total', rawurlencode($domain)), $params);
return $this->serializer->deserialize($response, TotalResponse::class);
}
/**
* @param $domain
* @param array $params
*
* @return AllResponse|array
*/
public function all($domain, array $params = [])
{
Assert::stringNotEmpty($domain);
$response = $this->get(sprintf('/v3/%s/stats', rawurlencode($domain)), $params);
return $this->serializer->deserialize($response, AllResponse::class);
}
}

18
src/Mailgun/Assert.php Normal file
View File

@ -0,0 +1,18 @@
<?php
namespace Mailgun;
use Mailgun\Exception\InvalidArgumentException;
/**
* We need to override Webmozart\Assert because we want to throw our own Exception.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class Assert extends \Webmozart\Assert\Assert
{
protected static function createInvalidArgumentException($message)
{
return new InvalidArgumentException($message);
}
}

View File

@ -9,7 +9,9 @@
namespace Mailgun\Connection\Exceptions; namespace Mailgun\Connection\Exceptions;
class GenericHTTPError extends \Exception use Mailgun\Exception;
class GenericHTTPError extends \Exception implements Exception
{ {
protected $httpResponseCode; protected $httpResponseCode;
protected $httpResponseBody; protected $httpResponseBody;

View File

@ -9,6 +9,8 @@
namespace Mailgun\Connection\Exceptions; namespace Mailgun\Connection\Exceptions;
class InvalidCredentials extends \Exception use Mailgun\Exception;
class InvalidCredentials extends \Exception implements Exception
{ {
} }

View File

@ -9,6 +9,8 @@
namespace Mailgun\Connection\Exceptions; namespace Mailgun\Connection\Exceptions;
class MissingEndpoint extends \Exception use Mailgun\Exception;
class MissingEndpoint extends \Exception implements Exception
{ {
} }

View File

@ -9,6 +9,8 @@
namespace Mailgun\Connection\Exceptions; namespace Mailgun\Connection\Exceptions;
class MissingRequiredParameters extends \Exception use Mailgun\Exception;
class MissingRequiredParameters extends \Exception implements Exception
{ {
} }

View File

@ -9,6 +9,8 @@
namespace Mailgun\Connection\Exceptions; namespace Mailgun\Connection\Exceptions;
class NoDomainsConfigured extends \Exception use Mailgun\Exception;
class NoDomainsConfigured extends \Exception implements Exception
{ {
} }

12
src/Mailgun/Exception.php Normal file
View File

@ -0,0 +1,12 @@
<?php
namespace Mailgun;
/**
* All Mailgun exception implements this exception.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
interface Exception
{
}

View File

@ -0,0 +1,31 @@
<?php
namespace Mailgun\Exception;
use Mailgun\Exception;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class HttpClientException extends \RuntimeException implements Exception
{
public static function badRequest()
{
return new self('The parameters passed to the API were invalid. Check your inputs!', 400);
}
public static function unauthorized()
{
return new self('Your credentials are incorrect.', 401);
}
public static function requestFailed()
{
return new self('Parameters were valid but request failed. Try again.', 402);
}
public static function notFound()
{
return new self('The endpoint you tried to access does not exist. Check your URL.', 404);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Mailgun\Exception;
use Mailgun\Exception;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class HttpServerException extends \RuntimeException implements Exception
{
public static function serverError($httpStatus = 500)
{
return new self('An unexpected error occurred at Mailgun\'s servers. Try again later and contact support of the error sill exists.', $httpStatus);
}
public static function networkError(\Exception $previous)
{
return new self('Mailgun\'s servers was unreachable.', 0, $previous);
}
public static function unknownHttpResponseCode($code)
{
return new self(sprintf('Unknown HTTP response code ("%d") received from the API server', $code));
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Mailgun\Exception;
use Mailgun\Exception;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class InvalidArgumentException extends \InvalidArgumentException implements Exception
{
}

View File

@ -0,0 +1,9 @@
<?php
namespace Mailgun\Exception;
use Mailgun\Exception;
class SerializeException extends \RuntimeException implements Exception
{
}

View File

@ -0,0 +1,142 @@
<?php
namespace Mailgun;
use Http\Client\HttpClient;
use Http\Client\Common\PluginClient;
use Http\Discovery\HttpClientDiscovery;
use Http\Discovery\UriFactoryDiscovery;
use Http\Message\UriFactory;
use Http\Client\Common\Plugin;
/**
* Configure a HTTP client.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class HttpClientConfigurator
{
/**
* @var string
*/
private $endpoint = 'https://api.mailgun.net';
/**
* @var string
*/
private $apiKey;
/**
* @var UriFactory
*/
private $uriFactory;
/**
* @var HttpClient
*/
private $httpClient;
/**
* @return PluginClient
*/
public function createConfiguredClient()
{
$plugins = [
new Plugin\AddHostPlugin($this->getUriFactory()->createUri($this->getEndpoint())),
new Plugin\HeaderDefaultsPlugin([
'User-Agent' => 'mailgun-sdk-php/v2 (https://github.com/mailgun/mailgun-php)',
'Authorization' => 'Basic '.base64_encode(sprintf('api:%s', $this->getApiKey())),
]),
];
return new PluginClient($this->getHttpClient(), $plugins);
}
/**
* @return string
*/
private function getEndpoint()
{
return $this->endpoint;
}
/**
* @param string $endpoint
*
* @return HttpClientConfigurator
*/
public function setEndpoint($endpoint)
{
$this->endpoint = $endpoint;
return $this;
}
/**
* @return string
*/
private function getApiKey()
{
return $this->apiKey;
}
/**
* @param string $apiKey
*
* @return HttpClientConfigurator
*/
public function setApiKey($apiKey)
{
$this->apiKey = $apiKey;
return $this;
}
/**
* @return UriFactory
*/
private function getUriFactory()
{
if ($this->uriFactory === null) {
$this->uriFactory = UriFactoryDiscovery::find();
}
return $this->uriFactory;
}
/**
* @param UriFactory $uriFactory
*
* @return HttpClientConfigurator
*/
public function setUriFactory(UriFactory $uriFactory)
{
$this->uriFactory = $uriFactory;
return $this;
}
/**
* @return HttpClient
*/
private function getHttpClient()
{
if ($this->httpClient === null) {
$this->httpClient = HttpClientDiscovery::find();
}
return $this->httpClient;
}
/**
* @param HttpClient $httpClient
*
* @return HttpClientConfigurator
*/
public function setHttpClient(HttpClient $httpClient)
{
$this->httpClient = $httpClient;
return $this;
}
}

View File

@ -9,24 +9,28 @@
namespace Mailgun; namespace Mailgun;
use Http\Client\Common\HttpMethodsClient;
use Http\Client\HttpClient; use Http\Client\HttpClient;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Message\RequestFactory;
use Mailgun\Connection\RestClient; use Mailgun\Connection\RestClient;
use Mailgun\Constants\ExceptionMessages; use Mailgun\Constants\ExceptionMessages;
use Mailgun\Lists\OptInHandler; use Mailgun\Lists\OptInHandler;
use Mailgun\Messages\BatchMessage; use Mailgun\Messages\BatchMessage;
use Mailgun\Messages\Exceptions; use Mailgun\Messages\Exceptions;
use Mailgun\Messages\MessageBuilder; use Mailgun\Messages\MessageBuilder;
use Mailgun\Serializer\ObjectSerializer;
use Mailgun\Serializer\ResponseDeserializer;
/** /**
* This class is the base class for the Mailgun SDK. * This class is the base class for the Mailgun SDK.
* See the official documentation (link below) for usage instructions.
*
* @link https://github.com/mailgun/mailgun-php/blob/master/README.md
*/ */
class Mailgun class Mailgun
{ {
/** /**
* @var RestClient * @var RestClient
*
* @depracated Will be removed in 3.0
*/ */
protected $restClient; protected $restClient;
@ -36,17 +40,56 @@ class Mailgun
protected $apiKey; protected $apiKey;
/** /**
* @param string|null $apiKey * @var HttpMethodsClient
* @param HttpClient $httpClient */
* @param string $apiEndpoint private $httpClient;
/**
* @var ResponseDeserializer
*/
private $serializer;
/**
* @var RequestFactory
*/
private $requestFactory;
/**
* @param string|null $apiKey
* @param HttpClient|null $httpClient
* @param string $apiEndpoint
* @param ResponseDeserializer|null $serializer
* @param HttpClientConfigurator|null $clientConfigurator
*/ */
public function __construct( public function __construct(
$apiKey = null, $apiKey = null,
HttpClient $httpClient = null, HttpClient $httpClient = null, /* Deprecated, will be removed in 3.0 */
$apiEndpoint = 'api.mailgun.net' $apiEndpoint = 'api.mailgun.net', /* Deprecated, will be removed in 3.0 */
ResponseDeserializer $serializer = null,
HttpClientConfigurator $clientConfigurator = null
) { ) {
$this->apiKey = $apiKey; $this->apiKey = $apiKey;
$this->restClient = new RestClient($apiKey, $apiEndpoint, $httpClient); $this->restClient = new RestClient($apiKey, $apiEndpoint, $httpClient);
if (null === $clientConfigurator) {
$clientConfigurator = new HttpClientConfigurator();
/*
* To be backward compatible
*/
if ($apiEndpoint !== 'api.mailgun.net') {
$clientConfigurator->setEndpoint($apiEndpoint);
}
if ($httpClient !== null) {
$clientConfigurator->setHttpClient($httpClient);
}
}
$clientConfigurator->setApiKey($apiKey);
$this->httpClient = $clientConfigurator->createConfiguredClient();
$this->requestFactory = MessageFactoryDiscovery::find();
$this->serializer = $serializer ?: new ObjectSerializer();
} }
/** /**
@ -209,4 +252,12 @@ class Mailgun
{ {
return new BatchMessage($this->restClient, $workingDomain, $autoSend); return new BatchMessage($this->restClient, $workingDomain, $autoSend);
} }
/**
* @return Api\Stats
*/
public function getStatsApi()
{
return new Api\Stats($this->httpClient, $this->requestFactory, $this->serializer);
}
} }

View File

@ -9,6 +9,8 @@
namespace Mailgun\Messages\Exceptions; namespace Mailgun\Messages\Exceptions;
class InvalidParameter extends \Exception use Mailgun\Exception;
class InvalidParameter extends \Exception implements Exception
{ {
} }

View File

@ -9,6 +9,8 @@
namespace Mailgun\Messages\Exceptions; namespace Mailgun\Messages\Exceptions;
class InvalidParameterType extends \Exception use Mailgun\Exception;
class InvalidParameterType extends \Exception implements Exception
{ {
} }

View File

@ -9,6 +9,8 @@
namespace Mailgun\Messages\Exceptions; namespace Mailgun\Messages\Exceptions;
class MissingRequiredMIMEParameters extends \Exception use Mailgun\Exception;
class MissingRequiredMIMEParameters extends \Exception implements Exception
{ {
} }

View File

@ -9,6 +9,8 @@
namespace Mailgun\Messages\Exceptions; namespace Mailgun\Messages\Exceptions;
class TooManyParameters extends \Exception use Mailgun\Exception;
class TooManyParameters extends \Exception implements Exception
{ {
} }

View File

@ -0,0 +1,62 @@
<?php
namespace Mailgun\Resource\Api\Stats;
use Mailgun\Resource\CreatableFromArray;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class AllResponse implements CreatableFromArray
{
/**
* @var int
*/
private $totalCount;
/**
* @var Item[]
*/
private $items;
/**
* @param int $totalCount
* @param Item[] $items
*/
public function __construct($totalCount, array $items)
{
$this->totalCount = $totalCount;
$this->items = $items;
}
/**
* @param array $data
*
* @return AllResponse
*/
public static function createFromArray(array $data)
{
$items = [];
foreach ($data['items'] as $i) {
$items[] = new Item($i['id'], $i['event'], $i['total_count'], $i['tags'], new \DateTime($i['created_at']));
}
return new self($data['total_count'], $items);
}
/**
* @return int
*/
public function getTotalCount()
{
return $this->totalCount;
}
/**
* @return Item[]
*/
public function getItems()
{
return $this->items;
}
}

View File

@ -0,0 +1,87 @@
<?php
namespace Mailgun\Resource\Api\Stats;
class Item
{
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $event;
/**
* @var string
*/
private $totalCount;
/**
* @var string[]
*/
private $tags;
/**
* @var \DateTime
*/
private $createdAt;
/**
* @param string $id
* @param string $event
* @param string $totalCount
* @param \string[] $tags
* @param \DateTime $createdAt
*/
public function __construct($id, $event, $totalCount, array $tags, \DateTime $createdAt)
{
$this->id = $id;
$this->event = $event;
$this->totalCount = $totalCount;
$this->tags = $tags;
$this->createdAt = $createdAt;
}
/**
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getEvent()
{
return $this->event;
}
/**
* @return string
*/
public function getTotalCount()
{
return $this->totalCount;
}
/**
* @return \string[]
*/
public function getTags()
{
return $this->tags;
}
/**
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace Mailgun\Resource\Api\Stats;
use Mailgun\Resource\CreatableFromArray;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class TotalResponse implements CreatableFromArray
{
/**
* @var \DateTime
*/
private $start;
/**
* @var \DateTime
*/
private $end;
/**
* @var string
*/
private $resolution;
/**
* @var TotalStats[]
*/
private $stats;
/**
* @param \DateTime $start
* @param \DateTime $end
* @param string $resolution
* @param TotalStats[] $stats
*/
public function __construct(\DateTime $start, \DateTime $end, $resolution, array $stats)
{
$this->start = $start;
$this->end = $end;
$this->resolution = $resolution;
$this->stats = $stats;
}
/**
* @param array $data
*
* @return TotalResponse
*/
public static function createFromArray(array $data)
{
$stats = [];
foreach ($data['stats'] as $s) {
$stats[] = new TotalStats(new \DateTime($s['time']), $s['accepted'], $s['delivered'], $s['failed']);
}
return new self(new \DateTime($data['start']), new \DateTime($data['end']), $data['resolution'], $stats);
}
/**
* @return \DateTime
*/
public function getStart()
{
return $this->start;
}
/**
* @return \DateTime
*/
public function getEnd()
{
return $this->end;
}
/**
* @return string
*/
public function getResolution()
{
return $this->resolution;
}
/**
* @return TotalStats[]
*/
public function getStats()
{
return $this->stats;
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace Mailgun\Resource\Api\Stats;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class TotalStats
{
/**
* @var \DateTime
*/
private $time;
/**
* @var array
*/
private $accepted;
/**
* @var array
*/
private $delivered;
/**
* @var array
*/
private $failed;
/**
* @param \DateTime $time
* @param array $accepted
* @param array $delivered
* @param array $failed
*/
public function __construct(\DateTime $time, array $accepted, array $delivered, array $failed)
{
$this->time = $time;
$this->accepted = $accepted;
$this->delivered = $delivered;
$this->failed = $failed;
}
/**
* @return \DateTime
*/
public function getTime()
{
return $this->time;
}
/**
* @return array
*/
public function getAccepted()
{
return $this->accepted;
}
/**
* @return array
*/
public function getDelivered()
{
return $this->delivered;
}
/**
* @return array
*/
public function getFailed()
{
return $this->failed;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Mailgun\Resource;
interface CreatableFromArray
{
/**
* @param array $data
*
* @return self
*/
public static function createFromArray(array $data);
}

View File

@ -0,0 +1,35 @@
<?php
namespace Mailgun\Serializer;
use Mailgun\Exception\SerializeException;
use Psr\Http\Message\ResponseInterface;
/**
* Serialize an HTTP response to array.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class ArraySerializer implements ResponseDeserializer
{
/**
* @param ResponseInterface $response
* @param string $class
*
* @return array
*/
public function deserialize(ResponseInterface $response, $class)
{
$body = $response->getBody()->__toString();
if (strpos($response->getHeaderLine('Content-Type'), 'application/json') !== 0) {
throw new SerializeException('The ArraySerializer cannot deserialize response with Content-Type:'.$response->getHeaderLine('Content-Type'));
}
$content = json_decode($body, true);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new SerializeException(sprintf('Error (%d) when trying to json_decode response', json_last_error()));
}
return $content;
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace Mailgun\Serializer;
use Mailgun\Exception\SerializeException;
use Mailgun\Resource\CreatableFromArray;
use Psr\Http\Message\ResponseInterface;
/**
* Serialize an HTTP response to domain object.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class ObjectSerializer implements ResponseDeserializer
{
/**
* @param ResponseInterface $response
* @param string $class
*
* @return ResponseInterface
*/
public function deserialize(ResponseInterface $response, $class)
{
$body = $response->getBody()->__toString();
if (strpos($response->getHeaderLine('Content-Type'), 'application/json') !== 0) {
throw new SerializeException('The ObjectSerializer cannot deserialize response with Content-Type:'.$response->getHeaderLine('Content-Type'));
}
$data = json_decode($body, true);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new SerializeException(sprintf('Error (%d) when trying to json_decode response', json_last_error()));
}
if (is_subclass_of($class, CreatableFromArray::class)) {
$object = call_user_func($class.'::createFromArray', $data);
} else {
$object = new $class($data);
}
return $object;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Mailgun\Serializer;
use Psr\Http\Message\ResponseInterface;
/**
* Do not serialize at all. Just return a PSR-7 response.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class PSR7Serializer implements ResponseDeserializer
{
/**
* @param ResponseInterface $response
* @param string $class
*
* @return ResponseInterface
*/
public function deserialize(ResponseInterface $response, $class)
{
return $response;
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Mailgun\Serializer;
use Psr\Http\Message\ResponseInterface;
/**
* Deserialize a PSR-7 response to something else.
*/
interface ResponseDeserializer
{
/**
* @param ResponseInterface $response
* @param string $class
*
* @return mixed
*/
public function deserialize(ResponseInterface $response, $class);
}

64
tests/Api/StatsTest.php Normal file
View File

@ -0,0 +1,64 @@
<?php
namespace Mailgun\Tests\Api;
use GuzzleHttp\Psr7\Response;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class StatsTest extends TestCase
{
protected function getApiClass()
{
return 'Mailgun\Api\Stats';
}
public function testTotal()
{
$data = [
'foo' => 'bar',
];
$api = $this->getApiMock();
$api->expects($this->once())
->method('get')
->with('/v3/domain/stats/total', $data)
->willReturn(new Response());
$api->total('domain', $data);
}
/**
* expectedException \Mailgun\Exception\InvalidArgumentException.
*/
//public function testTotalInvalidArgument()
//{
// $api = $this->getApiMock();
// $api->total('');
//}
public function testAll()
{
$data = [
'foo' => 'bar',
];
$api = $this->getApiMock();
$api->expects($this->once())
->method('get')
->with('/v3/domain/stats', $data)
->willReturn(new Response());
$api->all('domain', $data);
}
/*
* expectedException \Mailgun\Exception\InvalidArgumentException
*/
//public function testAllInvalidArgument()
//{
// $api = $this->getApiMock();
// $api->all('');
//}
}

35
tests/Api/TestCase.php Normal file
View File

@ -0,0 +1,35 @@
<?php
namespace Mailgun\Tests\Api;
/**
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
* @author Contributors of https://github.com/KnpLabs/php-github-api
*/
abstract class TestCase extends \PHPUnit_Framework_TestCase
{
abstract protected function getApiClass();
protected function getApiMock()
{
$httpClient = $this->getMockBuilder('Http\Client\HttpClient')
->setMethods(['sendRequest'])
->getMock();
$httpClient
->expects($this->any())
->method('sendRequest');
$requestClient = $this->getMockBuilder('Http\Message\MessageFactory')
->setMethods(['createRequest', 'createResponse'])
->getMock();
$serializer = $this->getMockBuilder('Mailgun\Serializer\ResponseDeserializer')
->setMethods(['deserialize'])
->getMock();
return $this->getMockBuilder($this->getApiClass())
->setMethods(['get', 'post', 'postRaw', 'delete', 'put'])
->setConstructorArgs([$httpClient, $requestClient, $serializer])
->getMock();
}
}