Extract simple workers common code into a base class [PREMIUM-4]

This commit is contained in:
Alexey Stoletniy
2017-05-08 07:38:56 +03:00
parent 4b1f216cd3
commit 3f151fd235
18 changed files with 416 additions and 649 deletions

View File

@ -3,8 +3,8 @@ namespace MailPoet\Cron;
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker; use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker; use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
use MailPoet\Cron\Workers\Bounce as BounceWorker; use MailPoet\Cron\Workers\Bounce as BounceWorker;
use MailPoet\Cron\Workers\PremiumKeyCheck as PremiumKeyCheckWorker; use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck as PremiumKeyCheckWorker;
use MailPoet\Cron\Workers\SendingServiceKeyCheck as SendingServiceKeyCheckWorker; use MailPoet\Cron\Workers\KeyCheck\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
require_once(ABSPATH . 'wp-includes/pluggable.php'); require_once(ABSPATH . 'wp-includes/pluggable.php');

View File

@ -5,8 +5,8 @@ use MailPoet\Cron\CronHelper;
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker; use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker; use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
use MailPoet\Cron\Workers\Bounce as BounceWorker; use MailPoet\Cron\Workers\Bounce as BounceWorker;
use MailPoet\Cron\Workers\PremiumKeyCheck as PremiumKeyCheckWorker; use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck as PremiumKeyCheckWorker;
use MailPoet\Cron\Workers\SendingServiceKeyCheck as SendingServiceKeyCheckWorker; use MailPoet\Cron\Workers\KeyCheck\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
use MailPoet\Mailer\MailerLog; use MailPoet\Mailer\MailerLog;
use MailPoet\Services\Bridge; use MailPoet\Services\Bridge;

View File

@ -1,7 +1,6 @@
<?php <?php
namespace MailPoet\Cron\Workers; namespace MailPoet\Cron\Workers;
use Carbon\Carbon;
use MailPoet\Cron\CronHelper; use MailPoet\Cron\CronHelper;
use MailPoet\Mailer\Mailer; use MailPoet\Mailer\Mailer;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
@ -12,7 +11,7 @@ use MailPoet\Util\Helpers;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class Bounce { class Bounce extends SimpleWorker {
const TASK_TYPE = 'bounce'; const TASK_TYPE = 'bounce';
const BATCH_SIZE = 100; const BATCH_SIZE = 100;
@ -20,15 +19,8 @@ class Bounce {
const BOUNCED_SOFT = 'soft'; const BOUNCED_SOFT = 'soft';
const NOT_BOUNCED = null; const NOT_BOUNCED = null;
public $timer;
public $api; public $api;
function __construct($timer = false) {
$this->timer = ($timer) ? $timer : microtime(true);
// abort if execution limit is reached
CronHelper::enforceExecutionLimit($this->timer);
}
function initApi() { function initApi() {
if(!$this->api) { if(!$this->api) {
$mailer_config = Mailer::getMailerConfig(); $mailer_config = Mailer::getMailerConfig();
@ -36,50 +28,11 @@ class Bounce {
} }
} }
function process() { function checkProcessingRequirements() {
if(!Bridge::isMPSendingServiceEnabled()) { return Bridge::isMPSendingServiceEnabled();
return false;
}
$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() { function prepareQueue(SendingQueue $queue) {
$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) {
$subscribers = Subscriber::select('id') $subscribers = Subscriber::select('id')
->whereNull('deleted_at') ->whereNull('deleted_at')
->whereIn('status', array( ->whereIn('status', array(
@ -101,16 +54,11 @@ class Bounce {
) )
); );
$queue->count_total = $queue->count_to_process = count($subscribers); $queue->count_total = $queue->count_to_process = count($subscribers);
$queue->status = null;
$queue->save();
// abort if execution limit is reached return parent::prepareQueue($queue);
CronHelper::enforceExecutionLimit($this->timer);
return true;
} }
function processBounceQueue(SendingQueue $queue) { function processQueue(SendingQueue $queue) {
$queue->subscribers = $queue->getSubscribers(); $queue->subscribers = $queue->getSubscribers();
if(empty($queue->subscribers['to_process'])) { if(empty($queue->subscribers['to_process'])) {
$queue->delete(); $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);
}
} }

View 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();
}

View 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;
}
}

View 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;
}
}

View File

@ -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\Mailer as MailerTask;
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask; use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
use MailPoet\Mailer\MailerLog; use MailPoet\Mailer\MailerLog;
use MailPoet\Models\NewsletterLink;
use MailPoet\Models\SendingQueue as SendingQueueModel; use MailPoet\Models\SendingQueue as SendingQueueModel;
use MailPoet\Models\Setting;
use MailPoet\Models\StatisticsNewsletters as StatisticsNewslettersModel; use MailPoet\Models\StatisticsNewsletters as StatisticsNewslettersModel;
use MailPoet\Models\Subscriber as SubscriberModel; use MailPoet\Models\Subscriber as SubscriberModel;
use MailPoet\Router\Endpoints\Track; use MailPoet\Router\Endpoints\Track;
use MailPoet\Router\Router;
use MailPoet\Subscription\Url;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -3,7 +3,6 @@ namespace MailPoet\Cron\Workers\SendingQueue\Tasks;
use MailPoet\Mailer\Mailer as MailerFactory; use MailPoet\Mailer\Mailer as MailerFactory;
use MailPoet\Mailer\MailerLog; use MailPoet\Mailer\MailerLog;
use MailPoet\Subscription\Url;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;

View File

@ -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);
}
}

