Extract simple workers common code into a base class [PREMIUM-4]
This commit is contained in:
@ -3,8 +3,8 @@ namespace MailPoet\Cron;
|
||||
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
|
||||
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
|
||||
use MailPoet\Cron\Workers\Bounce as BounceWorker;
|
||||
use MailPoet\Cron\Workers\PremiumKeyCheck as PremiumKeyCheckWorker;
|
||||
use MailPoet\Cron\Workers\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
|
||||
use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck as PremiumKeyCheckWorker;
|
||||
use MailPoet\Cron\Workers\KeyCheck\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||
|
@ -5,8 +5,8 @@ use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
|
||||
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
|
||||
use MailPoet\Cron\Workers\Bounce as BounceWorker;
|
||||
use MailPoet\Cron\Workers\PremiumKeyCheck as PremiumKeyCheckWorker;
|
||||
use MailPoet\Cron\Workers\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
|
||||
use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck as PremiumKeyCheckWorker;
|
||||
use MailPoet\Cron\Workers\KeyCheck\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
|
||||
use MailPoet\Mailer\MailerLog;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
@ -12,7 +11,7 @@ use MailPoet\Util\Helpers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Bounce {
|
||||
class Bounce extends SimpleWorker {
|
||||
const TASK_TYPE = 'bounce';
|
||||
const BATCH_SIZE = 100;
|
||||
|
||||
@ -20,15 +19,8 @@ class Bounce {
|
||||
const BOUNCED_SOFT = 'soft';
|
||||
const NOT_BOUNCED = null;
|
||||
|
||||
public $timer;
|
||||
public $api;
|
||||
|
||||
function __construct($timer = false) {
|
||||
$this->timer = ($timer) ? $timer : microtime(true);
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
}
|
||||
|
||||
function initApi() {
|
||||
if(!$this->api) {
|
||||
$mailer_config = Mailer::getMailerConfig();
|
||||
@ -36,50 +28,11 @@ class Bounce {
|
||||
}
|
||||
}
|
||||
|
||||
function process() {
|
||||
if(!Bridge::isMPSendingServiceEnabled()) {
|
||||
return false;
|
||||
function checkProcessingRequirements() {
|
||||
return Bridge::isMPSendingServiceEnabled();
|
||||
}
|
||||
|
||||
$this->initApi();
|
||||
|
||||
$scheduled_queues = self::getScheduledQueues();
|
||||
$running_queues = self::getRunningQueues();
|
||||
|
||||
if(!$scheduled_queues && !$running_queues) {
|
||||
self::scheduleBounceSync();
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($scheduled_queues as $i => $queue) {
|
||||
$this->prepareBounceQueue($queue);
|
||||
}
|
||||
foreach($running_queues as $i => $queue) {
|
||||
$this->processBounceQueue($queue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static function scheduleBounceSync() {
|
||||
$already_scheduled = SendingQueue::where('type', self::TASK_TYPE)
|
||||
->whereNull('deleted_at')
|
||||
->where('status', SendingQueue::STATUS_SCHEDULED)
|
||||
->findMany();
|
||||
if($already_scheduled) {
|
||||
return false;
|
||||
}
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = self::TASK_TYPE;
|
||||
$queue->status = SendingQueue::STATUS_SCHEDULED;
|
||||
$queue->priority = SendingQueue::PRIORITY_LOW;
|
||||
$queue->scheduled_at = self::getNextRunDate();
|
||||
$queue->newsletter_id = 0;
|
||||
$queue->save();
|
||||
return $queue;
|
||||
}
|
||||
|
||||
function prepareBounceQueue(SendingQueue $queue) {
|
||||
function prepareQueue(SendingQueue $queue) {
|
||||
$subscribers = Subscriber::select('id')
|
||||
->whereNull('deleted_at')
|
||||
->whereIn('status', array(
|
||||
@ -101,16 +54,11 @@ class Bounce {
|
||||
)
|
||||
);
|
||||
$queue->count_total = $queue->count_to_process = count($subscribers);
|
||||
$queue->status = null;
|
||||
$queue->save();
|
||||
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
|
||||
return true;
|
||||
return parent::prepareQueue($queue);
|
||||
}
|
||||
|
||||
function processBounceQueue(SendingQueue $queue) {
|
||||
function processQueue(SendingQueue $queue) {
|
||||
$queue->subscribers = $queue->getSubscribers();
|
||||
if(empty($queue->subscribers['to_process'])) {
|
||||
$queue->delete();
|
||||
@ -157,39 +105,4 @@ class Bounce {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function getNextRunDate() {
|
||||
$date = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
// Random day of the next week
|
||||
$date->setISODate($date->format('o'), $date->format('W') + 1, mt_rand(1, 7));
|
||||
$date->startOfDay();
|
||||
return $date;
|
||||
}
|
||||
|
||||
static function getScheduledQueues($future = false) {
|
||||
$dateWhere = ($future) ? 'whereGt' : 'whereLte';
|
||||
return SendingQueue::where('type', self::TASK_TYPE)
|
||||
->$dateWhere('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
|
||||
->whereNull('deleted_at')
|
||||
->where('status', SendingQueue::STATUS_SCHEDULED)
|
||||
->findMany();
|
||||
}
|
||||
|
||||
static function getRunningQueues() {
|
||||
return SendingQueue::where('type', self::TASK_TYPE)
|
||||
->whereLte('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
|
||||
->whereNull('deleted_at')
|
||||
->whereNull('status')
|
||||
->findMany();
|
||||
}
|
||||
|
||||
static function getAllDueQueues() {
|
||||
$scheduled_queues = self::getScheduledQueues();
|
||||
$running_queues = self::getRunningQueues();
|
||||
return array_merge((array)$scheduled_queues, (array)$running_queues);
|
||||
}
|
||||
|
||||
static function getFutureQueues() {
|
||||
return self::getScheduledQueues(true);
|
||||
}
|
||||
}
|
||||
|
38
lib/Cron/Workers/KeyCheck/KeyCheckWorker.php
Normal file
38
lib/Cron/Workers/KeyCheck/KeyCheckWorker.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers\KeyCheck;
|
||||
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Cron\Workers\SimpleWorker;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
abstract class KeyCheckWorker extends SimpleWorker {
|
||||
const UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT = 60;
|
||||
|
||||
public $bridge;
|
||||
|
||||
function initApi() {
|
||||
if(!$this->bridge) {
|
||||
$this->bridge = new Bridge();
|
||||
}
|
||||
}
|
||||
|
||||
function processQueueLogic(SendingQueue $queue) {
|
||||
try {
|
||||
$result = $this->checkKey();
|
||||
} catch (\Exception $e) {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
if(empty($result['code']) || $result['code'] == Bridge::CHECK_ERROR_UNAVAILABLE) {
|
||||
$this->reschedule($queue, self::UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract function checkKey();
|
||||
}
|
21
lib/Cron/Workers/KeyCheck/PremiumKeyCheck.php
Normal file
21
lib/Cron/Workers/KeyCheck/PremiumKeyCheck.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers\KeyCheck;
|
||||
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class PremiumKeyCheck extends KeyCheckWorker {
|
||||
const TASK_TYPE = 'premium_key_check';
|
||||
|
||||
function checkProcessingRequirements() {
|
||||
return Bridge::isPremiumKeySpecified();
|
||||
}
|
||||
|
||||
function checkKey() {
|
||||
$premium_key = Setting::getValue(Bridge::PREMIUM_KEY_STATE_SETTING_NAME);
|
||||
$result = $this->bridge->checkPremiumKey($premium_key);
|
||||
return $result;
|
||||
}
|
||||
}
|
22
lib/Cron/Workers/KeyCheck/SendingServiceKeyCheck.php
Normal file
22
lib/Cron/Workers/KeyCheck/SendingServiceKeyCheck.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers\KeyCheck;
|
||||
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class SendingServiceKeyCheck extends KeyCheckWorker {
|
||||
const TASK_TYPE = 'sending_service_key_check';
|
||||
|
||||
function checkProcessingRequirements() {
|
||||
return Bridge::isMPSendingServiceEnabled();
|
||||
}
|
||||
|
||||
function checkKey() {
|
||||
$mailer_config = Mailer::getMailerConfig();
|
||||
$result = $this->bridge->checkMSSKey($mailer_config['mailpoet_api_key']);
|
||||
$this->bridge->updateSubscriberCount($result);
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -6,14 +6,10 @@ use MailPoet\Cron\Workers\SendingQueue\Tasks\Links;
|
||||
use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
|
||||
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
|
||||
use MailPoet\Mailer\MailerLog;
|
||||
use MailPoet\Models\NewsletterLink;
|
||||
use MailPoet\Models\SendingQueue as SendingQueueModel;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\StatisticsNewsletters as StatisticsNewslettersModel;
|
||||
use MailPoet\Models\Subscriber as SubscriberModel;
|
||||
use MailPoet\Router\Endpoints\Track;
|
||||
use MailPoet\Router\Router;
|
||||
use MailPoet\Subscription\Url;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
|
@ -3,7 +3,6 @@ namespace MailPoet\Cron\Workers\SendingQueue\Tasks;
|
||||
|
||||
use MailPoet\Mailer\Mailer as MailerFactory;
|
||||
use MailPoet\Mailer\MailerLog;
|
||||
use MailPoet\Subscription\Url;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
|
@ -1,147 +0,0 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class SendingServiceKeyCheck {
|
||||
const TASK_TYPE = 'sending_service_key_check';
|
||||
const UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT = 60;
|
||||
|
||||
public $timer;
|
||||
public $bridge;
|
||||
|
||||
function __construct($timer = false) {
|
||||
$this->timer = ($timer) ? $timer : microtime(true);
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
}
|
||||
|
||||
function initApi() {
|
||||
if(!$this->bridge) {
|
||||
$this->bridge = new Bridge();
|
||||
}
|
||||
}
|
||||
|
||||
function process() {
|
||||
if(!Bridge::isMPSendingServiceEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->initApi();
|
||||
|
||||
$scheduled_queues = self::getScheduledQueues();
|
||||
$running_queues = self::getRunningQueues();
|
||||
|
||||
if(!$scheduled_queues && !$running_queues) {
|
||||
self::schedule();
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($scheduled_queues as $i => $queue) {
|
||||
$this->prepareQueue($queue);
|
||||
}
|
||||
foreach($running_queues as $i => $queue) {
|
||||
$this->processQueue($queue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static function schedule() {
|
||||
$already_scheduled = SendingQueue::where('type', self::TASK_TYPE)
|
||||
->whereNull('deleted_at')
|
||||
->where('status', SendingQueue::STATUS_SCHEDULED)
|
||||
->findMany();
|
||||
if($already_scheduled) {
|
||||
return false;
|
||||
}
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = self::TASK_TYPE;
|
||||
$queue->status = SendingQueue::STATUS_SCHEDULED;
|
||||
$queue->priority = SendingQueue::PRIORITY_LOW;
|
||||
$queue->scheduled_at = self::getNextRunDate();
|
||||
$queue->newsletter_id = 0;
|
||||
$queue->save();
|
||||
return $queue;
|
||||
}
|
||||
|
||||
function prepareQueue(SendingQueue $queue) {
|
||||
$queue->status = null;
|
||||
$queue->save();
|
||||
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function processQueue(SendingQueue $queue) {
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
|
||||
try {
|
||||
$mailer_config = Mailer::getMailerConfig();
|
||||
$result = $this->bridge->checkMSSKey($mailer_config['mailpoet_api_key']);
|
||||
$this->bridge->updateSubscriberCount($result);
|
||||
} catch (\Exception $e) {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
if(empty($result['code']) || $result['code'] == Bridge::CHECK_ERROR_UNAVAILABLE) {
|
||||
// reschedule the check
|
||||
$scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->scheduled_at = $scheduled_at->addMinutes(
|
||||
self::UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT
|
||||
);
|
||||
$queue->save();
|
||||
return false;
|
||||
}
|
||||
|
||||
$queue->processed_at = current_time('mysql');
|
||||
$queue->status = SendingQueue::STATUS_COMPLETED;
|
||||
$queue->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static function getNextRunDate() {
|
||||
$date = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
// Random day of the next week
|
||||
$date->setISODate($date->format('o'), $date->format('W') + 1, mt_rand(1, 7));
|
||||
$date->startOfDay();
|
||||
return $date;
|
||||
}
|
||||
|
||||
static function getScheduledQueues($future = false) {
|
||||
$dateWhere = ($future) ? 'whereGt' : 'whereLte';
|
||||
return SendingQueue::where('type', self::TASK_TYPE)
|
||||
->$dateWhere('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
|
||||
->whereNull('deleted_at')
|
||||
->where('status', SendingQueue::STATUS_SCHEDULED)
|
||||
->findMany();
|
||||
}
|
||||
|
||||
static function getRunningQueues() {
|
||||
return SendingQueue::where('type', self::TASK_TYPE)
|
||||
->whereLte('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
|
||||
->whereNull('deleted_at')
|
||||
->whereNull('status')
|
||||
->findMany();
|
||||
}
|
||||
|
||||
static function getAllDueQueues() {
|
||||
$scheduled_queues = self::getScheduledQueues();
|
||||
$running_queues = self::getRunningQueues();
|
||||
return array_merge((array)$scheduled_queues, (array)$running_queues);
|
||||
}
|
||||
|
||||
static function getFutureQueues() {
|
||||
return self::getScheduledQueues(true);
|
||||
}
|
||||
}
|
@ -4,36 +4,37 @@ namespace MailPoet\Cron\Workers;
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class PremiumKeyCheck {
|
||||
const TASK_TYPE = 'premium_key_check';
|
||||
const UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT = 60;
|
||||
|
||||
abstract class SimpleWorker {
|
||||
public $timer;
|
||||
public $bridge;
|
||||
|
||||
function __construct($timer = false) {
|
||||
if(!defined('static::TASK_TYPE')) {
|
||||
throw new \Exception('Constant TASK_TYPE is not defined on subclass ' . get_class($this));
|
||||
}
|
||||
$this->timer = ($timer) ? $timer : microtime(true);
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
}
|
||||
|
||||
function initApi() {
|
||||
if(!$this->bridge) {
|
||||
$this->bridge = new Bridge();
|
||||
function init() {
|
||||
if(is_callable(array($this, 'initApi'))) {
|
||||
$this->initApi();
|
||||
}
|
||||
}
|
||||
|
||||
function checkProcessingRequirements() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function process() {
|
||||
if(!Bridge::isPremiumKeySpecified()) {
|
||||
if(!$this->checkProcessingRequirements()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->initApi();
|
||||
$this->init();
|
||||
|
||||
$scheduled_queues = self::getScheduledQueues();
|
||||
$running_queues = self::getRunningQueues();
|
||||
@ -54,7 +55,7 @@ class PremiumKeyCheck {
|
||||
}
|
||||
|
||||
static function schedule() {
|
||||
$already_scheduled = SendingQueue::where('type', self::TASK_TYPE)
|
||||
$already_scheduled = SendingQueue::where('type', static::TASK_TYPE)
|
||||
->whereNull('deleted_at')
|
||||
->where('status', SendingQueue::STATUS_SCHEDULED)
|
||||
->findMany();
|
||||
@ -62,7 +63,7 @@ class PremiumKeyCheck {
|
||||
return false;
|
||||
}
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = self::TASK_TYPE;
|
||||
$queue->type = static::TASK_TYPE;
|
||||
$queue->status = SendingQueue::STATUS_SCHEDULED;
|
||||
$queue->priority = SendingQueue::PRIORITY_LOW;
|
||||
$queue->scheduled_at = self::getNextRunDate();
|
||||
@ -85,28 +86,28 @@ class PremiumKeyCheck {
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
|
||||
try {
|
||||
$premium_key = Setting::getValue(Bridge::PREMIUM_KEY_STATE_SETTING_NAME);
|
||||
$result = $this->bridge->checkPremiumKey($premium_key);
|
||||
} catch (\Exception $e) {
|
||||
$result = false;
|
||||
if($this->processQueueLogic($queue)) {
|
||||
$this->complete($queue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(empty($result['code']) || $result['code'] == Bridge::CHECK_ERROR_UNAVAILABLE) {
|
||||
// reschedule the check
|
||||
$scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->scheduled_at = $scheduled_at->addMinutes(
|
||||
self::UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT
|
||||
);
|
||||
$queue->save();
|
||||
return false;
|
||||
}
|
||||
|
||||
function processQueueLogic(SendingQueue $queue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function complete(SendingQueue $queue) {
|
||||
$queue->processed_at = current_time('mysql');
|
||||
$queue->status = SendingQueue::STATUS_COMPLETED;
|
||||
$queue->save();
|
||||
}
|
||||
|
||||
return true;
|
||||
function reschedule(SendingQueue $queue, $timeout) {
|
||||
$scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->scheduled_at = $scheduled_at->addMinutes($timeout);
|
||||
$queue->save();
|
||||
}
|
||||
|
||||
static function getNextRunDate() {
|
||||
@ -119,7 +120,7 @@ class PremiumKeyCheck {
|
||||
|
||||
static function getScheduledQueues($future = false) {
|
||||
$dateWhere = ($future) ? 'whereGt' : 'whereLte';
|
||||
return SendingQueue::where('type', self::TASK_TYPE)
|
||||
return SendingQueue::where('type', static::TASK_TYPE)
|
||||
->$dateWhere('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
|
||||
->whereNull('deleted_at')
|
||||
->where('status', SendingQueue::STATUS_SCHEDULED)
|
||||
@ -127,7 +128,7 @@ class PremiumKeyCheck {
|
||||
}
|
||||
|
||||
static function getRunningQueues() {
|
||||
return SendingQueue::where('type', self::TASK_TYPE)
|
||||
return SendingQueue::where('type', static::TASK_TYPE)
|
||||
->whereLte('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
|
||||
->whereNull('deleted_at')
|
||||
->whereNull('status')
|
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Cron\Workers\Bounce;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Services\Bridge\API;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
require_once('BounceTestMockAPI.php');
|
||||
@ -26,113 +26,58 @@ class BounceTest extends MailPoetTest {
|
||||
));
|
||||
}
|
||||
|
||||
$this->bounce = new Bounce(microtime(true));
|
||||
$this->worker = new Bounce(microtime(true));
|
||||
|
||||
$this->bounce->api = new MailPoet\Cron\Workers\Bounce\MockAPI('key');
|
||||
}
|
||||
|
||||
function testItConstructs() {
|
||||
expect($this->bounce->timer)->notEmpty();
|
||||
$this->worker->api = new MailPoet\Cron\Workers\Bounce\MockAPI('key');
|
||||
}
|
||||
|
||||
function testItDefinesConstants() {
|
||||
expect(Bounce::BATCH_SIZE)->equals(100);
|
||||
}
|
||||
|
||||
function testItThrowsExceptionWhenExecutionLimitIsReached() {
|
||||
try {
|
||||
$bounce = new Bounce(microtime(true) - CronHelper::DAEMON_EXECUTION_LIMIT);
|
||||
self::fail('Maximum execution time limit exception was not thrown.');
|
||||
} catch(\Exception $e) {
|
||||
expect($e->getMessage())->equals('Maximum execution time has been reached.');
|
||||
}
|
||||
}
|
||||
|
||||
function testItSchedulesBounceSync() {
|
||||
expect(SendingQueue::where('type', 'bounce')->findMany())->isEmpty();
|
||||
Bounce::scheduleBounceSync();
|
||||
expect(SendingQueue::where('type', 'bounce')->findMany())->notEmpty();
|
||||
}
|
||||
|
||||
function testItDoesNotScheduleBounceSyncTwice() {
|
||||
expect(count(SendingQueue::where('type', 'bounce')->findMany()))->equals(0);
|
||||
Bounce::scheduleBounceSync();
|
||||
expect(count(SendingQueue::where('type', 'bounce')->findMany()))->equals(1);
|
||||
Bounce::scheduleBounceSync();
|
||||
expect(count(SendingQueue::where('type', 'bounce')->findMany()))->equals(1);
|
||||
}
|
||||
|
||||
function testItCanGetScheduledQueues() {
|
||||
expect(Bounce::getScheduledQueues())->isEmpty();
|
||||
$this->createScheduledQueue();
|
||||
expect(Bounce::getScheduledQueues())->notEmpty();
|
||||
}
|
||||
|
||||
function testItCanGetRunningQueues() {
|
||||
expect(Bounce::getRunningQueues())->isEmpty();
|
||||
$this->createRunningQueue();
|
||||
expect(Bounce::getRunningQueues())->notEmpty();
|
||||
}
|
||||
|
||||
function testItCanGetAllDueQueues() {
|
||||
expect(Bounce::getAllDueQueues())->isEmpty();
|
||||
|
||||
// scheduled for now
|
||||
$this->createScheduledQueue();
|
||||
|
||||
// running
|
||||
$this->createRunningQueue();
|
||||
|
||||
// scheduled in the future (should not be retrieved)
|
||||
$queue = $this->createScheduledQueue();
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'))->addDays(7);
|
||||
$queue->save();
|
||||
|
||||
// completed (should not be retrieved)
|
||||
$queue = $this->createRunningQueue();
|
||||
$queue->status = SendingQueue::STATUS_COMPLETED;
|
||||
$queue->save();
|
||||
|
||||
expect(count(Bounce::getAllDueQueues()))->equals(2);
|
||||
}
|
||||
|
||||
function testItCanGetFutureQueues() {
|
||||
expect(Bounce::getFutureQueues())->isEmpty();
|
||||
$queue = $this->createScheduledQueue();
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'))->addDays(7);
|
||||
$queue->save();
|
||||
expect(count(Bounce::getFutureQueues()))->notEmpty();
|
||||
}
|
||||
|
||||
function testItFailsToProcessWithoutMailPoetMethodSetUp() {
|
||||
expect($this->bounce->process())->false();
|
||||
}
|
||||
|
||||
function testItFailsToProcessWithoutQueues() {
|
||||
function testItCanInitializeBridgeAPI() {
|
||||
$this->setMailPoetSendingMethod();
|
||||
expect($this->bounce->process())->false();
|
||||
$worker = new Bounce(microtime(true));
|
||||
$worker->initApi();
|
||||
expect($worker->api instanceof API)->true();
|
||||
}
|
||||
|
||||
function testItProcesses() {
|
||||
function testItRequiresMailPoetMethodToBeSetUp() {
|
||||
expect($this->worker->checkProcessingRequirements())->false();
|
||||
$this->setMailPoetSendingMethod();
|
||||
$this->createScheduledQueue();
|
||||
$this->createRunningQueue();
|
||||
expect($this->bounce->process())->true();
|
||||
expect($this->worker->checkProcessingRequirements())->true();
|
||||
}
|
||||
|
||||
function testItPreparesBounceQueue() {
|
||||
function testItDeletesQueueIfThereAreNoSubscribersWhenPreparingQueue() {
|
||||
Subscriber::deleteMany();
|
||||
$queue = $this->createScheduledQueue();
|
||||
$result = $this->worker->prepareQueue($queue);
|
||||
expect(SendingQueue::findOne($queue->id))->isEmpty();
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function testItPreparesQueue() {
|
||||
$queue = $this->createScheduledQueue();
|
||||
expect(empty($queue->subscribers['to_process']))->true();
|
||||
$this->bounce->prepareBounceQueue($queue);
|
||||
$this->worker->prepareQueue($queue);
|
||||
expect($queue->status)->null();
|
||||
expect(!empty($queue->subscribers['to_process']))->true();
|
||||
}
|
||||
|
||||
function testItProcessesBounceQueue() {
|
||||
function testItDeletesQueueIfThereAreNoSubscribersToProcessWhenProcessingQueue() {
|
||||
$queue = $this->createScheduledQueue();
|
||||
$queue->subscribers = null;
|
||||
$queue->save();
|
||||
$result = $this->worker->processQueue($queue);
|
||||
expect(SendingQueue::findOne($queue->id))->isEmpty();
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function testItProcessesQueue() {
|
||||
$queue = $this->createRunningQueue();
|
||||
$this->bounce->prepareBounceQueue($queue);
|
||||
$this->worker->prepareQueue($queue);
|
||||
expect(!empty($queue->subscribers['to_process']))->true();
|
||||
$this->bounce->processBounceQueue($queue);
|
||||
$this->worker->processQueue($queue);
|
||||
expect(!empty($queue->subscribers['processed']))->true();
|
||||
}
|
||||
|
||||
@ -140,7 +85,7 @@ class BounceTest extends MailPoetTest {
|
||||
$emails = Subscriber::select('email')->findArray();
|
||||
$emails = Helpers::arrayColumn($emails, 'email');
|
||||
|
||||
$this->bounce->processEmails($emails);
|
||||
$this->worker->processEmails($emails);
|
||||
|
||||
$subscribers = Subscriber::findMany();
|
||||
|
||||
@ -149,16 +94,6 @@ class BounceTest extends MailPoetTest {
|
||||
expect($subscribers[2]->status)->equals(Subscriber::STATUS_SUBSCRIBED);
|
||||
}
|
||||
|
||||
function testItCalculatesNextRunDateWithinNextWeekBoundaries() {
|
||||
$current_date = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$next_run_date = Bounce::getNextRunDate();
|
||||
$difference = $next_run_date->diffInDays($current_date);
|
||||
// Subtract days left in the current week
|
||||
$difference -= (Carbon::DAYS_PER_WEEK - $current_date->format('N'));
|
||||
expect($difference)->lessOrEquals(7);
|
||||
expect($difference)->greaterOrEquals(0);
|
||||
}
|
||||
|
||||
private function setMailPoetSendingMethod() {
|
||||
Setting::setValue(
|
||||
Mailer::MAILER_CONFIG_SETTING_NAME,
|
||||
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers\KeyCheck;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class MockKeyCheckWorker extends KeyCheckWorker {
|
||||
const TASK_TYPE = 'mock_key_check_worker';
|
||||
|
||||
function checkKey() {
|
||||
return array('code' => 12345); // bogus code
|
||||
}
|
||||
}
|
70
tests/unit/Cron/Workers/KeyCheck/KeyCheckWorkerTest.php
Normal file
70
tests/unit/Cron/Workers/KeyCheck/KeyCheckWorkerTest.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
require_once('KeyCheckWorkerMockImplementation.php');
|
||||
use MailPoet\Cron\Workers\KeyCheck\MockKeyCheckWorker;
|
||||
|
||||
class KeyCheckWorkerTest extends MailPoetTest {
|
||||
function _before() {
|
||||
$this->worker = new MockKeyCheckWorker();
|
||||
}
|
||||
|
||||
function testItCanInitializeBridgeAPI() {
|
||||
$this->worker->initApi();
|
||||
expect($this->worker->bridge instanceof Bridge)->true();
|
||||
}
|
||||
|
||||
function testItReturnsTrueOnSuccessfulKeyCheck() {
|
||||
$queue = $this->createRunningQueue();
|
||||
$result = $this->worker->processQueueLogic($queue);
|
||||
expect($result)->true();
|
||||
}
|
||||
|
||||
function testItReschedulesCheckOnException() {
|
||||
$worker = Stub::make(
|
||||
$this->worker,
|
||||
array(
|
||||
'checkKey' => function () { throw new \Exception; },
|
||||
'reschedule' => Stub::once()
|
||||
),
|
||||
$this
|
||||
);
|
||||
$queue = $this->createRunningQueue();
|
||||
$result = $worker->processQueueLogic($queue);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
function testItReschedulesCheckOnError() {
|
||||
$worker = Stub::make(
|
||||
$this->worker,
|
||||
array(
|
||||
'checkKey' => array('code' => Bridge::CHECK_ERROR_UNAVAILABLE),
|
||||
'reschedule' => Stub::once()
|
||||
),
|
||||
$this
|
||||
);
|
||||
$queue = $this->createRunningQueue();
|
||||
$result = $worker->processQueueLogic($queue);
|
||||
expect($result)->false();
|
||||
}
|
||||
|
||||
private function createRunningQueue() {
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = MockKeyCheckWorker::TASK_TYPE;
|
||||
$queue->status = null;
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->newsletter_id = 0;
|
||||
$queue->save();
|
||||
return $queue;
|
||||
}
|
||||
|
||||
function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Setting::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
||||
}
|
||||
}
|
40
tests/unit/Cron/Workers/KeyCheck/PremiumKeyCheckTest.php
Normal file
40
tests/unit/Cron/Workers/KeyCheck/PremiumKeyCheckTest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
class PremiumKeyCheckTest extends MailPoetTest {
|
||||
function _before() {
|
||||
$this->worker = new PremiumKeyCheck(microtime(true));
|
||||
}
|
||||
|
||||
function testItRequiresPremiumKeyToBeSpecified() {
|
||||
expect($this->worker->checkProcessingRequirements())->false();
|
||||
$this->fillPremiumKey();
|
||||
expect($this->worker->checkProcessingRequirements())->true();
|
||||
}
|
||||
|
||||
function testItChecksPremiumKey() {
|
||||
$response = array('code' => Bridge::PREMIUM_KEY_VALID);
|
||||
$this->worker->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkPremiumKey' => $response),
|
||||
$this
|
||||
);
|
||||
$this->fillPremiumKey();
|
||||
expect($this->worker->checkKey())->equals($response);
|
||||
}
|
||||
|
||||
private function fillPremiumKey() {
|
||||
Setting::setValue(
|
||||
Bridge::PREMIUM_KEY_SETTING_NAME,
|
||||
'123457890abcdef'
|
||||
);
|
||||
}
|
||||
|
||||
function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Setting::$_table);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Cron\Workers\KeyCheck\SendingServiceKeyCheck;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
class SendingServiceKeyCheckTest extends MailPoetTest {
|
||||
function _before() {
|
||||
$this->worker = new SendingServiceKeyCheck(microtime(true));
|
||||
}
|
||||
|
||||
function testItRequiresMailPoetMethodToBeSetUp() {
|
||||
expect($this->worker->checkProcessingRequirements())->false();
|
||||
$this->setMailPoetSendingMethod();
|
||||
expect($this->worker->checkProcessingRequirements())->true();
|
||||
}
|
||||
|
||||
function testItChecksMSSKey() {
|
||||
$response = array('code' => Bridge::MAILPOET_KEY_VALID);
|
||||
$this->worker->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array(
|
||||
'checkMSSKey' => $response,
|
||||
'updateSubscriberCount' => Stub::once()
|
||||
),
|
||||
$this
|
||||
);
|
||||
$this->setMailPoetSendingMethod();
|
||||
expect($this->worker->checkKey())->equals($response);
|
||||
}
|
||||
|
||||
private function setMailPoetSendingMethod() {
|
||||
Setting::setValue(
|
||||
Mailer::MAILER_CONFIG_SETTING_NAME,
|
||||
array(
|
||||
'method' => 'MailPoet',
|
||||
'mailpoet_api_key' => 'some_key',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Setting::$_table);
|
||||
}
|
||||
}
|
@ -1,198 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Cron\Workers\SendingServiceKeyCheck;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
class SendingServiceKeyCheckTest extends MailPoetTest {
|
||||
function _before() {
|
||||
$this->sskeycheck = new SendingServiceKeyCheck(microtime(true));
|
||||
}
|
||||
|
||||
function testItConstructs() {
|
||||
expect($this->sskeycheck->timer)->notEmpty();
|
||||
}
|
||||
|
||||
function testItThrowsExceptionWhenExecutionLimitIsReached() {
|
||||
try {
|
||||
$sskeycheck = new SendingServiceKeyCheck(microtime(true) - CronHelper::DAEMON_EXECUTION_LIMIT);
|
||||
self::fail('Maximum execution time limit exception was not thrown.');
|
||||
} catch(\Exception $e) {
|
||||
expect($e->getMessage())->equals('Maximum execution time has been reached.');
|
||||
}
|
||||
}
|
||||
|
||||
function testItSchedulesSendingServiceKeyCheck() {
|
||||
expect(SendingQueue::where('type', SendingServiceKeyCheck::TASK_TYPE)->findMany())->isEmpty();
|
||||
SendingServiceKeyCheck::schedule();
|
||||
expect(SendingQueue::where('type', SendingServiceKeyCheck::TASK_TYPE)->findMany())->notEmpty();
|
||||
}
|
||||
|
||||
function testItDoesNotScheduleSendingServiceKeyCheckTwice() {
|
||||
expect(count(SendingQueue::where('type', SendingServiceKeyCheck::TASK_TYPE)->findMany()))->equals(0);
|
||||
SendingServiceKeyCheck::schedule();
|
||||
expect(count(SendingQueue::where('type', SendingServiceKeyCheck::TASK_TYPE)->findMany()))->equals(1);
|
||||
SendingServiceKeyCheck::schedule();
|
||||
expect(count(SendingQueue::where('type', SendingServiceKeyCheck::TASK_TYPE)->findMany()))->equals(1);
|
||||
}
|
||||
|
||||
function testItCanGetScheduledQueues() {
|
||||
expect(SendingServiceKeyCheck::getScheduledQueues())->isEmpty();
|
||||
$this->createScheduledQueue();
|
||||
expect(SendingServiceKeyCheck::getScheduledQueues())->notEmpty();
|
||||
}
|
||||
|
||||
function testItCanGetRunningQueues() {
|
||||
expect(SendingServiceKeyCheck::getRunningQueues())->isEmpty();
|
||||
$this->createRunningQueue();
|
||||
expect(SendingServiceKeyCheck::getRunningQueues())->notEmpty();
|
||||
}
|
||||
|
||||
function testItCanGetAllDueQueues() {
|
||||
expect(SendingServiceKeyCheck::getAllDueQueues())->isEmpty();
|
||||
|
||||
// scheduled for now
|
||||
$this->createScheduledQueue();
|
||||
|
||||
// running
|
||||
$this->createRunningQueue();
|
||||
|
||||
// scheduled in the future (should not be retrieved)
|
||||
$queue = $this->createScheduledQueue();
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'))->addDays(7);
|
||||
$queue->save();
|
||||
|
||||
// completed (should not be retrieved)
|
||||
$queue = $this->createRunningQueue();
|
||||
$queue->status = SendingQueue::STATUS_COMPLETED;
|
||||
$queue->save();
|
||||
|
||||
expect(count(SendingServiceKeyCheck::getAllDueQueues()))->equals(2);
|
||||
}
|
||||
|
||||
function testItCanGetFutureQueues() {
|
||||
expect(SendingServiceKeyCheck::getFutureQueues())->isEmpty();
|
||||
$queue = $this->createScheduledQueue();
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'))->addDays(7);
|
||||
$queue->save();
|
||||
expect(count(SendingServiceKeyCheck::getFutureQueues()))->notEmpty();
|
||||
}
|
||||
|
||||
function testItFailsToProcessWithoutMailPoetMethodSetUp() {
|
||||
expect($this->sskeycheck->process())->false();
|
||||
}
|
||||
|
||||
function testItFailsToProcessWithoutQueues() {
|
||||
$this->setMailPoetSendingMethod();
|
||||
expect($this->sskeycheck->process())->false();
|
||||
}
|
||||
|
||||
function testItProcesses() {
|
||||
$this->sskeycheck->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkMSSKey' => array('code' => Bridge::MAILPOET_KEY_VALID)),
|
||||
$this
|
||||
);
|
||||
$this->setMailPoetSendingMethod();
|
||||
$this->createScheduledQueue();
|
||||
$this->createRunningQueue();
|
||||
expect($this->sskeycheck->process())->true();
|
||||
}
|
||||
|
||||
function testItPreparesSendingServiceKeyCheckQueue() {
|
||||
$queue = $this->createScheduledQueue();
|
||||
$this->sskeycheck->prepareQueue($queue);
|
||||
expect($queue->status)->null();
|
||||
}
|
||||
|
||||
function testItProcessesSendingServiceKeyCheckQueue() {
|
||||
$this->sskeycheck->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkMSSKey' => array('code' => Bridge::MAILPOET_KEY_VALID)),
|
||||
$this
|
||||
);
|
||||
$this->setMailPoetSendingMethod();
|
||||
$queue = $this->createRunningQueue();
|
||||
$this->sskeycheck->prepareQueue($queue);
|
||||
$this->sskeycheck->processQueue($queue);
|
||||
expect($queue->status)->equals(SendingQueue::STATUS_COMPLETED);
|
||||
}
|
||||
|
||||
function testItReschedulesCheckOnException() {
|
||||
$this->sskeycheck->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkMSSKey' => function () { throw new \Exception(); }),
|
||||
$this
|
||||
);
|
||||
$this->setMailPoetSendingMethod();
|
||||
$queue = $this->createRunningQueue();
|
||||
$scheduled_at = $queue->scheduled_at;
|
||||
$this->sskeycheck->prepareQueue($queue);
|
||||
$this->sskeycheck->processQueue($queue);
|
||||
expect($scheduled_at < $queue->scheduled_at)->true();
|
||||
}
|
||||
|
||||
function testItReschedulesCheckOnError() {
|
||||
$this->sskeycheck->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkMSSKey' => array('code' => Bridge::CHECK_ERROR_UNAVAILABLE)),
|
||||
$this
|
||||
);
|
||||
$this->setMailPoetSendingMethod();
|
||||
$queue = $this->createRunningQueue();
|
||||
$scheduled_at = $queue->scheduled_at;
|
||||
$this->sskeycheck->prepareQueue($queue);
|
||||
$this->sskeycheck->processQueue($queue);
|
||||
expect($scheduled_at < $queue->scheduled_at)->true();
|
||||
}
|
||||
|
||||
function testItCalculatesNextRunDateWithinNextWeekBoundaries() {
|
||||
$current_date = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$next_run_date = SendingServiceKeyCheck::getNextRunDate();
|
||||
$difference = $next_run_date->diffInDays($current_date);
|
||||
// Subtract days left in the current week
|
||||
$difference -= (Carbon::DAYS_PER_WEEK - $current_date->format('N'));
|
||||
expect($difference)->lessOrEquals(7);
|
||||
expect($difference)->greaterOrEquals(0);
|
||||
}
|
||||
|
||||
private function setMailPoetSendingMethod() {
|
||||
Setting::setValue(
|
||||
Mailer::MAILER_CONFIG_SETTING_NAME,
|
||||
array(
|
||||
'method' => 'MailPoet',
|
||||
'mailpoet_api_key' => 'some_key',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function createScheduledQueue() {
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = SendingServiceKeyCheck::TASK_TYPE;
|
||||
$queue->status = SendingQueue::STATUS_SCHEDULED;
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->newsletter_id = 0;
|
||||
$queue->save();
|
||||
return $queue;
|
||||
}
|
||||
|
||||
private function createRunningQueue() {
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = SendingServiceKeyCheck::TASK_TYPE;
|
||||
$queue->status = null;
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->newsletter_id = 0;
|
||||
$queue->save();
|
||||
return $queue;
|
||||
}
|
||||
|
||||
function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Setting::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
||||
}
|
||||
}
|
12
tests/unit/Cron/Workers/SimpleWorkerMockImplementation.php
Normal file
12
tests/unit/Cron/Workers/SimpleWorkerMockImplementation.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class MockSimpleWorker extends SimpleWorker {
|
||||
const TASK_TYPE = 'mock_simple_worker';
|
||||
|
||||
function initApi() {
|
||||
// to be mocked
|
||||
}
|
||||
}
|
@ -3,15 +3,31 @@
|
||||
use Carbon\Carbon;
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Cron\Workers\PremiumKeyCheck;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Cron\Workers\SimpleWorker;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
class PremiumKeyCheckTest extends MailPoetTest {
|
||||
require_once('SimpleWorkerMockImplementation.php');
|
||||
use MailPoet\Cron\Workers\MockSimpleWorker;
|
||||
|
||||
class SimpleWorkerTest extends MailPoetTest {
|
||||
function _before() {
|
||||
$this->worker = new PremiumKeyCheck(microtime(true));
|
||||
$this->worker = new MockSimpleWorker();
|
||||
}
|
||||
|
||||
function testItRequiresTaskTypeToConstruct() {
|
||||
$worker = Stub::make(
|
||||
'MailPoet\Cron\Workers\SimpleWorker',
|
||||
array(),
|
||||
$this
|
||||
);
|
||||
try {
|
||||
$worker_class = get_class($worker);
|
||||
new $worker_class();
|
||||
$this->fail('SimpleWorker did not throw an exception');
|
||||
} catch(\Exception $e) {
|
||||
expect($e->getMessage())->equals('Constant TASK_TYPE is not defined on subclass ' . $worker_class);
|
||||
}
|
||||
}
|
||||
|
||||
function testItConstructs() {
|
||||
@ -20,41 +36,43 @@ class PremiumKeyCheckTest extends MailPoetTest {
|
||||
|
||||
function testItThrowsExceptionWhenExecutionLimitIsReached() {
|
||||
try {
|
||||
$sskeycheck = new PremiumKeyCheck(microtime(true) - CronHelper::DAEMON_EXECUTION_LIMIT);
|
||||
$worker = new MockSimpleWorker(
|
||||
microtime(true) - CronHelper::DAEMON_EXECUTION_LIMIT
|
||||
);
|
||||
self::fail('Maximum execution time limit exception was not thrown.');
|
||||
} catch(\Exception $e) {
|
||||
expect($e->getMessage())->equals('Maximum execution time has been reached.');
|
||||
}
|
||||
}
|
||||
|
||||
function testItSchedulesPremiumKeyCheck() {
|
||||
expect(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany())->isEmpty();
|
||||
PremiumKeyCheck::schedule();
|
||||
expect(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany())->notEmpty();
|
||||
function testItSchedulesTask() {
|
||||
expect(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany())->isEmpty();
|
||||
MockSimpleWorker::schedule();
|
||||
expect(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany())->notEmpty();
|
||||
}
|
||||
|
||||
function testItDoesNotSchedulePremiumKeyCheckTwice() {
|
||||
expect(count(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany()))->equals(0);
|
||||
PremiumKeyCheck::schedule();
|
||||
expect(count(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany()))->equals(1);
|
||||
PremiumKeyCheck::schedule();
|
||||
expect(count(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany()))->equals(1);
|
||||
function testItDoesNotScheduleTaskTwice() {
|
||||
expect(count(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany()))->equals(0);
|
||||
MockSimpleWorker::schedule();
|
||||
expect(count(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany()))->equals(1);
|
||||
MockSimpleWorker::schedule();
|
||||
expect(count(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany()))->equals(1);
|
||||
}
|
||||
|
||||
function testItCanGetScheduledQueues() {
|
||||
expect(PremiumKeyCheck::getScheduledQueues())->isEmpty();
|
||||
expect(MockSimpleWorker::getScheduledQueues())->isEmpty();
|
||||
$this->createScheduledQueue();
|
||||
expect(PremiumKeyCheck::getScheduledQueues())->notEmpty();
|
||||
expect(MockSimpleWorker::getScheduledQueues())->notEmpty();
|
||||
}
|
||||
|
||||
function testItCanGetRunningQueues() {
|
||||
expect(PremiumKeyCheck::getRunningQueues())->isEmpty();
|
||||
expect(MockSimpleWorker::getRunningQueues())->isEmpty();
|
||||
$this->createRunningQueue();
|
||||
expect(PremiumKeyCheck::getRunningQueues())->notEmpty();
|
||||
expect(MockSimpleWorker::getRunningQueues())->notEmpty();
|
||||
}
|
||||
|
||||
function testItCanGetAllDueQueues() {
|
||||
expect(PremiumKeyCheck::getAllDueQueues())->isEmpty();
|
||||
expect(MockSimpleWorker::getAllDueQueues())->isEmpty();
|
||||
|
||||
// scheduled for now
|
||||
$this->createScheduledQueue();
|
||||
@ -72,88 +90,83 @@ class PremiumKeyCheckTest extends MailPoetTest {
|
||||
$queue->status = SendingQueue::STATUS_COMPLETED;
|
||||
$queue->save();
|
||||
|
||||
expect(count(PremiumKeyCheck::getAllDueQueues()))->equals(2);
|
||||
expect(count(MockSimpleWorker::getAllDueQueues()))->equals(2);
|
||||
}
|
||||
|
||||
function testItCanGetFutureQueues() {
|
||||
expect(PremiumKeyCheck::getFutureQueues())->isEmpty();
|
||||
expect(MockSimpleWorker::getFutureQueues())->isEmpty();
|
||||
$queue = $this->createScheduledQueue();
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'))->addDays(7);
|
||||
$queue->save();
|
||||
expect(count(PremiumKeyCheck::getFutureQueues()))->notEmpty();
|
||||
}
|
||||
|
||||
function testItFailsToProcessWithoutMailPoetMethodSetUp() {
|
||||
expect($this->worker->process())->false();
|
||||
expect(count(MockSimpleWorker::getFutureQueues()))->notEmpty();
|
||||
}
|
||||
|
||||
function testItFailsToProcessWithoutQueues() {
|
||||
$this->fillPremiumKey();
|
||||
expect($this->worker->process())->false();
|
||||
}
|
||||
|
||||
function testItProcesses() {
|
||||
$this->worker->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkPremiumKey' => array('code' => Bridge::PREMIUM_KEY_VALID)),
|
||||
function testItFailsToProcessWithoutProcessingRequirementsMet() {
|
||||
$this->createScheduledQueue();
|
||||
$this->createRunningQueue();
|
||||
$worker = Stub::make(
|
||||
$this->worker,
|
||||
array('checkProcessingRequirements' => false),
|
||||
$this
|
||||
);
|
||||
$this->fillPremiumKey();
|
||||
expect($worker->process())->false();
|
||||
}
|
||||
|
||||
function testItCanInitAPIBeforeProcessing() {
|
||||
$worker = Stub::make(
|
||||
$this->worker,
|
||||
array('initApi' => Stub::once()),
|
||||
$this
|
||||
);
|
||||
$worker->process();
|
||||
}
|
||||
|
||||
function testItProcesses() {
|
||||
$this->createScheduledQueue();
|
||||
$this->createRunningQueue();
|
||||
expect($this->worker->process())->true();
|
||||
}
|
||||
|
||||
function testItPreparesPremiumKeyCheckQueue() {
|
||||
function testItPreparesQueue() {
|
||||
$queue = $this->createScheduledQueue();
|
||||
$this->worker->prepareQueue($queue);
|
||||
expect($queue->status)->null();
|
||||
}
|
||||
|
||||
function testItProcessesPremiumKeyCheckQueue() {
|
||||
$this->worker->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkPremiumKey' => array('code' => Bridge::PREMIUM_KEY_VALID)),
|
||||
$this
|
||||
);
|
||||
$this->fillPremiumKey();
|
||||
function testItProcessesQueue() {
|
||||
$queue = $this->createRunningQueue();
|
||||
$this->worker->prepareQueue($queue);
|
||||
$this->worker->processQueue($queue);
|
||||
$result = $this->worker->processQueue($queue);
|
||||
expect($queue->status)->equals(SendingQueue::STATUS_COMPLETED);
|
||||
expect($result)->equals(true);
|
||||
}
|
||||
|
||||
function testItReschedulesCheckOnException() {
|
||||
$this->worker->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkPremiumKey' => function () { throw new \Exception(); }),
|
||||
function testItReturnsFalseIfInnerProcessingFunctionReturnsFalse() {
|
||||
$queue = $this->createRunningQueue();
|
||||
$worker = Stub::construct(
|
||||
$this->worker,
|
||||
array(),
|
||||
array('processQueueLogic' => false),
|
||||
$this
|
||||
);
|
||||
$this->fillPremiumKey();
|
||||
$queue = $this->createRunningQueue();
|
||||
$scheduled_at = $queue->scheduled_at;
|
||||
$this->worker->prepareQueue($queue);
|
||||
$this->worker->processQueue($queue);
|
||||
expect($scheduled_at < $queue->scheduled_at)->true();
|
||||
$result = $worker->processQueue($queue);
|
||||
expect($queue->status)->equals(null);
|
||||
expect($result)->equals(false);
|
||||
}
|
||||
|
||||
function testItReschedulesCheckOnError() {
|
||||
$this->worker->bridge = Stub::make(
|
||||
new Bridge,
|
||||
array('checkPremiumKey' => array('code' => Bridge::CHECK_ERROR_UNAVAILABLE)),
|
||||
$this
|
||||
);
|
||||
$this->fillPremiumKey();
|
||||
function testItCanRescheduleTasks() {
|
||||
$queue = $this->createRunningQueue();
|
||||
$scheduled_at = $queue->scheduled_at;
|
||||
$this->worker->prepareQueue($queue);
|
||||
$this->worker->processQueue($queue);
|
||||
$this->worker->reschedule($queue, 10);
|
||||
expect($scheduled_at < $queue->scheduled_at)->true();
|
||||
}
|
||||
|
||||
function testItCalculatesNextRunDateWithinNextWeekBoundaries() {
|
||||
$current_date = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$next_run_date = PremiumKeyCheck::getNextRunDate();
|
||||
$next_run_date = MockSimpleWorker::getNextRunDate();
|
||||
$difference = $next_run_date->diffInDays($current_date);
|
||||
// Subtract days left in the current week
|
||||
$difference -= (Carbon::DAYS_PER_WEEK - $current_date->format('N'));
|
||||
@ -161,16 +174,9 @@ class PremiumKeyCheckTest extends MailPoetTest {
|
||||
expect($difference)->greaterOrEquals(0);
|
||||
}
|
||||
|
||||
private function fillPremiumKey() {
|
||||
Setting::setValue(
|
||||
Bridge::PREMIUM_KEY_SETTING_NAME,
|
||||
'123457890abcdef'
|
||||
);
|
||||
}
|
||||
|
||||
private function createScheduledQueue() {
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = PremiumKeyCheck::TASK_TYPE;
|
||||
$queue->type = MockSimpleWorker::TASK_TYPE;
|
||||
$queue->status = SendingQueue::STATUS_SCHEDULED;
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->newsletter_id = 0;
|
||||
@ -180,7 +186,7 @@ class PremiumKeyCheckTest extends MailPoetTest {
|
||||
|
||||
private function createRunningQueue() {
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = PremiumKeyCheck::TASK_TYPE;
|
||||
$queue->type = MockSimpleWorker::TASK_TYPE;
|
||||
$queue->status = null;
|
||||
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->newsletter_id = 0;
|
Reference in New Issue
Block a user