Files
piratepoet/tests/integration/Mailer/WordPress/WordpressMailerTest.php
Rodrigo Primo f8388c5497 Fix reply-to address when sending WP e-mails
This commit makes sure that the reply-to set for WP e-mails is
preserved when MailPoet is used to send them. Before this change,
MailPoet would ignore whatever was set for the reply-to field for WP
e-mails and use the same address as the one used for the sender instead.

I'm not super happy with the solution proposed here. I couldn't find an
easy way to simple set the reply-to address in the Mailer class and that
is why I'm calling Mailer::init() inside WordPressMailer.

[MAILPOET-3707]
2021-08-30 15:21:09 +02:00

372 lines
13 KiB
PHP

<?php
namespace MailPoet\Mailer\WordPress;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Mailer\Mailer;
use MailPoet\Mailer\MailerError;
use MailPoet\Mailer\MetaInfo;
use MailPoet\Settings\SettingsController;
use MailPoet\Subscribers\SubscribersRepository;
// phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
class WordpressMailerTest extends \MailPoetTest {
/** @var SubscribersRepository */
private $subscribersRepository;
public function _before() {
$this->subscribersRepository = $this->diContainer->get(SubscribersRepository::class);
$this->subscribersRepository->truncate();
}
public function testItdoesNotSendWhenPreSendCheckFails() {
$mailer = $this->createMock(Mailer::class);
$mailer->expects($this->never())->method('send');
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->From = 'email-from@example.com';
$this->expectException(\phpmailerException::class);
$wpMailer->send();
}
public function testItFormatsTextNewsletterForMailer() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->with($this->equalTo([
'subject' => 'Subject',
'body' => [
'text' => 'Email Text Body',
],
]))
->willReturn(['response' => true]);
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Subject = 'Subject';
$wpMailer->Body = 'Email Text Body';
$wpMailer->isHTML(false);
$wpMailer->send();
}
public function testItFormatsSubscriberForMailer() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->with($this->anything(), [
'full_name' => 'Full Name',
'address' => 'email@example.com',
])
->willReturn(['response' => true]);
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Subject = 'Subject';
$wpMailer->Body = 'Body';
$wpMailer->isHTML(false);
$wpMailer->send();
}
public function testItFormatsHtmlNewsletterForMailer() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->with($this->equalTo([
'subject' => 'Subject',
'body' => [
'text' => 'Email Html Body',
'html' => 'Email Html Body',
],
]))
->willReturn(['response' => true]);
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Subject = 'Subject';
$wpMailer->Body = 'Email Html Body';
$wpMailer->isHTML(true);
$wpMailer->send();
}
public function testItFormatsMultipartNewsletterForMailer() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->with($this->equalTo([
'subject' => 'Subject',
'body' => [
'text' => 'Email Text Body',
'html' => 'Email Html Body',
],
]))
->willReturn(['response' => true]);
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Subject = 'Subject';
$wpMailer->Body = 'Email Html Body';
$wpMailer->AltBody = 'Email Text Body';
$wpMailer->isHTML(true);
$wpMailer->ContentType = 'multipart/alternative';
$wpMailer->send();
}
public function testItReturnsOnSuccess() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->willReturn(['response' => true]);
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'body';
expect($wpMailer->send())->true();
}
public function testItUsesBackupMailerWhenPrimaryFails() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->willThrowException(new \Exception());
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer
->expects($this->once())
->method('send')
->willReturn(['response' => true]);
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'body';
expect($wpMailer->send())->true();
}
public function testItThrowsOnError() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->willReturn(['response' => false, 'error' => new MailerError('send', MailerError::LEVEL_HARD, 'Error from primary mailer')]);
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer
->expects($this->once())
->method('send')
->willReturn(['response' => false, 'error' => new MailerError('send', MailerError::LEVEL_HARD, 'Error from fallback mailer')]);
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'body';
$errorMessage = null;
try {
$wpMailer->send();
} catch (\phpmailerException $e) {
$errorMessage = $e->getMessage();
}
// ensure error from primary mailer is thrown
expect($errorMessage)->same('Error from primary mailer');
}
public function testItThrowsOnUnknownContentType() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->never())
->method('send');
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com');
$wpMailer->Body = 'body';
$wpMailer->From = 'email-from@example.com';
$wpMailer->ContentType = 'application/json';
$this->expectException(\phpmailerException::class);
$wpMailer->send();
}
public function testItTranslateExeceptionsToPhpmailerException() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->willThrowException(new \Exception('Exception from primary mailer'));
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer
->expects($this->once())
->method('send')
->willThrowException(new \Exception('Exception from fallback mailer'));
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'body';
$errorMessage = null;
try {
$wpMailer->send();
} catch (\phpmailerException $e) {
$errorMessage = $e->getMessage();
}
// ensure exception from primary mailer is thrown
expect($errorMessage)->same('Exception from primary mailer');
}
public function testItAddSubscriberMetaInfo() {
$mailer = $this->createMock(Mailer::class);
$mailer
->expects($this->once())
->method('send')
->with($this->anything(), $this->anything(), [
'meta' => [
'email_type' => 'transactional',
'subscriber_status' => 'subscribed',
'subscriber_source' => 'form',
],
])
->willReturn(['response' => true]);
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
$subscriber = new SubscriberEntity();
$subscriber->setEmail('email@example.com');
$subscriber->setStatus(SubscriberEntity::STATUS_SUBSCRIBED);
$subscriber->setSource('form');
$this->subscribersRepository->persist($subscriber);
$this->subscribersRepository->flush();
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->Subject = 'Subject';
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
}
/*
* Test for issue https://mailpoet.atlassian.net/browse/MAILPOET-3707
*/
public function testItPreservesWPReplyTo() {
list($mailer, $fallbackMailer) = $this->getMailerInstancesForReplyToTests();
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->addReplyTo('reply-to@example.com', 'Reply To');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
$mailer = $this->getPrivateProperty($wpMailer, 'mailer');
$this->assertEquals('reply-to@example.com', $mailer->replyTo['reply_to_email']);
$this->assertEquals('Reply To', $mailer->replyTo['reply_to_name']);
}
/*
* Test for issue https://mailpoet.atlassian.net/browse/MAILPOET-3707
*/
public function testItSetsSenderAsReplyToWhenReplyToIsNotDefined() {
list($mailer, $fallbackMailer) = $this->getMailerInstancesForReplyToTests();
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
$mailer = $this->getPrivateProperty($wpMailer, 'mailer');
$this->assertEquals('staff@mailinator.com', $mailer->replyTo['reply_to_email']);
$this->assertEquals('Sender', $mailer->replyTo['reply_to_name']);
}
/*
* Test for issue https://mailpoet.atlassian.net/browse/MAILPOET-3707
*/
public function testItChangesReplyToEmailOnDifferentCalls() {
list($mailer, $fallbackMailer) = $this->getMailerInstancesForReplyToTests();
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->addReplyTo('reply-to@example.com', 'Reply To');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
$mailer = $this->getPrivateProperty($wpMailer, 'mailer');
$this->assertEquals('reply-to@example.com', $mailer->replyTo['reply_to_email']);
$this->assertEquals('Reply To', $mailer->replyTo['reply_to_name']);
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
$mailer = $this->getPrivateProperty($wpMailer, 'mailer');
$this->assertEquals('staff@mailinator.com', $mailer->replyTo['reply_to_email']);
$this->assertEquals('Sender', $mailer->replyTo['reply_to_name']);
}
private function getMailerInstancesForReplyToTests() {
$settings = SettingsController::getInstance();
$settings->set(
'sender',
[
'name' => 'Sender',
'address' => 'staff@mailinator.com',
]
);
$mailer = new Mailer();
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
return [
$mailer,
$fallbackMailer,
];
}
private function getPrivateProperty($object, $property) {
$reflectedClass = new \ReflectionClass($object);
$reflection = $reflectedClass->getProperty($property);
$reflection->setAccessible(true);
return $reflection->getValue($object);
}
public function _after() {
$this->subscribersRepository->truncate();
}
}
// phpcs:enable