From b73adaf60c2dd38853e71f679f6e5ece0e1131d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois-Xavier=20de=20Guillebon?= Date: Fri, 1 Dec 2017 21:10:21 +0100 Subject: [PATCH] Fixed stats retrieval (#384) * [Stats] Fixed stats always empty * Added tests --- src/Mailgun/Model/Stats/TotalResponse.php | 2 +- src/Mailgun/Model/Stats/TotalResponseItem.php | 6 +- tests/Api/StatsTest.php | 98 +++++++++++++++++-- tests/Api/TestCase.php | 34 ++++--- 4 files changed, 113 insertions(+), 27 deletions(-) diff --git a/src/Mailgun/Model/Stats/TotalResponse.php b/src/Mailgun/Model/Stats/TotalResponse.php index b9c6894..cef5bb5 100644 --- a/src/Mailgun/Model/Stats/TotalResponse.php +++ b/src/Mailgun/Model/Stats/TotalResponse.php @@ -58,7 +58,7 @@ final class TotalResponse implements ApiResponse public static function create(array $data) { $stats = []; - if (isset($data['status'])) { + if (isset($data['stats'])) { foreach ($data['stats'] as $s) { $stats[] = TotalResponseItem::create($s); } diff --git a/src/Mailgun/Model/Stats/TotalResponseItem.php b/src/Mailgun/Model/Stats/TotalResponseItem.php index 21e384b..a19db50 100644 --- a/src/Mailgun/Model/Stats/TotalResponseItem.php +++ b/src/Mailgun/Model/Stats/TotalResponseItem.php @@ -43,9 +43,9 @@ class TotalResponseItem { return new self( isset($data['time']) ? new \DateTime($data['time']) : null, - isset($data['accepted']) ? $data['accepted'] : null, - isset($data['delivered']) ? $data['delivered'] : null, - isset($data['failed']) ? $data['failed'] : null + isset($data['accepted']) ? $data['accepted'] : [], + isset($data['delivered']) ? $data['delivered'] : [], + isset($data['failed']) ? $data['failed'] : [] ); } diff --git a/tests/Api/StatsTest.php b/tests/Api/StatsTest.php index 80a8a4e..4611d64 100644 --- a/tests/Api/StatsTest.php +++ b/tests/Api/StatsTest.php @@ -10,6 +10,9 @@ namespace Mailgun\Tests\Api; use GuzzleHttp\Psr7\Response; +use Mailgun\Hydrator\ModelHydrator; +use Mailgun\Model\Stats\TotalResponse; +use Mailgun\Model\Stats\TotalResponseItem; /** * @author Tobias Nyholm @@ -21,19 +24,22 @@ class StatsTest extends TestCase return 'Mailgun\Api\Stats'; } - public function testTotal() + /** + * @dataProvider totalProvider + */ + public function testTotal($queryParameters, $responseData) { - $data = [ - 'foo' => 'bar', - ]; - - $api = $this->getApiMock(); + $api = $this->getApiMock(null, null, new ModelHydrator()); $api->expects($this->once()) ->method('httpGet') - ->with('/v3/domain/stats/total', $data) - ->willReturn(new Response()); + ->with('/v3/domain/stats/total', $queryParameters) + ->willReturn(new Response(200, ['Content-Type' => 'application/json'], \json_encode($responseData))); - $api->total('domain', $data); + $total = $api->total('domain', $queryParameters); + + $this->assertInstanceOf(TotalResponse::class, $total); + $this->assertCount(count($responseData['stats']), $total->getStats()); + $this->assertContainsOnlyInstancesOf(TotalResponseItem::class, $total->getStats()); } /** @@ -69,4 +75,78 @@ class StatsTest extends TestCase $api->all(''); } + + public function totalProvider() + { + return [ + 'accepted events' => [ + 'queryParameters' => [ + 'event' => 'accepted', + ], + 'responseData' => $this->generateTotalResponsePayload([ + [ + 'time' => $this->formatDate('-7 days'), + 'accepted' => [ + 'outgoing' => 10, + 'incoming' => 5, + 'total' => 15, + ], + ], + ]), + ], + 'failed events' => [ + 'queryParameters' => [ + 'event' => 'failed', + ], + 'responseData' => $this->generateTotalResponsePayload([ + [ + 'time' => $this->formatDate('-7 days'), + 'failed' => [ + 'permanent' => [ + 'bounce' => 4, + 'delayed-bounce' => 1, + 'suppress-bounce' => 1, + 'suppress-unsubscribe' => 2, + 'suppress-complaint' => 3, + 'total' => 10, + ], + 'temporary' => [ + 'espblock' => 1, + ], + ], + ], + ]), + ], + 'delivered events' => [ + 'queryParameters' => [ + 'event' => 'delivered', + ], + 'responseData' => $this->generateTotalResponsePayload([ + [ + 'time' => $this->formatDate('-7 days'), + 'delivered' => [ + 'smtp' => 15, + 'http' => 5, + 'total' => 20, + ], + ], + ]), + ], + ]; + } + + private function generateTotalResponsePayload(array $stats, $start = '-7 days', $end = 'now', $resolution = 'day') + { + return [ + 'end' => $this->formatDate($end), + 'resolution' => $resolution, + 'start' => $this->formatDate($start), + 'stats' => $stats, + ]; + } + + private function formatDate($time = 'now') + { + return (new \DateTime($time, new \DateTimeZone('UTC')))->format('D, d M Y H:i:s T'); + } } diff --git a/tests/Api/TestCase.php b/tests/Api/TestCase.php index 55ce246..34f9832 100644 --- a/tests/Api/TestCase.php +++ b/tests/Api/TestCase.php @@ -38,7 +38,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase */ protected $testDomain; - public function __construct() + protected function setUp() { $this->apiPrivKey = getenv('MAILGUN_PRIV_KEY'); $this->apiPubKey = getenv('MAILGUN_PUB_KEY'); @@ -47,22 +47,28 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase abstract protected function getApiClass(); - protected function getApiMock() + protected function getApiMock($httpClient = null, $requestClient = null, $hydrator = null) { - $httpClient = $this->getMockBuilder('Http\Client\HttpClient') - ->setMethods(['sendRequest']) - ->getMock(); - $httpClient - ->expects($this->any()) - ->method('sendRequest'); + if (null === $httpClient) { + $httpClient = $this->getMockBuilder('Http\Client\HttpClient') + ->setMethods(['sendRequest']) + ->getMock(); + $httpClient + ->expects($this->any()) + ->method('sendRequest'); + } - $requestClient = $this->getMockBuilder('Mailgun\RequestBuilder') - ->setMethods(['create']) - ->getMock(); + if (null === $requestClient) { + $requestClient = $this->getMockBuilder('Mailgun\RequestBuilder') + ->setMethods(['create']) + ->getMock(); + } - $hydrator = $this->getMockBuilder('Mailgun\Hydrator\Hydrator') - ->setMethods(['hydrate']) - ->getMock(); + if (null === $hydrator) { + $hydrator = $this->getMockBuilder('Mailgun\Hydrator\Hydrator') + ->setMethods(['hydrate']) + ->getMock(); + } return $this->getMockBuilder($this->getApiClass()) ->setMethods(['httpGet', 'httpPost', 'httpPostRaw', 'httpDelete', 'httpPut'])