Suppression Whitelists

This commit is contained in:
Artem Bondarenko 2020-10-15 22:02:50 +03:00 committed by David Garcia
parent 1fd018d61c
commit 9fd5ae16dc
19 changed files with 907 additions and 1 deletions

View File

@ -69,7 +69,7 @@ abstract class HttpApi
return $response; return $response;
} }
if (200 !== $response->getStatusCode() && 201 !== $response->getStatusCode()) { if (!in_array($response->getStatusCode(), [200, 201, 202], true)) {
$this->handleErrors($response); $this->handleErrors($response);
} }

View File

@ -14,6 +14,7 @@ namespace Mailgun\Api;
use Mailgun\Api\Suppression\Bounce; use Mailgun\Api\Suppression\Bounce;
use Mailgun\Api\Suppression\Complaint; use Mailgun\Api\Suppression\Complaint;
use Mailgun\Api\Suppression\Unsubscribe; use Mailgun\Api\Suppression\Unsubscribe;
use Mailgun\Api\Suppression\Whitelist;
use Mailgun\HttpClient\RequestBuilder; use Mailgun\HttpClient\RequestBuilder;
use Mailgun\Hydrator\Hydrator; use Mailgun\Hydrator\Hydrator;
use Psr\Http\Client\ClientInterface; use Psr\Http\Client\ClientInterface;
@ -61,4 +62,9 @@ class Suppression
{ {
return new Unsubscribe($this->httpClient, $this->requestBuilder, $this->hydrator); return new Unsubscribe($this->httpClient, $this->requestBuilder, $this->hydrator);
} }
public function whitelists(): Whitelist
{
return new Whitelist($this->httpClient, $this->requestBuilder, $this->hydrator);
}
} }

View File

@ -0,0 +1,149 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Api\Suppression;
use InvalidArgumentException;
use Mailgun\Api\HttpApi;
use Mailgun\Api\Pagination;
use Mailgun\Assert;
use Mailgun\Model\Suppression\Whitelist\CreateResponse;
use Mailgun\Model\Suppression\Whitelist\DeleteAllResponse;
use Mailgun\Model\Suppression\Whitelist\DeleteResponse;
use Mailgun\Model\Suppression\Whitelist\ImportResponse;
use Mailgun\Model\Suppression\Whitelist\IndexResponse;
use Mailgun\Model\Suppression\Whitelist\ShowResponse;
/**
* @see https://documentation.mailgun.com/en/latest/api-suppressions.html#whitelists
*
* @author Artem Bondarenko <artem@uartema.com>
*/
class Whitelist extends HttpApi
{
use Pagination;
/**
* @param string $domain Domain to get whitelist for
* @param int $limit optional
*
* @return IndexResponse
*/
public function index(string $domain, int $limit = 100)
{
Assert::stringNotEmpty($domain);
Assert::range($limit, 1, 10000, 'Limit parameter must be between 1 and 10000');
$params = [
'limit' => $limit,
];
$response = $this->httpGet(sprintf('/v3/%s/whitelists', $domain), $params);
return $this->hydrateResponse($response, IndexResponse::class);
}
/**
* @param string $domain Domain to show whitelist for
* @param string $address whitelist address
*
* @return ShowResponse
*/
public function show(string $domain, string $address)
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($address);
$response = $this->httpGet(sprintf('/v3/%s/whitelists/%s', $domain, $address));
return $this->hydrateResponse($response, ShowResponse::class);
}
/**
* @param string $domain Domain to create whitelist for
* @param string $address whitelist email address or domain name
* @param array $params optional
*
* @return CreateResponse
*/
public function create(string $domain, string $address, array $params = [])
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($address);
if (false !== filter_var($address, FILTER_VALIDATE_EMAIL)) {
$params['address'] = $address;
} elseif (false !== filter_var($address, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) {
$params['domain'] = $address;
} else {
throw new InvalidArgumentException('Address should be valid email or domain name');
}
$response = $this->httpPost(sprintf('/v3/%s/whitelists', $domain), $params);
return $this->hydrateResponse($response, CreateResponse::class);
}
/**
* @param string $domain Domain to create whitelist for
* @param string $filePath csv file path
* @param array $params optional
*
* @return ImportResponse
*/
public function import(string $domain, string $filePath, array $params = [])
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($filePath);
Assert::fileExists($filePath);
$response = $this->httpPost(
sprintf('/v3/%s/whitelists/import', $domain),
['file' => fopen($filePath, 'r')],
array_merge($params, [
'filename' => basename($filePath),
])
);
return $this->hydrateResponse($response, ImportResponse::class);
}
/**
* @param string $domain Domain to delete whitelist for
* @param string $address whitelist address
* @param array $params optional
*
* @return DeleteResponse
*/
public function delete(string $domain, string $address, array $params = [])
{
Assert::stringNotEmpty($domain);
Assert::stringNotEmpty($address);
$response = $this->httpDelete(sprintf('/v3/%s/whitelists/%s', $domain, $address), $params);
return $this->hydrateResponse($response, DeleteResponse::class);
}
/**
* @param string $domain Domain to delete all whitelists for
*
* @return DeleteAllResponse
*/
public function deleteAll(string $domain)
{
Assert::stringNotEmpty($domain);
$response = $this->httpDelete(sprintf('/v3/%s/whitelists', $domain));
return $this->hydrateResponse($response, DeleteAllResponse::class);
}
}

