Test that Premium hooks are executed [PREMIUM-2]

This commit is contained in:
Alexey Stoletniy
2017-03-21 21:36:36 +03:00
parent d686f75222
commit 32097b4512
10 changed files with 263 additions and 11 deletions

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

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