Test that Premium hooks are executed [PREMIUM-2]
This commit is contained in:
@ -3,6 +3,7 @@ namespace MailPoet\API;
|
||||
|
||||
use MailPoet\Util\Helpers;
|
||||
use MailPoet\Util\Security;
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
@ -40,7 +41,7 @@ class API {
|
||||
}
|
||||
|
||||
function setupAjax() {
|
||||
do_action('mailpoet_api_setup', array($this));
|
||||
Hooks::doAction('mailpoet_api_setup', array($this));
|
||||
|
||||
$this->getRequestData($_POST);
|
||||
|
||||
|
@ -15,6 +15,7 @@ use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Renderer\Renderer;
|
||||
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||
use MailPoet\Newsletter\Url as NewsletterUrl;
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
@ -33,7 +34,7 @@ class Newsletters extends APIEndpoint {
|
||||
->withSegments()
|
||||
->withOptions()
|
||||
->asArray();
|
||||
$newsletter = apply_filters('mailpoet_api_newsletters_get_after', $newsletter);
|
||||
$newsletter = Hooks::applyFilters('mailpoet_api_newsletters_get_after', $newsletter);
|
||||
return $this->successResponse($newsletter);
|
||||
}
|
||||
}
|
||||
@ -51,7 +52,7 @@ class Newsletters extends APIEndpoint {
|
||||
unset($data['options']);
|
||||
}
|
||||
|
||||
$data = apply_filters('mailpoet_api_newsletters_save_before', $data);
|
||||
$data = Hooks::applyFilters('mailpoet_api_newsletters_save_before', $data);
|
||||
|
||||
$newsletter = Newsletter::createOrUpdate($data);
|
||||
$errors = $newsletter->getErrors();
|
||||
@ -109,7 +110,7 @@ class Newsletters extends APIEndpoint {
|
||||
}
|
||||
}
|
||||
|
||||
do_action('mailpoet_api_newsletters_save_after', $newsletter);
|
||||
Hooks::doAction('mailpoet_api_newsletters_save_after', $newsletter);
|
||||
|
||||
return $this->successResponse($newsletter->asArray());
|
||||
}
|
||||
@ -208,7 +209,7 @@ class Newsletters extends APIEndpoint {
|
||||
if(!empty($errors)) {
|
||||
return $this->errorResponse($errors);
|
||||
} else {
|
||||
do_action('mailpoet_api_newsletters_duplicate_after', $newsletter, $duplicate);
|
||||
Hooks::doAction('mailpoet_api_newsletters_duplicate_after', $newsletter, $duplicate);
|
||||
return $this->successResponse(
|
||||
Newsletter::findOne($duplicate->id)->asArray(),
|
||||
array('count' => 1)
|
||||
|
@ -10,6 +10,7 @@ use MailPoet\Models\Setting;
|
||||
use MailPoet\Newsletter\Links\Links as NewsletterLinks;
|
||||
use MailPoet\Newsletter\Renderer\PostProcess\OpenTracking;
|
||||
use MailPoet\Util\Helpers;
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
@ -36,7 +37,7 @@ class Newsletter {
|
||||
$this->tracking_image_inserted = OpenTracking::addTrackingImage();
|
||||
// render newsletter
|
||||
$rendered_newsletter = $newsletter->render();
|
||||
$rendered_newsletter = apply_filters(
|
||||
$rendered_newsletter = Hooks::applyFilters(
|
||||
'mailpoet_sending_newsletter_render_after',
|
||||
$rendered_newsletter,
|
||||
$newsletter
|
||||
@ -46,7 +47,7 @@ class Newsletter {
|
||||
} else {
|
||||
// render newsletter
|
||||
$rendered_newsletter = $newsletter->render();
|
||||
$rendered_newsletter = apply_filters(
|
||||
$rendered_newsletter = Hooks::applyFilters(
|
||||
'mailpoet_sending_newsletter_render_after',
|
||||
$rendered_newsletter,
|
||||
$newsletter
|
||||
|
28
lib/WP/Hooks.php
Normal file
28
lib/WP/Hooks.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace MailPoet\WP;
|
||||
|
||||
class Hooks {
|
||||
static function addFilter() {
|
||||
return self::callWithFallback('add_filter', func_get_args());
|
||||
}
|
||||
|
||||
static function applyFilters() {
|
||||
return self::callWithFallback('apply_filters', func_get_args());
|
||||
}
|
||||
|
||||
static function addAction() {
|
||||
return self::callWithFallback('add_action', func_get_args());
|
||||
}
|
||||
|
||||
static function doAction() {
|
||||
return self::callWithFallback('do_action', func_get_args());
|
||||
}
|
||||
|
||||
private static function callWithFallback($func, $args) {
|
||||
$local_func = __NAMESPACE__ . '\\' . $func;
|
||||
if(function_exists($local_func)) {
|
||||
return call_user_func_array($local_func, $args);
|
||||
}
|
||||
return call_user_func_array($func, $args);
|
||||
}
|
||||
}
|
@ -28,9 +28,30 @@ class WordPress extends \Codeception\Module
|
||||
// WP function overrides for \MailPoet namespace go here
|
||||
namespace MailPoet\WP;
|
||||
|
||||
function get_option($key) {
|
||||
if($callback = \Helper\WordPress::getInterceptor('get_option')) {
|
||||
return $callback($key);
|
||||
function override($func, $args) {
|
||||
$func = str_replace(__NAMESPACE__ . '\\', '', $func);
|
||||
if($callback = \Helper\WordPress::getInterceptor($func)) {
|
||||
return call_user_func_array($callback, $args);
|
||||
}
|
||||
return \get_option($key);
|
||||
return call_user_func_array('\\' . $func, $args);
|
||||
}
|
||||
|
||||
function get_option($key) {
|
||||
return override(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
function add_filter() {
|
||||
return override(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
function apply_filters() {
|
||||
return override(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
function add_action() {
|
||||
return override(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
function do_action() {
|
||||
return override(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
93
tests/_support/Helper/WordPressHooks.php
Normal file
93
tests/_support/Helper/WordPressHooks.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
namespace Helper;
|
||||
// here you can define custom actions
|
||||
// all public methods declared in helper class will be available in $I
|
||||
|
||||
class WordPressHooks extends \Codeception\Module
|
||||
{
|
||||
private static $filters_applied = array();
|
||||
private static $filters_added = array();
|
||||
private static $actions_done = array();
|
||||
private static $actions_added = array();
|
||||
|
||||
static function interceptApplyFilters() {
|
||||
WordPress::interceptFunction('apply_filters', array(__CLASS__, 'applyFilters'));
|
||||
}
|
||||
|
||||
static function interceptAddFilter() {
|
||||
WordPress::interceptFunction('add_filter', array(__CLASS__, 'addFilter'));
|
||||
}
|
||||
|
||||
static function interceptDoAction() {
|
||||
WordPress::interceptFunction('do_action', array(__CLASS__, 'doAction'));
|
||||
}
|
||||
|
||||
static function interceptAddAction() {
|
||||
WordPress::interceptFunction('add_action', array(__CLASS__, 'addAction'));
|
||||
}
|
||||
|
||||
static function applyFilters() {
|
||||
$args = func_get_args();
|
||||
$hook_name = array_shift($args);
|
||||
self::$filters_applied[$hook_name] = $args;
|
||||
return func_get_arg(1);
|
||||
}
|
||||
|
||||
static function addFilter() {
|
||||
$args = func_get_args();
|
||||
$hook_name = array_shift($args);
|
||||
self::$filters_added[$hook_name] = $args;
|
||||
}
|
||||
|
||||
static function doAction() {
|
||||
$args = func_get_args();
|
||||
$hook_name = array_shift($args);
|
||||
self::$actions_done[$hook_name] = $args;
|
||||
}
|
||||
|
||||
static function addAction() {
|
||||
$args = func_get_args();
|
||||
$hook_name = array_shift($args);
|
||||
self::$actions_added[$hook_name] = $args;
|
||||
}
|
||||
|
||||
static function isFilterApplied($hook_name) {
|
||||
return isset(self::$filters_applied[$hook_name]);
|
||||
}
|
||||
|
||||
static function isFilterAdded($hook_name) {
|
||||
return isset(self::$filters_added[$hook_name]);
|
||||
}
|
||||
|
||||
static function isActionDone($hook_name) {
|
||||
return isset(self::$actions_done[$hook_name]);
|
||||
}
|
||||
|
||||
static function isActionAdded($hook_name) {
|
||||
return isset(self::$actions_added[$hook_name]);
|
||||
}
|
||||
|
||||
static function getFilterApplied($hook_name) {
|
||||
return self::isFilterApplied($hook_name) ? self::$filters_applied[$hook_name] : null;
|
||||
}
|
||||
|
||||
static function getFilterAdded($hook_name) {
|
||||
return self::isFilterAdded($hook_name) ? self::$filters_added[$hook_name] : null;
|
||||
}
|
||||
|
||||
static function getActionDone($hook_name) {
|
||||
return self::isActionDone($hook_name) ? self::$actions_done[$hook_name] : null;
|
||||
}
|
||||
|
||||
static function getActionAdded($hook_name) {
|
||||
return self::isActionAdded($hook_name) ? self::$actions_added[$hook_name] : null;
|
||||
}
|
||||
|
||||
static function releaseAllHooks() {
|
||||
WordPress::releaseAllFunctions();
|
||||
self::$filters_applied = array();
|
||||
self::$filters_added = array();
|
||||
self::$actions_done = array();
|
||||
self::$actions_added = array();
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
use Carbon\Carbon;
|
||||
use Codeception\Util\Fixtures;
|
||||
use Codeception\Util\Stub;
|
||||
use Helper\WordPressHooks as WPHooksHelper;
|
||||
use MailPoet\API\Endpoints\Newsletters;
|
||||
use MailPoet\API\Response as APIResponse;
|
||||
use MailPoet\Models\Newsletter;
|
||||
@ -43,6 +44,8 @@ class NewslettersTest extends MailPoetTest {
|
||||
expect($response->errors[0]['message'])
|
||||
->equals('This newsletter does not exist.');
|
||||
|
||||
WPHooksHelper::interceptApplyFilters();
|
||||
|
||||
$response = $router->get(array('id' => $this->newsletter->id));
|
||||
expect($response->status)->equals(APIResponse::STATUS_OK);
|
||||
expect($response->data)->equals(
|
||||
@ -51,6 +54,9 @@ class NewslettersTest extends MailPoetTest {
|
||||
->withOptions()
|
||||
->asArray()
|
||||
);
|
||||
$hook_name = 'mailpoet_api_newsletters_get_after';
|
||||
expect(WPHooksHelper::isFilterApplied($hook_name))->true();
|
||||
expect(WPHooksHelper::getFilterApplied($hook_name)[0])->internalType('array');
|
||||
}
|
||||
|
||||
function testItCanSaveANewNewsletter() {
|
||||
@ -67,6 +73,9 @@ class NewslettersTest extends MailPoetTest {
|
||||
)
|
||||
);
|
||||
|
||||
WPHooksHelper::interceptApplyFilters();
|
||||
WPHooksHelper::interceptDoAction();
|
||||
|
||||
$router = new Newsletters();
|
||||
$response = $router->save($valid_data);
|
||||
$saved_newsletter = Newsletter::filter('filterWithOptions')
|
||||
@ -76,6 +85,14 @@ class NewslettersTest extends MailPoetTest {
|
||||
// newsletter option should be saved
|
||||
expect($saved_newsletter->some_option)->equals('some_option_value');
|
||||
|
||||
$hook_name = 'mailpoet_api_newsletters_save_before';
|
||||
expect(WPHooksHelper::isFilterApplied($hook_name))->true();
|
||||
expect(WPHooksHelper::getFilterApplied($hook_name)[0])->internalType('array');
|
||||
$hook_name = 'mailpoet_api_newsletters_save_after';
|
||||
expect(WPHooksHelper::isActionDone($hook_name))->true();
|
||||
expect(WPHooksHelper::getActionDone($hook_name)[0] instanceof Newsletter)->true();
|
||||
|
||||
|
||||
$invalid_data = array(
|
||||
'subject' => 'Missing newsletter type'
|
||||
);
|
||||
@ -305,6 +322,8 @@ class NewslettersTest extends MailPoetTest {
|
||||
}
|
||||
|
||||
function testItCanDuplicateANewsletter() {
|
||||
WPHooksHelper::interceptDoAction();
|
||||
|
||||
$router = new Newsletters();
|
||||
$response = $router->duplicate(array('id' => $this->newsletter->id));
|
||||
expect($response->status)->equals(APIResponse::STATUS_OK);
|
||||
@ -315,6 +334,10 @@ class NewslettersTest extends MailPoetTest {
|
||||
);
|
||||
expect($response->meta['count'])->equals(1);
|
||||
|
||||
$hook_name = 'mailpoet_api_newsletters_duplicate_after';
|
||||
expect(WPHooksHelper::isActionDone($hook_name))->true();
|
||||
expect(WPHooksHelper::getActionDone($hook_name)[0] instanceof Newsletter)->true();
|
||||
|
||||
$response = $router->duplicate(array('id' => $this->post_notification->id));
|
||||
expect($response->status)->equals(APIResponse::STATUS_OK);
|
||||
expect($response->data)->equals(
|
||||
@ -614,6 +637,7 @@ class NewslettersTest extends MailPoetTest {
|
||||
}
|
||||
|
||||
function _after() {
|
||||
WPHooksHelper::releaseAllHooks();
|
||||
ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . NewsletterSegment::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . NewsletterOptionField::$_table);
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
use Codeception\Util\Fixtures;
|
||||
use Helper\WordPressHooks as WPHooksHelper;
|
||||
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\NewsletterLink;
|
||||
@ -47,6 +48,7 @@ class NewsletterTaskTest extends MailPoetTest {
|
||||
}
|
||||
|
||||
function testItHashesLinksAndInsertsTrackingImageWhenTrackingIsEnabled() {
|
||||
WPHooksHelper::interceptApplyFilters();
|
||||
$newsletter_task = $this->newsletter_task;
|
||||
$newsletter_task->tracking_enabled = true;
|
||||
$newsletter_task->getAndPreProcess($this->queue);
|
||||
@ -58,9 +60,15 @@ class NewsletterTaskTest extends MailPoetTest {
|
||||
->contains('[mailpoet_click_data]-' . $link->hash);
|
||||
expect($rendered_newsletter['html'])
|
||||
->contains('[mailpoet_open_data]');
|
||||
|
||||
$hook_name = 'mailpoet_sending_newsletter_render_after';
|
||||
expect(WPHooksHelper::isFilterApplied($hook_name))->true();
|
||||
expect(WPHooksHelper::getFilterApplied($hook_name)[0])->internalType('array');
|
||||
expect(WPHooksHelper::getFilterApplied($hook_name)[1] instanceof Newsletter)->true();
|
||||
}
|
||||
|
||||
function testItDoesNotHashLinksAndInsertTrackingCodeWhenTrackingIsDisabled() {
|
||||
WPHooksHelper::interceptApplyFilters();
|
||||
$newsletter_task = $this->newsletter_task;
|
||||
$newsletter_task->tracking_enabled = false;
|
||||
$newsletter_task->getAndPreProcess($this->queue);
|
||||
@ -73,6 +81,11 @@ class NewsletterTaskTest extends MailPoetTest {
|
||||
->notContains('[mailpoet_click_data]');
|
||||
expect($rendered_newsletter['html'])
|
||||
->notContains('[mailpoet_open_data]');
|
||||
|
||||
$hook_name = 'mailpoet_sending_newsletter_render_after';
|
||||
expect(WPHooksHelper::isFilterApplied($hook_name))->true();
|
||||
expect(WPHooksHelper::getFilterApplied($hook_name)[0])->internalType('array');
|
||||
expect(WPHooksHelper::getFilterApplied($hook_name)[1] instanceof Newsletter)->true();
|
||||
}
|
||||
|
||||
function testItReturnsFalseAndDeletesNewsletterWhenPostNotificationContainsNoPostsn() {
|
||||
@ -168,6 +181,7 @@ class NewsletterTaskTest extends MailPoetTest {
|
||||
}
|
||||
|
||||
function _after() {
|
||||
WPHooksHelper::releaseAllHooks();
|
||||
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
||||
|
@ -49,6 +49,31 @@ class LinksTest extends MailPoetTest {
|
||||
expect($updated_content)->notContains('link');
|
||||
}
|
||||
|
||||
function testItDoesNotReplaceUnprocessedLinks() {
|
||||
$template = '<a href="http://link1.com">some site</a> [link:some_link_shortcode]';
|
||||
$extracted_links = Links::extract($template);
|
||||
|
||||
$processed_links = array(
|
||||
'http://link1.com' => array(
|
||||
'url' => 'http://link1.com',
|
||||
'processed_link' => 'replace by this'
|
||||
)
|
||||
);
|
||||
|
||||
list($updated_content, $replaced_links) =
|
||||
Links::replace($template, $extracted_links, $processed_links);
|
||||
|
||||
// 1 links was replaced
|
||||
expect(count($replaced_links))->equals(1);
|
||||
// links in returned content were replaced with hashes
|
||||
expect($updated_content)
|
||||
->contains('replace by this');
|
||||
expect($updated_content)
|
||||
->contains('[link:some_link_shortcode]');
|
||||
expect($updated_content)->notContains('http://link1.com');
|
||||
}
|
||||
|
||||
|
||||
function testItCreatesAndTransformsUrlDataObject() {
|
||||
$subscriber_email = 'test@example.com';
|
||||
$data = array(
|
||||
|
44
tests/unit/WP/HooksTest.php
Normal file
44
tests/unit/WP/HooksTest.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
class WPHooksTest extends MailPoetTest {
|
||||
function _before() {
|
||||
$this->action = 'mailpoet_test_action';
|
||||
$this->filter = 'mailpoet_test_filter';
|
||||
}
|
||||
|
||||
function testItCanProcessActions() {
|
||||
$test_value = array('abc', 'def');
|
||||
$test_value2 = new StdClass;
|
||||
$called = false;
|
||||
|
||||
$callback = function ($value, $value2) use ($test_value, $test_value2, &$called) {
|
||||
$called = true;
|
||||
expect($value)->same($test_value);
|
||||
expect($value2)->same($test_value2);
|
||||
};
|
||||
|
||||
Hooks::addAction($this->action, $callback, 10, 2);
|
||||
Hooks::doAction($this->action, $test_value, $test_value2);
|
||||
|
||||
expect($called)->true();
|
||||
}
|
||||
|
||||
function testItCanProcessFilters() {
|
||||
$test_value = array('abc', 'def');
|
||||
|
||||
$called = false;
|
||||
|
||||
$callback = function ($value) use ($test_value, &$called) {
|
||||
$called = true;
|
||||
return $test_value;
|
||||
};
|
||||
|
||||
Hooks::addFilter($this->filter, $callback);
|
||||
$result = Hooks::applyFilters($this->filter, $test_value);
|
||||
|
||||
expect($called)->true();
|
||||
expect($result)->equals($test_value);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user