View File

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class CreateResponse implements ApiResponse
{
private $type;
private $value;
private $message;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->type = $data['type'] ?? '';
$model->value = $data['value'] ?? '';
$model->message = $data['message'] ?? '';
return $model;
}
public function getType(): string
{
return $this->type;
}
public function getValue(): string
{
return $this->value;
}
public function getMessage(): string
{
return $this->message;
}
}

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class DeleteAllResponse implements ApiResponse
{
private $message;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->message = $data['message'] ?? '';
return $model;
}
public function getMessage(): string
{
return $this->message;
}
}

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class DeleteResponse implements ApiResponse
{
private $value;
private $message;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->value = $data['value'] ?? '';
$model->message = $data['message'] ?? '';
return $model;
}
public function getValue(): string
{
return $this->value;
}
public function getMessage(): string
{
return $this->message;
}
}

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class ImportResponse implements ApiResponse
{
private $message;
final private function __construct()
{
}
public static function create(array $data): self
{
$model = new static();
$model->message = $data['message'] ?? null;
return $model;
}
public function getMessage(): ?string
{
return $this->message;
}
}

View File

@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
use Mailgun\Model\PaginationResponse;
use Mailgun\Model\PagingProvider;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class IndexResponse implements ApiResponse, PagingProvider
{
use PaginationResponse;
/**
* Array to store a list of whitelist items from
* index response.
*
* @var Whitelist[]
*/
private $items = [];
/**
* Store the total number of whitelists items.
*
* @var int
*/
private $totalCount;
private function __construct()
{
}
public static function create(array $data): self
{
$whitelists = [];
if (isset($data['items'])) {
foreach ($data['items'] as $item) {
$whitelists[] = Whitelist::create($item);
}
}
$model = new self();
$model->items = $whitelists;
$model->paging = $data['paging'];
return $model;
}
/**
* @return Whitelist[]
*/
public function getItems(): array
{
return $this->items;
}
public function getTotalCount(): int
{
if (null === $this->totalCount) {
$this->totalCount = count($this->items);
}
return $this->totalCount;
}
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use Mailgun\Model\ApiResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
final class ShowResponse extends Whitelist implements ApiResponse
{
}

View File

@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Model\Suppression\Whitelist;
use DateTimeImmutable;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
class Whitelist
{
private $value;
private $reason;
private $type;
private $createdAt;
private function __construct()
{
}
public static function create(array $data): self
{
$model = new self();
$model->value = $data['value'] ?? null;
$model->reason = $data['reason'] ?? null;
$model->type = $data['type'] ?? null;
$model->createdAt = isset($data['createdAt']) ? new DateTimeImmutable($data['createdAt']) : null;
return $model;
}
public function getValue(): ?string
{
return $this->value;
}
public function getReason(): ?string
{
return $this->reason;
}
public function getType(): ?string
{
return $this->type;
}
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;
}
}

View File

