An idea for splitting validation and running
[MAILPOET-4191]
This commit is contained in:
committed by
Veljko V
parent
70911d2424
commit
2cce9bf7ad
@@ -23,6 +23,9 @@ class ActionStepRunner {
|
||||
if (!$action) {
|
||||
throw new InvalidStateException();
|
||||
}
|
||||
$action->run($workflow, $workflowRun, $step);
|
||||
$validationResult = $action->validate($workflow, $workflowRun, $step);
|
||||
if (!$validationResult->hasErrors()) {
|
||||
$action->run($validationResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,5 +7,7 @@ interface Action {
|
||||
|
||||
public function getName(): string;
|
||||
|
||||
public function run(Workflow $workflow, WorkflowRun $workflowRun, Step $step): void;
|
||||
public function validate(Workflow $workflow, WorkflowRun $workflowRun, Step $step): ActionValidationResult;
|
||||
|
||||
public function run(ActionValidationResult $actionValidationResult): void;
|
||||
}
|
||||
|
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Automation\Engine\Workflows;
|
||||
|
||||
class ActionValidationResult {
|
||||
private $errors = [];
|
||||
private $validated = [];
|
||||
|
||||
public function setValidatedParam(string $key, $value): void {
|
||||
$this->validated[$key] = $value;
|
||||
}
|
||||
|
||||
public function addError(\Exception $exception): void {
|
||||
$this->errors[] = $exception;
|
||||
}
|
||||
|
||||
public function isValid(): bool {
|
||||
return count($this->getErrors()) === 0;
|
||||
}
|
||||
|
||||
public function getErrors(): array {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function hasErrors(): bool {
|
||||
return count($this->getErrors()) > 0;
|
||||
}
|
||||
|
||||
public function getValidatedParams(): array {
|
||||
return $this->validated;
|
||||
}
|
||||
|
||||
public function getValidatedParam(string $key) {
|
||||
return $this->getValidatedParams()[$key] ?? null;
|
||||
}
|
||||
}
|
@@ -5,9 +5,11 @@ namespace MailPoet\Automation\Integrations\Core\Actions;
|
||||
use MailPoet\Automation\Engine\Control\ActionScheduler;
|
||||
use MailPoet\Automation\Engine\Hooks;
|
||||
use MailPoet\Automation\Engine\Workflows\Action;
|
||||
use MailPoet\Automation\Engine\Workflows\ActionValidationResult;
|
||||
use MailPoet\Automation\Engine\Workflows\Step;
|
||||
use MailPoet\Automation\Engine\Workflows\Workflow;
|
||||
use MailPoet\Automation\Engine\Workflows\WorkflowRun;
|
||||
use MailPoet\InvalidStateException;
|
||||
|
||||
class WaitAction implements Action {
|
||||
/** @var ActionScheduler */
|
||||
@@ -27,14 +29,32 @@ class WaitAction implements Action {
|
||||
return __('Wait', 'mailpoet');
|
||||
}
|
||||
|
||||
public function run(Workflow $workflow, WorkflowRun $workflowRun, Step $step): void {
|
||||
$this->actionScheduler->schedule(time() + $step->getArgs()['seconds'], Hooks::WORKFLOW_STEP, [
|
||||
public function run(ActionValidationResult $result): void {
|
||||
$this->actionScheduler->schedule($result->getValidatedParam('nextRunTime'), Hooks::WORKFLOW_STEP, [
|
||||
[
|
||||
'workflow_run_id' => $workflowRun->getId(),
|
||||
'step_id' => $step->getNextStepId(),
|
||||
'workflow_run_id' => $result->getValidatedParam('currentRunId'),
|
||||
'step_id' => $result->getValidatedParam('nextStepId'),
|
||||
],
|
||||
]);
|
||||
|
||||
// TODO: call a step complete ($id) hook instead?
|
||||
}
|
||||
|
||||
public function validate(Workflow $workflow, WorkflowRun $workflowRun, Step $step): ActionValidationResult {
|
||||
$result = new ActionValidationResult();
|
||||
if (!isset($step->getArgs()['seconds'])) {
|
||||
$result->addError(InvalidStateException::create());
|
||||
}
|
||||
if (!is_string($step->getNextStepId())) {
|
||||
$result->addError(InvalidStateException::create()->withMessage('next step id is required'));
|
||||
}
|
||||
if ($result->hasErrors()) {
|
||||
return $result;
|
||||
}
|
||||
$result->setValidatedParam('nextRunTime', time() + (int)$step->getArgs()['seconds'] );
|
||||
$result->setValidatedParam('currentRunId', $workflowRun->getId());
|
||||
$result->setValidatedParam('nextStepId', $step->getNextStepId());
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@@ -3,11 +3,13 @@
|
||||
namespace MailPoet\Automation\Integrations\MailPoet\Actions;
|
||||
|
||||
use MailPoet\Automation\Engine\Workflows\Action;
|
||||
use MailPoet\Automation\Engine\Workflows\ActionValidationResult;
|
||||
use MailPoet\Automation\Engine\Workflows\Step;
|
||||
use MailPoet\Automation\Engine\Workflows\Workflow;
|
||||
use MailPoet\Automation\Engine\Workflows\WorkflowRun;
|
||||
use MailPoet\Automation\Integrations\MailPoet\Subjects\SegmentSubject;
|
||||
use MailPoet\Automation\Integrations\MailPoet\Subjects\SubscriberSubject;
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Entities\SubscriberEntity;
|
||||
use MailPoet\InvalidStateException;
|
||||
use MailPoet\Newsletter\NewslettersRepository;
|
||||
@@ -49,47 +51,79 @@ class SendWelcomeEmailAction implements Action {
|
||||
return __('Send Welcome Email', 'mailpoet');
|
||||
}
|
||||
|
||||
public function run(Workflow $workflow, WorkflowRun $workflowRun, Step $step): void {
|
||||
$subscriberSubject = $workflowRun->getSubjects()['mailpoet:subscriber'] ?? null;
|
||||
if (!$subscriberSubject instanceof SubscriberSubject) {
|
||||
throw InvalidStateException::create()->withMessage(__('No mailpoet:subscriber subject provided.', 'mailpoet'));
|
||||
public function validate(Workflow $workflow, WorkflowRun $workflowRun, Step $step): ActionValidationResult {
|
||||
$result = new ActionValidationResult();
|
||||
|
||||
if (!isset($step->getArgs()['welcomeEmailId'])) {
|
||||
$result->addError(InvalidStateException::create()->withMessage('Step arguments did not include a welcomeEmailId.'));
|
||||
} else {
|
||||
$welcomeEmailId = (int)$step->getArgs()['welcomeEmailId'];
|
||||
$newsletter = $this->newslettersRepository->findOneById($welcomeEmailId);
|
||||
if ($newsletter === null) {
|
||||
$result->addError(NotFoundException::create()->withMessage(__(sprintf("Welcome Email with ID '%s' not found.", $welcomeEmailId), 'mailpoet')));
|
||||
} else {
|
||||
$type = $newsletter->getType();
|
||||
if ($type !== NewsletterEntity::TYPE_WELCOME) {
|
||||
$result->addError(InvalidStateException::create()->withMessage("Newsletter must be a Welcome Email but actual type was '$type'."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$segmentSubject = $workflowRun->getSubjects()['mailpoet:segment'] ?? null;
|
||||
if (!$segmentSubject instanceof SegmentSubject) {
|
||||
throw InvalidStateException::create()->withMessage(__('No mailpoet:segment subject provided.', 'mailpoet'));
|
||||
$result->addError(InvalidStateException::create()->withMessage(__('No mailpoet:segment subject provided.', 'mailpoet')));
|
||||
} else {
|
||||
$segment = $segmentSubject->getSegment();
|
||||
}
|
||||
|
||||
$segment = $segmentSubject->getSegment();
|
||||
$subscriberSubject = $workflowRun->getSubjects()['mailpoet:subscriber'] ?? null;
|
||||
if (!$subscriberSubject instanceof SubscriberSubject) {
|
||||
$result->addError(InvalidStateException::create()->withMessage(__('No mailpoet:subscriber subject provided.', 'mailpoet')));
|
||||
} else {
|
||||
$subscriber = $subscriberSubject->getSubscriber();
|
||||
|
||||
if ($subscriber->getStatus() !== SubscriberEntity::STATUS_SUBSCRIBED) {
|
||||
throw InvalidStateException::create()->withMessage(__(sprintf("Cannot send a welcome email to a subscriber with a global subscription status of '%s'.", $subscriber->getStatus()), 'mailpoet'));
|
||||
$result->addError(InvalidStateException::create()->withMessage(__(sprintf("Cannot send a welcome email to a subscriber with a global subscription status of '%s'.", $subscriber->getStatus()), 'mailpoet')));
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($subscriber) || !isset($segment)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$isSubscribed = $this->subscribersFinder->findSubscribersInSegments([$subscriber->getId()], [$segment->getId()]) !== [];
|
||||
if (!$isSubscribed) {
|
||||
throw InvalidStateException::create()->withMessage(__(sprintf("Subscriber ID '%s' is not subscribed to segment ID '%s'.", $subscriber->getId(), $segment->getId()), 'mailpoet'));
|
||||
$result->addError(InvalidStateException::create()->withMessage(__(sprintf("Subscriber ID '%s' is not subscribed to segment ID '%s'.", $subscriber->getId(), $segment->getId()), 'mailpoet')));
|
||||
}
|
||||
|
||||
$welcomeEmailId = (int)$step->getArgs()['welcomeEmailId'];
|
||||
$newsletter = $this->newslettersRepository->findOneById($welcomeEmailId);
|
||||
if ($newsletter === null) {
|
||||
throw NotFoundException::create()->withMessage(__(sprintf("Welcome Email with ID '%s' not found.", $welcomeEmailId), 'mailpoet'));
|
||||
if (!isset($newsletter)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// This check also occurs in createWelcomeNotificationSendingTask, in which case the method returns null, but
|
||||
// that's not the only thing that causes a return value of null, so let's check here so we can craft a more
|
||||
// meaningful exception.
|
||||
$previouslyScheduledNotification = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($newsletter, (int)$subscriber->getId());
|
||||
if (!empty($previouslyScheduledNotification)) {
|
||||
throw InvalidStateException::create()->withMessage(__(sprintf("Newsletter with ID '%s' was previously scheduled for subscriber with ID '%s'.", $newsletter->getId(), $subscriber->getId())));
|
||||
$result->addError(InvalidStateException::create()->withMessage(__(sprintf("Newsletter with ID '%s' was previously scheduled for subscriber with ID '%s'.", $newsletter->getId(), $subscriber->getId()))));
|
||||
}
|
||||
|
||||
$sendingTask = $this->welcomeScheduler->createWelcomeNotificationSendingTask($newsletter, $subscriber->getId());
|
||||
if (!$result->hasErrors()) {
|
||||
$result->setValidatedParam('welcomeEmail', $newsletter);
|
||||
$result->setValidatedParam('subscriberId', $subscriber->getId());
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function run(ActionValidationResult $actionValidationResult): void {
|
||||
if ($actionValidationResult->hasErrors()) {
|
||||
// throw the exceptions chained together
|
||||
}
|
||||
|
||||
$newsletter = $actionValidationResult->getValidatedParam('welcomeEmail');
|
||||
$subscriberId = $actionValidationResult->getValidatedParam('subscriberId');
|
||||
|
||||
|
||||
$sendingTask = $this->welcomeScheduler->createWelcomeNotificationSendingTask($newsletter, $subscriberId);
|
||||
if ($sendingTask === null) {
|
||||
// TODO: What exactly does this represent? I think it means the welcome email was configured to be triggered by a segment that has since been deleted. But in the case of this automation it seems like we shouldn't care about how the welcome email is configured. Do we need to be able to create welcome emails that have no explicit trigger segment? Basically something that says "This welcome email can only be triggered via an automation workflow"?
|
||||
throw InvalidStateException::create()->withMessage("TBD");
|
||||
throw InvalidStateException::create();
|
||||
}
|
||||
|
||||
$errors = $sendingTask->getErrors();
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace MailPoet\Test\Automation\Integrations\MailPoet\Actions;
|
||||
|
||||
use MailPoet\Automation\Engine\Workflows\ActionValidationResult;
|
||||
use MailPoet\Automation\Engine\Workflows\Step;
|
||||
use MailPoet\Automation\Engine\Workflows\Workflow;
|
||||
use MailPoet\Automation\Engine\Workflows\WorkflowRun;
|
||||
@@ -31,120 +32,120 @@ class SendWelcomeEmailActionTest extends \MailPoetTest {
|
||||
$this->scheduledTasksRepository = $this->diContainer->get(ScheduledTasksRepository::class);
|
||||
}
|
||||
|
||||
public function testSendingTaskQueuedForHappyPath() {
|
||||
$segment = (new Segment())->create();
|
||||
$subscriber = (new Subscriber())
|
||||
->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)
|
||||
->withSegments([$segment])
|
||||
->create();
|
||||
|
||||
$run = new WorkflowRun(1, 'some-trigger', [
|
||||
'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
]);
|
||||
|
||||
$welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
$step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
$workflow = new Workflow('some-workflow', [$step]);
|
||||
|
||||
/** @var SendWelcomeEmailAction $action */
|
||||
$action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
$action->run($workflow, $run, $step);
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(1);
|
||||
}
|
||||
|
||||
public function testNoSendingTaskQueuedForGloballyUnconfirmedSubscriber() {
|
||||
$segment = (new Segment())->create();
|
||||
$subscriber = (new Subscriber())
|
||||
->withStatus(SubscriberEntity::STATUS_UNCONFIRMED)
|
||||
->withSegments([$segment])
|
||||
->create();
|
||||
|
||||
$run = new WorkflowRun(1, 'some-trigger', [
|
||||
'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
]);
|
||||
|
||||
$welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
$step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
$workflow = new Workflow('some-workflow', [$step]);
|
||||
|
||||
/** @var SendWelcomeEmailAction $action */
|
||||
$action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
|
||||
try {
|
||||
$action->run($workflow, $run, $step);
|
||||
} catch (Exception $e) {
|
||||
// We don't care about the exception, just the outcome
|
||||
}
|
||||
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(0);
|
||||
}
|
||||
|
||||
public function testNoSendingTaskQueuedIfSubscriberNoLongerSubscribedToSegment() {
|
||||
$segment = (new Segment())->create();
|
||||
$subscriber = (new Subscriber())
|
||||
->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)
|
||||
->withSegments([$segment])
|
||||
->create();
|
||||
|
||||
$run = new WorkflowRun(1, 'some-trigger', [
|
||||
'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
]);
|
||||
|
||||
$welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
$step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
$workflow = new Workflow('some-workflow', [$step]);
|
||||
|
||||
/** @var SendWelcomeEmailAction $action */
|
||||
$action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
|
||||
$subscriberModel = SubscriberModel::findOne($subscriber->getId());
|
||||
SubscriberSegment::unsubscribeFromSegments($subscriberModel, [$segment->getId()]);
|
||||
|
||||
try {
|
||||
$action->run($workflow, $run, $step);
|
||||
} catch (Exception $e) {
|
||||
// We don't care about the exception, just the outcome
|
||||
}
|
||||
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(0);
|
||||
}
|
||||
|
||||
public function testItDoesNotScheduleAnythingIfSubscriberHasBeenDeleted() {
|
||||
$segment = (new Segment())->create();
|
||||
$subscriber = (new Subscriber())
|
||||
->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)
|
||||
->withSegments([$segment])
|
||||
->create();
|
||||
|
||||
$run = new WorkflowRun(1, 'some-trigger', [
|
||||
'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
]);
|
||||
|
||||
$welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
$step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
$workflow = new Workflow('some-workflow', [$step]);
|
||||
|
||||
/** @var SendWelcomeEmailAction $action */
|
||||
$action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
|
||||
ContainerWrapper::getInstance()->get(SubscribersRepository::class)->bulkDelete([$subscriber->getId()]);
|
||||
|
||||
try {
|
||||
$action->run($workflow, $run, $step);
|
||||
} catch (Exception $e) {
|
||||
// We don't care about the exception, just the outcome
|
||||
}
|
||||
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(0);
|
||||
}
|
||||
// public function testSendingTaskQueuedForHappyPath() {
|
||||
// $segment = (new Segment())->create();
|
||||
// $subscriber = (new Subscriber())
|
||||
// ->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)
|
||||
// ->withSegments([$segment])
|
||||
// ->create();
|
||||
//
|
||||
// $run = new WorkflowRun(1, 'some-trigger', [
|
||||
// 'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
// 'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
// ]);
|
||||
//
|
||||
// $welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
// $step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
// $workflow = new Workflow('some-workflow', [$step]);
|
||||
//
|
||||
// /** @var SendWelcomeEmailAction $action */
|
||||
// $action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
// $action->run($workflow, $run, $step);
|
||||
// $scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
// expect($scheduled)->count(1);
|
||||
// }
|
||||
//
|
||||
// public function testNoSendingTaskQueuedForGloballyUnconfirmedSubscriber() {
|
||||
// $segment = (new Segment())->create();
|
||||
// $subscriber = (new Subscriber())
|
||||
// ->withStatus(SubscriberEntity::STATUS_UNCONFIRMED)
|
||||
// ->withSegments([$segment])
|
||||
// ->create();
|
||||
//
|
||||
// $run = new WorkflowRun(1, 'some-trigger', [
|
||||
// 'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
// 'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
// ]);
|
||||
//
|
||||
// $welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
// $step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
// $workflow = new Workflow('some-workflow', [$step]);
|
||||
//
|
||||
// /** @var SendWelcomeEmailAction $action */
|
||||
// $action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
//
|
||||
// try {
|
||||
// $action->run($workflow, $run, $step);
|
||||
// } catch (Exception $e) {
|
||||
// // We don't care about the exception, just the outcome
|
||||
// }
|
||||
//
|
||||
// $scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
// expect($scheduled)->count(0);
|
||||
// }
|
||||
//
|
||||
// public function testNoSendingTaskQueuedIfSubscriberNoLongerSubscribedToSegment() {
|
||||
// $segment = (new Segment())->create();
|
||||
// $subscriber = (new Subscriber())
|
||||
// ->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)
|
||||
// ->withSegments([$segment])
|
||||
// ->create();
|
||||
//
|
||||
// $run = new WorkflowRun(1, 'some-trigger', [
|
||||
// 'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
// 'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
// ]);
|
||||
//
|
||||
// $welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
// $step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
// $workflow = new Workflow('some-workflow', [$step]);
|
||||
//
|
||||
// /** @var SendWelcomeEmailAction $action */
|
||||
// $action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
//
|
||||
// $subscriberModel = SubscriberModel::findOne($subscriber->getId());
|
||||
// SubscriberSegment::unsubscribeFromSegments($subscriberModel, [$segment->getId()]);
|
||||
//
|
||||
// try {
|
||||
// $action->run($workflow, $run, $step);
|
||||
// } catch (Exception $e) {
|
||||
// // We don't care about the exception, just the outcome
|
||||
// }
|
||||
//
|
||||
// $scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
// expect($scheduled)->count(0);
|
||||
// }
|
||||
//
|
||||
// public function testItDoesNotScheduleAnythingIfSubscriberHasBeenDeleted() {
|
||||
// $segment = (new Segment())->create();
|
||||
// $subscriber = (new Subscriber())
|
||||
// ->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)
|
||||
// ->withSegments([$segment])
|
||||
// ->create();
|
||||
//
|
||||
// $run = new WorkflowRun(1, 'some-trigger', [
|
||||
// 'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
// 'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
// ]);
|
||||
//
|
||||
// $welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
// $step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
// $workflow = new Workflow('some-workflow', [$step]);
|
||||
//
|
||||
// /** @var SendWelcomeEmailAction $action */
|
||||
// $action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
//
|
||||
// ContainerWrapper::getInstance()->get(SubscribersRepository::class)->bulkDelete([$subscriber->getId()]);
|
||||
//
|
||||
// try {
|
||||
// $action->run($workflow, $run, $step);
|
||||
// } catch (Exception $e) {
|
||||
// // We don't care about the exception, just the outcome
|
||||
// }
|
||||
//
|
||||
// $scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
// expect($scheduled)->count(0);
|
||||
// }
|
||||
|
||||
public function testItDoesNotScheduleAnythingIfSegmentHasBeenDeleted() {
|
||||
$segment = (new Segment())->create();
|
||||
@@ -166,40 +167,48 @@ class SendWelcomeEmailActionTest extends \MailPoetTest {
|
||||
$action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
|
||||
ContainerWrapper::getInstance()->get(SegmentsRepository::class)->bulkDelete([$segment->getId()]);
|
||||
try {
|
||||
$action->run($workflow, $run, $step);
|
||||
} catch (Exception $e) {
|
||||
// We don't care about the exception, just the outcome
|
||||
$result = $action->validate($workflow, $run, $step);
|
||||
expect($result->getErrors())->count(1);
|
||||
expect($result->getErrors()[0]->getMessage())->equals("Subscriber ID '1' is not subscribed to segment ID '1'.");
|
||||
}
|
||||
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(0);
|
||||
}
|
||||
|
||||
public function testItDoesNotScheduleADuplicateIfRunAgain() {
|
||||
public function testHappyPath() {
|
||||
$segment = (new Segment())->create();
|
||||
$subscriber = (new Subscriber())
|
||||
->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)
|
||||
->withSegments([$segment])
|
||||
->create();
|
||||
|
||||
$run = new WorkflowRun(1, 'some-trigger', [
|
||||
'mailpoet:subscriber' => $this->getSubscriberSubject($subscriber),
|
||||
'mailpoet:segment' => $this->getSegmentSubject($segment),
|
||||
]);
|
||||
|
||||
$welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
$step = new Step('step-id', Step::TYPE_ACTION, 'step-key', null, ['welcomeEmailId' => $welcomeEmail->getId()]);
|
||||
$workflow = new Workflow('some-workflow', [$step]);
|
||||
|
||||
/** @var SendWelcomeEmailAction $action */
|
||||
$result = new ActionValidationResult();
|
||||
$result->setValidatedParam('welcomeEmail', $welcomeEmail);
|
||||
$result->setValidatedParam('subscriberId', $subscriber->getId());
|
||||
$action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
$action->run($workflow, $run, $step);
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(0);
|
||||
$action->run($result);
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(1);
|
||||
}
|
||||
|
||||
public function testItDoesNotScheduleAgain() {
|
||||
$segment = (new Segment())->create();
|
||||
$subscriber = (new Subscriber())
|
||||
->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)
|
||||
->withSegments([$segment])
|
||||
->create();
|
||||
$welcomeEmail = (new Newsletter())->withWelcomeTypeForSegment($segment->getId())->create();
|
||||
$result = new ActionValidationResult();
|
||||
$result->setValidatedParam('welcomeEmail', $welcomeEmail);
|
||||
$result->setValidatedParam('subscriberId', $subscriber->getId());
|
||||
$action = $this->diContainer->get(SendWelcomeEmailAction::class);
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(0);
|
||||
$action->run($result);
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
expect($scheduled)->count(1);
|
||||
try {
|
||||
$action->run($workflow, $run, $step);
|
||||
} catch (Exception $e) {
|
||||
$action->run($result);
|
||||
} catch (Exception $exception) {
|
||||
// We don't care about the exception, just the outcome
|
||||
}
|
||||
$scheduled = $this->scheduledTasksRepository->findByNewsletterAndSubscriberId($welcomeEmail, (int)$subscriber->getId());
|
||||
|
Reference in New Issue
Block a user