View File

@ -4,36 +4,37 @@ namespace MailPoet\Cron\Workers;
use Carbon\Carbon; use Carbon\Carbon;
use MailPoet\Cron\CronHelper; use MailPoet\Cron\CronHelper;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
use MailPoet\Models\Setting;
use MailPoet\Services\Bridge;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
class PremiumKeyCheck { abstract class SimpleWorker {
const TASK_TYPE = 'premium_key_check';
const UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT = 60;
public $timer; public $timer;
public $bridge;
function __construct($timer = false) { 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); $this->timer = ($timer) ? $timer : microtime(true);
// abort if execution limit is reached // abort if execution limit is reached
CronHelper::enforceExecutionLimit($this->timer); CronHelper::enforceExecutionLimit($this->timer);
} }
function initApi() { function init() {
if(!$this->bridge) { if(is_callable(array($this, 'initApi'))) {
$this->bridge = new Bridge(); $this->initApi();
} }
} }
function checkProcessingRequirements() {
return true;
}
function process() { function process() {
if(!Bridge::isPremiumKeySpecified()) { if(!$this->checkProcessingRequirements()) {
return false; return false;
} }
$this->initApi(); $this->init();
$scheduled_queues = self::getScheduledQueues(); $scheduled_queues = self::getScheduledQueues();
$running_queues = self::getRunningQueues(); $running_queues = self::getRunningQueues();
@ -54,7 +55,7 @@ class PremiumKeyCheck {
} }
static function schedule() { static function schedule() {
$already_scheduled = SendingQueue::where('type', self::TASK_TYPE) $already_scheduled = SendingQueue::where('type', static::TASK_TYPE)
->whereNull('deleted_at') ->whereNull('deleted_at')
->where('status', SendingQueue::STATUS_SCHEDULED) ->where('status', SendingQueue::STATUS_SCHEDULED)
->findMany(); ->findMany();
@ -62,7 +63,7 @@ class PremiumKeyCheck {
return false; return false;
} }
$queue = SendingQueue::create(); $queue = SendingQueue::create();
$queue->type = self::TASK_TYPE; $queue->type = static::TASK_TYPE;
$queue->status = SendingQueue::STATUS_SCHEDULED; $queue->status = SendingQueue::STATUS_SCHEDULED;
$queue->priority = SendingQueue::PRIORITY_LOW; $queue->priority = SendingQueue::PRIORITY_LOW;
$queue->scheduled_at = self::getNextRunDate(); $queue->scheduled_at = self::getNextRunDate();
@ -85,28 +86,28 @@ class PremiumKeyCheck {
// abort if execution limit is reached // abort if execution limit is reached
CronHelper::enforceExecutionLimit($this->timer); CronHelper::enforceExecutionLimit($this->timer);
try { if($this->processQueueLogic($queue)) {
$premium_key = Setting::getValue(Bridge::PREMIUM_KEY_STATE_SETTING_NAME); $this->complete($queue);
$result = $this->bridge->checkPremiumKey($premium_key); return true;
} catch (\Exception $e) {
$result = false;
} }
if(empty($result['code']) || $result['code'] == Bridge::CHECK_ERROR_UNAVAILABLE) { return false;
// 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->processed_at = current_time('mysql');
$queue->status = SendingQueue::STATUS_COMPLETED; $queue->status = SendingQueue::STATUS_COMPLETED;
$queue->save(); $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() { static function getNextRunDate() {
@ -119,7 +120,7 @@ class PremiumKeyCheck {
static function getScheduledQueues($future = false) { static function getScheduledQueues($future = false) {
$dateWhere = ($future) ? 'whereGt' : 'whereLte'; $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'))) ->$dateWhere('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
->whereNull('deleted_at') ->whereNull('deleted_at')
->where('status', SendingQueue::STATUS_SCHEDULED) ->where('status', SendingQueue::STATUS_SCHEDULED)
@ -127,7 +128,7 @@ class PremiumKeyCheck {
} }
static function getRunningQueues() { 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'))) ->whereLte('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
->whereNull('deleted_at') ->whereNull('deleted_at')
->whereNull('status') ->whereNull('status')

View File

@ -1,12 +1,12 @@
<?php <?php
use Carbon\Carbon; use Carbon\Carbon;
use MailPoet\Cron\CronHelper;
use MailPoet\Cron\Workers\Bounce; use MailPoet\Cron\Workers\Bounce;
use MailPoet\Mailer\Mailer; use MailPoet\Mailer\Mailer;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
use MailPoet\Models\Setting; use MailPoet\Models\Setting;
use MailPoet\Models\Subscriber; use MailPoet\Models\Subscriber;
use MailPoet\Services\Bridge\API;
use MailPoet\Util\Helpers; use MailPoet\Util\Helpers;
require_once('BounceTestMockAPI.php'); 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'); $this->worker->api = new MailPoet\Cron\Workers\Bounce\MockAPI('key');
}
function testItConstructs() {
expect($this->bounce->timer)->notEmpty();
} }
function testItDefinesConstants() { function testItDefinesConstants() {
expect(Bounce::BATCH_SIZE)->equals(100); expect(Bounce::BATCH_SIZE)->equals(100);
} }
function testItThrowsExceptionWhenExecutionLimitIsReached() { function testItCanInitializeBridgeAPI() {
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() {
$this->setMailPoetSendingMethod(); $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->setMailPoetSendingMethod();
$this->createScheduledQueue(); expect($this->worker->checkProcessingRequirements())->true();
$this->createRunningQueue();
expect($this->bounce->process())->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(); $queue = $this->createScheduledQueue();
expect(empty($queue->subscribers['to_process']))->true(); expect(empty($queue->subscribers['to_process']))->true();
$this->bounce->prepareBounceQueue($queue); $this->worker->prepareQueue($queue);
expect($queue->status)->null(); expect($queue->status)->null();
expect(!empty($queue->subscribers['to_process']))->true(); 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(); $queue = $this->createRunningQueue();
$this->bounce->prepareBounceQueue($queue); $this->worker->prepareQueue($queue);
expect(!empty($queue->subscribers['to_process']))->true(); expect(!empty($queue->subscribers['to_process']))->true();
$this->bounce->processBounceQueue($queue); $this->worker->processQueue($queue);
expect(!empty($queue->subscribers['processed']))->true(); expect(!empty($queue->subscribers['processed']))->true();
} }
@ -140,7 +85,7 @@ class BounceTest extends MailPoetTest {
$emails = Subscriber::select('email')->findArray(); $emails = Subscriber::select('email')->findArray();
$emails = Helpers::arrayColumn($emails, 'email'); $emails = Helpers::arrayColumn($emails, 'email');
$this->bounce->processEmails($emails); $this->worker->processEmails($emails);
$subscribers = Subscriber::findMany(); $subscribers = Subscriber::findMany();
@ -149,16 +94,6 @@ class BounceTest extends MailPoetTest {
expect($subscribers[2]->status)->equals(Subscriber::STATUS_SUBSCRIBED); 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() { private function setMailPoetSendingMethod() {
Setting::setValue( Setting::setValue(
Mailer::MAILER_CONFIG_SETTING_NAME, Mailer::MAILER_CONFIG_SETTING_NAME,

View File

@ -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
}
}

View 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);
}
}

View 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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View 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
}
}

View File

@ -3,15 +3,31 @@
use Carbon\Carbon; use Carbon\Carbon;
use Codeception\Util\Stub; use Codeception\Util\Stub;
use MailPoet\Cron\CronHelper; use MailPoet\Cron\CronHelper;
use MailPoet\Cron\Workers\PremiumKeyCheck; use MailPoet\Cron\Workers\SimpleWorker;
use MailPoet\Mailer\Mailer;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
use MailPoet\Models\Setting; 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() { 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() { function testItConstructs() {
@ -20,41 +36,43 @@ class PremiumKeyCheckTest extends MailPoetTest {
function testItThrowsExceptionWhenExecutionLimitIsReached() { function testItThrowsExceptionWhenExecutionLimitIsReached() {
try { 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.'); self::fail('Maximum execution time limit exception was not thrown.');
} catch(\Exception $e) { } catch(\Exception $e) {
expect($e->getMessage())->equals('Maximum execution time has been reached.'); expect($e->getMessage())->equals('Maximum execution time has been reached.');
} }
} }
function testItSchedulesPremiumKeyCheck() { function testItSchedulesTask() {
expect(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany())->isEmpty(); expect(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany())->isEmpty();
PremiumKeyCheck::schedule(); MockSimpleWorker::schedule();
expect(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany())->notEmpty(); expect(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany())->notEmpty();
} }
function testItDoesNotSchedulePremiumKeyCheckTwice() { function testItDoesNotScheduleTaskTwice() {
expect(count(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany()))->equals(0); expect(count(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany()))->equals(0);
PremiumKeyCheck::schedule(); MockSimpleWorker::schedule();
expect(count(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany()))->equals(1); expect(count(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany()))->equals(1);
PremiumKeyCheck::schedule(); MockSimpleWorker::schedule();
expect(count(SendingQueue::where('type', PremiumKeyCheck::TASK_TYPE)->findMany()))->equals(1); expect(count(SendingQueue::where('type', MockSimpleWorker::TASK_TYPE)->findMany()))->equals(1);
} }
function testItCanGetScheduledQueues() { function testItCanGetScheduledQueues() {
expect(PremiumKeyCheck::getScheduledQueues())->isEmpty(); expect(MockSimpleWorker::getScheduledQueues())->isEmpty();
$this->createScheduledQueue(); $this->createScheduledQueue();
expect(PremiumKeyCheck::getScheduledQueues())->notEmpty(); expect(MockSimpleWorker::getScheduledQueues())->notEmpty();
} }
function testItCanGetRunningQueues() { function testItCanGetRunningQueues() {
expect(PremiumKeyCheck::getRunningQueues())->isEmpty(); expect(MockSimpleWorker::getRunningQueues())->isEmpty();
$this->createRunningQueue(); $this->createRunningQueue();
expect(PremiumKeyCheck::getRunningQueues())->notEmpty(); expect(MockSimpleWorker::getRunningQueues())->notEmpty();
} }
function testItCanGetAllDueQueues() { function testItCanGetAllDueQueues() {
expect(PremiumKeyCheck::getAllDueQueues())->isEmpty(); expect(MockSimpleWorker::getAllDueQueues())->isEmpty();
// scheduled for now // scheduled for now
$this->createScheduledQueue(); $this->createScheduledQueue();
@ -72,88 +90,83 @@ class PremiumKeyCheckTest extends MailPoetTest {
$queue->status = SendingQueue::STATUS_COMPLETED; $queue->status = SendingQueue::STATUS_COMPLETED;
$queue->save(); $queue->save();
expect(count(PremiumKeyCheck::getAllDueQueues()))->equals(2); expect(count(MockSimpleWorker::getAllDueQueues()))->equals(2);
} }
function testItCanGetFutureQueues() { function testItCanGetFutureQueues() {
expect(PremiumKeyCheck::getFutureQueues())->isEmpty(); expect(MockSimpleWorker::getFutureQueues())->isEmpty();
$queue = $this->createScheduledQueue(); $queue = $this->createScheduledQueue();
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'))->addDays(7); $queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'))->addDays(7);
$queue->save(); $queue->save();
expect(count(PremiumKeyCheck::getFutureQueues()))->notEmpty(); expect(count(MockSimpleWorker::getFutureQueues()))->notEmpty();
}
function testItFailsToProcessWithoutMailPoetMethodSetUp() {
expect($this->worker->process())->false();
} }
function testItFailsToProcessWithoutQueues() { function testItFailsToProcessWithoutQueues() {
$this->fillPremiumKey();
expect($this->worker->process())->false(); expect($this->worker->process())->false();
} }
function testItProcesses() { function testItFailsToProcessWithoutProcessingRequirementsMet() {
$this->worker->bridge = Stub::make( $this->createScheduledQueue();
new Bridge, $this->createRunningQueue();
array('checkPremiumKey' => array('code' => Bridge::PREMIUM_KEY_VALID)), $worker = Stub::make(
$this->worker,
array('checkProcessingRequirements' => false),
$this $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->createScheduledQueue();
$this->createRunningQueue(); $this->createRunningQueue();
expect($this->worker->process())->true(); expect($this->worker->process())->true();
} }
function testItPreparesPremiumKeyCheckQueue() { function testItPreparesQueue() {
$queue = $this->createScheduledQueue(); $queue = $this->createScheduledQueue();
$this->worker->prepareQueue($queue); $this->worker->prepareQueue($queue);
expect($queue->status)->null(); expect($queue->status)->null();
} }
function testItProcessesPremiumKeyCheckQueue() { function testItProcessesQueue() {
$this->worker->bridge = Stub::make(
new Bridge,
array('checkPremiumKey' => array('code' => Bridge::PREMIUM_KEY_VALID)),
$this
);
$this->fillPremiumKey();
$queue = $this->createRunningQueue(); $queue = $this->createRunningQueue();
$this->worker->prepareQueue($queue); $result = $this->worker->processQueue($queue);
$this->worker->processQueue($queue);
expect($queue->status)->equals(SendingQueue::STATUS_COMPLETED); expect($queue->status)->equals(SendingQueue::STATUS_COMPLETED);
expect($result)->equals(true);
} }
function testItReschedulesCheckOnException() { function testItReturnsFalseIfInnerProcessingFunctionReturnsFalse() {
$this->worker->bridge = Stub::make( $queue = $this->createRunningQueue();
new Bridge, $worker = Stub::construct(
array('checkPremiumKey' => function () { throw new \Exception(); }), $this->worker,
array(),
array('processQueueLogic' => false),
$this $this
); );
$this->fillPremiumKey(); $result = $worker->processQueue($queue);
$queue = $this->createRunningQueue(); expect($queue->status)->equals(null);
$scheduled_at = $queue->scheduled_at; expect($result)->equals(false);
$this->worker->prepareQueue($queue);
$this->worker->processQueue($queue);
expect($scheduled_at < $queue->scheduled_at)->true();
} }
function testItReschedulesCheckOnError() { function testItCanRescheduleTasks() {
$this->worker->bridge = Stub::make(
new Bridge,
array('checkPremiumKey' => array('code' => Bridge::CHECK_ERROR_UNAVAILABLE)),
$this
);
$this->fillPremiumKey();
$queue = $this->createRunningQueue(); $queue = $this->createRunningQueue();
$scheduled_at = $queue->scheduled_at; $scheduled_at = $queue->scheduled_at;
$this->worker->prepareQueue($queue); $this->worker->reschedule($queue, 10);
$this->worker->processQueue($queue);
expect($scheduled_at < $queue->scheduled_at)->true(); expect($scheduled_at < $queue->scheduled_at)->true();
} }
function testItCalculatesNextRunDateWithinNextWeekBoundaries() { function testItCalculatesNextRunDateWithinNextWeekBoundaries() {
$current_date = Carbon::createFromTimestamp(current_time('timestamp')); $current_date = Carbon::createFromTimestamp(current_time('timestamp'));
$next_run_date = PremiumKeyCheck::getNextRunDate(); $next_run_date = MockSimpleWorker::getNextRunDate();
$difference = $next_run_date->diffInDays($current_date); $difference = $next_run_date->diffInDays($current_date);
// Subtract days left in the current week // Subtract days left in the current week
$difference -= (Carbon::DAYS_PER_WEEK - $current_date->format('N')); $difference -= (Carbon::DAYS_PER_WEEK - $current_date->format('N'));
@ -161,16 +174,9 @@ class PremiumKeyCheckTest extends MailPoetTest {
expect($difference)->greaterOrEquals(0); expect($difference)->greaterOrEquals(0);
} }
private function fillPremiumKey() {
Setting::setValue(
Bridge::PREMIUM_KEY_SETTING_NAME,
'123457890abcdef'
);
}
private function createScheduledQueue() { private function createScheduledQueue() {
$queue = SendingQueue::create(); $queue = SendingQueue::create();
$queue->type = PremiumKeyCheck::TASK_TYPE; $queue->type = MockSimpleWorker::TASK_TYPE;
$queue->status = SendingQueue::STATUS_SCHEDULED; $queue->status = SendingQueue::STATUS_SCHEDULED;
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp')); $queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
$queue->newsletter_id = 0; $queue->newsletter_id = 0;
@ -180,7 +186,7 @@ class PremiumKeyCheckTest extends MailPoetTest {
private function createRunningQueue() { private function createRunningQueue() {
$queue = SendingQueue::create(); $queue = SendingQueue::create();
$queue->type = PremiumKeyCheck::TASK_TYPE; $queue->type = MockSimpleWorker::TASK_TYPE;
$queue->status = null; $queue->status = null;
$queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp')); $queue->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
$queue->newsletter_id = 0; $queue->newsletter_id = 0;