merged master

This commit is contained in:
Jonathan Labreuille
2015-10-16 14:40:32 +02:00
57 changed files with 1923 additions and 648 deletions

View File

@ -1,5 +1,2 @@
WP_TEST_URL="http://localhost"
WP_TEST_USER="admin"
WP_TEST_PASSWORD="password"
WP_TEST_PATH="/var/www/wordpress"

View File

@ -94,17 +94,6 @@ class RoboFile extends \Robo\Tasks {
$this->_exec('vendor/bin/codecept run unit '.(($file) ? $file : ''));
}
function testAcceptance($file = null) {
$this->loadEnv();
$this->_exec('vendor/bin/codecept build');
$this
->taskExec('phantomjs --webdriver=4444')
->background()
->run();
sleep(2);
$this->_exec('vendor/bin/codecept run acceptance '.(($file) ? $file : ''));
}
function testJavascript() {
$this->compileJs();
@ -115,13 +104,6 @@ class RoboFile extends \Robo\Tasks {
)));
}
function testAll() {
$this->loadEnv();
$this->_exec('vendor/bin/codecept build');
$this->startPhantomJS();
$this->_exec('vendor/bin/codecept run');
}
function testDebug() {
$this->_exec('vendor/bin/codecept build');
$this->loadEnv();
@ -138,24 +120,5 @@ class RoboFile extends \Robo\Tasks {
protected function loadEnv() {
$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();
$this
->taskWriteToFile('tests/acceptance.suite.yml')
->textFromFile('tests/acceptance.suite.src')
->run();
$this
->taskReplaceInFile('tests/acceptance.suite.yml')
->regex("/url.*/")
->to('url: ' . "'" . getenv('WP_TEST_URL'). "'")
->run();
}
protected function startPhantomJS() {
$this
->taskexec('phantomjs --webdriver=4444')
->background()
->run();
sleep(3);
}
}

View File

@ -205,7 +205,7 @@ select.mailpoet_font-size
border-bottom-left-radius: 0
.mailpoet_text_content p
margin: 0
margin: 1em 0
.mailpoet_separator
margin: 17px 20px

View File

@ -6,7 +6,12 @@
z-index: 19
width: 100%
height: 100%
background: rgba(255, 255, 255, 0)
transition: background .15s ease-out
&:hover
background: rgba(255, 255, 255, 0.7)
cursor: pointer
.mailpoet_automated_latest_content_block_posts
overflow: auto

View File

@ -61,7 +61,7 @@ define([
};
},
initialize: function() {
base.BlockModel.prototype.initialize.apply(this);
base.BlockView.prototype.initialize.apply(this, arguments);
this.fetchPosts();
this.on('change:amount change:contentType change:terms change:inclusionType change:displayType change:titleFormat change:titlePosition change:titleAlignment change:titleIsLink change:imagePadded 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);
@ -69,13 +69,12 @@ define([
},
fetchPosts: function() {
var that = this;
// TODO: Migrate to new AJAX queries
//mailpoet_post_wpi('automated_latest_content.php', this.toJSON(), function(response) {
//console.log('ALC fetched', arguments);
//that.get('_container').get('blocks').reset(response, {parse: true});
//}, function() {
//console.log('ALC fetchPosts error', arguments);
//});
WordpressComponent.getTransformedPosts(this.toJSON()).done(function(content) {
console.log('ALC fetched', arguments);
that.get('_container').get('blocks').reset(content, {parse: true});
}).fail(function(error) {
console.log('ALC fetchPosts error', arguments);
});
},
/**
* Batch more changes during a specific time, instead of fetching
@ -101,6 +100,9 @@ define([
toolsRegion: '.mailpoet_tools',
postsRegion: '.mailpoet_automated_latest_content_block_posts',
},
events: _.extend(base.BlockView.prototype.events, {
'click .mailpoet_automated_latest_content_block_overlay': 'showSettings',
}),
onDragSubstituteBy: function() { return Module.AutomatedLatestContentWidgetView; },
onRender: function() {
var ContainerView = App.getBlockTypeView('container'),
@ -236,6 +238,7 @@ define([
});
},
onBeforeDestroy: function() {
base.BlockSettingsView.prototype.onBeforeDestroy.apply(this, arguments);
// Force close select2 if it hasn't closed yet
this.$('.mailpoet_automated_latest_content_categories_and_tags').select2('close');
},
@ -336,7 +339,10 @@ define([
cloneOriginal: true,
drop: function() {
return new Module.AutomatedLatestContentBlockModel({}, { parse: true });
}
},
onDrop: function(options) {
options.droppedView.triggerMethod('showSettings');
},
}
},
});

View File

@ -87,6 +87,9 @@ define([
AugmentedView.apply(this, arguments);
this.$el.addClass('mailpoet_editor_view_' + this.cid);
},
initialize: function() {
this.on('showSettings', this.showSettings);
},
showTools: function(_event) {
if (!this.showingToolsDisabled) {
this.$('> .mailpoet_tools').show();
@ -104,6 +107,9 @@ define([
this.showingToolsDisabled = true;
this.hideTools();
},
showSettings: function(options) {
this.toolsView.triggerMethod('showSettings', options);
},
/**
* Defines drop behavior of BlockView instance
*/
@ -141,6 +147,7 @@ define([
// Automatically cancel deletion
this.on('hideTools', this.hideDeletionConfirmation, this);
this.on('showSettings', this.changeSettings);
},
templateHelpers: function() {
return {
@ -149,9 +156,9 @@ define([
tools: this.tools,
};
},
changeSettings: function() {
changeSettings: function(options) {
var ViewType = this.getSettingsView();
(new ViewType({ model: this.model })).render();
(new ViewType(_.extend({ model: this.model }, options || {}))).render();
},
showDeletionConfirmation: function() {
this.$('.mailpoet_delete_block').addClass('mailpoet_delete_block_activated');
@ -182,7 +189,6 @@ define([
});
},
close: function(event) {
MailPoet.Modal.cancel();
this.destroy();
},
changeField: function(field, event) {
@ -204,6 +210,9 @@ define([
}
this.model.set(field, value);
},
onBeforeDestroy: function() {
MailPoet.Modal.close();
},
});
Module.WidgetView = Marionette.ItemView.extend({

View File

@ -35,9 +35,6 @@ define([
Module.ImageBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_image_block mailpoet_droppable_block",
getTemplate: function() { return templates.imageBlock; },
initialize: function() {
this.on('showSettings', this.showSettings);
},
onDragSubstituteBy: function() { return Module.ImageWidgetView; },
templateHelpers: function() {
return {
@ -56,29 +53,10 @@ define([
this.$el.addClass('mailpoet_full_image');
}
},
showSettings: function(options) {
this.toolsView.triggerMethod('showSettings', options);
},
onBeforeDestroy: function() {
this.off('showSettings');
},
});
Module.ImageBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.ImageBlockSettingsView; },
initialize: function() {
base.BlockToolsView.prototype.initialize.apply(this, arguments);
this.on('showSettings', this.changeSettings);
},
changeSettings: function(options) {
(new Module.ImageBlockSettingsView({
model: this.model,
showImageManager: (options.showImageManager === true),
})).render();
},
onBeforeDestroy: function() {
this.off('showSettings');
},
});
Module.ImageBlockSettingsView = base.BlockSettingsView.extend({
@ -349,6 +327,7 @@ define([
this._mediaManager.open();
},
onBeforeDestroy: function() {
base.BlockSettingsView.prototype.onBeforeDestroy.apply(this, arguments);
if (typeof this._mediaManager === 'object') {
this._mediaManager.remove();
}

View File

@ -132,8 +132,8 @@ define([
modelEvents: {},
onDragSubstituteBy: function() { return Module.PostsWidgetView; },
initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments);
this.toolsView = new Module.PostsBlockToolsView({ model: this.model });
this.on('showSettings', this.showSettings);
this.model.reply('blockView', this.notifyAboutSelf, this);
},
onRender: function() {
@ -142,9 +142,6 @@ define([
}
this.trigger('showSettings');
},
showSettings: function(options) {
this.toolsView.triggerMethod('showSettings', options);
},
notifyAboutSelf: function() {
return this;
},
@ -155,19 +152,6 @@ define([
Module.PostsBlockToolsView = base.BlockToolsView.extend({
getSettingsView: function() { return Module.PostsBlockSettingsView; },
initialize: function() {
base.BlockToolsView.prototype.initialize.apply(this, arguments);
this.on('showSettings', this.changeSettings);
this.settingsView = new Module.PostsBlockSettingsView({ model: this.model });
},
changeSettings: function() {
this.settingsView.render();
},
onBeforeDestroy: function() {
this.settingsView.destroy();
this.off('showSettings');
MailPoet.Modal.close();
},
});
Module.PostsBlockSettingsView = base.BlockSettingsView.extend({
@ -320,6 +304,7 @@ define([
});
},
onBeforeDestroy: function() {
base.BlockSettingsView.prototype.onBeforeDestroy.apply(this, arguments);
// Force close select2 if it hasn't closed yet
this.$('.mailpoet_posts_categories_and_tags').select2('close');
},

View File

@ -22,10 +22,10 @@ define(
var messages = {
updated: function() {
MailPoet.Notice.success('Segment succesfully updated!');
MailPoet.Notice.success('Segment successfully updated!');
},
created: function() {
MailPoet.Notice.success('Segment succesfully added!');
MailPoet.Notice.success('Segment successfully added!');
}
};

View File

@ -42,10 +42,10 @@ define(
var messages = {
updated: function() {
MailPoet.Notice.success('Subscriber succesfully updated!');
MailPoet.Notice.success('Subscriber successfully updated!');
},
created: function() {
MailPoet.Notice.success('Subscriber succesfully added!');
MailPoet.Notice.success('Subscriber successfully added!');
}
};

2
build
View File

@ -16,7 +16,7 @@ rm composer.lock;
# Copy release folders.
cp -rf lang wysija-newsletters;
cp -rf assets wysija-newsletters;
cp -rfL assets wysija-newsletters;
cp -rf lib wysija-newsletters;
cp -rf vendor wysija-newsletters;
cp -rf views wysija-newsletters;

View File

@ -6,7 +6,8 @@
"cerdic/css-tidy": "*",
"sunra/php-simple-html-dom-parser": "*",
"tburry/pquery": "*",
"j4mie/paris": "1.5.4"
"j4mie/paris": "1.5.4",
"swiftmailer/swiftmailer": "^5.4"
},
"require-dev": {
"codeception/codeception": "*",

53
composer.lock generated
View File

@ -261,6 +261,59 @@
],
"time": "2013-05-04 14:32:03"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.4.1",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/0697e6aa65c83edf97bb0f23d8763f94e3f11421",
"reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"mockery/mockery": "~0.9.1,<0.9.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
}
},
"autoload": {
"files": [
"lib/swift_required.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Corbyn"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "http://swiftmailer.org",
"keywords": [
"email",
"mail",
"mailer"
],
"time": "2015-06-06 14:19:39"
},
{
"name": "tburry/pquery",
"version": "v1.1.0",

View File

@ -41,6 +41,8 @@ class Initializer {
$segments = Env::$db_prefix . 'segments';
$subscriber_segment = Env::$db_prefix . 'subscriber_segment';
$newsletter_segment = Env::$db_prefix . 'newsletter_segment';
$custom_fields = Env::$db_prefix . 'custom_fields';
$subscriber_custom_field = Env::$db_prefix . 'subscriber_custom_field';
define('MP_SUBSCRIBERS_TABLE', $subscribers);
define('MP_SETTINGS_TABLE', $settings);
@ -49,6 +51,8 @@ class Initializer {
define('MP_SUBSCRIBER_SEGMENT_TABLE', $subscriber_segment);
define('MP_NEWSLETTER_TEMPLATES_TABLE', $newsletter_templates);
define('MP_NEWSLETTER_SEGMENT_TABLE', $newsletter_segment);
define('MP_CUSTOM_FIELDS_TABLE', $custom_fields);
define('MP_SUBSCRIBER_CUSTOM_FIELD_TABLE', $subscriber_custom_field);
}
function setupActivator() {

View File

@ -16,7 +16,9 @@ class Migrator {
'newsletter_templates',
'segments',
'subscriber_segment',
'newsletter_segment'
'newsletter_segment',
'custom_fields',
'subscriber_custom_field'
);
}
@ -133,6 +135,31 @@ class Migrator {
return $this->sqlify(__FUNCTION__, $attributes);
}
function custom_fields() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'name varchar(90) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id),',
'UNIQUE KEY name (name)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
function subscriber_custom_field() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'subscriber_id mediumint(9) NOT NULL,',
'custom_field_id mediumint(9) NOT NULL,',
'value varchar(255) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
private function sqlify($model, $attributes) {
$table = $this->prefix . $model;

View File

@ -0,0 +1,108 @@
<?php
namespace MailPoet\Mailer\API;
if(!defined('ABSPATH')) exit;
class AmazonSES {
function __construct($region, $accessKey, $secretKey, $from) {
$this->awsAccessKey = $accessKey;
$this->awsSecret_key = $secretKey;
$this->awsRegion = $region;
$this->awsEndpoint = sprintf('email.%s.amazonaws.com', $region);
$this->awsSigningAlgorithm = 'AWS4-HMAC-SHA256';
$this->awsService = 'ses';
$this->awsTerminationString = 'aws4_request';
$this->hashAlgorithm = 'sha256';
$this->url = 'https://' . $this->awsEndpoint;
$this->from = $from;
$this->date = gmdate('Ymd\THis\Z');
$this->dateWithoutTime = gmdate('Ymd');
}
function send($newsletter, $subscriber) {
$result = wp_remote_post(
$this->url,
$this->request($newsletter, $subscriber)
);
return (
!is_wp_error($result) === true &&
wp_remote_retrieve_response_code($result) === 200
);
}
function getBody($newsletter, $subscriber) {
return array(
'Action' => 'SendEmail',
'Version' => '2010-12-01',
'Source' => $this->from,
'Destination.ToAddresses.member.1' => $subscriber,
'Message.Subject.Data' => $newsletter['subject'],
'Message.Body.Html.Data' => $newsletter['body']['html'],
'Message.Body.Text.Data' => $newsletter['body']['text'],
'ReturnPath' => $this->from
);
}
function request($newsletter, $subscriber) {
$body = $this->getBody($newsletter, $subscriber);
return array(
'timeout' => 10,
'httpversion' => '1.1',
'method' => 'POST',
'headers' => array(
'Host' => $this->awsEndpoint,
'Authorization' => $this->signRequest($body),
'X-Amz-Date' => $this->date
),
'body' => urldecode(http_build_query($body))
);
}
function signRequest($body) {
$stringToSign = $this->createStringToSign(
$this->getCredentialScope(),
$this->getCanonicalRequest($body)
);
$signature = hash_hmac($this->hashAlgorithm, $stringToSign, $this->getSigningKey());
return sprintf(
'%s Credential=%s/%s, SignedHeaders=host;x-amz-date, Signature=%s',
$this->awsSigningAlgorithm,
$this->awsAccessKey,
$this->getCredentialScope(),
$signature);
}
function getCredentialScope() {
return sprintf('%s/%s/%s/%s', $this->dateWithoutTime, $this->awsRegion, $this->awsService, $this->awsTerminationString);
}
function getCanonicalRequest($body) {
return implode("\n", array(
'POST',
'/',
'',
'host:' . $this->awsEndpoint,
'x-amz-date:' . $this->date,
'',
'host;x-amz-date',
hash($this->hashAlgorithm, urldecode(http_build_query($body)))
));
}
function createStringToSign($credentialScope, $canonicalRequest) {
return implode("\n", array(
$this->awsSigningAlgorithm,
$this->date,
$credentialScope,
hash($this->hashAlgorithm, $canonicalRequest)
));
}
function getSigningKey() {
$dateKey = hash_hmac($this->hashAlgorithm, $this->dateWithoutTime, 'AWS4' . $this->awsSecret_key, true);
$regionKey = hash_hmac($this->hashAlgorithm, $this->awsRegion, $dateKey, true);
$serviceKey = hash_hmac($this->hashAlgorithm, $this->awsService, $regionKey, true);
return hash_hmac($this->hashAlgorithm, $this->awsTerminationString, $serviceKey, true);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace MailPoet\Mailer\API;
if(!defined('ABSPATH')) exit;
class ElasticEmail {
function __construct($apiKey, $fromEmail, $fromName) {
$this->url = 'https://api.elasticemail.com/mailer/send';
$this->apiKey = $apiKey;
$this->fromEmail = $fromEmail;
$this->fromName = $fromName;
}
function send($newsletter, $subscriber) {
$result = wp_remote_post(
$this->url,
$this->request($newsletter, $subscriber));
return (
!is_wp_error($result) === true &&
!preg_match('/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/', $result['body']) === false
);
}
function getBody($newsletter, $subscriber) {
return array(
'api_key' => $this->apiKey,
'from' => $this->fromEmail,
'from_name' => $this->fromName,
'to' => $subscriber,
'subject' => $newsletter['subject'],
'body_html' => $newsletter['body']['html'],
'body_text' => $newsletter['body']['text']
);
}
function request($newsletter, $subscriber) {
$body = $this->getBody($newsletter, $subscriber);
return array(
'timeout' => 10,
'httpversion' => '1.0',
'method' => 'POST',
'body' => urldecode(http_build_query($body))
);
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace MailPoet\Mailer\API;
if(!defined('ABSPATH')) exit;
class MailGun {
function __construct($domain, $apiKey, $from) {
$this->url = sprintf('https://api.mailgun.net/v3/%s/messages', $domain);
$this->apiKey = $apiKey;
$this->from = $from;
}
function send($newsletter, $subscriber) {
$result = wp_remote_post(
$this->url,
$this->request($newsletter, $subscriber)
);
return (
!is_wp_error($result) === true &&
wp_remote_retrieve_response_code($result) === 200
);
}
function getBody($newsletter, $subscriber) {
return array(
'from' => $this->from,
'to' => $subscriber,
'subject' => $newsletter['subject'],
'html' => $newsletter['body']['html'],
'text' => $newsletter['body']['text']
);
}
function auth() {
return 'Basic ' . base64_encode('api:' . $this->apiKey);
}
function request($newsletter, $subscriber) {
$body = $this->getBody($newsletter, $subscriber);
return array(
'timeout' => 10,
'httpversion' => '1.0',
'method' => 'POST',
'headers' => array(
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => $this->auth()
),
'body' => urldecode(http_build_query($body))
);
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace MailPoet\Mailer\API;
if(!defined('ABSPATH')) exit;
class Mandrill {
function __construct($apiKey, $fromEmail, $fromName) {
$this->url = 'https://mandrillapp.com/api/1.0/messages/send.json';
$this->apiKey = $apiKey;
$this->fromName = $fromName;
$this->fromEmail = $fromEmail;
}
function send($newsletter, $subscriber) {
$result = wp_remote_post(
$this->url,
$this->request($newsletter, $this->processSubscriber($subscriber))
);
return (
!is_wp_error($result) === true &&
!preg_match('!invalid!', $result['body']) === true &&
wp_remote_retrieve_response_code($result) === 200
);
}
function processSubscriber($subscriber) {
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriberData);
if(!isset($subscriberData['email'])) {
$subscriberData = array(
'email' => $subscriber,
);
}
return array(
'email' => $subscriberData['email'],
'name' => (isset($subscriberData['name'])) ? $subscriberData['name'] : ''
);
}
function getBody($newsletter, $subscriber) {
return array(
'key' => $this->apiKey,
'message' => array(
'from_email' => $this->fromEmail,
'from_name' => $this->fromName,
'to' => array($subscriber),
'subject' => $newsletter['subject'],
'html' => $newsletter['body']['html'],
'text' => $newsletter['body']['text']
),
'async' => false,
);
}
function request($newsletter, $subscriber) {
$body = $this->getBody($newsletter, $subscriber);
return array(
'timeout' => 10,
'httpversion' => '1.0',
'method' => 'POST',
'headers' => array(
'Content-Type' => 'application/json'
),
'body' => json_encode($body)
);
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace MailPoet\Mailer\API;
if(!defined('ABSPATH')) exit;
class SendGrid {
function __construct($apiKey, $fromEmail, $fromName) {
$this->url = 'https://api.sendgrid.com/api/mail.send.json';
$this->apiKey = $apiKey;
$this->fromEmail = $fromEmail;
$this->fromName = $fromName;
}
function send($newsletter, $subscriber) {
$result = wp_remote_post(
$this->url,
$this->request($newsletter, $subscriber)
);
return (
!is_wp_error($result) === true &&
!preg_match('!invalid!', $result['body']) === true &&
!isset(json_decode($result['body'], true)['errors']) === true &&
wp_remote_retrieve_response_code($result) === 200
);
}
function getBody($newsletter, $subscriber) {
return array(
'to' => $subscriber,
'from' => $this->fromEmail,
'fromname' => $this->fromName,
'subject' => $newsletter['subject'],
'html' => $newsletter['body']['html'],
'text' => $newsletter['body']['text']
);
}
function auth() {
return 'Bearer ' . $this->apiKey;
}
function request($newsletter, $subscriber) {
$body = $this->getBody($newsletter, $subscriber);
return array(
'timeout' => 10,
'httpversion' => '1.1',
'method' => 'POST',
'headers' => array(
'Authorization' => $this->auth()
),
'body' => urldecode(http_build_query($body))
);
}
}

View File

@ -1,111 +0,0 @@
<?php
namespace MailPoet\Mailer;
use MailPoet\Models\Setting;
if(!defined('ABSPATH')) exit;
class Bridge {
protected $from_address = null;
protected $from_name = '';
protected $reply_to_address = null;
protected $reply_to_name = '';
protected $newsletter = null;
protected $subscribers = null;
protected $api_key = null;
function __construct($newsletter, $subscribers) {
$this->newsletter = $newsletter;
$this->subscribers = $subscribers;
$this->from_address = (
isset($this->newsletter['from_address'])
)
? $this->newsletter['from_address']
: Setting::getValue('from_address');
$this->from_name = (
isset($this->newsletter['from_name'])
)
? $this->newsletter['from_name']
: Setting::getValue('from_name', '');
$this->reply_to_address = (
isset($this->newsletter['reply_to_address'])
)
? $this->newsletter['reply_to_address']
: Setting::getValue('reply_to_address');
$this->reply_to_name = (
isset($this->newsletter['reply_to_name'])
)
? $this->newsletter['reply_to_name']
: Setting::getValue('reply_to_name', '');
$this->api_key = Setting::where('name', 'api_key')->findOne()->value;
}
function messages() {
$messages = array_map(
array($this, 'generateMessage'),
$this->subscribers
);
return $messages;
}
function generateMessage($subscriber) {
$message = array(
'subject' => $this->newsletter['subject'],
'to' => array(
'address' => $subscriber['email'],
'name' => $subscriber['first_name'].' '.$subscriber['last_name']
),
'from' => array(
'address' => $this->from_address,
'name' => $this->from_name
),
'text' => "",
'html' => $this->newsletter['body']
);
if($this->reply_to_address !== null) {
$message['reply_to'] = array(
'address' => $this->reply_to_address,
'name' => $this->reply_to_name
);
}
return $message;
}
function auth() {
$auth = 'Basic '
. base64_encode('api:' . $this->api_key);
return $auth;
}
function request() {
$request = array(
'timeout' => 10,
'httpversion' => '1.0',
'method' => 'POST',
'headers' => array(
'Authorization' => $this->auth(),
'Content-Type' => 'application/json'
),
'body' => json_encode($this->messages())
);
return $request;
}
function send() {
$result = wp_remote_post(
'https://bridge.mailpoet.com/api/messages',
$this->request()
);
$success =
(wp_remote_retrieve_response_code($result) === 201);
return $success;
}
}

71
lib/Mailer/MailPoet.php Normal file
View File

@ -0,0 +1,71 @@
<?php
namespace MailPoet\Mailer;
if(!defined('ABSPATH')) exit;
class MailPoet {
function __construct($apiKey, $fromEmail, $fromName) {
$this->url = 'https://bridge.mailpoet.com/api/messages';
$this->apiKey = $apiKey;
$this->fromEmail = $fromEmail;
$this->fromName = $fromName;
}
function send($newsletter, $subscriber) {
$result = wp_remote_post(
$this->url,
$this->request($newsletter, $this->processSubscriber($subscriber))
);
return (
!is_wp_error($result) === true &&
wp_remote_retrieve_response_code($result) === 201
);
}
function processSubscriber($subscriber) {
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriberData);
if(!isset($subscriberData['email'])) {
$subscriberData = array(
'email' => $subscriber,
);
}
return array(
'email' => $subscriberData['email'],
'name' => (isset($subscriberData['name'])) ? $subscriberData['name'] : ''
);
}
function getBody($newsletter, $subscriber) {
return array(
'to' => (array(
'address' => $subscriber['email'],
'name' => $subscriber['name']
)),
'from' => (array(
'address' => $this->fromEmail,
'name' => $this->fromName
)),
'subject' => $newsletter['subject'],
'html' => $newsletter['body']['html'],
'text' => $newsletter['body']['text']
);
}
function auth() {
return 'Basic ' . base64_encode('api:' . $this->apiKey);
}
function request($newsletter, $subscriber) {
$body = array($this->getBody($newsletter, $subscriber));
return array(
'timeout' => 10,
'httpversion' => '1.0',
'method' => 'POST',
'headers' => array(
'Content-Type' => 'application/json',
'Authorization' => $this->auth()
),
'body' => json_encode($body)
);
}
}

62
lib/Mailer/SMTP.php Normal file
View File

@ -0,0 +1,62 @@
<?php
namespace MailPoet\Mailer;
if(!defined('ABSPATH')) exit;
class SMTP {
function __construct($host, $port, $authentication, $encryption,
$fromEmail, $fromName) {
$this->host = $host;
$this->port = $port;
$this->authentication = $authentication;
$this->encryption = $encryption;
$this->fromName = $fromName;
$this->fromEmail = $fromEmail;
$this->mailer = $this->buildMailer();
}
function send($newsletter, $subscriber) {
try {
$message = $this->createMessage($newsletter, $subscriber);
$result = $this->mailer->send($message);
} catch (\Exception $e) {
$result = false;
}
return ($result === 1);
}
function buildMailer() {
$transport = \Swift_SmtpTransport::newInstance(
$this->host, $this->port, $this->encryption);
$transport->setTimeout(10);
if($this->authentication) {
$transport
->setUsername($this->authentication['login'])
->setPassword($this->authentication['password']);
}
return \Swift_Mailer::newInstance($transport);
}
function createMessage($newsletter, $subscriber) {
return \Swift_Message::newInstance()
->setFrom(array($this->fromEmail => $this->fromName))
->setTo($this->processSubscriber($subscriber))
->setSubject($newsletter['subject'])
->setBody($newsletter['body']['html'], 'text/html')
->addPart($newsletter['body']['text'], 'text/plain');
}
function processSubscriber($subscriber) {
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriberData);
if(!isset($subscriberData['email'])) {
$subscriberData = array(
'email' => $subscriber,
);
}
return array(
$subscriberData['email'] =>
(isset($subscriberData['name'])) ? $subscriberData['name'] : '',
);
}
}

58
lib/Mailer/WPMail.php Normal file
View File

@ -0,0 +1,58 @@
<?php
namespace MailPoet\Mailer;
require_once(ABSPATH . 'wp-includes/pluggable.php');
if(!defined('ABSPATH')) exit;
class WPMail {
function __construct($fromEmail, $fromName) {
$this->fromEmail = $fromEmail;
$this->fromName = $fromName;
add_filter('wp_mail_from', array(
$this,
'setFromEmail'
));
$this->filters = array(
'wp_mail_from' => 'setFromEmail',
'wp_mail_from_name' => 'setFromName',
'wp_mail_content_type' => 'setContentType'
);
}
function addFilters() {
foreach ($this->filters as $filter => $method) {
add_filter($filter, array(
$this,
$method
));
}
}
function removeFilters() {
foreach ($this->filters as $filter => $method) {
remove_filter($filter, array(
$this,
$method
));
}
}
function setFromEmail() {
return $this->fromEmail;
}
function setFromName() {
return $this->fromName;
}
function setContentType() {
return 'text/html';
}
function send($newsletter, $subscriber) {
$this->addFilters();
$result = wp_mail($subscriber, $newsletter['subject'], $newsletter['body']['html']);
$this->removeFilters();
return ($result === true);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace MailPoet\Models;
if(!defined('ABSPATH')) exit;
class CustomField extends Model {
public static $_table = MP_CUSTOM_FIELDS_TABLE;
function __construct() {
parent::__construct();
$this->addValidations('name', array(
'required' => __('You need to specify a name.')
));
}
function subscribers() {
return $this->has_many_through(
__NAMESPACE__ . '\Subscriber',
__NAMESPACE__ . '\SubscriberCustomField',
'custom_field_id',
'subscriber_id'
);
}
}

View File

@ -132,6 +132,15 @@ class Subscriber extends Model {
);
}
function customFields() {
return $this->has_many_through(
__NAMESPACE__.'\CustomField',
__NAMESPACE__.'\SubscriberCustomField',
'subscriber_id',
'custom_field_id'
)->select_expr(MP_SUBSCRIBER_CUSTOM_FIELD_TABLE.'.value');
}
static function createOrUpdate($data = array()) {
$subscriber = false;

View File

@ -0,0 +1,12 @@
<?php
namespace MailPoet\Models;
if(!defined('ABSPATH')) exit;
class SubscriberCustomField extends Model {
public static $_table = MP_SUBSCRIBER_CUSTOM_FIELD_TABLE;
function __construct() {
parent::__construct();
}
}

148
lib/Router/Mailer.php Normal file
View File

@ -0,0 +1,148 @@
<?php
namespace MailPoet\Router;
if(!defined('ABSPATH')) exit;
class Mailer {
function __construct() {
$this->fromName = $this->getSetting('from_name');
$this->fromEmail = $this->getSetting('from_address');
$this->mailer = $this->getSetting('mailer');
$this->from = sprintf('%s <%s>', $this->fromName, $this->fromEmail);
}
function send($newsletter, $subscriber) {
$subscriber = $this->transformSubscriber($subscriber);
$mailer = $this->buildMailer();
return wp_send_json($mailer->send($newsletter, $subscriber));
}
function buildMailer() {
switch ($this->mailer['name']) {
case 'AmazonSES':
$mailer = new $this->mailer['class'](
$this->mailer['region'],
$this->mailer['access_key'],
$this->mailer['secret_key'],
$this->from
);
break;
case 'ElasticEmail':
$mailer = new $this->mailer['class'](
$this->mailer['api_key'],
$this->fromEmail, $this->fromName
);
break;
case 'MailGun':
$mailer = new $this->mailer['class'](
$this->mailer['domain'],
$this->mailer['api_key'],
$this->from
);
break;
case 'MailPoet':
$mailer = new $this->mailer['class'](
$this->mailer['api_key'],
$this->fromEmail,
$this->fromName
);
break;
case 'Mandrill':
$mailer = new $this->mailer['class'](
$this->mailer['api_key'],
$this->fromEmail, $this->fromName
);
break;
case 'SendGrid':
$mailer = new $this->mailer['class'](
$this->mailer['api_key'],
$this->fromEmail,
$this->fromName
);
break;
case 'SMTP':
$mailer = new $this->mailer['class'](
$this->mailer['host'],
$this->mailer['port'],
$this->mailer['authentication'],
$this->mailer['encryption'],
$this->fromEmail,
$this->fromName);
break;
}
return $mailer;
}
function transformSubscriber($subscriber) {
if(!is_array($subscriber)) return $subscriber;
$first_name = (isset($subscriber['first_name'])) ? $subscriber['first_name'] : '';
$last_name = (isset($subscriber['last_name'])) ? $subscriber['last_name'] : '';
if(!$first_name && !$last_name) return $subscriber['email'];
$subscriber = sprintf('%s %s <%s>', $first_name, $last_name, $subscriber['email']);
$subscriber = trim(preg_replace('!\s\s+!', ' ', $subscriber));
return $subscriber;
}
function getSetting($setting) {
if($setting === 'mailer') {
$mailers = array(
array(
'name' => 'AmazonSES',
'type' => 'API',
'access_key' => 'AKIAJM6Y5HMGXBLDNSRA',
'secret_key' => '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',
'region' => 'us-east-1'
),
array(
'name' => 'ElasticEmail',
'type' => 'API',
'api_key' => '997f1f7f-41de-4d7f-a8cb-86c8481370fa'
),
array(
'name' => 'MailGun',
'type' => 'API',
'api_key' => 'key-6cf5g5qjzenk-7nodj44gdt8phe6vam2',
'domain' => 'mrcasual.com'
),
array(
'name' => 'MailPoet',
'api_key' => 'dhNSqj1XHkVltIliyQDvMiKzQShOA5rs0m_DdRUVZHU'
),
array(
'name' => 'Mandrill',
'type' => 'API',
'api_key' => '692ys1B7REEoZN7R-dYwNA'
),
array(
'name' => 'SendGrid',
'type' => 'API',
'api_key' => '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'
),
array(
'name' => 'SMTP',
'host' => 'email-smtp.us-west-2.amazonaws.com',
'port' => 587,
'authentication' => array(
'login' => 'AKIAIGPBLH6JWG5VCBQQ',
'password' => 'AudVHXHaYkvr54veCzqiqOxDiMMyfQW3/V6F1tYzGXY3'
),
'encryption' => 'tls'
),
array(
'name' => 'WPMail'
)
);
$mailer = $mailers[array_rand($mailers)];
$mailer['class'] = 'MailPoet\\Mailer\\' .
((isset($mailer['type'])) ?
$mailer['type'] . '\\' . $mailer['name'] :
$mailer['name']
);
return $mailer;
}
if($setting === 'from_name') return 'Sender';
if($setting === 'from_address') return 'staff@mailpoet.com';
return Setting::where('name', $setting)
->findOne()->value;
}
}

View File

@ -2,9 +2,10 @@
namespace MailPoet\Router;
use MailPoet\Listing;
use MailPoet\Mailer\Bridge;
use MailPoet\Mailer\API\MailPoet;
use MailPoet\Models\Newsletter;
use MailPoet\Models\Segment;
use MailPoet\Models\Setting;
use MailPoet\Models\Subscriber;
use MailPoet\Models\NewsletterTemplate;
use MailPoet\Models\NewsletterSegment;
@ -103,10 +104,24 @@ class Newsletters {
// END - TO REMOVE
$renderer = new Renderer(json_decode($newsletter['body'], true));
$newsletter['body'] = $renderer->renderAll();
$newsletter['body']['html'] = $renderer->renderAll();
$newsletter['body']['text'] = '';
$mailer = new Bridge($newsletter, array_values($subscribers));
wp_send_json($mailer->send());
$subscribers = Subscriber::find_array();
$fromEmail = Setting::where('name', 'from_address')->findOne()->value;
$fromName = Setting::where('name', 'from_name')->findOne()->value;
$apiKey = Setting::where('name', 'api_key')->findOne()->value;
$mailer = new MailPoet($apiKey, $fromEmail, $fromName);
foreach ($subscribers as $subscriber) {
$result = $mailer->send(
$newsletter,
sprintf('%s %s <%s>', $subscriber['first_name'], $subscriber['last_name'], $subscriber['email'])
);
if ($result !== true) wp_send_json(false);
}
wp_send_json(true);
}
function render($data = array()) {

26
tests/Actions.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
*
* @SuppressWarnings(PHPMD)
*/
class extends \Codeception\Actor
{
use _generated\Actions;
/**
* Define custom actions here
*/
}

View File

@ -7,10 +7,14 @@ require_once(getenv('WP_TEST_PATH') . '/wp-load.php');
$console->writeln('Cleaning up database...');
$models = array(
'Subscriber',
'Setting',
'CustomField',
'Newsletter',
'NewsletterSegment',
'NewsletterTemplate',
'Segment',
'Setting',
'Subscriber',
'SubscriberCustomField',
'SubscriberSegment'
);
$destroy = function ($model) {

View File

@ -0,0 +1,18 @@
<?php //[STAMP] d305d58a783adf00ac0f766f93b4b7f1
namespace _generated;
// This class was automatically generated by build task
// You should not change it manually as it will be overwritten on next build
// @codingStandardsIgnoreFile
trait Actions
{
/**
* @return \Codeception\Scenario
*/
abstract protected function getScenario();
}

View File

@ -1,15 +0,0 @@
# Codeception Test Suite Configuration
#
# Suite for acceptance tests.
# Perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.
class_name: AcceptanceTester
modules:
enabled:
- \Helper\Acceptance
- WebDriver:
url: 'http://localhost'
browser: phantomjs
capabilities:
webStorageEnabled: true

View File

@ -1,23 +0,0 @@
<?php
class ActivationCest {
public function _before(AcceptanceTester $I) {
$I->login();
}
public function iCanActivate(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/plugins.php');
$I->see('MailPoet');
$I->click('#mailpoet .deactivate a');
$I->see('Plugin deactivated');
$I->see('MailPoet');
$I->click('#mailpoet .activate a');
$I->see('Plugin Activated');
}
public function _after(AcceptanceTester $I) {
}
}

View File

@ -1,70 +0,0 @@
<?php
class FormWidgetCest {
function _before(AcceptanceTester $I) {
$I->login();
// make sure we are not in responsive mode
$I->resizeWindow(960, 600);
}
function iCanAddTheWidget(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/widgets.php');
$I->see('MailPoet Subscription Form');
// select the mailpoet form widget
$I->click('div[id*="mailpoet_form"] .widget-title');
$I->waitForText(
'Add Widget',
1,
'div[id*="mailpoet_form"]'
);
// add it as a widget
$I->click(
'Add Widget',
'div[id*="mailpoet_form"]'
);
sleep(1);
// save
$I->click(
'Save',
'#widgets-right div[id*="mailpoet_form"]:last-child'
);
}
function iSeeTheWidget(AcceptanceTester $I) {
$I->amOnPage('/');
$I->see('Subscribe to our Newsletter');
$I->seeElement('.widget_mailpoet_form');
$I->seeElement('input', ['name' => 'email']);
$I->seeElement('input', ['value' => 'Subscribe!']);
}
function iCanDeleteTheWidget(AcceptanceTester $I) {return;
$I->amOnPage('/wp-admin/widgets.php');
$I->see('MailPoet Subscription Form', '#widgets-right');
// select an active mailpoet form widget
$I->click('#widgets-right div[id*="mailpoet_form"] .widget-action');
$I->waitForElementVisible(
'#widgets-right div[id*="mailpoet_form"]:last-child '.
'.widget-control-remove',
1
);
// delete widget
$I->click(
'Delete',
'#widgets-right div[id*="mailpoet_form"]:last-child'
);
}
}

View File

@ -1,15 +0,0 @@
<?php
class HomePageCest {
function _before(AcceptanceTester $I) {
}
function iCanSeeATitle(AcceptanceTester $I) {
$I->amOnPage('/');
$I->see('Hello');
}
function _after(AcceptanceTester $I) {
}
}

View File

@ -1,68 +0,0 @@
<?php
use Helper\Acceptance;
class NewslettersPageCest {
function _before(AcceptanceTester $I) {
$I->login();
$I->resizeWindow(1024, 768);
$this->first_row = 'id("newsletters")//table/tbody/tr[2]';
$this->timeout = 3;
}
function iCanSeeTheTitle(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/admin.php?page=mailpoet-newsletters');
$I->see('Newsletters');
}
function iCanAddANewsletter(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/admin.php?page=mailpoet-newsletters');
$I->see('No newsletters found');
$I->click('New', '#newsletters');
$I->fillField('subject', 'first newsletter');
$I->fillField('Body', 'some body');
$I->click('Save');
$I->waitForText('1 item', $this->timeout);
}
function iCanAddAnotherNewsletter(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/admin.php?page=mailpoet-newsletters#/new');
$I->fillField('subject', 'second newsletter');
$I->fillField('Body', 'some body');
$I->click('Save');
$I->waitForText('2 item', $this->timeout);
}
function iCanSortNewsletterBySubject(AcceptanceTester $I) {
$I->click('Subject');
$I->waitForText('first', $this->timeout, $this->first_row);
$I->click('Subject');
$I->waitForText('second', $this->timeout, $this->first_row);
}
function iCanSortNewsletterByCreatedDate(AcceptanceTester $I) {
$I->click('Created on');
$I->waitForText('first', $this->timeout, $this->first_row);
$I->click('Created on');
$I->waitForText('second', $this->timeout, $this->first_row);
}
function iCanSearchNewsletters(AcceptanceTester $I) {
$search_term = 'second';
$I->fillField('Search', $search_term);
$I->click('Search');
$I->waitForText($search_term, $this->timeout, $this->first_row);
}
function iCanSeeMobileView(AcceptanceTester $I) {
$listing_header = 'id("newsletters")//table/thead';
$I->resizeWindow(640, 480);
$I->dontSee('Created on', $listing_header);
$I->dontSee('Last modified', $listing_header);
$I->see('Subject', $listing_header);
}
function _after(AcceptanceTester $I) {
}
}

View File

@ -1,23 +0,0 @@
<?php
class SettingsPageCest {
function _before(AcceptanceTester $I) {
$I->login();
}
function iCanSeeTheTitle(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/admin.php?page=mailpoet-settings');
$I->see('Settings');
}
function iCanReachItFromTheWelcomePage(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/admin.php?page=mailpoet');
$I->see('Welcome!');
$I->click('Setup');
$I->see('Settings');
}
function _after(AcceptanceTester $I) {
}
}

View File

@ -1,16 +0,0 @@
<?php
class SubscribersPageCest {
function _before(AcceptanceTester $I) {
$I->login();
}
function iCanSeeTheTitle(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/admin.php?page=mailpoet-subscribers');
$I->see('Subscribers');
}
function _after(AcceptanceTester $I) {
}
}

View File

@ -1,16 +0,0 @@
<?php
class WelcomePageCest {
function _before(AcceptanceTester $I) {
$I->login();
}
function iCanSeeTheTitle(AcceptanceTester $I) {
$I->amOnPage('/wp-admin/admin.php?page=mailpoet');
$I->see('Welcome!');
}
function _after(AcceptanceTester $I) {
}
}

View File

@ -1,2 +0,0 @@
<?php
// Here you can initialize variables that will be available to your tests

View File

@ -1,18 +1,29 @@
define([
'newsletter_editor/App',
'newsletter_editor/blocks/automatedLatestContent',
'amd-inject-loader!newsletter_editor/blocks/automatedLatestContent',
'newsletter_editor/components/wordpress',
], function(EditorApplication, AutomatedLatestContentBlock, WordpressComponent) {
], function(EditorApplication, AutomatedLatestContentBlock, AutomatedLatestContentInjector, WordpressComponent) {
describe('Automated latest content', function () {
describe('model', function () {
var model;
var model, module;
before(function() {
module = AutomatedLatestContentInjector({
'newsletter_editor/components/wordpress': {
getTransformedPosts: function() {
return jQuery.Deferred();
}
},
});
});
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.SuperModel);
model = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockModel)();
model = new (module.AutomatedLatestContentBlockModel)();
});
afterEach(function () {
@ -151,7 +162,7 @@ define([
},
},
});
var model = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockModel)();
var model = new (module.AutomatedLatestContentBlockModel)();
expect(model.get('amount')).to.equal('17');
expect(model.get('contentType')).to.equal('mailpoet_page');
@ -184,15 +195,25 @@ define([
});
describe('block view', function () {
var model, view;
var model, view, module;
before(function() {
module = AutomatedLatestContentInjector({
'newsletter_editor/components/wordpress': {
getTransformedPosts: function() {
return jQuery.Deferred();
}
},
});
});
beforeEach(function () {
global.stubChannel(EditorApplication);
global.stubConfig(EditorApplication);
EditorApplication.getBlockTypeModel = sinon.stub().returns(Backbone.Model);
EditorApplication.getBlockTypeView = sinon.stub().returns(Backbone.View);
model = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockModel)();
view = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockView)({model: model});
model = new (module.AutomatedLatestContentBlockModel)();
view = new (module.AutomatedLatestContentBlockView)({model: model});
});
afterEach(function () {
@ -206,7 +227,20 @@ define([
});
describe('block settings view', function () {
var model, view;
var model, view, module;
before(function() {
module = AutomatedLatestContentInjector({
'newsletter_editor/components/wordpress': {
getTransformedPosts: function() {
return jQuery.Deferred();
},
getPostTypes: function() {
return jQuery.Deferred();
}
},
});
});
before(function () {
WordpressComponent.getPostTypes = function() {
@ -243,8 +277,8 @@ define([
});
beforeEach(function() {
model = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockModel)();
view = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockSettingsView)({model: model});
model = new (module.AutomatedLatestContentBlockModel)();
view = new (module.AutomatedLatestContentBlockSettingsView)({model: model});
});
after(function () {
@ -257,8 +291,8 @@ define([
describe('once rendered', function () {
beforeEach(function() {
model = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockModel)();
view = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockSettingsView)({model: model});
model = new (module.AutomatedLatestContentBlockModel)();
view = new (module.AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
});
@ -367,8 +401,8 @@ define([
describe('when "title only" display type is selected', function() {
var model, view;
beforeEach(function() {
model = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockModel)();
view = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockSettingsView)({model: model});
model = new (module.AutomatedLatestContentBlockModel)();
view = new (module.AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_automated_latest_content_display_type').val('titleOnly').change();
});
@ -380,8 +414,8 @@ define([
describe('when "title as list" is selected', function() {
var model, view;
beforeEach(function() {
model = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockModel)();
view = new (AutomatedLatestContentBlock.AutomatedLatestContentBlockSettingsView)({model: model});
model = new (module.AutomatedLatestContentBlockModel)();
view = new (module.AutomatedLatestContentBlockSettingsView)({model: model});
view.render();
view.$('.mailpoet_automated_latest_content_display_type').val('titleOnly').change();
view.$('.mailpoet_automated_latest_content_title_format').val('ul').change();

View File

@ -0,0 +1,155 @@
<?php
use MailPoet\Mailer\API\AmazonSES;
class AmazonSESCest {
function _before() {
$this->settings = array(
'name' => 'AmazonSES',
'type' => 'API',
'access_key' => 'AKIAJM6Y5HMGXBLDNSRA',
'secret_key' => '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',
'region' => 'us-east-1',
);
$this->from = 'Sender <vlad@mailpoet.com>';
$this->mailer = new AmazonSES(
$this->settings['region'],
$this->settings['access_key'],
$this->settings['secret_key'],
$this->from);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing AmazonSES',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itsConstructorWorks() {
expect($this->mailer->awsEndpoint)
->equals(
sprintf('email.%s.amazonaws.com', $this->settings['region'])
);
expect($this->mailer->url) ->equals(
sprintf('https://email.%s.amazonaws.com', $this->settings['region'])
);
expect(preg_match('!^\d{8}T\d{6}Z$!', $this->mailer->date))->equals(1);
expect(preg_match('!^\d{8}$!', $this->mailer->dateWithoutTime))->equals(1);
}
function itCanGenerateBody() {
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
expect($body['Action'])->equals('SendEmail');
expect($body['Version'])->equals('2010-12-01');
expect($body['Source'])->equals($this->from);
expect($body['Destination.ToAddresses.member.1'])
->contains($this->subscriber);
expect($body['Message.Subject.Data'])
->equals($this->newsletter['subject']);
expect($body['Message.Body.Html.Data'])
->equals($this->newsletter['body']['html']);
expect($body['Message.Body.Text.Data'])
->equals($this->newsletter['body']['text']);
expect($body['ReturnPath'])->equals($this->from);
}
function itCanCreateRequest() {
$request = $this->mailer->request($this->newsletter, $this->subscriber);
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
expect($request['timeout'])->equals(10);
expect($request['httpversion'])->equals('1.1');
expect($request['method'])->equals('POST');
expect($request['headers']['Host'])->equals($this->mailer->awsEndpoint);
expect($request['headers']['Authorization'])
->equals($this->mailer->signRequest($body));
expect($request['headers']['X-Amz-Date'])->equals($this->mailer->date);
expect($request['body'])->equals(urldecode(http_build_query($body)));
}
function itCanCreateCanonicalRequest() {
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
$canonicalRequest = explode(
"\n",
$this->mailer->getCanonicalRequest($body)
);
expect($canonicalRequest)
->equals(
array(
'POST',
'/',
'',
'host:' . $this->mailer->awsEndpoint,
'x-amz-date:' . $this->mailer->date,
'',
'host;x-amz-date',
hash($this->mailer->hashAlgorithm,
urldecode(http_build_query($body))
)
)
);
}
function itCanCreateCredentialScope() {
$credentialScope = $this->mailer->getCredentialScope();
expect($credentialScope)
->equals(
$this->mailer->dateWithoutTime . '/' .
$this->mailer->awsRegion . '/' .
$this->mailer->awsService . '/' .
$this->mailer->awsTerminationString
);
}
function itCanCreateStringToSign() {
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
$credentialScope = $this->mailer->getCredentialScope();
$canonicalRequest = $this->mailer->getCanonicalRequest($body);
$stringToSing = $this->mailer->createStringToSign(
$credentialScope,
$canonicalRequest
);
$stringToSing = explode("\n", $stringToSing);
expect($stringToSing)
->equals(
array(
$this->mailer->awsSigningAlgorithm,
$this->mailer->date,
$credentialScope,
hash($this->mailer->hashAlgorithm, $canonicalRequest)
)
);
}
function itCanSignRequest() {
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
$signedRequest = $this->mailer->signRequest($body);
expect($signedRequest)
->contains(
$this->mailer->awsSigningAlgorithm . ' Credential=' .
$this->mailer->awsAccessKey . '/' .
$this->mailer->getCredentialScope() . ', ' .
'SignedHeaders=host;x-amz-date, Signature='
);
expect(preg_match('!Signature=[A-Fa-f0-9]{64}$!', $signedRequest))
->equals(1);
}
function itCannotSendWithoutProperAccessKey() {
$this->mailer->awsAccessKey = 'somekey';
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->false();
}
function itCanSend() {
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->true();
}
}

View File

@ -0,0 +1,65 @@
<?php
use MailPoet\Mailer\API\ElasticEmail;
class ElasticEmailCest {
function _before() {
$this->settings = array(
'name' => 'ElasticEmail',
'type' => 'API',
'api_key' => '997f1f7f-41de-4d7f-a8cb-86c8481370fa'
);
$this->fromEmail = 'staff@mailpoet.com';
$this->fromName = 'Sender';
$this->mailer = new ElasticEmail(
$this->settings['api_key'],
$this->fromEmail,
$this->fromName
);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing ElasticEmail',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itCanGenerateBody() {
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
expect($body['api_key'])->equals($this->settings['api_key']);
expect($body['from'])->equals($this->fromEmail);
expect($body['from_name'])->equals($this->fromName);
expect($body['to'])->contains($this->subscriber);
expect($body['subject'])->equals($this->newsletter['subject']);
expect($body['body_html'])->equals($this->newsletter['body']['html']);
expect($body['body_text'])->equals($this->newsletter['body']['text']);
}
function itCanCreateRequest() {
$request = $this->mailer->request($this->newsletter, $this->subscriber);
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
expect($request['timeout'])->equals(10);
expect($request['httpversion'])->equals('1.0');
expect($request['method'])->equals('POST');
expect($request['body'])->equals(urldecode(http_build_query($body)));
}
function itCannotSendWithoutProperAPIKey() {
$this->mailer->apiKey = 'someapi';
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->false();
}
function itCanSend() {
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->true();
}
}

View File

@ -0,0 +1,82 @@
<?php
use MailPoet\Mailer\API\MailGun;
class MailGunCest {
function _before() {
$this->settings = array(
'name' => 'MailGun',
'type' => 'API',
'api_key' => 'key-6cf5g5qjzenk-7nodj44gdt8phe6vam2',
'domain' => 'mrcasual.com'
);
$this->from = 'Sender <staff@mailpoet.com>';
$this->mailer = new MailGun(
$this->settings['domain'],
$this->settings['api_key'],
$this->from
);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing MailGun',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itCanGenerateBody() {
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
expect($body['from'])->equals($this->from);
expect($body['to'])->equals($this->subscriber);
expect($body['subject'])->equals($this->newsletter['subject']);
expect($body['html'])->equals($this->newsletter['body']['html']);
expect($body['text'])->equals($this->newsletter['body']['text']);
}
function itCanDoBasicAuth() {
expect($this->mailer->auth())
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
}
function itCanCreateRequest() {
$request = $this->mailer->request($this->newsletter, $this->subscriber);
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
expect($request['timeout'])->equals(10);
expect($request['httpversion'])->equals('1.0');
expect($request['method'])->equals('POST');
expect($request['headers']['Content-Type'])
->equals('application/x-www-form-urlencoded');
expect($request['headers']['Authorization'])
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
expect($request['body'])->equals(urldecode(http_build_query($body)));
}
function itCannotSendWithoutProperAPIKey() {
$this->mailer->apiKey = 'someapi';
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->false();
}
function itCannotSendWithoutProperDomain() {
$this->mailer->url =
str_replace($this->settings['domain'], 'somedomain', $this->mailer->url);
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->false();
}
function itCanSend() {
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->true();
}
}

View File

@ -0,0 +1,90 @@
<?php
use MailPoet\Mailer\API\Mandrill;
class MandrillCest {
function _before() {
$this->settings = array(
'name' => 'Mandrill',
'type' => 'API',
'api_key' => '692ys1B7REEoZN7R-dYwNA'
);
$this->fromEmail = 'staff@mailpoet.com';
$this->fromName = 'Sender';
$this->mailer = new Mandrill(
$this->settings['api_key'],
$this->fromEmail,
$this->fromName
);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing Mandrill',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itCanGenerateBody() {
$subscriber = $this->mailer->processSubscriber($this->subscriber);
$body = $this->mailer->getBody($this->newsletter, $subscriber);
expect($body['key'])->equals($this->settings['api_key']);
expect($body['message']['from_email'])->equals($this->fromEmail);
expect($body['message']['from_name'])->equals($this->fromName);
expect($body['message']['to'])->equals(array($subscriber));
expect($body['message']['subject'])->equals($this->newsletter['subject']);
expect($body['message']['html'])->equals($this->newsletter['body']['html']);
expect($body['message']['text'])->equals($this->newsletter['body']['text']);
expect($body['async'])->false();
}
function itCanCreateRequest() {
$subscriber = $this->mailer->processSubscriber($this->subscriber);
$body = $this->mailer->getBody($this->newsletter, $subscriber);
$request = $this->mailer->request($this->newsletter, $subscriber);
expect($request['timeout'])->equals(10);
expect($request['httpversion'])->equals('1.0');
expect($request['method'])->equals('POST');
expect($request['headers']['Content-Type'])->equals('application/json');
expect($request['body'])->equals(json_encode($body));
}
function itCanProcessSubscriber() {
expect($this->mailer->processSubscriber('test@test.com'))
->equals(
array(
'email' => 'test@test.com',
'name' => ''
));
expect($this->mailer->processSubscriber('First <test@test.com>'))
->equals(
array(
'email' => 'test@test.com',
'name' => 'First'
));
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
->equals(
array(
'email' => 'test@test.com',
'name' => 'First Last'
));
}
function itCannotSendWithoutProperAPIKey() {
$this->mailer->apiKey = 'someapi';
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->false();
}
function itCanSend() {
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->true();
}
}

View File

@ -0,0 +1,71 @@
<?php
use MailPoet\Mailer\API\SendGrid;
class SendGridCest {
function _before() {
$this->settings = array(
'name' => 'SendGrid',
'type' => 'API',
'api_key' => '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'
);
$this->fromEmail = 'staff@mailpoet.com';
$this->fromName = 'Sender';
$this->mailer = new SendGrid(
$this->settings['api_key'],
$this->fromEmail,
$this->fromName
);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing SendGrid',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itCanGenerateBody() {
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
expect($body['to'])->contains($this->subscriber);
expect($body['from'])->equals($this->fromEmail);
expect($body['fromname'])->equals($this->fromName);
expect($body['subject'])->equals($this->newsletter['subject']);
expect($body['html'])->equals($this->newsletter['body']['html']);
expect($body['text'])->equals($this->newsletter['body']['text']);
}
function itCanCreateRequest() {
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
$request = $this->mailer->request($this->newsletter, $this->subscriber);
expect($request['timeout'])->equals(10);
expect($request['httpversion'])->equals('1.1');
expect($request['method'])->equals('POST');
expect($request['headers']['Authorization'])
->equals('Bearer ' . $this->settings['api_key']);
expect($request['body'])->equals(urldecode(http_build_query($body)));
}
function itCanDoBasicAuth() {
expect($this->mailer->auth())
->equals('Bearer ' . $this->settings['api_key']);
}
function itCannotSendWithoutProperAPIKey() {
$this->mailer->apiKey = 'someapi';
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->false();
}
function itCanSend() {
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->true();
}
}

View File

@ -1,123 +0,0 @@
<?php
use MailPoet\Mailer\Bridge;
use MailPoet\Models\Setting;
class BridgeCest {
function _before() {
$from_name = Setting::create();
$from_name->name = 'from_name';
$from_name->value = 'Marco';
$from_name->save();
$from_address = Setting::create();
$from_address->name = 'from_address';
$from_address->value = 'marco@mailpoet.com';
$from_address->save();
$api_key = Setting::create();
$api_key->name = 'api_key';
$api_key->value = 'xxxccc';
$api_key->save();
$this->newsletter = array(
'subject' => 'A test message from mp3',
'body' => 'Hey, I am mp3, chapter two.'
);
$this->subscribers = array(
array(
'first_name' => 'Marco',
'last_name' => 'Lisci',
'email' => 'marco@mailpoet.com'
),
array(
'first_name' => 'Jonathan',
'last_name' => 'Labreuille',
'email' => 'jonathan@mailpoet.com'
)
);
$this->mailer = new Bridge(
$this->newsletter,
$this->subscribers
);
}
function itCanDoBasicAuth() {
$api_key = Setting::where('name', 'api_key')
->findOne()->value;
expect($this->mailer->auth())->equals(
'Basic '
. base64_encode('api:' . $api_key)
);
}
function itCanGenerateACorrectMessage() {
$subscriber = $this->subscribers[0];
$message =
$this->mailer->generateMessage($subscriber);
expect($message['to']['address'])
->equals($subscriber['email']);
expect($message['to']['name'])
->equals($subscriber['first_name'].' '.$subscriber['last_name']);
expect($message['subject'])
->equals($this->newsletter['subject']);
expect($message['html'])
->equals($this->newsletter['body']);
expect($message['text'])
->equals('');
}
function itCanGenerateCorrectMessages() {
$messages = $this->mailer->messages();
expect(count($messages))
->equals(count($this->subscribers));
}
function itCanCreateARequest() {
$request = $this->mailer->request();
expect($request['timeout'])
->equals(10);
expect($request['httpversion'])
->equals('1.0');
expect($request['method'])
->equals('POST');
expect($request['headers']['Content-Type'])
->equals('application/json');
}
function itCannotSendWithoutSubscribers() {
$subscribers = array();
$mailer = new Bridge(
$this->newsletter,
$subscribers
);
expect($mailer->send())->equals(false);
}
function itCanSend() {
/* $result = $this->mailer->send(); */
/* expect($result)->equals(true); */
}
function _after() {
Setting::where('name', 'from_name')
->findOne()->delete();
Setting::where('name', 'from_address')
->findOne()->delete();
Setting::where('name', 'api_key')
->findOne()->delete();
}
}

View File

@ -0,0 +1,95 @@
<?php
use MailPoet\Mailer\MailPoet;
class MailPoetCest {
function _before() {
$this->settings = array(
'name' => 'MailPoet',
'api_key' => 'dhNSqj1XHkVltIliyQDvMiKzQShOA5rs0m_DdRUVZHU'
);
$this->fromEmail = 'staff@mailpoet.com';
$this->fromName = 'Sender';
$this->mailer = new MailPoet(
$this->settings['api_key'],
$this->fromEmail,
$this->fromName
);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing MailPoet',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itCanGenerateBody() {
$subscriber = $this->mailer->processSubscriber($this->subscriber);
$body = $this->mailer->getBody($this->newsletter, $subscriber);
expect($body['to']['address'])->equals($subscriber['email']);
expect($body['to']['name'])->equals($subscriber['name']);
expect($body['from']['address'])->equals($this->fromEmail);
expect($body['subject'])->equals($this->newsletter['subject']);
expect($body['html'])->equals($this->newsletter['body']['html']);
expect($body['text'])->equals($this->newsletter['body']['text']);
}
function itCanCreateRequest() {
$subscriber = $this->mailer->processSubscriber(
'Recipient <mailpoet-phoenix-test@mailinator.com>'
);
$body = array($this->mailer->getBody($this->newsletter, $subscriber));
$request = $this->mailer->request($this->newsletter, $subscriber);
expect($request['timeout'])->equals(10);
expect($request['httpversion'])->equals('1.0');
expect($request['method'])->equals('POST');
expect($request['headers']['Content-Type'])->equals('application/json');
expect($request['headers']['Authorization'])->equals($this->mailer->auth());
expect($request['body'])->equals(json_encode($body));
}
function itCanProcessSubscriber() {
expect($this->mailer->processSubscriber('test@test.com'))
->equals(
array(
'email' => 'test@test.com',
'name' => ''
));
expect($this->mailer->processSubscriber('First <test@test.com>'))
->equals(
array(
'email' => 'test@test.com',
'name' => 'First'
));
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
->equals(
array(
'email' => 'test@test.com',
'name' => 'First Last'
));
}
function itCanDoBasicAuth() {
expect($this->mailer->auth())
->equals('Basic ' . base64_encode('api:' . $this->settings['api_key']));
}
function itCannotSendWithoutProperAPIKey() {
$this->mailer->apiKey = 'someapi';
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->false();
}
function itCanSend() {
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->true();
}
}

View File

@ -0,0 +1,91 @@
<?php
use MailPoet\Mailer\SMTP;
class SMTPCest {
function _before() {
$this->settings = array(
'name' => 'SMTP',
'host' => 'email-smtp.us-west-2.amazonaws.com',
'port' => 587,
'authentication' => array(
'login' => 'AKIAIGPBLH6JWG5VCBQQ',
'password' => 'AudVHXHaYkvr54veCzqiqOxDiMMyfQW3/V6F1tYzGXY3'
),
'encryption' => 'tls'
);
$this->fromEmail = 'staff@mailpoet.com';
$this->fromName = 'Sender';
$this->mailer = new SMTP(
$this->settings['host'],
$this->settings['port'],
$this->settings['authentication'],
$this->settings['encryption'],
$this->fromEmail,
$this->fromName
);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing SMTP',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itCanBuildMailer() {
$mailer = $this->mailer->buildMailer();
expect($mailer->getTransport()->getHost())
->equals($this->settings['host']);
expect($mailer->getTransport()->getPort())
->equals($this->settings['port']);
expect($mailer->getTransport()->getUsername())
->equals($this->settings['authentication']['login']);
expect($mailer->getTransport()->getPassword())
->equals($this->settings['authentication']['password']);
expect($mailer->getTransport()->getEncryption())
->equals($this->settings['encryption']);
}
function itCanCreateMessage() {
$message = $this->mailer->createMessage($this->newsletter, $this->subscriber);
expect($message->getTo())
->equals(array('mailpoet-phoenix-test@mailinator.com' => 'Recipient'));
expect($message->getFrom())
->equals(array($this->fromEmail => $this->fromName));
expect($message->getSubject())
->equals($this->newsletter['subject']);
expect($message->getBody())
->equals($this->newsletter['body']['html']);
expect($message->getChildren()[0]->getContentType())
->equals('text/plain');
}
function itCanProcessSubscriber() {
expect($this->mailer->processSubscriber('test@test.com'))
->equals(array('test@test.com' => ''));
expect($this->mailer->processSubscriber('First <test@test.com>'))
->equals(array('test@test.com' => 'First'));
expect($this->mailer->processSubscriber('First Last <test@test.com>'))
->equals(array('test@test.com' => 'First Last'));
}
function itCantSentWithoutProperAuthentication() {
$this->mailer->authentication['login'] = 'someone';
$this->mailer->mailer = $this->mailer->buildMailer();
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->false();
}
function itCanSend() {
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->true();
}
}

View File

@ -0,0 +1,70 @@
<?php
use MailPoet\Mailer\WPMail;
class WPMailCest {
function _before() {
$this->settings = array(
'name' => 'WPMail'
);
$this->fromEmail = 'staff@mailpoet.com';
$this->fromName = 'Sender';
$this->mailer = new WPMail(
$this->fromEmail,
$this->fromName
);
$this->subscriber = 'Recipient <mailpoet-phoenix-test@mailinator.com>';
$this->newsletter = array(
'subject' => 'testing SMTP',
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
}
function itCanAddFilters() {
$this->mailer->addFilters();
expect(has_filter('wp_mail_from_name', array(
$this->mailer,
'setFromName'
)))->notEmpty();
expect(has_filter('wp_mail_from', array(
$this->mailer,
'setFromEmail'
)))->notEmpty();
expect(has_filter('wp_mail_content_type', array(
$this->mailer,
'setContentType'
)))->notEmpty();
}
function itCanRemoveFilters() {
$this->mailer->addFilters();
$this->mailer->removeFilters();
expect(has_filter('wp_mail_from_name'))->false();
expect(has_filter('wp_mail_from'))->false();
expect(has_filter('wp_mail_content_type'))->false();
}
function itCanSetFromName() {
expect($this->mailer->setFromName())->equals($this->fromName);
}
function itCanSetFromEmail() {
expect($this->mailer->setFromName())->equals($this->fromName);
}
function itCanSetContentType() {
expect($this->mailer->setContentType())->equals('text/html');
}
function itCanSend() {
$_SERVER['SERVER_NAME'] = 'localhost';
$result = $this->mailer->send(
$this->newsletter,
$this->subscriber
);
expect($result)->true();
}
}

View File

@ -0,0 +1,114 @@
<?php
use MailPoet\Models\CustomField;
use MailPoet\Models\Subscriber;
use MailPoet\Models\SubscriberCustomField;
class CustomFieldCest {
function _before() {
$this->before_time = time();
$this->data = array(
'name' => 'city',
);
$this->customField = CustomField::create();
$this->customField->hydrate($this->data);
$this->saved = $this->customField->save();
$this->subscribersData = array(
array(
'first_name' => 'John',
'last_name' => 'Mailer',
'email' => 'john@mailpoet.com'
),
array(
'first_name' => 'Mike',
'last_name' => 'Smith',
'email' => 'mike@maipoet.com'
)
);
}
function itCanBeCreated() {
expect($this->saved)->equals(true);
}
function itHasToBeValid() {
expect($this->saved)->equals(true);
$empty_model = CustomField::create();
expect($empty_model->save())->notEquals(true);
$validations = $empty_model->getValidationErrors();
expect(count($validations))->equals(1);
}
function itHasACreatedAtOnCreation() {
$customField = CustomField::where('name', $this->data['name'])
->findOne();
$time_difference = strtotime($customField->created_at) >= $this->before_time;
expect($time_difference)->equals(true);
}
function itHasAnUpdatedAtOnCreation() {
$customField = CustomField::where('name', $this->data['name'])
->findOne();
$time_difference = strtotime($customField->updated_at) >= $this->before_time;
expect($time_difference)->equals(true);
}
function itKeepsTheCreatedAtOnUpdate() {
$customField = CustomField::where('name', $this->data['name'])
->findOne();
$old_created_at = $customField->created_at;
$customField->name = 'new name';
$customField->save();
expect($old_created_at)->equals($customField->created_at);
}
function itUpdatesTheUpdatedAtOnUpdate() {
$customField = CustomField::where('name', $this->data['name'])
->findOne();
$update_time = time();
$customField->name = 'new name';
$customField->save();
$time_difference = strtotime($customField->updated_at) >= $update_time;
expect($time_difference)->equals(true);
}
function itCanHaveManySubscribers() {
foreach ($this->subscribersData as $data) {
$subscriber = Subscriber::create();
$subscriber->hydrate($data);
$subscriber->save();
$association = SubscriberCustomField::create();
$association->subscriber_id = $subscriber->id;
$association->custom_field_id = $this->customField->id;
$association->save();
}
$customField = CustomField::findOne($this->customField->id);
$subscribers = $customField->subscribers()
->findArray();
expect(count($subscribers))->equals(2);
}
function itCanStoreCustomFieldValue() {
$subscriber = Subscriber::create();
$subscriber->hydrate($this->subscribersData[0]);
$subscriber->save();
$association = SubscriberCustomField::create();
$association->subscriber_id = $subscriber->id;
$association->custom_field_id = $this->customField->id;
$association->value = 'test';
$association->save();
$customField = CustomField::findOne($this->customField->id);
$subscriber = $customField->subscribers()
->findOne();
expect($subscriber->value)->equals($association->value);
}
function _after() {
ORM::forTable(CustomField::$_table)
->deleteMany();
ORM::forTable(Subscriber::$_table)
->deleteMany();
ORM::forTable(SubscriberCustomField::$_table)
->deleteMany();
}
}

View File

@ -1,6 +1,8 @@
<?php
use MailPoet\Models\Subscriber;
use MailPoet\Models\CustomField;
use MailPoet\Models\Segment;
use MailPoet\Models\Subscriber;
use MailPoet\Models\SubscriberCustomField;
use MailPoet\Models\SubscriberSegment;
class SubscriberCest {
@ -11,7 +13,6 @@ class SubscriberCest {
'last_name' => 'Mailer',
'email' => 'john@mailpoet.com'
);
$this->subscriber = Subscriber::create();
$this->subscriber->hydrate($this->data);
$this->saved = $this->subscriber->save();
@ -21,7 +22,7 @@ class SubscriberCest {
expect($this->saved)->equals(true);
}
function itHasAFirstName() {
function itHasFirstName() {
$subscriber =
Subscriber::where('email', $this->data['email'])
->findOne();
@ -29,7 +30,7 @@ class SubscriberCest {
->equals($this->data['first_name']);
}
function itHasALastName() {
function itHasLastName() {
$subscriber =
Subscriber::where('email', $this->data['email'])
->findOne();
@ -37,7 +38,7 @@ class SubscriberCest {
->equals($this->data['last_name']);
}
function itHasAnEmail() {
function itHasEmail() {
$subscriber =
Subscriber::where('email', $this->data['email'])
->findOne();
@ -52,59 +53,60 @@ class SubscriberCest {
expect($saved)->notEquals(true);
}
function itHasAStatus() {
function itHasStatus() {
$subscriber =
Subscriber::where('email', $this->data['email'])
->findOne();
expect($subscriber->status)->equals('unconfirmed');
}
function itCanChangeStatus() {
$subscriber = Subscriber::where('email', $this->data['email'])->findOne();
$subscriber = Subscriber::where('email', $this->data['email'])
->findOne();
$subscriber->status = 'subscribed';
expect($subscriber->save())->equals(true);
$subscriber_updated = Subscriber::where(
'email',
$this->data['email']
)->findOne();
)
->findOne();
expect($subscriber_updated->status)->equals('subscribed');
}
function itHasASearchFilter() {
$subscriber = Subscriber::filter('search', 'john')->findOne();
function itHasSearchFilter() {
$subscriber = Subscriber::filter('search', 'john')
->findOne();
expect($subscriber->first_name)->equals($this->data['first_name']);
$subscriber = Subscriber::filter('search', 'mailer')->findOne();
$subscriber = Subscriber::filter('search', 'mailer')
->findOne();
expect($subscriber->last_name)->equals($this->data['last_name']);
$subscriber = Subscriber::filter('search', 'mailpoet')->findOne();
$subscriber = Subscriber::filter('search', 'mailpoet')
->findOne();
expect($subscriber->email)->equals($this->data['email']);
}
function itHasAGroupFilter() {
$subscribers = Subscriber::filter('groupBy', 'unconfirmed')->findMany();
foreach($subscribers as $subscriber) {
function itHasGroupFilter() {
$subscribers = Subscriber::filter('groupBy', 'unconfirmed')
->findMany();
foreach ($subscribers as $subscriber) {
expect($subscriber->status)->equals('unconfirmed');
}
$subscribers = Subscriber::filter('groupBy', 'subscribed')->findMany();
foreach($subscribers as $subscriber) {
$subscribers = Subscriber::filter('groupBy', 'subscribed')
->findMany();
foreach ($subscribers as $subscriber) {
expect($subscriber->status)->equals('subscribed');
}
$subscribers = Subscriber::filter('groupBy', 'unsubscribed')->findMany();
foreach($subscribers as $subscriber) {
$subscribers = Subscriber::filter('groupBy', 'unsubscribed')
->findMany();
foreach ($subscribers as $subscriber) {
expect($subscriber->status)->equals('unsubscribed');
}
}
function itCanHaveASegment() {
function itCanHaveSegment() {
$segmentData = array(
'name' => 'some name'
);
$segment = Segment::create();
$segment->hydrate($segmentData);
$segment->save();
@ -112,32 +114,46 @@ class SubscriberCest {
$association->subscriber_id = $this->subscriber->id;
$association->segment_id = $segment->id;
$association->save();
$subscriber = Subscriber::findOne($this->subscriber->id);
$subscriberSegment = $subscriber->segments()->findOne();
$subscriberSegment = $subscriber->segments()
->findOne();
expect($subscriberSegment->id)->equals($segment->id);
}
function itCanHaveCustomField() {
$customFieldData = array(
'name' => 'city'
);
$customField = CustomField::create();
$customField->hydrate($customFieldData);
$customField->save();
$association = SubscriberCustomField::create();
$association->subscriber_id = $this->subscriber->id;
$association->custom_field_id = $customField->id;
$association->save();
$subscriber = Subscriber::findOne($this->subscriber->id);
$subscriberCustomField = $subscriber->customFields()
->findOne();
expect($subscriberCustomField->id)->equals($customField->id);
}
function itCanCreateOrUpdate() {
$data = array(
'email' => 'john.doe@mailpoet.com',
'first_name' => 'John',
'last_name' => 'Doe'
);
$result = Subscriber::createOrUpdate($data);
expect($result)->equals(true);
$record = Subscriber::where('email', $data['email'])
->findOne();
expect($record->first_name)->equals($data['first_name']);
expect($record->last_name)->equals($data['last_name']);
$record->last_name = 'Mailer';
$result = Subscriber::createOrUpdate($record->asArray());
expect($result)->equals(true);
$record = Subscriber::where('email', $data['email'])->findOne();
$record = Subscriber::where('email', $data['email'])
->findOne();
expect($record->last_name)->equals('Mailer');
}
@ -148,5 +164,9 @@ class SubscriberCest {
->deleteMany();
ORM::forTable(SubscriberSegment::$_table)
->deleteMany();
ORM::forTable(CustomField::$_table)
->deleteMany();
ORM::forTable(SubscriberCustomField::$_table)
->deleteMany();
}
}

View File

@ -0,0 +1,69 @@
<?php
use MailPoet\Router\Mailer;
class MailerCest {
function __construct() {
$this->router = new Mailer();
}
function itCanConstruct() {
expect($this->router->from)->equals('Sender <staff@mailpoet.com>');
}
function itCanTransformSubscriber() {
expect($this->router->transformSubscriber('test@email.com'))
->equals('test@email.com');
expect($this->router->transformSubscriber(
array(
'email' => 'test@email.com'
))
)->equals('test@email.com');
expect($this->router->transformSubscriber(
array(
'first_name' => 'First',
'email' => 'test@email.com'
))
)->equals('First <test@email.com>');
expect($this->router->transformSubscriber(
array(
'last_name' => 'Last',
'email' => 'test@email.com'
))
)->equals('Last <test@email.com>');
expect($this->router->transformSubscriber(
array(
'first_name' => 'First',
'last_name' => 'Last',
'email' => 'test@email.com'
))
)->equals('First Last <test@email.com>');
}
function itCanConfigureMailer() {
$mailer = $this->router->buildMailer();
$class = 'Mailpoet\\Mailer\\' .
((isset($this->router->mailer['type'])) ?
$this->router->mailer['type'] . '\\' . $this->router->mailer['name'] :
$this->router->mailer['name']
);
expect($mailer instanceof $class)->true();
expect(method_exists($mailer, 'send'))->true();
}
function itCanSend() {
$newsletter = array(
'subject' => 'testing Mailer router with ' . $this->router->mailer['name'],
'body' => array(
'html' => 'HTML body',
'text' => 'TEXT body'
)
);
$subscriber = array(
'first_name' => 'First',
'last_name' => 'Last',
'email' => 'mailpoet-phoenix-test@mailinator.com'
);
expect($this->router->send($newsletter, $subscriber))->true();
}
}

View File

@ -1855,7 +1855,7 @@
customFieldsWindowTitle: '<%= __('Select a shortcode') %>',
unsubscribeLinkMissing: '<%= __('Please include an unsubscribe link to continue.') %>',
testEmailSent: '<%= __('Test email succesfully sent!') %>',
testEmailSent: '<%= __('Test email successfully sent!') %>',
unknownErrorOccurred: '<%= __('An unknown error occurred, please check your settings.') %>',
},
sidepanelWidth: '331px',

View File

@ -1236,7 +1236,7 @@
unsubscribeLinkMissing:
'<%= __('Please include an unsubscribe link to continue.') %>',
testEmailSent:
'<%= __('Test email succesfully sent!') %>',
'<%= __('Test email successfully sent!') %>',
unknownErrorOccurred:
'<%= __('An unknown error occurred, please check your settings.') %>',
},

View File

@ -1,7 +1,7 @@
<h3><%= __('Post selection') %></h3>
<div class="mailpoet_form_field">
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Show:') %></div>
<div class="mailpoet_form_field_title mailpoet_form_field_title_inline"><%= __('Show:') %></div>
<div class="mailpoet_form_field_input_option">
<input type="text" class="mailpoet_input mailpoet_input_small mailpoet_automated_latest_content_show_amount" value="{{ model.amount }}" />
<select class="mailpoet_select mailpoet_select_small mailpoet_automated_latest_content_content_type">