@ -0,0 +1,134 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Tests\Api;
use Mailgun\Api\Suppression\Whitelist;
use Mailgun\Model\Suppression\Whitelist\CreateResponse;
use Mailgun\Model\Suppression\Whitelist\DeleteAllResponse;
use Mailgun\Model\Suppression\Whitelist\DeleteResponse;
use Mailgun\Model\Suppression\Whitelist\ImportResponse;
use Mailgun\Model\Suppression\Whitelist\IndexResponse;
use Mailgun\Model\Suppression\Whitelist\ShowResponse;
/**
* @author Artem Bondarenko <artem@uartema.com>
*/
class WhitelistTest extends TestCase
{
public function testIndex()
{
$this->setRequestMethod('GET');
$this->setRequestUri('/v3/example.com/whitelists?limit=25');
$this->setHydrateClass(IndexResponse::class);
$api = $this->getApiInstance();
$api->index('example.com', 25);
}
public function testShow()
{
$this->setRequestMethod('GET');
$this->setRequestUri('/v3/example.com/whitelists/foo@bar.com');
$this->setHydrateClass(ShowResponse::class);
$api = $this->getApiInstance();
$api->show('example.com', 'foo@bar.com');
}
public function testCreateDomain()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/example.com/whitelists');
$this->setHydrateClass(CreateResponse::class);
$this->setRequestBody([
'address' => 'foo@bar.com',
]);
$api = $this->getApiInstance();
$api->create('example.com', 'foo@bar.com');
}
public function testCreateEmail()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/example.com/whitelists');
$this->setHydrateClass(CreateResponse::class);
$this->setRequestBody([
'domain' => 'foobar.com',
]);
$api = $this->getApiInstance();
$api->create('example.com', 'foobar.com');
}
public function testCreateNonValidDomainOrAddress()
{
$this->expectException(\InvalidArgumentException::class);
$api = $this->getApiInstance();
$api->create('example.com', '_123');
}
public function testImport()
{
$this->setRequestMethod('POST');
$this->setRequestUri('/v3/example.com/whitelists/import');
$this->setHydrateClass(ImportResponse::class);
$this->setRequestBody([
'file' => 'resource',
]);
$this->setRequestHeaders([
'filename' => basename(__FILE__),
]);
$api = $this->getApiInstance();
$api->import('example.com', __FILE__);
}
public function testDelete()
{
$this->setRequestMethod('DELETE');
$this->setRequestUri('/v3/example.com/whitelists/foo@bar.com');
$this->setHydrateClass(DeleteResponse::class);
$api = $this->getApiInstance();
$api->delete('example.com', 'foo@bar.com');
}
public function testDeleteDomain()
{
$this->setRequestMethod('DELETE');
$this->setRequestUri('/v3/example.com/whitelists/foobar.com');
$this->setHydrateClass(DeleteResponse::class);
$api = $this->getApiInstance();
$api->delete('example.com', 'foobar.com');
}
public function testDeleteAll()
{
$this->setRequestMethod('DELETE');
$this->setRequestUri('/v3/example.com/whitelists');
$this->setHydrateClass(DeleteAllResponse::class);
$api = $this->getApiInstance();
$api->deleteAll('example.com');
}
/**
* {@inheritdoc}
*/
protected function getApiClass()
{
return Whitelist::class;
}
}

View File

