Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
fb51765d3f | |||
088ad5fb42 | |||
2f5b3c0c0a | |||
04ac4d896c | |||
f3b96af863 | |||
eb42b0b98d | |||
304667eb49 | |||
dad1082cd7 | |||
37cf0f3d29 | |||
d61c6dff58 | |||
3734ac578d | |||
b3f56c9d8e | |||
3603eeee77 | |||
59d30cc139 | |||
6ff3bbbb72 | |||
a561e10156 | |||
99f2cf6702 | |||
c6b72e729b | |||
c5bc0f36a4 | |||
efc5c34bf9 | |||
3929efbdd9 | |||
0e0c41882e | |||
79cc708fc6 | |||
8fa98879b8 | |||
331ba385e9 | |||
71ce46d78d | |||
c493de6569 | |||
ff2c2ace86 | |||
7fa789cfd1 | |||
ae6269eb63 | |||
a8f4779bfe | |||
6868142e35 | |||
133d123919 | |||
05c128d12d | |||
bdab0c12fa | |||
75b94690e2 | |||
80fddd6c58 | |||
c807ead5fd | |||
f004bb5368 |
40
RoboFile.php
40
RoboFile.php
@ -102,31 +102,51 @@ class RoboFile extends \Robo\Tasks {
|
||||
);
|
||||
}
|
||||
|
||||
function testUnit($file = null) {
|
||||
function testUnit($opts=['file' => null, 'xml' => false]) {
|
||||
$this->loadEnv();
|
||||
$this->_exec('vendor/bin/codecept build');
|
||||
$this->_exec('vendor/bin/codecept run unit -f '.(($file) ? $file : ''));
|
||||
|
||||
$command = 'vendor/bin/codecept run unit -f '.(($opts['file']) ? $opts['file'] : '');
|
||||
|
||||
if($opts['xml']) {
|
||||
$command .= ' --xml';
|
||||
}
|
||||
return $this->_exec($command);
|
||||
}
|
||||
|
||||
function testCoverage($file = null) {
|
||||
function testCoverage($opts=['file' => null, 'xml' => false]) {
|
||||
$this->loadEnv();
|
||||
$this->_exec('vendor/bin/codecept build');
|
||||
$this->_exec(join(' ', array(
|
||||
$command = join(' ', array(
|
||||
'vendor/bin/codecept run',
|
||||
(($file) ? $file : ''),
|
||||
(($opts['file']) ? $opts['file'] : ''),
|
||||
'--coverage',
|
||||
'--coverage-html'
|
||||
)));
|
||||
($opts['xml']) ? '--coverage-xml' : '--coverage-html'
|
||||
));
|
||||
|
||||
if($opts['xml']) {
|
||||
$command .= ' --xml';
|
||||
}
|
||||
return $this->_exec($command);
|
||||
}
|
||||
|
||||
function testJavascript() {
|
||||
function testJavascript($xml_output_file = null) {
|
||||
$this->compileJs();
|
||||
|
||||
$this->_exec(join(' ', array(
|
||||
$command = join(' ', array(
|
||||
'./node_modules/.bin/mocha',
|
||||
'-r tests/javascript/mochaTestHelper.js',
|
||||
'tests/javascript/testBundles/**/*.js'
|
||||
)));
|
||||
));
|
||||
|
||||
if(!empty($xml_output_file)) {
|
||||
$command .= sprintf(
|
||||
' --reporter xunit --reporter-options output="%s"',
|
||||
$xml_output_file
|
||||
);
|
||||
}
|
||||
|
||||
return $this->_exec($command);
|
||||
}
|
||||
|
||||
function testDebug() {
|
||||
|
@ -35,7 +35,12 @@ define([
|
||||
|
||||
Module.ALCSupervisor = SuperModel.extend({
|
||||
initialize: function() {
|
||||
this.listenTo(App.getChannel(), 'automatedLatestContentRefresh', this.refresh);
|
||||
var DELAY_REFRESH_FOR_MS = 500;
|
||||
this.listenTo(
|
||||
App.getChannel(),
|
||||
'automatedLatestContentRefresh',
|
||||
_.debounce(this.refresh, DELAY_REFRESH_FOR_MS)
|
||||
);
|
||||
},
|
||||
refresh: function() {
|
||||
var models = App.findModels(function(model) {
|
||||
@ -107,9 +112,7 @@ define([
|
||||
this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:featuredImagePosition change:titleAlignment change:titleIsLink change:imageFullWidth change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:sortBy change:showDivider', this._scheduleFetchPosts, this);
|
||||
this.listenTo(this.get('readMoreButton'), 'change', this._scheduleFetchPosts);
|
||||
this.listenTo(this.get('divider'), 'change', this._scheduleFetchPosts);
|
||||
this.on('add remove update reset', function(model, collection, options) {
|
||||
App.getChannel().trigger('automatedLatestContentRefresh');
|
||||
});
|
||||
this.on('add remove update reset', this._scheduleFetchPosts);
|
||||
this.on('refreshPosts', this.updatePosts, this);
|
||||
},
|
||||
updatePosts: function(posts) {
|
||||
@ -120,16 +123,7 @@ define([
|
||||
* ALC posts on each model change
|
||||
*/
|
||||
_scheduleFetchPosts: function() {
|
||||
var TIMEOUT = 500,
|
||||
that = this;
|
||||
if (this._fetchPostsTimer !== undefined) {
|
||||
clearTimeout(this._fetchPostsTimer);
|
||||
}
|
||||
this._fetchPostsTimer = setTimeout(function() {
|
||||
//that.fetchPosts();
|
||||
App.getChannel().trigger('automatedLatestContentRefresh');
|
||||
that._fetchPostsTimer = undefined;
|
||||
}, TIMEOUT);
|
||||
App.getChannel().trigger('automatedLatestContentRefresh');
|
||||
},
|
||||
});
|
||||
|
||||
|
53
circle.yml
Normal file
53
circle.yml
Normal file
@ -0,0 +1,53 @@
|
||||
machine:
|
||||
timezone:
|
||||
UTC
|
||||
|
||||
hosts:
|
||||
mailpoet.loc: 127.0.0.1
|
||||
|
||||
## Customize dependencies
|
||||
dependencies:
|
||||
pre:
|
||||
- composer install
|
||||
- ./do install
|
||||
|
||||
# Set up Wordpress
|
||||
# No password is required for the MySQL user `ubuntu`
|
||||
- mysql -u ubuntu -e "create database wordpress"
|
||||
# Use cURL to fetch WP-CLI
|
||||
- curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
|
||||
# Make sure WP-CLI is executable
|
||||
- chmod +x wp-cli.phar
|
||||
# Download WordPress into `wordpress` directory
|
||||
- ./wp-cli.phar core download --allow-root --path=wordpress
|
||||
# Generate `wp-config.php` file
|
||||
- echo "define(\"WP_DEBUG\", true);" | ./wp-cli.phar core config --allow-root --dbname=wordpress --dbuser=ubuntu --dbhost=127.0.0.1:3306 --path=wordpress --extra-php
|
||||
# Install WordPress
|
||||
- ./wp-cli.phar core install --allow-root --admin_name=admin --admin_password=admin --admin_email=admin@mailpoet.loc --url=http://mailpoet.loc:8080 --title=WordPress --path=wordpress
|
||||
# Softlink MailPoet to plugin path
|
||||
- ln -s ../../.. wordpress/wp-content/plugins/mailpoet
|
||||
# Activate MailPoet
|
||||
- ./wp-cli.phar plugin activate mailpoet --path=wordpress
|
||||
# Create .env file with correct path to WP installation
|
||||
- echo "WP_TEST_PATH=\"/home/ubuntu/mailpoet/wordpress\"" > .env
|
||||
|
||||
# Enable XDebug for coverage reports.
|
||||
# Comment out if not running PHP coverage reports, for performance
|
||||
#- sed -i 's/^;//' /opt/circleci/php/$(phpenv global)/etc/conf.d/xdebug.ini
|
||||
|
||||
## tests override
|
||||
test:
|
||||
override:
|
||||
# Run JS tests
|
||||
- mkdir $CIRCLE_TEST_REPORTS/mocha
|
||||
- ./do t:j $CIRCLE_TEST_REPORTS/mocha/junit.xml
|
||||
|
||||
# Run PHP tests
|
||||
- ./do t:u --xml
|
||||
# Uncomment to run coverage tests instead
|
||||
#- ./do t:c --xml
|
||||
# Copy the report
|
||||
- mkdir $CIRCLE_TEST_REPORTS/codeception
|
||||
- cp tests/_output/report.xml $CIRCLE_TEST_REPORTS/codeception/report.xml
|
||||
# Uncomment to copy PHP coverage report
|
||||
#- cp tests/_output/coverage.xml $CIRCLE_TEST_REPORTS/codeception/coverage.xml
|
@ -10,6 +10,7 @@ settings:
|
||||
colors: true
|
||||
memory_limit: 1024M
|
||||
log: true
|
||||
strict_xml: true
|
||||
extensions:
|
||||
enabled:
|
||||
- Codeception\Extension\RunFailed
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoet\Config;
|
||||
|
||||
use MailPoet\Models;
|
||||
use MailPoet\Cron\CronTrigger;
|
||||
use MailPoet\Router;
|
||||
use MailPoet\API;
|
||||
@ -122,7 +121,7 @@ class Initializer {
|
||||
|
||||
try {
|
||||
$this->setupAPI();
|
||||
$this->setupFrontRouter();
|
||||
$this->setupRouter();
|
||||
$this->setupPages();
|
||||
} catch(\Exception $e) {
|
||||
$this->handleFailedInitialization($e);
|
||||
@ -187,8 +186,8 @@ class Initializer {
|
||||
$api->init();
|
||||
}
|
||||
|
||||
function setupFrontRouter() {
|
||||
$router = new Router\Front();
|
||||
function setupRouter() {
|
||||
$router = new Router\Router();
|
||||
$router->init();
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ use MailPoet\Models\CustomField;
|
||||
use MailPoet\Models\Form;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Shortcodes\ShortcodesHelper;
|
||||
use MailPoet\Settings\Hosts;
|
||||
use MailPoet\Settings\Pages;
|
||||
@ -368,6 +369,7 @@ class Menu {
|
||||
$data = array(
|
||||
'shortcodes' => ShortcodesHelper::getShortcodes(),
|
||||
'settings' => Setting::getAll(),
|
||||
'current_wp_user' => Subscriber::getCurrentWPUser(),
|
||||
'sub_menu' => 'mailpoet-newsletters'
|
||||
);
|
||||
wp_enqueue_media();
|
||||
|
@ -3,7 +3,7 @@ namespace MailPoet\Cron;
|
||||
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Router\Endpoints\Queue as QueueEndpoint;
|
||||
use MailPoet\Router\Front as FrontRouter;
|
||||
use MailPoet\Router\Router;
|
||||
use MailPoet\Util\Security;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -55,7 +55,7 @@ class CronHelper {
|
||||
|
||||
static function accessDaemon($token, $timeout = self::DAEMON_REQUEST_TIMEOUT) {
|
||||
$data = array('token' => $token);
|
||||
$url = FrontRouter::buildRequest(
|
||||
$url = Router::buildRequest(
|
||||
QueueEndpoint::ENDPOINT,
|
||||
QueueEndpoint::ACTION_RUN,
|
||||
$data
|
||||
|
@ -2,7 +2,7 @@
|
||||
namespace MailPoet\Newsletter\Links;
|
||||
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Router\Front as FrontRouter;
|
||||
use MailPoet\Router\Router;
|
||||
use MailPoet\Router\Endpoints\Track as TrackEndpoint;
|
||||
use MailPoet\Models\NewsletterLink;
|
||||
use MailPoet\Newsletter\Shortcodes\Shortcodes;
|
||||
@ -35,12 +35,14 @@ class Links {
|
||||
// extract shortcodes with [link:*] format
|
||||
$shortcodes = new Shortcodes();
|
||||
$shortcodes = $shortcodes->extract($content, $categories = array('link'));
|
||||
$extracted_links = array_map(function ($shortcode) {
|
||||
return array(
|
||||
'html' => $shortcode,
|
||||
'link' => $shortcode
|
||||
);
|
||||
}, $shortcodes);
|
||||
if($shortcodes) {
|
||||
$extracted_links = array_map(function($shortcode) {
|
||||
return array(
|
||||
'html' => $shortcode,
|
||||
'link' => $shortcode
|
||||
);
|
||||
}, $shortcodes);
|
||||
}
|
||||
// extract urls with href="url" format
|
||||
preg_match_all($regex, $content, $matched_urls);
|
||||
$matched_urls_count = count($matched_urls[0]);
|
||||
@ -121,7 +123,7 @@ class Links {
|
||||
$router_action = ($matches[2][$index] === self::DATA_TAG_CLICK) ?
|
||||
TrackEndpoint::ACTION_CLICK :
|
||||
TrackEndpoint::ACTION_OPEN;
|
||||
$link = FrontRouter::buildRequest(
|
||||
$link = Router::buildRequest(
|
||||
TrackEndpoint::ENDPOINT,
|
||||
$router_action,
|
||||
$data
|
||||
|
@ -13,8 +13,9 @@ class Renderer {
|
||||
const NEWSLETTER_TEMPLATE = 'Template.html';
|
||||
const POST_PROCESS_FILTER = 'mailpoet_rendering_post_process';
|
||||
|
||||
function __construct(array $newsletter, $preview = false) {
|
||||
$this->newsletter = $newsletter;
|
||||
function __construct($newsletter, $preview = false) {
|
||||
// TODO: remove ternary condition, refactor to use model objects
|
||||
$this->newsletter = (is_object($newsletter)) ? $newsletter->asArray() : $newsletter;
|
||||
$this->preview = $preview;
|
||||
$this->blocks_renderer = new Blocks\Renderer($this->newsletter, $this->preview);
|
||||
$this->columns_renderer = new Columns\Renderer();
|
||||
|
@ -1,9 +1,8 @@
|
||||
<?php
|
||||
namespace MailPoet\Newsletter;
|
||||
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Router\Front as FrontRouter;
|
||||
use MailPoet\Router\Router;
|
||||
use MailPoet\Router\Endpoints\ViewInBrowser as ViewInBrowserEndpoint;
|
||||
use MailPoet\Models\Subscriber;
|
||||
|
||||
@ -44,7 +43,7 @@ class Url {
|
||||
$queue,
|
||||
'preview' => $preview
|
||||
);
|
||||
return FrontRouter::buildRequest(
|
||||
return Router::buildRequest(
|
||||
ViewInBrowserEndpoint::ENDPOINT,
|
||||
ViewInBrowserEndpoint::ACTION_VIEW,
|
||||
$data
|
||||
|
@ -1,73 +1,34 @@
|
||||
<?php
|
||||
namespace MailPoet\Newsletter;
|
||||
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Links\Links;
|
||||
use MailPoet\Newsletter\Renderer\Renderer;
|
||||
use MailPoet\Newsletter\Shortcodes\Shortcodes;
|
||||
|
||||
class ViewInBrowser {
|
||||
static function view($data) {
|
||||
$data = self::preProcessData($data);
|
||||
if(!self::validateData($data)) self::abort();
|
||||
$rendered_newsletter =
|
||||
self::getAndRenderNewsletter(
|
||||
$data->newsletter,
|
||||
$data->subscriber,
|
||||
$data->queue,
|
||||
$data->preview
|
||||
);
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
echo $rendered_newsletter;
|
||||
exit;
|
||||
function view($data) {
|
||||
$wp_user_preview = ($data->preview && $data->subscriber->isWPUser());
|
||||
return $this->renderNewsletter(
|
||||
$data->newsletter,
|
||||
$data->subscriber,
|
||||
$data->queue,
|
||||
$wp_user_preview
|
||||
);
|
||||
}
|
||||
|
||||
static function preProcessData($data) {
|
||||
$data = (object)$data;
|
||||
if(empty($data->subscriber_id) ||
|
||||
empty($data->subscriber_token) ||
|
||||
empty($data->newsletter_id)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
$data->newsletter = Newsletter::findOne($data->newsletter_id);
|
||||
$data->subscriber = Subscriber::findOne($data->subscriber_id);
|
||||
$data->queue = ($data->queue_id) ?
|
||||
SendingQueue::findOne($data->queue_id) :
|
||||
false;
|
||||
return $data;
|
||||
}
|
||||
|
||||
static function validateData($data) {
|
||||
if(!$data || !$data->subscriber || !$data->newsletter) return false;
|
||||
$subscriber_token_match =
|
||||
Subscriber::verifyToken($data->subscriber->email, $data->subscriber_token);
|
||||
if(!$subscriber_token_match) return false;
|
||||
// return if this is a WP user previewing the newsletter
|
||||
if($data->subscriber->isWPUser() && $data->preview) {
|
||||
return $data;
|
||||
}
|
||||
// if queue exists, check if the newsletter was sent to the subscriber
|
||||
if($data->queue && !$data->queue->isSubscriberProcessed($data->subscriber->id)) {
|
||||
$data = false;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
static function getAndRenderNewsletter($newsletter, $subscriber, $queue, $preview) {
|
||||
function renderNewsletter($newsletter, $subscriber, $queue, $wp_user_preview) {
|
||||
if($queue && $queue->newsletter_rendered_body) {
|
||||
$newsletter_body = $queue->getRenderedNewsletterBody();
|
||||
} else {
|
||||
$renderer = new Renderer($newsletter, $preview);
|
||||
$renderer = new Renderer($newsletter, $wp_user_preview);
|
||||
$newsletter_body = $renderer->render();
|
||||
}
|
||||
$shortcodes = new Shortcodes(
|
||||
$newsletter,
|
||||
$subscriber,
|
||||
$queue
|
||||
|
||||
);
|
||||
$rendered_newsletter = $shortcodes->replace($newsletter_body['html']);
|
||||
if($queue && (boolean)Setting::getValue('tracking.enabled')) {
|
||||
@ -75,14 +36,9 @@ class ViewInBrowser {
|
||||
$subscriber->id,
|
||||
$queue->id,
|
||||
$rendered_newsletter,
|
||||
$preview
|
||||
$wp_user_preview
|
||||
);
|
||||
}
|
||||
return $rendered_newsletter;
|
||||
}
|
||||
|
||||
private static function abort() {
|
||||
status_header(404);
|
||||
exit;
|
||||
}
|
||||
}
|
@ -8,9 +8,15 @@ if(!defined('ABSPATH')) exit;
|
||||
class Queue {
|
||||
const ENDPOINT = 'queue';
|
||||
const ACTION_RUN = 'run';
|
||||
public $allowed_actions = array(self::ACTION_RUN);
|
||||
public $data;
|
||||
|
||||
static function run($data) {
|
||||
$queue = new Daemon($data);
|
||||
function __construct($data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
function run() {
|
||||
$queue = new Daemon($this->data);
|
||||
$queue->run();
|
||||
}
|
||||
}
|
@ -7,18 +7,31 @@ if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Subscription {
|
||||
const ENDPOINT = 'subscription';
|
||||
const ACTION_CONFIRM = 'confirm';
|
||||
const ACTION_MANAGE = 'manage';
|
||||
const ACTION_UNSUBSCRIBE = 'unsubscribe';
|
||||
public $allowed_actions = array(
|
||||
self::ACTION_CONFIRM,
|
||||
self::ACTION_MANAGE,
|
||||
self::ACTION_UNSUBSCRIBE
|
||||
);
|
||||
public $data;
|
||||
|
||||
static function confirm($data) {
|
||||
$subscription = new UserSubscription\Pages('confirm', $data);
|
||||
function __construct($data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
function confirm() {
|
||||
$subscription = new UserSubscription\Pages('confirm', $this->data);
|
||||
$subscription->confirm();
|
||||
}
|
||||
|
||||
static function manage($data) {
|
||||
$subscription = new UserSubscription\Pages('manage', $data);
|
||||
function manage() {
|
||||
$subscription = new UserSubscription\Pages('manage', $this->data);
|
||||
}
|
||||
|
||||
static function unsubscribe($data) {
|
||||
$subscription = new UserSubscription\Pages('unsubscribe', $data);
|
||||
function unsubscribe() {
|
||||
$subscription = new UserSubscription\Pages('unsubscribe', $this->data);
|
||||
$subscription->unsubscribe();
|
||||
}
|
||||
}
|
@ -14,18 +14,27 @@ class Track {
|
||||
const ENDPOINT = 'track';
|
||||
const ACTION_CLICK = 'click';
|
||||
const ACTION_OPEN = 'open';
|
||||
public $allowed_actions = array(
|
||||
self::ACTION_CLICK,
|
||||
self::ACTION_OPEN
|
||||
);
|
||||
public $data;
|
||||
|
||||
static function click($data) {
|
||||
function __construct($data) {
|
||||
$this->data = $this->_processTrackData($data);
|
||||
}
|
||||
|
||||
function click() {
|
||||
$click_event = new Clicks();
|
||||
return $click_event->track(self::_processTrackData($data));
|
||||
return $click_event->track($this->data);
|
||||
}
|
||||
|
||||
static function open($data) {
|
||||
function open() {
|
||||
$open_event = new Opens();
|
||||
return $open_event->track(self::_processTrackData($data));
|
||||
return $open_event->track($this->data);
|
||||
}
|
||||
|
||||
static function _processTrackData($data) {
|
||||
function _processTrackData($data) {
|
||||
$data = (object)$data;
|
||||
if(empty($data->queue_id) ||
|
||||
empty($data->subscriber_id) ||
|
||||
@ -41,10 +50,10 @@ class Track {
|
||||
if(!empty($data->link_hash)) {
|
||||
$data->link = NewsletterLink::getByHash($data->link_hash);
|
||||
}
|
||||
return self::_validateTrackData($data);
|
||||
return $this->_validateTrackData($data);
|
||||
}
|
||||
|
||||
static function _validateTrackData($data) {
|
||||
function _validateTrackData($data) {
|
||||
if(!$data->subscriber || !$data->queue || !$data->newsletter) return false;
|
||||
$subscriber_token_match =
|
||||
Subscriber::verifyToken($data->subscriber->email, $data->subscriber_token);
|
||||
|
@ -1,6 +1,9 @@
|
||||
<?php
|
||||
namespace MailPoet\Router\Endpoints;
|
||||
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\ViewInBrowser as NewsletterViewInBrowser;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -8,8 +11,61 @@ if(!defined('ABSPATH')) exit;
|
||||
class ViewInBrowser {
|
||||
const ENDPOINT = 'view_in_browser';
|
||||
const ACTION_VIEW = 'view';
|
||||
public $allowed_actions = array(self::ACTION_VIEW);
|
||||
public $data;
|
||||
|
||||
static function view($data) {
|
||||
NewsletterViewInBrowser::view($data);
|
||||
function __construct($data) {
|
||||
$this->data = $this->_processBrowserPreviewData($data);
|
||||
}
|
||||
|
||||
function view() {
|
||||
$view_in_browser = new NewsletterViewInBrowser();
|
||||
return $this->_displayNewsletter($view_in_browser->view($this->data));
|
||||
}
|
||||
|
||||
function _processBrowserPreviewData($data) {
|
||||
$data = (object)$data;
|
||||
if(empty($data->subscriber_id) ||
|
||||
empty($data->subscriber_token) ||
|
||||
empty($data->newsletter_id)
|
||||
) {
|
||||
$this->_abort();
|
||||
} else {
|
||||
$data->newsletter = Newsletter::findOne($data->newsletter_id);
|
||||
$data->subscriber = Subscriber::findOne($data->subscriber_id);
|
||||
$data->queue = ($data->queue_id) ?
|
||||
SendingQueue::findOne($data->queue_id) :
|
||||
false;
|
||||
return ($this->_validateBrowserPreviewData($data)) ?
|
||||
$data :
|
||||
$this->_abort();
|
||||
}
|
||||
}
|
||||
|
||||
function _validateBrowserPreviewData($data) {
|
||||
if(!$data || !$data->subscriber || !$data->newsletter) return false;
|
||||
$subscriber_token_match =
|
||||
Subscriber::verifyToken($data->subscriber->email, $data->subscriber_token);
|
||||
if(!$subscriber_token_match) return false;
|
||||
// return if this is a WP user previewing the newsletter
|
||||
if($data->subscriber->isWPUser() && $data->preview) {
|
||||
return $data;
|
||||
}
|
||||
// if queue exists, check if the newsletter was sent to the subscriber
|
||||
if($data->queue && !$data->queue->isSubscriberProcessed($data->subscriber->id)) {
|
||||
$data = false;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
function _displayNewsletter($result) {
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
echo $result;
|
||||
exit;
|
||||
}
|
||||
|
||||
function _abort() {
|
||||
status_header(404);
|
||||
exit;
|
||||
}
|
||||
}
|
@ -1,15 +1,16 @@
|
||||
<?php
|
||||
namespace MailPoet\Router;
|
||||
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Front {
|
||||
class Router {
|
||||
public $api_request;
|
||||
public $endpoint;
|
||||
public $action;
|
||||
public $data;
|
||||
const NAME = 'mailpoet_api';
|
||||
const NAME = 'mailpoet_router';
|
||||
const RESPONSE_ERROR = 404;
|
||||
|
||||
function __construct($api_data = false) {
|
||||
@ -27,43 +28,31 @@ class Front {
|
||||
}
|
||||
|
||||
function init() {
|
||||
$class = __NAMESPACE__ . "\\Endpoints\\" . ucfirst($this->endpoint);
|
||||
|
||||
$endpoint_class = __NAMESPACE__ . "\\Endpoints\\" . ucfirst($this->endpoint);
|
||||
if(!$this->api_request) return;
|
||||
if(!$this->endpoint || !class_exists($class)) {
|
||||
self::terminateRequest(self::RESPONSE_ERROR, __('Invalid Router endpoint.'));
|
||||
if(!$this->endpoint || !class_exists($endpoint_class)) {
|
||||
return $this->terminateRequest(self::RESPONSE_ERROR, __('Invalid router endpoint.'));
|
||||
}
|
||||
$this->callEndpoint(
|
||||
$class,
|
||||
$this->action,
|
||||
$this->data
|
||||
);
|
||||
}
|
||||
|
||||
function callEndpoint($endpoint, $action, $data) {
|
||||
if(!method_exists($endpoint, $action)) {
|
||||
self::terminateRequest(self::RESPONSE_ERROR, __('Invalid Router action.'));
|
||||
$endpoint = new $endpoint_class($this->data);
|
||||
if(!method_exists($endpoint, $this->action) || !in_array($this->action, $endpoint->allowed_actions)) {
|
||||
return $this->terminateRequest(self::RESPONSE_ERROR, __('Invalid router endpoint action.'));
|
||||
}
|
||||
call_user_func(
|
||||
return call_user_func(
|
||||
array(
|
||||
$endpoint,
|
||||
$action
|
||||
),
|
||||
$data
|
||||
$this->action
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static function decodeRequestData($data) {
|
||||
$data = base64_decode($data);
|
||||
|
||||
if(is_serialized($data)) {
|
||||
$data = unserialize($data);
|
||||
}
|
||||
|
||||
if(!is_array($data)) {
|
||||
$data = array();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@ -82,7 +71,7 @@ class Front {
|
||||
return add_query_arg($params, home_url());
|
||||
}
|
||||
|
||||
static function terminateRequest($code, $message) {
|
||||
function terminateRequest($code, $message) {
|
||||
status_header($code, $message);
|
||||
exit;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoet\Subscription;
|
||||
|
||||
use MailPoet\Router\Front as FrontRouter;
|
||||
use MailPoet\Router\Router;
|
||||
use MailPoet\Router\Endpoints\Subscription as SubscriptionEndpoint;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\Setting;
|
||||
@ -45,10 +45,10 @@ class Url {
|
||||
}
|
||||
|
||||
$params = array(
|
||||
FrontRouter::NAME,
|
||||
Router::NAME,
|
||||
'endpoint='.SubscriptionEndpoint::ENDPOINT,
|
||||
'action='.$action,
|
||||
'data='.FrontRouter::encodeRequestData($data)
|
||||
'data='.Router::encodeRequestData($data)
|
||||
);
|
||||
|
||||
// add parameters
|
||||
|
@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
|
||||
use \MailPoet\Config\Initializer;
|
||||
/*
|
||||
* Plugin Name: MailPoet
|
||||
* Version: 0.0.41
|
||||
* Version: 0.0.42
|
||||
* Plugin URI: http://www.mailpoet.com
|
||||
* Description: MailPoet Newsletters.
|
||||
* Author: MailPoet
|
||||
@ -22,7 +22,7 @@ use \MailPoet\Config\Initializer;
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
define('MAILPOET_VERSION', '0.0.41');
|
||||
define('MAILPOET_VERSION', '0.0.42');
|
||||
|
||||
$initializer = new Initializer(array(
|
||||
'file' => __FILE__,
|
||||
|
152
tests/unit/Newsletter/ViewInBrowserTest.php
Normal file
152
tests/unit/Newsletter/ViewInBrowserTest.php
Normal file
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\ViewInBrowser;
|
||||
use MailPoet\Router\Router;
|
||||
|
||||
class ViewInBrowserTest extends MailPoetTest {
|
||||
function __construct() {
|
||||
$this->newsletter = array(
|
||||
'body' => json_decode(
|
||||
'{
|
||||
"content": {
|
||||
"type": "container",
|
||||
"orientation": "vertical",
|
||||
"styles": {
|
||||
"block": {
|
||||
"backgroundColor": "transparent"
|
||||
}
|
||||
},
|
||||
"blocks": [
|
||||
{
|
||||
"type": "container",
|
||||
"orientation": "horizontal",
|
||||
"styles": {
|
||||
"block": {
|
||||
"backgroundColor": "transparent"
|
||||
}
|
||||
},
|
||||
"blocks": [
|
||||
{
|
||||
"type": "container",
|
||||
"orientation": "vertical",
|
||||
"styles": {
|
||||
"block": {
|
||||
"backgroundColor": "transparent"
|
||||
}
|
||||
},
|
||||
"blocks": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "<p>Rendered newsletter. Hello, [subscriber:firstname | default:reader] & [link:newsletter_view_in_browser_url]</p>"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}', true),
|
||||
'id' => 1,
|
||||
'subject' => 'Some subject',
|
||||
'preheader' => 'Some preheader',
|
||||
'type' => 'standard',
|
||||
'status' => 'active'
|
||||
);
|
||||
$this->queue_rendered_newsletter_without_tracking = json_encode(
|
||||
array(
|
||||
'html' => 'Newsletter from queue. Hello, [subscriber:firstname] &
|
||||
[link:newsletter_view_in_browser_url]'
|
||||
)
|
||||
);
|
||||
$this->queue_rendered_newsletter_with_tracking = json_encode(
|
||||
array(
|
||||
'html' => 'Newsletter from queue. Hello, [subscriber:firstname] &
|
||||
[mailpoet_click_data]-90e56'
|
||||
)
|
||||
);
|
||||
// instantiate class
|
||||
$this->view_in_browser = new ViewInBrowser();
|
||||
}
|
||||
|
||||
function _before() {
|
||||
// create newsletter
|
||||
$newsletter = Newsletter::create();
|
||||
$newsletter->hydrate($this->newsletter);
|
||||
$this->newsletter = $newsletter->save();
|
||||
// create subscriber
|
||||
$subscriber = Subscriber::create();
|
||||
$subscriber->email = 'test@example.com';
|
||||
$subscriber->first_name = 'First';
|
||||
$subscriber->last_name = 'Last';
|
||||
$this->subscriber = $subscriber->save();
|
||||
// create queue
|
||||
$queue = SendingQueue::create();
|
||||
$queue->newsletter_id = $newsletter->id;
|
||||
$queue->newsletter_rendered_body = $this->queue_rendered_newsletter_without_tracking;
|
||||
$queue->subscribers = array('processed' => array($subscriber->id));
|
||||
$this->queue = $queue->save();
|
||||
// build browser preview data
|
||||
$this->browser_preview_data = (object)array(
|
||||
'queue' => $this->queue,
|
||||
'subscriber' => $this->subscriber,
|
||||
'newsletter' => $this->newsletter,
|
||||
'preview' => false
|
||||
);
|
||||
}
|
||||
|
||||
function testItRendersNewsletter() {
|
||||
$rendered_body = ViewInBrowser::renderNewsletter(
|
||||
$this->newsletter,
|
||||
$this->subscriber,
|
||||
$queue = false,
|
||||
$preview = true
|
||||
);
|
||||
expect($rendered_body)->regExp('/Rendered newsletter/');
|
||||
}
|
||||
|
||||
function testItReusesRenderedNewsletterBodyWhenQueueExists() {
|
||||
$rendered_body = ViewInBrowser::renderNewsletter(
|
||||
$this->newsletter,
|
||||
$this->subscriber,
|
||||
$this->queue,
|
||||
$preview = true
|
||||
);
|
||||
expect($rendered_body)->regExp('/Newsletter from queue/');
|
||||
}
|
||||
|
||||
function testItConvertsShortcodes() {
|
||||
Setting::setValue('tracking.enabled', false);
|
||||
$rendered_body = ViewInBrowser::renderNewsletter(
|
||||
$this->newsletter,
|
||||
$this->subscriber,
|
||||
$this->queue,
|
||||
$preview = true
|
||||
);
|
||||
expect($rendered_body)->contains('Hello, First');
|
||||
expect($rendered_body)->contains(Router::NAME . '&endpoint=view_in_browser');
|
||||
}
|
||||
|
||||
function testItProcessesLinksWhenTrackingIsEnabled() {
|
||||
Setting::setValue('tracking.enabled', true);
|
||||
$queue = $this->queue;
|
||||
$queue->newsletter_rendered_body = $this->queue_rendered_newsletter_with_tracking;
|
||||
$rendered_body = ViewInBrowser::renderNewsletter(
|
||||
$this->newsletter,
|
||||
$this->subscriber,
|
||||
$queue,
|
||||
$preview = true
|
||||
);
|
||||
expect($rendered_body)->contains(Router::NAME . '&endpoint=track');
|
||||
}
|
||||
|
||||
function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
||||
}
|
||||
}
|
@ -39,21 +39,23 @@ class TrackTest extends MailPoetTest {
|
||||
'link_hash' => $link->hash,
|
||||
'preview' => false
|
||||
);
|
||||
// instantiate class
|
||||
$this->track = new Track($this->track_data);
|
||||
}
|
||||
|
||||
function testItReturnsFalseWhenTrackDataIsMissing() {
|
||||
// queue ID is required
|
||||
$data = $this->track_data;
|
||||
unset($data['queue_id']);
|
||||
expect(Track::_processTrackData($data))->false();
|
||||
expect($this->track->_processTrackData($data))->false();
|
||||
// subscriber ID is required
|
||||
$data = $this->track_data;
|
||||
unset($data['subscriber_id']);
|
||||
expect(Track::_processTrackData($data))->false();
|
||||
expect($this->track->_processTrackData($data))->false();
|
||||
// subscriber token is required
|
||||
$data = $this->track_data;
|
||||
unset($data['subscriber_token']);
|
||||
expect(Track::_processTrackData($data))->false();
|
||||
expect($this->track->_processTrackData($data))->false();
|
||||
}
|
||||
|
||||
function testItFailsWhenSubscriberTokenDoesNotMatch() {
|
||||
@ -66,7 +68,7 @@ class TrackTest extends MailPoetTest {
|
||||
)
|
||||
);
|
||||
$data->subscriber->email = 'random@email.com';
|
||||
expect(Track::_validateTrackData($data))->false();
|
||||
expect($this->track->_validateTrackData($data))->false();
|
||||
}
|
||||
|
||||
function testItFailsWhenSubscriberIsNotOnProcessedList() {
|
||||
@ -79,7 +81,7 @@ class TrackTest extends MailPoetTest {
|
||||
)
|
||||
);
|
||||
$data->subscriber->id = 99;
|
||||
expect(Track::_validateTrackData($data))->false();
|
||||
expect($this->track->_validateTrackData($data))->false();
|
||||
}
|
||||
|
||||
function testItDoesNotRequireWpUsersToBeOnProcessedListWhenPreviewIsEnabled() {
|
||||
@ -93,18 +95,26 @@ class TrackTest extends MailPoetTest {
|
||||
);
|
||||
$data->subscriber->wp_user_id = 99;
|
||||
$data->preview = true;
|
||||
expect(Track::_validateTrackData($data))->equals($data);
|
||||
expect($this->track->_validateTrackData($data))->equals($data);
|
||||
}
|
||||
|
||||
function testItCanGetNewsletterFromQueue() {
|
||||
function testItRequiresValidQueueToGetNewsletter() {
|
||||
$data = $this->track_data;
|
||||
$data['newsletter_id'] = false;
|
||||
$processed_data = Track::_processTrackData($this->track_data);
|
||||
$data['queue_id'] = 99;
|
||||
$processed_data = $this->track->_processTrackData($data);
|
||||
expect($processed_data)->false();
|
||||
}
|
||||
|
||||
function testItGetsNewsletterFromQueue() {
|
||||
$data = $this->track_data;
|
||||
$data['newsletter_id'] = false;
|
||||
$processed_data = $this->track->_processTrackData($data);
|
||||
expect($processed_data->newsletter->id)->equals($this->newsletter->id);
|
||||
}
|
||||
|
||||
function testItCanProcessTrackData() {
|
||||
$processed_data = Track::_processTrackData($this->track_data);
|
||||
function testItProcessesTrackData() {
|
||||
$processed_data = $this->track->_processTrackData($this->track_data);
|
||||
expect($processed_data->queue->id)->equals($this->queue->id);
|
||||
expect($processed_data->subscriber->id)->equals($this->subscriber->id);
|
||||
expect($processed_data->newsletter->id)->equals($this->newsletter->id);
|
||||
|
134
tests/unit/Router/Endpoints/ViewInBrowserTest.php
Normal file
134
tests/unit/Router/Endpoints/ViewInBrowserTest.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Router\Endpoints\ViewInBrowser;
|
||||
|
||||
class ViewInBrowserRouterTest extends MailPoetTest {
|
||||
function _before() {
|
||||
// create newsletter
|
||||
$newsletter = Newsletter::create();
|
||||
$newsletter->type = 'type';
|
||||
$this->newsletter = $newsletter->save();
|
||||
// create subscriber
|
||||
$subscriber = Subscriber::create();
|
||||
$subscriber->email = 'test@example.com';
|
||||
$subscriber->first_name = 'First';
|
||||
$subscriber->last_name = 'Last';
|
||||
$this->subscriber = $subscriber->save();
|
||||
// create queue
|
||||
$queue = SendingQueue::create();
|
||||
$queue->newsletter_id = $newsletter->id;
|
||||
$queue->subscribers = array('processed' => array($subscriber->id));
|
||||
$this->queue = $queue->save();
|
||||
// build browser preview data
|
||||
$this->browser_preview_data = array(
|
||||
'queue_id' => $queue->id,
|
||||
'subscriber_id' => $subscriber->id,
|
||||
'newsletter_id' => $newsletter->id,
|
||||
'subscriber_token' => Subscriber::generateToken($subscriber->email),
|
||||
'preview' => false
|
||||
);
|
||||
// instantiate class
|
||||
$this->view_in_browser = new ViewInBrowser($this->browser_preview_data);
|
||||
}
|
||||
|
||||
function testItAbortsWhenBrowserPreviewDataIsMissing() {
|
||||
$view_in_browser = Stub::make($this->view_in_browser, array(
|
||||
'_abort' => Stub::exactly(3, function() { })
|
||||
), $this);
|
||||
// newsletter ID is required
|
||||
$data = $this->browser_preview_data;
|
||||
unset($data['newsletter_id']);
|
||||
$view_in_browser->_processBrowserPreviewData($data);
|
||||
// subscriber ID is required
|
||||
$data = $this->browser_preview_data;
|
||||
unset($data['subscriber_id']);
|
||||
$view_in_browser->_processBrowserPreviewData($data);
|
||||
// subscriber token is required
|
||||
$data = $this->browser_preview_data;
|
||||
unset($data['subscriber_token']);
|
||||
$view_in_browser->_processBrowserPreviewData($data);
|
||||
}
|
||||
|
||||
function testItAbortsWhenBrowserPreviewDataIsInvalid() {
|
||||
$view_in_browser = Stub::make($this->view_in_browser, array(
|
||||
'_abort' => Stub::exactly(3, function() { })
|
||||
), $this);
|
||||
// newsletter ID is invalid
|
||||
$data = $this->browser_preview_data;
|
||||
$data['newsletter_id'] = 99;
|
||||
$view_in_browser->_processBrowserPreviewData($data);
|
||||
// subscriber ID is invalid
|
||||
$data = $this->browser_preview_data;
|
||||
$data['subscriber_id'] = 99;
|
||||
$view_in_browser->_processBrowserPreviewData($data);
|
||||
// subscriber token is invalid
|
||||
$data = $this->browser_preview_data;
|
||||
$data['subscriber_token'] = 'invalid';
|
||||
$view_in_browser->_processBrowserPreviewData($data);
|
||||
}
|
||||
|
||||
function testItFailsValidationWhenSubscriberTokenDoesNotMatch() {
|
||||
$data = (object)array_merge(
|
||||
$this->browser_preview_data,
|
||||
array(
|
||||
'queue' => $this->queue,
|
||||
'subscriber' => $this->subscriber,
|
||||
'newsletter' => $this->newsletter
|
||||
)
|
||||
);
|
||||
$data->subscriber->email = 'random@email.com';
|
||||
expect($this->view_in_browser->_validateBrowserPreviewData($data))->false();
|
||||
}
|
||||
|
||||
function testItFailsValidationWhenSubscriberIsNotOnProcessedList() {
|
||||
$data = (object)array_merge(
|
||||
$this->browser_preview_data,
|
||||
array(
|
||||
'queue' => $this->queue,
|
||||
'subscriber' => $this->subscriber,
|
||||
'newsletter' => $this->newsletter
|
||||
)
|
||||
);
|
||||
$data->subscriber->id = 99;
|
||||
expect($this->view_in_browser->_validateBrowserPreviewData($data))->false();
|
||||
}
|
||||
|
||||
function testItDoesNotRequireWpUsersToBeOnProcessedListWhenPreviewIsEnabled() {
|
||||
$data = (object)array_merge(
|
||||
$this->browser_preview_data,
|
||||
array(
|
||||
'queue' => $this->queue,
|
||||
'subscriber' => $this->subscriber,
|
||||
'newsletter' => $this->newsletter
|
||||
)
|
||||
);
|
||||
$data->subscriber->wp_user_id = 99;
|
||||
$data->preview = true;
|
||||
expect($this->view_in_browser->_validateBrowserPreviewData($data))->equals($data);
|
||||
}
|
||||
|
||||
function testItProcessesBrowserPreviewData() {
|
||||
$processed_data = $this->view_in_browser->_processBrowserPreviewData($this->browser_preview_data);
|
||||
expect($processed_data->queue->id)->equals($this->queue->id);
|
||||
expect($processed_data->subscriber->id)->equals($this->subscriber->id);
|
||||
expect($processed_data->newsletter->id)->equals($this->newsletter->id);
|
||||
}
|
||||
|
||||
function testItReturnsViewActionResult() {
|
||||
$view_in_browser = Stub::make($this->view_in_browser, array(
|
||||
'_displayNewsletter' => Stub::exactly(1, function() { })
|
||||
), $this);
|
||||
$view_in_browser->data = $view_in_browser->_processBrowserPreviewData($this->browser_preview_data);
|
||||
$view_in_browser->view();
|
||||
}
|
||||
|
||||
function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
|
||||
}
|
||||
}
|
130
tests/unit/Router/RouterTest.php
Normal file
130
tests/unit/Router/RouterTest.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
use Codeception\Util\Stub;
|
||||
use MailPoet\Router\Router;
|
||||
|
||||
require_once('RouterTestMockEndpoint.php');
|
||||
|
||||
class FrontRouterTest extends MailPoetTest {
|
||||
public $router_data;
|
||||
public $router;
|
||||
|
||||
function __construct() {
|
||||
$this->router_data = array(
|
||||
Router::NAME => '',
|
||||
'endpoint' => 'mock_endpoint',
|
||||
'action' => 'test',
|
||||
'data' => base64_encode(serialize(array('data' => 'dummy data')))
|
||||
);
|
||||
$this->router = new Router($this->router_data);
|
||||
}
|
||||
|
||||
function testItCanGetAPIDataFromGetRequest() {
|
||||
$data = array('data' => 'dummy data');
|
||||
$url = 'http://example.com/?' . Router::NAME . '&endpoint=view_in_browser&action=view&data='
|
||||
. base64_encode(serialize($data));
|
||||
parse_str(parse_url($url, PHP_URL_QUERY), $_GET);
|
||||
$router = new Router();
|
||||
expect($router->api_request)->equals(true);
|
||||
expect($router->endpoint)->equals('viewInBrowser');
|
||||
expect($router->action)->equals('view');
|
||||
expect($router->data)->equals($data);
|
||||
}
|
||||
|
||||
function testItContinuesExecutionWhenAPIRequestNotDetected() {
|
||||
$router_data = $this->router_data;
|
||||
unset($router_data[Router::NAME]);
|
||||
$router = Stub::construct(
|
||||
new Router(),
|
||||
array($router_data)
|
||||
);
|
||||
$result = $router->init();
|
||||
expect($result)->null();
|
||||
}
|
||||
|
||||
function testItTerminatesRequestWhenEndpointNotFound() {
|
||||
$router_data = $this->router_data;
|
||||
$router_data['endpoint'] = 'invalid_endpoint';
|
||||
$router = Stub::construct(
|
||||
new Router(),
|
||||
array($router_data),
|
||||
array(
|
||||
'terminateRequest' => function($code, $error) {
|
||||
return array(
|
||||
$code,
|
||||
$error
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
$result = $router->init();
|
||||
expect($result)->equals(
|
||||
array(
|
||||
404,
|
||||
'Invalid router endpoint.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function testItTerminatesRequestWhenEndpointActionNotFound() {
|
||||
$router_data = $this->router_data;
|
||||
$router_data['action'] = 'invalid_action';
|
||||
$router = Stub::construct(
|
||||
new Router(),
|
||||
array($router_data),
|
||||
array(
|
||||
'terminateRequest' => function($code, $error) {
|
||||
return array(
|
||||
$code,
|
||||
$error
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
$result = $router->init();
|
||||
expect($result)->equals(
|
||||
array(
|
||||
404,
|
||||
'Invalid router endpoint action.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function testItCallsEndpointAction() {
|
||||
$data = array('data' => 'dummy data');
|
||||
$result = $this->router->init();
|
||||
expect($result)->equals($data);
|
||||
}
|
||||
|
||||
function testItCanEncodeRequestData() {
|
||||
$data = array('data' => 'dummy data');
|
||||
$result = Router::encodeRequestData($data);
|
||||
expect($result)->equals(
|
||||
rtrim(base64_encode(serialize($data)), '=')
|
||||
);
|
||||
}
|
||||
|
||||
function testItReturnsEmptyArrayWhenRequestDataIsAString() {
|
||||
$encoded_data = 'test';
|
||||
$result = Router::decodeRequestData($encoded_data);
|
||||
expect($result)->equals(array());
|
||||
}
|
||||
|
||||
function testItCanDecodeRequestData() {
|
||||
$data = array('data' => 'dummy data');
|
||||
$encoded_data = rtrim(base64_encode(serialize($data)), '=');
|
||||
$result = Router::decodeRequestData($encoded_data);
|
||||
expect($result)->equals($data);
|
||||
}
|
||||
|
||||
function testItCanBuildRequest() {
|
||||
$data = array('data' => 'dummy data');
|
||||
$encoded_data = rtrim(base64_encode(serialize($data)), '=');
|
||||
$result = Router::buildRequest(
|
||||
'mock_endpoint',
|
||||
'test',
|
||||
$data
|
||||
);
|
||||
expect($result)->contains(Router::NAME . '&endpoint=mock_endpoint&action=test&data=' . $encoded_data);
|
||||
}
|
||||
}
|
19
tests/unit/Router/RouterTestMockEndpoint.php
Normal file
19
tests/unit/Router/RouterTestMockEndpoint.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Router\Endpoints;
|
||||
|
||||
class MockEndpoint {
|
||||
const ACTION_TEST = 'test';
|
||||
public $allowed_actions = array(
|
||||
self::ACTION_TEST
|
||||
);
|
||||
public $data;
|
||||
|
||||
function __construct($data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
function test() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
@ -135,7 +135,7 @@ class ClicksTest extends MailPoetTest {
|
||||
}
|
||||
|
||||
|
||||
function testItDoesNotConvertRegulaUrls() {
|
||||
function testItDoesNotConvertRegularUrls() {
|
||||
$link = $this->clicks->processUrl(
|
||||
'http://example.com',
|
||||
$this->newsletter,
|
||||
|
@ -1,16 +1,19 @@
|
||||
<div class="handlediv" title="Click to toggle"><br></div>
|
||||
<h3><%= __('Preview') %></h3>
|
||||
<div class="mailpoet_region_content">
|
||||
<div class="mailpoet_form_field">
|
||||
<label>
|
||||
<%= __('Send preview to') %><br />
|
||||
<input id="mailpoet_preview_to_email" class="mailpoet_input mailpoet_input_full" type="text" name="to_email" value="<%= settings.sender.address %>" />
|
||||
</label>
|
||||
</div>
|
||||
<iframe name="mailpoet_save_preview_email_for_autocomplete" style="display:none" src="about:blank"></iframe>
|
||||
<form target="mailpoet_save_preview_email_for_autocomplete" action="about:blank">
|
||||
<div class="mailpoet_form_field">
|
||||
<label>
|
||||
<%= __('Send preview to') %><br />
|
||||
<input id="mailpoet_preview_to_email" class="mailpoet_input mailpoet_input_full" type="text" name="to_email" value="<%= current_wp_user.email %>" autocomplete="email" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mailpoet_form_field">
|
||||
<input type="button" id="mailpoet_send_preview" class="button button-primary mailpoet_button_full" value="<%= __('Send preview') %>" />
|
||||
</div>
|
||||
<div class="mailpoet_form_field">
|
||||
<input type="submit" id="mailpoet_send_preview" class="button button-primary mailpoet_button_full" value="<%= __('Send preview') %>" />
|
||||
</div>
|
||||
</ofmr>
|
||||
|
||||
<hr class="mailpoet_separator" />
|
||||
|
||||
|
Reference in New Issue
Block a user