Move subscriber limit check into validator
[MAILPOET-4236]
This commit is contained in:
committed by
Veljko V
parent
9bfe2b2ca1
commit
8983d5e3f7
@ -25,7 +25,6 @@ use MailPoet\Newsletter\Scheduler\Scheduler;
|
|||||||
use MailPoet\Newsletter\Url as NewsletterUrl;
|
use MailPoet\Newsletter\Url as NewsletterUrl;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\UnexpectedValueException;
|
use MailPoet\UnexpectedValueException;
|
||||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
|
||||||
use MailPoet\Util\Security;
|
use MailPoet\Util\Security;
|
||||||
use MailPoet\WP\Emoji;
|
use MailPoet\WP\Emoji;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
@ -64,9 +63,6 @@ class Newsletters extends APIEndpoint {
|
|||||||
/** @var Emoji */
|
/** @var Emoji */
|
||||||
private $emoji;
|
private $emoji;
|
||||||
|
|
||||||
/** @var SubscribersFeature */
|
|
||||||
private $subscribersFeature;
|
|
||||||
|
|
||||||
/** @var SendPreviewController */
|
/** @var SendPreviewController */
|
||||||
private $sendPreviewController;
|
private $sendPreviewController;
|
||||||
|
|
||||||
@ -92,7 +88,6 @@ class Newsletters extends APIEndpoint {
|
|||||||
NewslettersResponseBuilder $newslettersResponseBuilder,
|
NewslettersResponseBuilder $newslettersResponseBuilder,
|
||||||
PostNotificationScheduler $postNotificationScheduler,
|
PostNotificationScheduler $postNotificationScheduler,
|
||||||
Emoji $emoji,
|
Emoji $emoji,
|
||||||
SubscribersFeature $subscribersFeature,
|
|
||||||
SendPreviewController $sendPreviewController,
|
SendPreviewController $sendPreviewController,
|
||||||
NewsletterSaveController $newsletterSaveController,
|
NewsletterSaveController $newsletterSaveController,
|
||||||
NewsletterUrl $newsletterUrl,
|
NewsletterUrl $newsletterUrl,
|
||||||
@ -108,7 +103,6 @@ class Newsletters extends APIEndpoint {
|
|||||||
$this->newslettersResponseBuilder = $newslettersResponseBuilder;
|
$this->newslettersResponseBuilder = $newslettersResponseBuilder;
|
||||||
$this->postNotificationScheduler = $postNotificationScheduler;
|
$this->postNotificationScheduler = $postNotificationScheduler;
|
||||||
$this->emoji = $emoji;
|
$this->emoji = $emoji;
|
||||||
$this->subscribersFeature = $subscribersFeature;
|
|
||||||
$this->sendPreviewController = $sendPreviewController;
|
$this->sendPreviewController = $sendPreviewController;
|
||||||
$this->newsletterSaveController = $newsletterSaveController;
|
$this->newsletterSaveController = $newsletterSaveController;
|
||||||
$this->newsletterUrl = $newsletterUrl;
|
$this->newsletterUrl = $newsletterUrl;
|
||||||
@ -171,12 +165,6 @@ class Newsletters extends APIEndpoint {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($status === NewsletterEntity::STATUS_ACTIVE && $this->subscribersFeature->check()) {
|
|
||||||
return $this->errorResponse([
|
|
||||||
APIError::FORBIDDEN => __('Subscribers limit reached.', 'mailpoet'),
|
|
||||||
], [], Response::STATUS_FORBIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
$newsletter = $this->getNewsletter($data);
|
$newsletter = $this->getNewsletter($data);
|
||||||
if ($newsletter === null) {
|
if ($newsletter === null) {
|
||||||
return $this->errorResponse([
|
return $this->errorResponse([
|
||||||
|
@ -5,6 +5,7 @@ namespace MailPoet\Newsletter;
|
|||||||
use MailPoet\Entities\NewsletterEntity;
|
use MailPoet\Entities\NewsletterEntity;
|
||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
use MailPoet\Settings\TrackingConfig;
|
use MailPoet\Settings\TrackingConfig;
|
||||||
|
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
||||||
use MailPoet\Validator\ValidationException;
|
use MailPoet\Validator\ValidationException;
|
||||||
|
|
||||||
class NewsletterValidator {
|
class NewsletterValidator {
|
||||||
@ -15,16 +16,22 @@ class NewsletterValidator {
|
|||||||
/** @var TrackingConfig */
|
/** @var TrackingConfig */
|
||||||
private $trackingConfig;
|
private $trackingConfig;
|
||||||
|
|
||||||
|
/** @var SubscribersFeature */
|
||||||
|
private $subscribersFeature;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Bridge $bridge,
|
Bridge $bridge,
|
||||||
TrackingConfig $trackingConfig
|
TrackingConfig $trackingConfig,
|
||||||
|
SubscribersFeature $subscribersFeature
|
||||||
) {
|
) {
|
||||||
$this->bridge = $bridge;
|
$this->bridge = $bridge;
|
||||||
$this->trackingConfig = $trackingConfig;
|
$this->trackingConfig = $trackingConfig;
|
||||||
|
$this->subscribersFeature = $subscribersFeature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate(NewsletterEntity $newsletterEntity): ?string {
|
public function validate(NewsletterEntity $newsletterEntity): ?string {
|
||||||
try {
|
try {
|
||||||
|
$this->validateSubscriberLimit();
|
||||||
$this->validateBody($newsletterEntity);
|
$this->validateBody($newsletterEntity);
|
||||||
$this->validateUnsubscribeRequirements($newsletterEntity);
|
$this->validateUnsubscribeRequirements($newsletterEntity);
|
||||||
$this->validateReEngagementRequirements($newsletterEntity);
|
$this->validateReEngagementRequirements($newsletterEntity);
|
||||||
@ -88,4 +95,10 @@ class NewsletterValidator {
|
|||||||
throw new ValidationException('Please add an “Automatic Latest Content” widget to the email from the right sidebar.');
|
throw new ValidationException('Please add an “Automatic Latest Content” widget to the email from the right sidebar.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function validateSubscriberLimit(): void {
|
||||||
|
if ($this->subscribersFeature->check()) {
|
||||||
|
throw new ValidationException('Subscribers limit reached.');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,14 @@ use MailPoet\Entities\SegmentEntity;
|
|||||||
use MailPoet\Entities\SendingQueueEntity;
|
use MailPoet\Entities\SendingQueueEntity;
|
||||||
use MailPoet\Entities\SubscriberEntity;
|
use MailPoet\Entities\SubscriberEntity;
|
||||||
use MailPoet\Entities\SubscriberSegmentEntity;
|
use MailPoet\Entities\SubscriberSegmentEntity;
|
||||||
use MailPoet\Listing\Handler;
|
|
||||||
use MailPoet\Models\ScheduledTask;
|
use MailPoet\Models\ScheduledTask;
|
||||||
use MailPoet\Models\SendingQueue;
|
use MailPoet\Models\SendingQueue;
|
||||||
use MailPoet\Newsletter\Listing\NewsletterListingRepository;
|
|
||||||
use MailPoet\Newsletter\NewsletterSaveController;
|
|
||||||
use MailPoet\Newsletter\NewslettersRepository;
|
use MailPoet\Newsletter\NewslettersRepository;
|
||||||
use MailPoet\Newsletter\NewsletterValidator;
|
use MailPoet\Newsletter\NewsletterValidator;
|
||||||
use MailPoet\Newsletter\Options\NewsletterOptionFieldsRepository;
|
use MailPoet\Newsletter\Options\NewsletterOptionFieldsRepository;
|
||||||
use MailPoet\Newsletter\Options\NewsletterOptionsRepository;
|
use MailPoet\Newsletter\Options\NewsletterOptionsRepository;
|
||||||
use MailPoet\Newsletter\Preview\SendPreviewController;
|
use MailPoet\Newsletter\Preview\SendPreviewController;
|
||||||
use MailPoet\Newsletter\Preview\SendPreviewException;
|
use MailPoet\Newsletter\Preview\SendPreviewException;
|
||||||
use MailPoet\Newsletter\Scheduler\PostNotificationScheduler;
|
|
||||||
use MailPoet\Newsletter\Scheduler\Scheduler;
|
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||||
use MailPoet\Newsletter\Segment\NewsletterSegmentRepository;
|
use MailPoet\Newsletter\Segment\NewsletterSegmentRepository;
|
||||||
use MailPoet\Newsletter\Sending\SendingQueuesRepository;
|
use MailPoet\Newsletter\Sending\SendingQueuesRepository;
|
||||||
@ -41,7 +37,7 @@ use MailPoet\Segments\SegmentsRepository;
|
|||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\Tasks\Sending as SendingTask;
|
use MailPoet\Tasks\Sending as SendingTask;
|
||||||
use MailPoet\Test\DataFactories\Newsletter;
|
use MailPoet\Test\DataFactories\Newsletter;
|
||||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
use MailPoet\Util\License\Features\Subscribers;
|
||||||
use MailPoet\WooCommerce\Helper as WCHelper;
|
use MailPoet\WooCommerce\Helper as WCHelper;
|
||||||
use MailPoet\WP\Emoji;
|
use MailPoet\WP\Emoji;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
@ -183,7 +179,6 @@ class NewslettersTest extends \MailPoetTest {
|
|||||||
$this->endpoint = $this->createNewslettersEndpointWithMocks([
|
$this->endpoint = $this->createNewslettersEndpointWithMocks([
|
||||||
'wp' => $wp,
|
'wp' => $wp,
|
||||||
'cronHelper' => $this->cronHelper,
|
'cronHelper' => $this->cronHelper,
|
||||||
'subscribersFeature' => Stub::make(SubscribersFeature::class),
|
|
||||||
]);
|
]);
|
||||||
$response = $this->endpoint->get(['id' => $this->newsletter->getId()]);
|
$response = $this->endpoint->get(['id' => $this->newsletter->getId()]);
|
||||||
|
|
||||||
@ -233,7 +228,9 @@ class NewslettersTest extends \MailPoetTest {
|
|||||||
public function testItReturnsErrorIfSubscribersLimitReached() {
|
public function testItReturnsErrorIfSubscribersLimitReached() {
|
||||||
$endpoint = $this->createNewslettersEndpointWithMocks([
|
$endpoint = $this->createNewslettersEndpointWithMocks([
|
||||||
'cronHelper' => $this->cronHelper,
|
'cronHelper' => $this->cronHelper,
|
||||||
'subscribersFeature' => Stub::make(SubscribersFeature::class, ['check' => true]),
|
'newsletterValidator' => $this->getServiceWithOverrides(NewsletterValidator::class, [
|
||||||
|
'subscribersFeature' => Stub::make(Subscribers::class, ['check' => true])
|
||||||
|
])
|
||||||
]);
|
]);
|
||||||
$res = $endpoint->setStatus([
|
$res = $endpoint->setStatus([
|
||||||
'id' => $this->newsletter->getId(),
|
'id' => $this->newsletter->getId(),
|
||||||
@ -375,7 +372,6 @@ class NewslettersTest extends \MailPoetTest {
|
|||||||
$this->endpoint = $this->createNewslettersEndpointWithMocks([
|
$this->endpoint = $this->createNewslettersEndpointWithMocks([
|
||||||
'wp' => $wp,
|
'wp' => $wp,
|
||||||
'cronHelper' => $this->cronHelper,
|
'cronHelper' => $this->cronHelper,
|
||||||
'subscribersFeature' => Stub::make(SubscribersFeature::class),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response = $this->endpoint->duplicate(['id' => $this->newsletter->getId()]);
|
$response = $this->endpoint->duplicate(['id' => $this->newsletter->getId()]);
|
||||||
@ -647,7 +643,6 @@ class NewslettersTest extends \MailPoetTest {
|
|||||||
'wp' => $wp,
|
'wp' => $wp,
|
||||||
'cronHelper' => $this->cronHelper,
|
'cronHelper' => $this->cronHelper,
|
||||||
'emoji' => $emoji,
|
'emoji' => $emoji,
|
||||||
'subscribersFeature' => Stub::make(SubscribersFeature::class),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response = $this->endpoint->showPreview($data);
|
$response = $this->endpoint->showPreview($data);
|
||||||
@ -679,23 +674,7 @@ class NewslettersTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function createNewslettersEndpointWithMocks(array $mocks): Newsletters {
|
private function createNewslettersEndpointWithMocks(array $mocks): Newsletters {
|
||||||
return new Newsletters(
|
return $this->getServiceWithOverrides(Newsletters::class, $mocks);
|
||||||
$this->diContainer->get(Handler::class),
|
|
||||||
$mocks['wp'] ?? $this->diContainer->get(WPFunctions::class),
|
|
||||||
$this->diContainer->get(SettingsController::class),
|
|
||||||
$mocks['cronHelper'] ?? $this->diContainer->get(CronHelper::class),
|
|
||||||
$this->diContainer->get(NewslettersRepository::class),
|
|
||||||
$this->diContainer->get(NewsletterListingRepository::class),
|
|
||||||
$this->diContainer->get(NewslettersResponseBuilder::class),
|
|
||||||
$this->diContainer->get(PostNotificationScheduler::class),
|
|
||||||
$mocks['emoji'] ?? $this->diContainer->get(Emoji::class),
|
|
||||||
$mocks['subscribersFeature'] ?? $this->diContainer->get(SubscribersFeature::class),
|
|
||||||
$mocks['sendPreviewController'] ?? $this->diContainer->get(SendPreviewController::class),
|
|
||||||
$this->diContainer->get(NewsletterSaveController::class),
|
|
||||||
$this->diContainer->get(Url::class),
|
|
||||||
$this->scheduler,
|
|
||||||
$this->diContainer->get(NewsletterValidator::class)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createNewsletterOptionField(string $name, string $type): NewsletterOptionFieldEntity {
|
private function createNewsletterOptionField(string $name, string $type): NewsletterOptionFieldEntity {
|
||||||
|
@ -23,8 +23,8 @@ use MailPoet\Segments\SubscribersFinder;
|
|||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\Settings\SettingsRepository;
|
use MailPoet\Settings\SettingsRepository;
|
||||||
use MailPoet\Settings\TrackingConfig;
|
|
||||||
use MailPoet\Tasks\Sending;
|
use MailPoet\Tasks\Sending;
|
||||||
|
use MailPoet\Test\DataFactories\Newsletter;
|
||||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
||||||
|
|
||||||
class SendingQueueTest extends \MailPoetTest {
|
class SendingQueueTest extends \MailPoetTest {
|
||||||
@ -141,38 +141,27 @@ class SendingQueueTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function testItRejectsNewsletterWithoutUnsubscribeLink() {
|
public function testItRejectsNewsletterWithoutUnsubscribeLink() {
|
||||||
$newsletter = new NewsletterEntity();
|
$newsletter = (new Newsletter())->withBody([
|
||||||
$newsletter->setSubject('subject');
|
'content' =>
|
||||||
$newsletter->setType(NewsletterEntity::TYPE_STANDARD);
|
[
|
||||||
$newsletter->setBody([
|
'type' => 'container',
|
||||||
'content' =>
|
'columnLayout' => false,
|
||||||
[
|
'orientation' => 'vertical',
|
||||||
'type' => 'container',
|
'blocks' => [
|
||||||
'columnLayout' => false,
|
[
|
||||||
'orientation' => 'vertical',
|
'type' => 'header',
|
||||||
'blocks' => [
|
'link' => '',
|
||||||
[
|
'text' => 'Hello!'
|
||||||
'type' => 'header',
|
]
|
||||||
'link' => '',
|
|
||||||
'text' => 'Hello!'
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
)->create();
|
||||||
|
$sendingQueue = $this->getServiceWithOverrides(SendingQueueAPI::class, [
|
||||||
|
'newsletterValidator' => $this->getServiceWithOverrides(NewsletterValidator::class, [
|
||||||
|
'bridge' => Stub::make(Bridge::class, ['isMailpoetSendingServiceEnabled' => true])
|
||||||
|
])
|
||||||
]);
|
]);
|
||||||
$this->entityManager->persist($newsletter);
|
|
||||||
$this->entityManager->flush();
|
|
||||||
$sendingQueue = new SendingQueueAPI(
|
|
||||||
$this->diContainer->get(SubscribersFeature::class),
|
|
||||||
$this->diContainer->get(NewslettersRepository::class),
|
|
||||||
$this->diContainer->get(SendingQueuesRepository::class),
|
|
||||||
$this->diContainer->get(SubscribersFinder::class),
|
|
||||||
$this->diContainer->get(ScheduledTasksRepository::class),
|
|
||||||
$this->diContainer->get(MailerFactory::class),
|
|
||||||
$this->diContainer->get(Scheduler::class),
|
|
||||||
new NewsletterValidator(Stub::make(Bridge::class, [
|
|
||||||
'isMailpoetSendingServiceEnabled' => true,
|
|
||||||
]), $this->diContainer->get(TrackingConfig::class))
|
|
||||||
);
|
|
||||||
$response = $sendingQueue->add(['newsletter_id' => $newsletter->getId()]);
|
$response = $sendingQueue->add(['newsletter_id' => $newsletter->getId()]);
|
||||||
$response = $response->getData();
|
$response = $response->getData();
|
||||||
expect($response['errors'][0])->array();
|
expect($response['errors'][0])->array();
|
||||||
|
@ -7,6 +7,7 @@ use MailPoet\Newsletter\NewsletterValidator;
|
|||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
use MailPoet\Settings\TrackingConfig;
|
use MailPoet\Settings\TrackingConfig;
|
||||||
use MailPoet\Test\DataFactories\Newsletter;
|
use MailPoet\Test\DataFactories\Newsletter;
|
||||||
|
use MailPoet\Util\License\Features\Subscribers;
|
||||||
|
|
||||||
class NewsletterValidatorTest extends \MailPoetTest {
|
class NewsletterValidatorTest extends \MailPoetTest {
|
||||||
/** @var NewsletterValidator */
|
/** @var NewsletterValidator */
|
||||||
@ -106,4 +107,13 @@ class NewsletterValidatorTest extends \MailPoetTest {
|
|||||||
expect($validationError)->null();
|
expect($validationError)->null();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testItIsNotValidIfSubscriberLimitReached() {
|
||||||
|
$newsletter = (new Newsletter())->withDefaultBody()->create();
|
||||||
|
$validator = $this->getServiceWithOverrides(NewsletterValidator::class, [
|
||||||
|
'subscribersFeature' => Stub::make(Subscribers::class, ['check' => true])
|
||||||
|
]);
|
||||||
|
$validationError = $validator->validate($newsletter);
|
||||||
|
expect($validationError)->equals('Subscribers limit reached.');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user