@ -36,6 +36,12 @@ class SuppressionTest extends TestCase
$this->assertInstanceOf(Suppression\Unsubscribe::class, $api->unsubscribes()); $this->assertInstanceOf(Suppression\Unsubscribe::class, $api->unsubscribes());
} }
public function testWhitelists()
{
$api = $this->getApiInstance();
$this->assertInstanceOf(Suppression\Whitelist::class, $api->whitelists());
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Tests\Model\Suppression\Whitelists;
use Mailgun\Model\Suppression\Whitelist\CreateResponse;
use Mailgun\Tests\Model\BaseModelTest;
class CreateResponseTest extends BaseModelTest
{
public function testCreate()
{
$json =
<<<'JSON'
{
"message":"Address/Domain has been added to the whitelists table",
"type":"domain",
"value":"example.com"
}
JSON;
$model = CreateResponse::create(json_decode($json, true));
$this->assertEquals('Address/Domain has been added to the whitelists table', $model->getMessage());
$this->assertEquals('domain', $model->getType());
$this->assertEquals('example.com', $model->getValue());
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Tests\Model\Suppression\Whitelists;
use Mailgun\Model\Suppression\Whitelist\DeleteAllResponse;
use Mailgun\Tests\Model\BaseModelTest;
class DeleteAllResponseTest extends BaseModelTest
{
public function testCreate()
{
$json =
<<<'JSON'
{
"message": "Whitelist addresses/domains for this domain have been removed"
}
JSON;
$model = DeleteAllResponse::create(json_decode($json, true));
$this->assertEquals('Whitelist addresses/domains for this domain have been removed', $model->getMessage());
}
}

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Tests\Model\Suppression\Whitelists;
use Mailgun\Model\Suppression\Whitelist\DeleteResponse;
use Mailgun\Tests\Model\BaseModelTest;
class DeleteResponseTest extends BaseModelTest
{
public function testCreate()
{
$json =
<<<'JSON'
{
"message":"Whitelist address/domain has been removed",
"value":"alice@example.com"
}
JSON;
$model = DeleteResponse::create(json_decode($json, true));
$this->assertEquals('Whitelist address/domain has been removed', $model->getMessage());
$this->assertEquals('alice@example.com', $model->getValue());
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Tests\Model\Suppression\Whitelists;
use Mailgun\Model\Suppression\Whitelist\ImportResponse;
use Mailgun\Tests\Model\BaseModelTest;
class ImportResponseTest extends BaseModelTest
{
public function testCreate()
{
$json =
<<<'JSON'
{
"message": "file uploaded successfully"
}
JSON;
$model = ImportResponse::create(json_decode($json, true));
$this->assertEquals('file uploaded successfully', $model->getMessage());
}
}

View File

@ -0,0 +1,72 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Tests\Model\Suppression\Whitelists;
use Mailgun\Model\Suppression\Whitelist\IndexResponse;
use Mailgun\Model\Suppression\Whitelist\Whitelist;
use Mailgun\Tests\Model\BaseModelTest;
class IndexResponseTest extends BaseModelTest
{
public function testCreate()
{
$json =
<<<'JSON'
{
"items": [
{
"value": "alice@example.com",
"reason": "reason of white listing",
"type": "address",
"createdAt": "Fri, 21 Oct 2011 11:02:55 UTC"
},
{
"value": "test.com",
"reason": "reason of white listing",
"type": "domain",
"createdAt": "Fri, 21 Oct 2012 11:02:56 UTC"
}
],
"paging": {
"first": "https://url_to_next_page",
"last": "https://url_to_last_page",
"next": "https://url_to_next_page",
"previous": "https://url_to_previous_page"
}
}
JSON;
$model = IndexResponse::create(json_decode($json, true));
$this->assertEquals(2, $model->getTotalCount());
$this->assertEquals('https://url_to_next_page', $model->getFirstUrl());
$this->assertEquals('https://url_to_last_page', $model->getLastUrl());
$this->assertEquals('https://url_to_next_page', $model->getNextUrl());
$this->assertEquals('https://url_to_previous_page', $model->getPreviousUrl());
$items = $model->getItems();
$this->assertCount(2, $items);
$item = $items[0];
$this->assertInstanceOf(Whitelist::class, $item);
$this->assertEquals('alice@example.com', $item->getValue());
$this->assertEquals('reason of white listing', $item->getReason());
$this->assertEquals('address', $item->getType());
$this->assertEquals('2011-10-21 11:02:55', $item->getCreatedAt()->format('Y-m-d H:i:s'));
$item = $items[1];
$this->assertInstanceOf(Whitelist::class, $item);
$this->assertEquals('test.com', $item->getValue());
$this->assertEquals('reason of white listing', $item->getReason());
$this->assertEquals('domain', $item->getType());
$this->assertEquals('2012-10-26 11:02:56', $item->getCreatedAt()->format('Y-m-d H:i:s'));
}
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Tests\Model\Suppression\Whitelists;
use Mailgun\Model\Suppression\Whitelist\ShowResponse;
use Mailgun\Tests\Model\BaseModelTest;
class ShowResponseTest extends BaseModelTest
{
public function testCreate()
{
$json =
<<<'JSON'
{
"value": "alice@example.com",
"reason": "why the record was created",
"type": "address",
"createdAt": "Fri, 21 Oct 2011 11:02:55 GMT"
}
JSON;
$model = ShowResponse::create(json_decode($json, true));
$this->assertEquals('alice@example.com', $model->getValue());
$this->assertEquals('why the record was created', $model->getReason());
$this->assertEquals('address', $model->getType());
$this->assertEquals('2011-10-21 11:02:55', $model->getCreatedAt()->format('Y-m-d H:i:s'));
}
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2013 Mailgun
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Mailgun\Tests\Model\Suppression\Whitelists;
use Mailgun\Model\Suppression\Whitelist\Whitelist;
use Mailgun\Tests\Model\BaseModelTest;
class WhitelistTest extends BaseModelTest
{
public function testCreate()
{
$json =
<<<'JSON'
{
"value": "alice@example.com",
"reason": "why the record was created",
"type": "address",
"createdAt": "Fri, 21 Oct 2011 11:02:55 GMT"
}
JSON;
$model = Whitelist::create(json_decode($json, true));
$this->assertEquals('alice@example.com', $model->getValue());
$this->assertEquals('why the record was created', $model->getReason());
$this->assertEquals('address', $model->getType());
$this->assertEquals('2011-10-21 11:02:55', $model->getCreatedAt()->format('Y-m-d H:i:s'));
}
}