automaticEmailScheduler = $this->diContainer->get(AutomaticEmailScheduler::class); $this->newslettersRepository = $this->diContainer->get(NewslettersRepository::class); $this->sendingQueuesRepository = $this->diContainer->get(SendingQueuesRepository::class); $this->scheduledTasksRepository = $this->diContainer->get(ScheduledTasksRepository::class); $this->newsletterFactory = new NewsletterFactory(); $this->newsletter = $this->createAutomaticNewsletter(); } public function testItCreatesScheduledAutomaticEmailSendingTaskForUser() { $newsletter = $this->newslettersRepository->findOneById($this->newsletter->getId()); $this->assertInstanceOf(NewsletterEntity::class, $newsletter); $subscriber = (new SubscriberFactory())->create(); $this->automaticEmailScheduler->createAutomaticEmailScheduledTask($newsletter, $subscriber); // new scheduled task should be created $task = $this->scheduledTasksRepository->findOneByNewsletter($newsletter); $queue = $this->sendingQueuesRepository->findOneBy(['newsletter' => $newsletter]); $expectedTime = Carbon::now()->millisecond(0)->addHours(2); $this->assertInstanceOf(ScheduledTaskEntity::class, $task); verify($task->getId())->greaterThanOrEqual(1); verify($task->getPriority())->equals(SendingQueueEntity::PRIORITY_MEDIUM); verify($task->getStatus())->equals(SendingQueueEntity::STATUS_SCHEDULED); $this->tester->assertEqualDateTimes($expectedTime, $task->getScheduledAt(), 1); $this->assertInstanceOf(SendingQueueEntity::class, $queue); verify($queue->getCountTotal())->equals(1); verify($queue->getCountToProcess())->equals(1); verify($queue->getCountProcessed())->equals(0); // task should have 1 associated user $subscribers = $task->getSubscribers()->toArray(); verify($subscribers)->arrayCount(1); verify($subscribers[0]->getSubscriber())->equals($subscriber); } public function testItAddsMetaToSendingQueueWhenCreatingAutomaticEmailSendingTask() { $newsletter = $this->newslettersRepository->findOneById($this->newsletter->getId()); $this->assertInstanceOf(NewsletterEntity::class, $newsletter); $subscriber = (new SubscriberFactory())->create(); $meta = ['some' => 'value']; $this->automaticEmailScheduler->createAutomaticEmailScheduledTask($newsletter, $subscriber, $meta); // new queue record should be created with meta data $queue = $this->sendingQueuesRepository->findOneBy(['newsletter' => $newsletter]); $this->assertInstanceOf(SendingQueueEntity::class, $queue); $this->assertEquals($meta, $queue->getMeta()); } public function testItCreatesAutomaticEmailSendingTaskForSegment() { $newsletter = $this->newslettersRepository->findOneById($this->newsletter->getId()); $this->assertInstanceOf(NewsletterEntity::class, $newsletter); $this->automaticEmailScheduler->createAutomaticEmailScheduledTask($newsletter, null); // new scheduled task should be created $task = $this->scheduledTasksRepository->findOneByNewsletter($newsletter); $expectedTime = Carbon::now()->millisecond(0)->addHours(2); $this->assertInstanceOf(ScheduledTaskEntity::class, $task); verify($task->getId())->greaterThanOrEqual(1); verify($task->getPriority())->equals(SendingQueueEntity::PRIORITY_MEDIUM); verify($task->getStatus())->equals(SendingQueueEntity::STATUS_SCHEDULED); $this->tester->assertEqualDateTimes($expectedTime, $task->getScheduledAt(), 1); // task should not have any subscribers $subscribers = $task->getSubscribers(); verify($subscribers)->arrayCount(0); } public function testItDoesNotScheduleAutomaticEmailWhenGroupDoesNotMatch() { $this->newsletterOptionFactory->createMultipleOptions( $this->newsletter, [ 'group' => 'some_group', 'event' => 'some_event', ] ); // email should not be scheduled when group is not matched $this->automaticEmailScheduler->scheduleAutomaticEmail('group_does_not_exist', 'some_event'); $this->assertCount(0, $this->sendingQueuesRepository->findAll()); } public function testItDoesNotScheduleAutomaticEmailWhenEventDoesNotMatch() { $this->newsletterOptionFactory->createMultipleOptions( $this->newsletter, [ 'group' => 'some_group', 'event' => 'some_event', ] ); // email should not be scheduled when event is not matched $this->automaticEmailScheduler->scheduleAutomaticEmail('some_group', 'event_does_not_exist'); $this->assertCount(0, $this->sendingQueuesRepository->findAll()); } public function testItCanCancelMultipleAutomaticEmails() { $newsletter = $this->newslettersRepository->findOneById($this->newsletter->getId()); $this->newsletterOptionFactory->createMultipleOptions( $this->newsletter, [ 'group' => 'some_group', 'event' => 'some_event', ] ); $newsletter2 = $this->createAutomaticNewsletter(); $this->newsletterOptionFactory->createMultipleOptions( $newsletter2, [ 'group' => 'some_group', 'event' => 'some_event', ] ); $this->assertInstanceOf(NewsletterEntity::class, $newsletter); $subscriber = (new SubscriberFactory())->create(); $this->automaticEmailScheduler->createAutomaticEmailScheduledTask($newsletter, $subscriber); $this->automaticEmailScheduler->createAutomaticEmailScheduledTask($newsletter2, $subscriber); $this->automaticEmailScheduler->cancelAutomaticEmail('some_group', 'some_event', $subscriber); } public function testItSchedulesAutomaticEmailWhenConditionMatches() { $this->newsletterOptionFactory->createMultipleOptions( $this->newsletter, [ 'group' => 'some_group', 'event' => 'some_event', ] ); $newsletter2 = $this->newsletterFactory->withAutomaticType()->withActiveStatus()->create(); $this->newsletterOptionFactory->createMultipleOptions( $newsletter2, [ 'group' => 'some_group', 'event' => 'some_event', 'sendTo' => 'segment', 'afterTimeType' => 'hours', 'afterTimeNumber' => 2, ] ); $condition = function(NewsletterEntity $email) { return $email->getOptionValue(NewsletterOptionFieldEntity::NAME_SEND_TO) === 'segment'; }; $expectedTime = Carbon::createFromTimestamp(WPFunctions::get()->currentTime('timestamp'))->addHours(2); $automaticEmailScheduler = $this->diContainer->get(AutomaticEmailScheduler::class); // email should only be scheduled if it matches condition ("send to segment") $automaticEmailScheduler->scheduleAutomaticEmail('some_group', 'some_event', $condition); $result = $this->sendingQueuesRepository->findAll(); $sendingQueue = reset($result); verify($result)->arrayCount(1); $this->assertInstanceOf(SendingQueueEntity::class, $sendingQueue); $newsletter = $sendingQueue->getNewsletter(); $this->assertInstanceOf(NewsletterEntity::class, $newsletter); verify($newsletter->getId())->equals($newsletter2->getId()); // scheduled task should be created $task = $sendingQueue->getTask(); $this->assertInstanceOf(ScheduledTaskEntity::class, $task); verify($task->getId())->greaterThanOrEqual(1); verify($task->getPriority())->equals(SendingQueueEntity::PRIORITY_MEDIUM); verify($task->getStatus())->equals(SendingQueueEntity::STATUS_SCHEDULED); $this->tester->assertEqualDateTimes($expectedTime, $task->getScheduledAt(), 1); } private function createAutomaticNewsletter(): NewsletterEntity { $newsletter = $this->newsletterFactory->withActiveStatus()->withAutomaticType()->create(); $this->newsletterOptionFactory = new NewsletterOptionFactory(); $this->newsletterOptionFactory->createMultipleOptions( $newsletter, [ 'sendTo' => 'user', 'afterTimeType' => 'hours', 'afterTimeNumber' => 2, ] ); return $newsletter; } }