Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>tags/v26.0.0beta2
Subproject commit 1d53ed4d3282427854fca7ee6ecbb945304272db | |||||
Subproject commit b31aba0505a3daf84b016f52873794b618694dff |
return; | return; | ||||
} | } | ||||
$senderName = $iTipMessage->senderName ?: null; | |||||
$recipientName = $iTipMessage->recipientName ?: null; | $recipientName = $iTipMessage->recipientName ?: null; | ||||
/** @var Parameter|string|null $senderName */ | |||||
$senderName = $iTipMessage->senderName ?: null; | |||||
if($senderName instanceof Parameter) { | |||||
$senderName = $senderName->getValue() ?? null; | |||||
} | |||||
if ($senderName === null || empty(trim($senderName))) { | if ($senderName === null || empty(trim($senderName))) { | ||||
$senderName = $this->userManager->getDisplayName($this->userId); | $senderName = $this->userManager->getDisplayName($this->userId); | ||||
} | } |
* @param string $mail_smtpmode | * @param string $mail_smtpmode | ||||
* @param string $mail_smtpsecure | * @param string $mail_smtpsecure | ||||
* @param string $mail_smtphost | * @param string $mail_smtphost | ||||
* @param string $mail_smtpauthtype | |||||
* @param int $mail_smtpauth | * @param int $mail_smtpauth | ||||
* @param string $mail_smtpport | * @param string $mail_smtpport | ||||
* @return DataResponse | * @return DataResponse | ||||
$mail_smtpmode, | $mail_smtpmode, | ||||
$mail_smtpsecure, | $mail_smtpsecure, | ||||
$mail_smtphost, | $mail_smtphost, | ||||
$mail_smtpauthtype, | |||||
$mail_smtpauth, | $mail_smtpauth, | ||||
$mail_smtpport, | $mail_smtpport, | ||||
$mail_sendmailmode) { | $mail_sendmailmode) { |
'mail_smtpsecure' => $this->config->getSystemValue('mail_smtpsecure', ''), | 'mail_smtpsecure' => $this->config->getSystemValue('mail_smtpsecure', ''), | ||||
'mail_smtphost' => $this->config->getSystemValue('mail_smtphost', ''), | 'mail_smtphost' => $this->config->getSystemValue('mail_smtphost', ''), | ||||
'mail_smtpport' => $this->config->getSystemValue('mail_smtpport', ''), | 'mail_smtpport' => $this->config->getSystemValue('mail_smtpport', ''), | ||||
'mail_smtpauthtype' => $this->config->getSystemValue('mail_smtpauthtype', ''), | |||||
'mail_smtpauth' => $this->config->getSystemValue('mail_smtpauth', false), | 'mail_smtpauth' => $this->config->getSystemValue('mail_smtpauth', false), | ||||
'mail_smtpname' => $this->config->getSystemValue('mail_smtpname', ''), | 'mail_smtpname' => $this->config->getSystemValue('mail_smtpname', ''), | ||||
'mail_smtppassword' => $this->config->getSystemValue('mail_smtppassword', ''), | 'mail_smtppassword' => $this->config->getSystemValue('mail_smtppassword', ''), |
/** @var \OCP\IL10N $l */ | /** @var \OCP\IL10N $l */ | ||||
/** @var array $_ */ | /** @var array $_ */ | ||||
$mail_smtpauthtype = [ | |||||
'' => $l->t('None'), | |||||
'LOGIN' => $l->t('Login'), | |||||
'PLAIN' => $l->t('Plain'), | |||||
'NTLM' => $l->t('NT LAN Manager'), | |||||
]; | |||||
$mail_smtpsecure = [ | $mail_smtpsecure = [ | ||||
'' => $l->t('None'), | '' => $l->t('None'), | ||||
'ssl' => $l->t('SSL/TLS'), | |||||
'tls' => $l->t('STARTTLS'), | |||||
'ssl' => $l->t('SSL/TLS') | |||||
]; | ]; | ||||
$mail_smtpmode = [ | $mail_smtpmode = [ | ||||
value="<?php p($_['mail_domain']) ?>" /> | value="<?php p($_['mail_domain']) ?>" /> | ||||
</p> | </p> | ||||
<p id="setting_smtpauth" <?php if ($_['mail_smtpmode'] !== 'smtp') { | |||||
print_unescaped(' class="hidden"'); | |||||
} ?>> | |||||
<label for="mail_smtpauthtype"><?php p($l->t('Authentication method')); ?></label> | |||||
<select name="mail_smtpauthtype" id="mail_smtpauthtype"> | |||||
<?php foreach ($mail_smtpauthtype as $authtype => $name): | |||||
$selected = ''; | |||||
if ($authtype == $_['mail_smtpauthtype']): | |||||
$selected = 'selected="selected"'; | |||||
endif; ?> | |||||
<option value="<?php p($authtype)?>" <?php p($selected) ?>><?php p($name) ?></option> | |||||
<?php endforeach;?> | |||||
</select> | |||||
<input type="checkbox" name="mail_smtpauth" id="mail_smtpauth" class="checkbox" value="1" | |||||
<?php if ($_['mail_smtpauth']) { | |||||
print_unescaped('checked="checked"'); | |||||
} ?> /> | |||||
<label for="mail_smtpauth"><?php p($l->t('Authentication required')); ?></label> | |||||
</p> | |||||
<!--lo--> | |||||
<p id="setting_smtphost" <?php if ($_['mail_smtpmode'] !== 'smtp') { | <p id="setting_smtphost" <?php if ($_['mail_smtpmode'] !== 'smtp') { | ||||
print_unescaped(' class="hidden"'); | print_unescaped(' class="hidden"'); | ||||
</p> | </p> | ||||
</form> | </form> | ||||
<form class="mail_settings" id="mail_credentials_settings"> | <form class="mail_settings" id="mail_credentials_settings"> | ||||
<p id="mail_credentials" <?php if (!$_['mail_smtpauth'] || $_['mail_smtpmode'] !== 'smtp') { | |||||
<p id="mail_credentials" <?php if ($_['mail_smtpmode'] !== 'smtp') { | |||||
print_unescaped(' class="hidden"'); | print_unescaped(' class="hidden"'); | ||||
} ?>> | } ?>> | ||||
<label for="mail_smtpname"><?php p($l->t('Credentials')); ?></label> | <label for="mail_smtpname"><?php p($l->t('Credentials')); ?></label> |
'mail_smtpmode' => 'smtp', | 'mail_smtpmode' => 'smtp', | ||||
'mail_smtpsecure' => 'ssl', | 'mail_smtpsecure' => 'ssl', | ||||
'mail_smtphost' => 'mx.nextcloud.org', | 'mail_smtphost' => 'mx.nextcloud.org', | ||||
'mail_smtpauthtype' => 'NTLM', | |||||
'mail_smtpauth' => 1, | 'mail_smtpauth' => 1, | ||||
'mail_smtpport' => '25', | 'mail_smtpport' => '25', | ||||
'mail_sendmailmode' => null, | 'mail_sendmailmode' => null, | ||||
'mail_smtpmode' => 'smtp', | 'mail_smtpmode' => 'smtp', | ||||
'mail_smtpsecure' => 'ssl', | 'mail_smtpsecure' => 'ssl', | ||||
'mail_smtphost' => 'mx.nextcloud.org', | 'mail_smtphost' => 'mx.nextcloud.org', | ||||
'mail_smtpauthtype' => 'NTLM', | |||||
'mail_smtpauth' => null, | 'mail_smtpauth' => null, | ||||
'mail_smtpport' => '25', | 'mail_smtpport' => '25', | ||||
'mail_smtpname' => null, | 'mail_smtpname' => null, | ||||
'smtp', | 'smtp', | ||||
'ssl', | 'ssl', | ||||
'mx.nextcloud.org', | 'mx.nextcloud.org', | ||||
'NTLM', | |||||
1, | 1, | ||||
'25', | '25', | ||||
null | null | ||||
'smtp', | 'smtp', | ||||
'ssl', | 'ssl', | ||||
'mx.nextcloud.org', | 'mx.nextcloud.org', | ||||
'NTLM', | |||||
0, | 0, | ||||
'25', | '25', | ||||
null | null |
['mail_smtpsecure', '', true], | ['mail_smtpsecure', '', true], | ||||
['mail_smtphost', '', 'smtp.nextcloud.com'], | ['mail_smtphost', '', 'smtp.nextcloud.com'], | ||||
['mail_smtpport', '', 25], | ['mail_smtpport', '', 25], | ||||
['mail_smtpauthtype', '', 'login'], | |||||
['mail_smtpauth', false, true], | ['mail_smtpauth', false, true], | ||||
['mail_smtpname', '', 'smtp.sender.com'], | ['mail_smtpname', '', 'smtp.sender.com'], | ||||
['mail_smtppassword', '', 'mypassword'], | ['mail_smtppassword', '', 'mypassword'], | ||||
'mail_smtpsecure' => true, | 'mail_smtpsecure' => true, | ||||
'mail_smtphost' => 'smtp.nextcloud.com', | 'mail_smtphost' => 'smtp.nextcloud.com', | ||||
'mail_smtpport' => 25, | 'mail_smtpport' => 25, | ||||
'mail_smtpauthtype' => 'login', | |||||
'mail_smtpauth' => true, | 'mail_smtpauth' => true, | ||||
'mail_smtpname' => 'smtp.sender.com', | 'mail_smtpname' => 'smtp.sender.com', | ||||
'mail_smtppassword' => '********', | 'mail_smtppassword' => '********', |
'mail_smtptimeout' => 10, | 'mail_smtptimeout' => 10, | ||||
/** | /** | ||||
* This depends on ``mail_smtpmode``. Specify when you are using ``ssl`` for SSL/TLS or | |||||
* ``tls`` for STARTTLS, or leave empty for no encryption. | |||||
* This depends on ``mail_smtpmode``. Specify ``ssl`` when you are using SSL/TLS. Any other value will be ignored. | |||||
* | |||||
* If the server advertises STARTTLS capabilities, they might be used, but they cannot be enforced by | |||||
* this config option. | |||||
* | * | ||||
* Defaults to ``''`` (empty string) | * Defaults to ``''`` (empty string) | ||||
*/ | */ | ||||
'mail_smtpsecure' => '', | 'mail_smtpsecure' => '', | ||||
/** | /** | ||||
* | |||||
* This depends on ``mail_smtpmode``. Change this to ``true`` if your mail | * This depends on ``mail_smtpmode``. Change this to ``true`` if your mail | ||||
* server requires authentication. | * server requires authentication. | ||||
* | * | ||||
*/ | */ | ||||
'mail_smtpauth' => false, | 'mail_smtpauth' => false, | ||||
/** | |||||
* This depends on ``mail_smtpmode``. If SMTP authentication is required, choose | |||||
* the authentication type as ``LOGIN`` or ``PLAIN``. | |||||
* | |||||
* Defaults to ``LOGIN`` | |||||
*/ | |||||
'mail_smtpauthtype' => 'LOGIN', | |||||
/** | /** | ||||
* This depends on ``mail_smtpauth``. Specify the username for authenticating to | * This depends on ``mail_smtpauth``. Specify the username for authenticating to | ||||
* the SMTP server. | * the SMTP server. | ||||
'preview_office_cl_parameters' => | 'preview_office_cl_parameters' => | ||||
' --headless --nologo --nofirststartwizard --invisible --norestore '. | ' --headless --nologo --nofirststartwizard --invisible --norestore '. | ||||
'--convert-to png --outdir ', | '--convert-to png --outdir ', | ||||
/** | /** | ||||
* custom path for ffmpeg binary | * custom path for ffmpeg binary | ||||
* | |||||
* | |||||
* Defaults to ``null`` and falls back to searching ``avconv`` and ``ffmpeg`` in the configured ``PATH`` environment | * Defaults to ``null`` and falls back to searching ``avconv`` and ``ffmpeg`` in the configured ``PATH`` environment | ||||
*/ | */ | ||||
'preview_ffmpeg_path' => '/usr/bin/ffmpeg', | |||||
'preview_ffmpeg_path' => '/usr/bin/ffmpeg', | |||||
/** | /** | ||||
* Set the URL of the Imaginary service to send image previews to. | * Set the URL of the Imaginary service to send image previews to. | ||||
* Also requires the ``OC\Preview\Imaginary`` provider to be enabled. | * Also requires the ``OC\Preview\Imaginary`` provider to be enabled. |
namespace OC\Mail; | namespace OC\Mail; | ||||
use OCP\Mail\IAttachment; | use OCP\Mail\IAttachment; | ||||
use Symfony\Component\Mime\Email; | |||||
/** | /** | ||||
* Class Attachment | * Class Attachment | ||||
* @since 13.0.0 | * @since 13.0.0 | ||||
*/ | */ | ||||
class Attachment implements IAttachment { | class Attachment implements IAttachment { | ||||
/** @var \Swift_Mime_Attachment */ | |||||
protected $swiftAttachment; | |||||
private ?string $body; | |||||
private ?string $name; | |||||
private ?string $contentType; | |||||
private ?string $path; | |||||
public function __construct(\Swift_Mime_Attachment $attachment) { | |||||
$this->swiftAttachment = $attachment; | |||||
public function __construct( | |||||
?string $body, | |||||
?string $name, | |||||
?string $contentType, | |||||
?string $path = null | |||||
) { | |||||
$this->body = $body; | |||||
$this->name = $name; | |||||
$this->contentType = $contentType; | |||||
$this->path = $path; | |||||
} | } | ||||
/** | /** | ||||
* @since 13.0.0 | * @since 13.0.0 | ||||
*/ | */ | ||||
public function setFilename(string $filename): IAttachment { | public function setFilename(string $filename): IAttachment { | ||||
$this->swiftAttachment->setFilename($filename); | |||||
$this->name = $filename; | |||||
return $this; | return $this; | ||||
} | } | ||||
* @since 13.0.0 | * @since 13.0.0 | ||||
*/ | */ | ||||
public function setContentType(string $contentType): IAttachment { | public function setContentType(string $contentType): IAttachment { | ||||
$this->swiftAttachment->setContentType($contentType); | |||||
$this->contentType = $contentType; | |||||
return $this; | return $this; | ||||
} | } | ||||
* @since 13.0.0 | * @since 13.0.0 | ||||
*/ | */ | ||||
public function setBody(string $body): IAttachment { | public function setBody(string $body): IAttachment { | ||||
$this->swiftAttachment->setBody($body); | |||||
$this->body = $body; | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | |||||
* @return \Swift_Mime_Attachment | |||||
*/ | |||||
public function getSwiftAttachment(): \Swift_Mime_Attachment { | |||||
return $this->swiftAttachment; | |||||
public function attach(Email $symfonyEmail): void { | |||||
if ($this->path !== null) { | |||||
$symfonyEmail->attachFromPath($this->path, $this->name, $this->contentType); | |||||
} else { | |||||
$symfonyEmail->attach($this->body, $this->name, $this->contentType); | |||||
} | |||||
} | } | ||||
} | } |
use OCP\Mail\IMailer; | use OCP\Mail\IMailer; | ||||
use OCP\Mail\IMessage; | use OCP\Mail\IMessage; | ||||
use Psr\Log\LoggerInterface; | use Psr\Log\LoggerInterface; | ||||
use Symfony\Component\Mailer\Exception\TransportExceptionInterface; | |||||
use Symfony\Component\Mailer\Mailer as SymfonyMailer; | |||||
use Symfony\Component\Mailer\MailerInterface; | |||||
use Symfony\Component\Mailer\Transport\SendmailTransport; | |||||
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; | |||||
use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; | |||||
use Symfony\Component\Mime\Email; | |||||
use Symfony\Component\Mime\Exception\InvalidArgumentException; | |||||
use Symfony\Component\Mime\Exception\RfcComplianceException; | |||||
/** | /** | ||||
* Class Mailer provides some basic functions to create a mail message that can be used in combination with | * Class Mailer provides some basic functions to create a mail message that can be used in combination with | ||||
* @package OC\Mail | * @package OC\Mail | ||||
*/ | */ | ||||
class Mailer implements IMailer { | class Mailer implements IMailer { | ||||
/** @var \Swift_Mailer Cached mailer */ | |||||
private $instance = null; | |||||
private ?MailerInterface $instance = null; | |||||
private IConfig $config; | private IConfig $config; | ||||
private LoggerInterface $logger; | private LoggerInterface $logger; | ||||
/** @var Defaults */ | |||||
private $defaults; | |||||
private Defaults $defaults; | |||||
private IURLGenerator $urlGenerator; | private IURLGenerator $urlGenerator; | ||||
private IL10N $l10n; | private IL10N $l10n; | ||||
private IEventDispatcher $dispatcher; | private IEventDispatcher $dispatcher; | ||||
/** | /** | ||||
* Creates a new message object that can be passed to send() | * Creates a new message object that can be passed to send() | ||||
* | * | ||||
* @return IMessage | |||||
* @return Message | |||||
*/ | */ | ||||
public function createMessage(): IMessage { | |||||
public function createMessage(): Message { | |||||
$plainTextOnly = $this->config->getSystemValue('mail_send_plaintext_only', false); | $plainTextOnly = $this->config->getSystemValue('mail_send_plaintext_only', false); | ||||
return new Message(new \Swift_Message(), $plainTextOnly); | |||||
return new Message(new Email(), $plainTextOnly); | |||||
} | } | ||||
/** | /** | ||||
* @since 13.0.0 | * @since 13.0.0 | ||||
*/ | */ | ||||
public function createAttachment($data = null, $filename = null, $contentType = null): IAttachment { | public function createAttachment($data = null, $filename = null, $contentType = null): IAttachment { | ||||
return new Attachment(new \Swift_Attachment($data, $filename, $contentType)); | |||||
return new Attachment($data, $filename, $contentType); | |||||
} | } | ||||
/** | /** | ||||
* @since 13.0.0 | * @since 13.0.0 | ||||
*/ | */ | ||||
public function createAttachmentFromPath(string $path, $contentType = null): IAttachment { | public function createAttachmentFromPath(string $path, $contentType = null): IAttachment { | ||||
return new Attachment(\Swift_Attachment::fromPath($path, $contentType)); | |||||
return new Attachment(null, null, $contentType, $path); | |||||
} | } | ||||
/** | /** | ||||
* Send the specified message. Also sets the from address to the value defined in config.php | * Send the specified message. Also sets the from address to the value defined in config.php | ||||
* if no-one has been passed. | * if no-one has been passed. | ||||
* | * | ||||
* @param IMessage|Message $message Message to send | |||||
* @return string[] Array with failed recipients. Be aware that this depends on the used mail backend and | |||||
* therefore should be considered | |||||
* @throws \Exception In case it was not possible to send the message. (for example if an invalid mail address | |||||
* has been supplied.) | |||||
* If sending failed, the recipients that failed will be returned (to, cc and bcc). | |||||
* Will output additional debug info if 'mail_smtpdebug' => 'true' is set in config.php | |||||
* | |||||
* @param IMessage $message Message to send | |||||
* @return string[] $failedRecipients | |||||
*/ | */ | ||||
public function send(IMessage $message): array { | public function send(IMessage $message): array { | ||||
$debugMode = $this->config->getSystemValue('mail_smtpdebug', false); | $debugMode = $this->config->getSystemValue('mail_smtpdebug', false); | ||||
if (!($message instanceof Message)) { | |||||
throw new InvalidArgumentException('Object not of type ' . Message::class); | |||||
} | |||||
if (empty($message->getFrom())) { | if (empty($message->getFrom())) { | ||||
$message->setFrom([\OCP\Util::getDefaultEmailAddress('no-reply') => $this->defaults->getName()]); | $message->setFrom([\OCP\Util::getDefaultEmailAddress('no-reply') => $this->defaults->getName()]); | ||||
} | } | ||||
$failedRecipients = []; | |||||
$mailer = $this->getInstance(); | $mailer = $this->getInstance(); | ||||
// Enable logger if debug mode is enabled | |||||
if ($debugMode) { | |||||
$mailLogger = new \Swift_Plugins_Loggers_ArrayLogger(); | |||||
$mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($mailLogger)); | |||||
} | |||||
$this->dispatcher->dispatchTyped(new BeforeMessageSent($message)); | |||||
try { | |||||
$message->setRecipients(); | |||||
} catch (InvalidArgumentException|RfcComplianceException $e) { | |||||
$logMessage = sprintf( | |||||
'Could not send mail to "%s" with subject "%s" as validation for address failed', | |||||
print_r(array_merge($message->getTo(), $message->getCc(), $message->getBcc()), true), | |||||
$message->getSubject() | |||||
); | |||||
$this->logger->debug($logMessage, ['app' => 'core', 'exception' => $e]); | |||||
$recipients = array_merge($message->getTo(), $message->getCc(), $message->getBcc()); | |||||
$failedRecipients = []; | |||||
array_walk($recipients, function ($value, $key) use (&$failedRecipients) { | |||||
if (is_numeric($key)) { | |||||
$failedRecipients[] = $value; | |||||
} else { | |||||
$failedRecipients[] = $key; | |||||
} | |||||
}); | |||||
$this->dispatcher->dispatchTyped(new BeforeMessageSent($message)); | |||||
return $failedRecipients; | |||||
} | |||||
$mailer->send($message->getSwiftMessage(), $failedRecipients); | |||||
try { | |||||
$mailer->send($message->getSymfonyEmail()); | |||||
} catch (TransportExceptionInterface $e) { | |||||
$logMessage = sprintf('Sending mail to "%s" with subject "%s" failed', print_r($message->getTo(), true), $message->getSubject()); | |||||
$this->logger->debug($logMessage, ['app' => 'core', 'exception' => $e]); | |||||
if ($debugMode) { | |||||
$this->logger->debug($e->getDebug(), ['app' => 'core']); | |||||
} | |||||
$recipients = array_merge($message->getTo(), $message->getCc(), $message->getBcc()); | |||||
$failedRecipients = []; | |||||
array_walk($recipients, function ($value, $key) use (&$failedRecipients) { | |||||
if (is_numeric($key)) { | |||||
$failedRecipients[] = $value; | |||||
} else { | |||||
$failedRecipients[] = $key; | |||||
} | |||||
}); | |||||
return $failedRecipients; | |||||
} | |||||
// Debugging logging | // Debugging logging | ||||
$logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject()); | $logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject()); | ||||
if (!empty($failedRecipients)) { | |||||
$logMessage .= sprintf(' (failed for "%s")', print_r($failedRecipients, true)); | |||||
} | |||||
$this->logger->debug($logMessage, ['app' => 'core']); | $this->logger->debug($logMessage, ['app' => 'core']); | ||||
if ($debugMode && isset($mailLogger)) { | |||||
$this->logger->debug($mailLogger->dump(), ['app' => 'core']); | |||||
} | |||||
return $failedRecipients; | |||||
return []; | |||||
} | } | ||||
/** | /** | ||||
* Checks if an e-mail address is valid | |||||
* @deprecated 26.0.0 Implicit validation is done in \OC\Mail\Message::setRecipients | |||||
* via \Symfony\Component\Mime\Address::__construct | |||||
* | * | ||||
* @param string $email Email address to be validated | * @param string $email Email address to be validated | ||||
* @return bool True if the mail address is valid, false otherwise | * @return bool True if the mail address is valid, false otherwise | ||||
$validator = new EmailValidator(); | $validator = new EmailValidator(); | ||||
$validation = new RFCValidation(); | $validation = new RFCValidation(); | ||||
return $validator->isValid($this->convertEmail($email), $validation); | |||||
return $validator->isValid($email, $validation); | |||||
} | } | ||||
/** | |||||
* SwiftMailer does currently not work with IDN domains, this function therefore converts the domains | |||||
* | |||||
* FIXME: Remove this once SwiftMailer supports IDN | |||||
* | |||||
* @param string $email | |||||
* @return string Converted mail address if `idn_to_ascii` exists | |||||
*/ | |||||
protected function convertEmail(string $email): string { | |||||
if (!function_exists('idn_to_ascii') || !defined('INTL_IDNA_VARIANT_UTS46') || strpos($email, '@') === false) { | |||||
return $email; | |||||
} | |||||
[$name, $domain] = explode('@', $email, 2); | |||||
$domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46); | |||||
return $name.'@'.$domain; | |||||
} | |||||
protected function getInstance(): \Swift_Mailer { | |||||
protected function getInstance(): MailerInterface { | |||||
if (!is_null($this->instance)) { | if (!is_null($this->instance)) { | ||||
return $this->instance; | return $this->instance; | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
return new \Swift_Mailer($transport); | |||||
return new SymfonyMailer($transport); | |||||
} | } | ||||
/** | /** | ||||
* Returns the SMTP transport | * Returns the SMTP transport | ||||
* | * | ||||
* @return \Swift_SmtpTransport | |||||
* Only supports ssl/tls | |||||
* starttls is not enforcable with Symfony Mailer but might be available | |||||
* via the automatic config (Symfony Mailer internal) | |||||
* | |||||
* @return EsmtpTransport | |||||
*/ | */ | ||||
protected function getSmtpInstance(): \Swift_SmtpTransport { | |||||
$transport = new \Swift_SmtpTransport(); | |||||
$transport->setTimeout($this->config->getSystemValue('mail_smtptimeout', 10)); | |||||
$transport->setHost($this->config->getSystemValue('mail_smtphost', '127.0.0.1')); | |||||
$transport->setPort($this->config->getSystemValue('mail_smtpport', 25)); | |||||
protected function getSmtpInstance(): EsmtpTransport { | |||||
// either null or true - if nothing is passed, let the symfony mailer figure out the configuration by itself | |||||
$mailSmtpsecure = ($this->config->getSystemValue('mail_smtpsecure', null) === 'ssl') ? true : null; | |||||
$transport = new EsmtpTransport( | |||||
$this->config->getSystemValue('mail_smtphost', '127.0.0.1'), | |||||
(int)$this->config->getSystemValue('mail_smtpport', 25), | |||||
$mailSmtpsecure, | |||||
null, | |||||
$this->logger | |||||
); | |||||
/** @var SocketStream $stream */ | |||||
$stream = $transport->getStream(); | |||||
/** @psalm-suppress InternalMethod */ | |||||
$stream->setTimeout($this->config->getSystemValue('mail_smtptimeout', 10)); | |||||
if ($this->config->getSystemValue('mail_smtpauth', false)) { | if ($this->config->getSystemValue('mail_smtpauth', false)) { | ||||
$transport->setUsername($this->config->getSystemValue('mail_smtpname', '')); | $transport->setUsername($this->config->getSystemValue('mail_smtpname', '')); | ||||
$transport->setPassword($this->config->getSystemValue('mail_smtppassword', '')); | $transport->setPassword($this->config->getSystemValue('mail_smtppassword', '')); | ||||
$transport->setAuthMode($this->config->getSystemValue('mail_smtpauthtype', 'LOGIN')); | |||||
} | |||||
$smtpSecurity = $this->config->getSystemValue('mail_smtpsecure', ''); | |||||
if (!empty($smtpSecurity)) { | |||||
$transport->setEncryption($smtpSecurity); | |||||
} | } | ||||
$streamingOptions = $this->config->getSystemValue('mail_smtpstreamoptions', []); | $streamingOptions = $this->config->getSystemValue('mail_smtpstreamoptions', []); | ||||
if (is_array($streamingOptions) && !empty($streamingOptions)) { | if (is_array($streamingOptions) && !empty($streamingOptions)) { | ||||
$transport->setStreamOptions($streamingOptions); | |||||
/** @psalm-suppress InternalMethod */ | |||||
$currentStreamingOptions = $stream->getStreamOptions(); | |||||
$currentStreamingOptions = array_merge_recursive($currentStreamingOptions, $streamingOptions); | |||||
/** @psalm-suppress InternalMethod */ | |||||
$stream->setStreamOptions($currentStreamingOptions); | |||||
} | } | ||||
$overwriteCliUrl = parse_url( | $overwriteCliUrl = parse_url( | ||||
/** | /** | ||||
* Returns the sendmail transport | * Returns the sendmail transport | ||||
* | * | ||||
* @return \Swift_SendmailTransport | |||||
* @return SendmailTransport | |||||
*/ | */ | ||||
protected function getSendMailInstance(): \Swift_SendmailTransport { | |||||
protected function getSendMailInstance(): SendmailTransport { | |||||
switch ($this->config->getSystemValue('mail_smtpmode', 'smtp')) { | switch ($this->config->getSystemValue('mail_smtpmode', 'smtp')) { | ||||
case 'qmail': | case 'qmail': | ||||
$binaryPath = '/var/qmail/bin/sendmail'; | $binaryPath = '/var/qmail/bin/sendmail'; | ||||
break; | break; | ||||
} | } | ||||
return new \Swift_SendmailTransport($binaryPath . $binaryParam); | |||||
return new SendmailTransport($binaryPath . $binaryParam, null, $this->logger); | |||||
} | } | ||||
} | } |
use OCP\Mail\IAttachment; | use OCP\Mail\IAttachment; | ||||
use OCP\Mail\IEMailTemplate; | use OCP\Mail\IEMailTemplate; | ||||
use OCP\Mail\IMessage; | use OCP\Mail\IMessage; | ||||
use Swift_Message; | |||||
use Symfony\Component\Mime\Address; | |||||
use Symfony\Component\Mime\Email; | |||||
use Symfony\Component\Mime\Exception\InvalidArgumentException; | |||||
use Symfony\Component\Mime\Exception\RfcComplianceException; | |||||
/** | /** | ||||
* Class Message provides a wrapper around SwiftMail | |||||
* Class Message provides a wrapper around Symfony\Component\Mime\Email (Used to be around SwiftMail) | |||||
* | * | ||||
* @package OC\Mail | * @package OC\Mail | ||||
*/ | */ | ||||
class Message implements IMessage { | class Message implements IMessage { | ||||
/** @var Swift_Message */ | |||||
private $swiftMessage; | |||||
/** @var bool */ | |||||
private $plainTextOnly; | |||||
private Email $symfonyEmail; | |||||
private bool $plainTextOnly; | |||||
public function __construct(Swift_Message $swiftMessage, bool $plainTextOnly) { | |||||
$this->swiftMessage = $swiftMessage; | |||||
private array $to; | |||||
private array $from; | |||||
private array $replyTo; | |||||
private array $cc; | |||||
private array $bcc; | |||||
public function __construct(Email $symfonyEmail, bool $plainTextOnly) { | |||||
$this->symfonyEmail = $symfonyEmail; | |||||
$this->plainTextOnly = $plainTextOnly; | $this->plainTextOnly = $plainTextOnly; | ||||
$this->to = []; | |||||
$this->from = []; | |||||
$this->replyTo = []; | |||||
$this->cc = []; | |||||
$this->bcc = []; | |||||
} | } | ||||
/** | /** | ||||
* @param IAttachment $attachment | |||||
* @return $this | * @return $this | ||||
* @since 13.0.0 | * @since 13.0.0 | ||||
*/ | */ | ||||
public function attach(IAttachment $attachment): IMessage { | public function attach(IAttachment $attachment): IMessage { | ||||
/** @var Attachment $attachment */ | /** @var Attachment $attachment */ | ||||
$this->swiftMessage->attach($attachment->getSwiftAttachment()); | |||||
$attachment->attach($this->symfonyEmail); | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* SwiftMailer does currently not work with IDN domains, this function therefore converts the domains | |||||
* FIXME: Remove this once SwiftMailer supports IDN | |||||
* Converts the [['displayName' => 'email'], ['displayName2' => 'email2']] arrays to valid Adresses | |||||
* | * | ||||
* @param array $addresses Array of mail addresses, key will get converted | |||||
* @return array Converted addresses if `idn_to_ascii` exists | |||||
* @param array $addresses Array of mail addresses | |||||
* @return Address[] | |||||
* @throws RfcComplianceException|InvalidArgumentException | |||||
*/ | */ | ||||
protected function convertAddresses(array $addresses): array { | protected function convertAddresses(array $addresses): array { | ||||
if (!function_exists('idn_to_ascii') || !defined('INTL_IDNA_VARIANT_UTS46')) { | |||||
return $addresses; | |||||
} | |||||
$convertedAddresses = []; | $convertedAddresses = []; | ||||
foreach ($addresses as $email => $readableName) { | |||||
$parsableEmail = is_numeric($email) ? $readableName : $email; | |||||
if (strpos($parsableEmail, '@') === false) { | |||||
$convertedAddresses[$parsableEmail] = $readableName; | |||||
continue; | |||||
} | |||||
if (empty($addresses)) { | |||||
return []; | |||||
} | |||||
[$name, $domain] = explode('@', $parsableEmail, 2); | |||||
$domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46); | |||||
array_walk($addresses, function ($readableName, $email) use (&$convertedAddresses) { | |||||
if (is_numeric($email)) { | if (is_numeric($email)) { | ||||
$convertedAddresses[] = $name . '@' . $domain; | |||||
$convertedAddresses[] = new Address($readableName); | |||||
} else { | } else { | ||||
$convertedAddresses[$name . '@' . $domain] = $readableName; | |||||
$convertedAddresses[] = new Address($email, $readableName); | |||||
} | } | ||||
} | |||||
}); | |||||
return $convertedAddresses; | return $convertedAddresses; | ||||
} | } | ||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setFrom(array $addresses): IMessage { | public function setFrom(array $addresses): IMessage { | ||||
$addresses = $this->convertAddresses($addresses); | |||||
$this->swiftMessage->setFrom($addresses); | |||||
$this->from = $addresses; | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Get the from address of this message. | * Get the from address of this message. | ||||
* | |||||
* @return array | |||||
*/ | */ | ||||
public function getFrom(): array { | public function getFrom(): array { | ||||
return $this->swiftMessage->getFrom() ?? []; | |||||
return $this->from; | |||||
} | } | ||||
/** | /** | ||||
* Set the Reply-To address of this message | * Set the Reply-To address of this message | ||||
* | * | ||||
* @param array $addresses | |||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setReplyTo(array $addresses): IMessage { | public function setReplyTo(array $addresses): IMessage { | ||||
$addresses = $this->convertAddresses($addresses); | |||||
$this->swiftMessage->setReplyTo($addresses); | |||||
$this->replyTo = $addresses; | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Returns the Reply-To address of this message | * Returns the Reply-To address of this message | ||||
* | |||||
* @return string | |||||
*/ | */ | ||||
public function getReplyTo(): string { | |||||
return $this->swiftMessage->getReplyTo(); | |||||
public function getReplyTo(): array { | |||||
return $this->replyTo; | |||||
} | } | ||||
/** | /** | ||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setTo(array $recipients): IMessage { | public function setTo(array $recipients): IMessage { | ||||
$recipients = $this->convertAddresses($recipients); | |||||
$this->swiftMessage->setTo($recipients); | |||||
$this->to = $recipients; | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Get the to address of this message. | * Get the to address of this message. | ||||
* | |||||
* @return array | |||||
*/ | */ | ||||
public function getTo(): array { | public function getTo(): array { | ||||
return $this->swiftMessage->getTo() ?? []; | |||||
return $this->to; | |||||
} | } | ||||
/** | /** | ||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setCc(array $recipients): IMessage { | public function setCc(array $recipients): IMessage { | ||||
$recipients = $this->convertAddresses($recipients); | |||||
$this->swiftMessage->setCc($recipients); | |||||
$this->cc = $recipients; | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Get the cc address of this message. | * Get the cc address of this message. | ||||
* | |||||
* @return array | |||||
*/ | */ | ||||
public function getCc(): array { | public function getCc(): array { | ||||
return $this->swiftMessage->getCc() ?? []; | |||||
return $this->cc; | |||||
} | } | ||||
/** | /** | ||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setBcc(array $recipients): IMessage { | public function setBcc(array $recipients): IMessage { | ||||
$recipients = $this->convertAddresses($recipients); | |||||
$this->swiftMessage->setBcc($recipients); | |||||
$this->bcc = $recipients; | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Get the Bcc address of this message. | * Get the Bcc address of this message. | ||||
* | |||||
* @return array | |||||
*/ | */ | ||||
public function getBcc(): array { | public function getBcc(): array { | ||||
return $this->swiftMessage->getBcc() ?? []; | |||||
return $this->bcc; | |||||
} | } | ||||
/** | /** | ||||
* Set the subject of this message. | * Set the subject of this message. | ||||
* | * | ||||
* @param string $subject | |||||
* @return IMessage | |||||
* @return $this | |||||
*/ | */ | ||||
public function setSubject(string $subject): IMessage { | public function setSubject(string $subject): IMessage { | ||||
$this->swiftMessage->setSubject($subject); | |||||
$this->symfonyEmail->subject($subject); | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Get the from subject of this message. | * Get the from subject of this message. | ||||
* | |||||
* @return string | |||||
*/ | */ | ||||
public function getSubject(): string { | public function getSubject(): string { | ||||
return $this->swiftMessage->getSubject(); | |||||
return $this->symfonyEmail->getSubject() ?? ''; | |||||
} | } | ||||
/** | /** | ||||
* Set the plain-text body of this message. | * Set the plain-text body of this message. | ||||
* | |||||
* @param string $body | |||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setPlainBody(string $body): IMessage { | public function setPlainBody(string $body): IMessage { | ||||
$this->swiftMessage->setBody($body); | |||||
$this->symfonyEmail->text($body); | |||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Get the plain body of this message. | * Get the plain body of this message. | ||||
* | |||||
* @return string | |||||
*/ | */ | ||||
public function getPlainBody(): string { | public function getPlainBody(): string { | ||||
return $this->swiftMessage->getBody(); | |||||
/** @var string $body */ | |||||
$body = $this->symfonyEmail->getTextBody() ?? ''; | |||||
return $body; | |||||
} | } | ||||
/** | /** | ||||
* Set the HTML body of this message. Consider also sending a plain-text body instead of only an HTML one. | * Set the HTML body of this message. Consider also sending a plain-text body instead of only an HTML one. | ||||
* | |||||
* @param string $body | |||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setHtmlBody($body) { | |||||
public function setHtmlBody(string $body): IMessage { | |||||
if (!$this->plainTextOnly) { | if (!$this->plainTextOnly) { | ||||
$this->swiftMessage->addPart($body, 'text/html'); | |||||
$this->symfonyEmail->html($body); | |||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Get's the underlying SwiftMessage | |||||
* @param Swift_Message $swiftMessage | |||||
* Set the underlying Email intance | |||||
*/ | */ | ||||
public function setSwiftMessage(Swift_Message $swiftMessage): void { | |||||
$this->swiftMessage = $swiftMessage; | |||||
public function setSymfonyEmail(Email $symfonyEmail): void { | |||||
$this->symfonyEmail = $symfonyEmail; | |||||
} | } | ||||
/** | /** | ||||
* Get's the underlying SwiftMessage | |||||
* @return Swift_Message | |||||
* Get the underlying Email instance | |||||
*/ | */ | ||||
public function getSwiftMessage(): Swift_Message { | |||||
return $this->swiftMessage; | |||||
public function getSymfonyEmail(): Email { | |||||
return $this->symfonyEmail; | |||||
} | } | ||||
/** | /** | ||||
* @param string $body | |||||
* @param string $contentType | |||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setBody($body, $contentType) { | |||||
public function setBody(string $body, string $contentType): IMessage { | |||||
if (!$this->plainTextOnly || $contentType !== 'text/html') { | if (!$this->plainTextOnly || $contentType !== 'text/html') { | ||||
$this->swiftMessage->setBody($body, $contentType); | |||||
if ($contentType === 'text/html') { | |||||
$this->symfonyEmail->html($body); | |||||
} else { | |||||
$this->symfonyEmail->text($body); | |||||
} | |||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* @param IEMailTemplate $emailTemplate | |||||
* Set the recipients on the symphony email | |||||
* | |||||
* Since | |||||
* | |||||
* setTo | |||||
* setFrom | |||||
* setReplyTo | |||||
* setCc | |||||
* setBcc | |||||
* | |||||
* could throw a \Symfony\Component\Mime\Exception\RfcComplianceException | |||||
* or a \Symfony\Component\Mime\Exception\InvalidArgumentException | |||||
* we wrap the calls here. We then have the validation errors all in one place and can | |||||
* throw shortly before \OC\Mail\Mailer::send | |||||
* | |||||
* @return void | |||||
* @throws InvalidArgumentException|RfcComplianceException | |||||
*/ | |||||
public function setRecipients() { | |||||
$this->symfonyEmail->to(...$this->convertAddresses($this->getTo())); | |||||
$this->symfonyEmail->from(...$this->convertAddresses($this->getFrom())); | |||||
$this->symfonyEmail->replyTo(...$this->convertAddresses($this->getReplyTo())); | |||||
$this->symfonyEmail->cc(...$this->convertAddresses($this->getCc())); | |||||
$this->symfonyEmail->bcc(...$this->convertAddresses($this->getBcc())); | |||||
} | |||||
/** | |||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function useTemplate(IEMailTemplate $emailTemplate): IMessage { | public function useTemplate(IEMailTemplate $emailTemplate): IMessage { | ||||
* @return $this | * @return $this | ||||
*/ | */ | ||||
public function setAutoSubmitted(string $value): IMessage { | public function setAutoSubmitted(string $value): IMessage { | ||||
$headers = $this->swiftMessage->getHeaders(); | |||||
$headers = $this->symfonyEmail->getHeaders(); | |||||
if ($headers->has(AutoSubmitted::HEADER)) { | if ($headers->has(AutoSubmitted::HEADER)) { | ||||
// if the header already exsists, remove it. | // if the header already exsists, remove it. | ||||
// of the interface \Swift_Mime_Header, however the | // of the interface \Swift_Mime_Header, however the | ||||
// interface doesn't, and this makes the static-code | // interface doesn't, and this makes the static-code | ||||
// analysis unhappy. | // analysis unhappy. | ||||
// @todo check if symfony mailer can modify the autosubmitted header | |||||
$headers->remove(AutoSubmitted::HEADER); | $headers->remove(AutoSubmitted::HEADER); | ||||
} | } | ||||
* @return string | * @return string | ||||
*/ | */ | ||||
public function getAutoSubmitted(): string { | public function getAutoSubmitted(): string { | ||||
$headers = $this->swiftMessage->getHeaders(); | |||||
$headers = $this->symfonyEmail->getHeaders(); | |||||
return $headers->has(AutoSubmitted::HEADER) ? | return $headers->has(AutoSubmitted::HEADER) ? | ||||
$headers->get(AutoSubmitted::HEADER)->toString() : AutoSubmitted::VALUE_NO; | |||||
$headers->get(AutoSubmitted::HEADER)->getBodyAsString() : AutoSubmitted::VALUE_NO; | |||||
} | } | ||||
} | } |
public function send(IMessage $message): array; | public function send(IMessage $message): array; | ||||
/** | /** | ||||
* Checks if an e-mail address is valid | |||||
* @deprecated 26.0.0 | |||||
* | * | ||||
* @param string $email Email address to be validated | * @param string $email Email address to be validated | ||||
* @return bool True if the mail address is valid, false otherwise | * @return bool True if the mail address is valid, false otherwise |
use OCP\L10N\IFactory; | use OCP\L10N\IFactory; | ||||
use OCP\Mail\Events\BeforeMessageSent; | use OCP\Mail\Events\BeforeMessageSent; | ||||
use Psr\Log\LoggerInterface; | use Psr\Log\LoggerInterface; | ||||
use Swift_SwiftException; | |||||
use Test\TestCase; | use Test\TestCase; | ||||
use PHPUnit\Framework\MockObject\MockObject; | |||||
use Symfony\Component\Mailer\Mailer as SymfonyMailer; | |||||
use Symfony\Component\Mime\Email; | |||||
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; | |||||
use Symfony\Component\Mailer\Transport\SendmailTransport; | |||||
class MailerTest extends TestCase { | class MailerTest extends TestCase { | ||||
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ | |||||
/** @var IConfig|MockObject */ | |||||
private $config; | private $config; | ||||
/** @var Defaults|\PHPUnit\Framework\MockObject\MockObject */ | |||||
/** @var Defaults|MockObject */ | |||||
private $defaults; | private $defaults; | ||||
/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ | |||||
/** @var LoggerInterface|MockObject */ | |||||
private $logger; | private $logger; | ||||
/** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ | |||||
/** @var IURLGenerator|MockObject */ | |||||
private $urlGenerator; | private $urlGenerator; | ||||
/** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ | |||||
/** @var IL10N|MockObject */ | |||||
private $l10n; | private $l10n; | ||||
/** @var Mailer */ | /** @var Mailer */ | ||||
private $mailer; | private $mailer; | ||||
$path = '/usr/sbin/sendmail'; | $path = '/usr/sbin/sendmail'; | ||||
} | } | ||||
$expected = new \Swift_SendmailTransport($path . $binaryParam); | |||||
$expected = new SendmailTransport($path . $binaryParam, null, $this->logger); | |||||
$this->assertEquals($expected, self::invokePrivate($this->mailer, 'getSendMailInstance')); | $this->assertEquals($expected, self::invokePrivate($this->mailer, 'getSendMailInstance')); | ||||
} | } | ||||
['mail_sendmailmode', 'smtp', $sendmailMode], | ['mail_sendmailmode', 'smtp', $sendmailMode], | ||||
]); | ]); | ||||
$this->assertEquals(new \Swift_SendmailTransport('/var/qmail/bin/sendmail' . $binaryParam), self::invokePrivate($this->mailer, 'getSendMailInstance')); | |||||
$sendmail = new SendmailTransport('/var/qmail/bin/sendmail' . $binaryParam, null, $this->logger); | |||||
$this->assertEquals($sendmail, self::invokePrivate($this->mailer, 'getSendMailInstance')); | |||||
} | } | ||||
public function testGetInstanceDefault() { | public function testGetInstanceDefault() { | ||||
$this->config | |||||
->method('getSystemValue') | |||||
->willReturnMap([ | |||||
['mail_smtphost', '127.0.0.1', '127.0.0.1'], | |||||
['mail_smtpport', 25, 25], | |||||
['mail_smtptimeout', 10, 10], | |||||
]); | |||||
$mailer = self::invokePrivate($this->mailer, 'getInstance'); | $mailer = self::invokePrivate($this->mailer, 'getInstance'); | ||||
$this->assertInstanceOf(\Swift_Mailer::class, $mailer); | |||||
$this->assertInstanceOf(\Swift_SmtpTransport::class, $mailer->getTransport()); | |||||
$this->assertInstanceOf(SymfonyMailer::class, $mailer); | |||||
$transport = self::invokePrivate($mailer, 'transport'); | |||||
$this->assertInstanceOf(EsmtpTransport::class, $transport); | |||||
} | } | ||||
public function testGetInstanceSendmail() { | public function testGetInstanceSendmail() { | ||||
]); | ]); | ||||
$mailer = self::invokePrivate($this->mailer, 'getInstance'); | $mailer = self::invokePrivate($this->mailer, 'getInstance'); | ||||
$this->assertInstanceOf(\Swift_Mailer::class, $mailer); | |||||
$this->assertInstanceOf(\Swift_SendmailTransport::class, $mailer->getTransport()); | |||||
$this->assertInstanceOf(SymfonyMailer::class, $mailer); | |||||
$transport = self::invokePrivate($mailer, 'transport'); | |||||
$this->assertInstanceOf(SendmailTransport::class, $transport); | |||||
} | } | ||||
public function testEvents() { | public function testEvents() { | ||||
$this->config | |||||
->method('getSystemValue') | |||||
->willReturnMap([ | |||||
['mail_smtphost', '127.0.0.1', '127.0.0.1'], | |||||
['mail_smtpport', 25, 25], | |||||
]); | |||||
$this->mailer = $this->getMockBuilder(Mailer::class) | |||||
->setMethods(['getInstance']) | |||||
->setConstructorArgs( | |||||
[ | |||||
$this->config, | |||||
$this->logger, | |||||
$this->defaults, | |||||
$this->urlGenerator, | |||||
$this->l10n, | |||||
$this->dispatcher, | |||||
$this->createMock(IFactory::class) | |||||
] | |||||
) | |||||
->getMock(); | |||||
$message = $this->createMock(Message::class); | $message = $this->createMock(Message::class); | ||||
$event = new BeforeMessageSent($message); | $event = new BeforeMessageSent($message); | ||||
->method('dispatchTyped') | ->method('dispatchTyped') | ||||
->with($this->equalTo($event)); | ->with($this->equalTo($event)); | ||||
# We do not care at this point about errors in Swiftmailer | |||||
try { | |||||
$this->mailer->send($message); | |||||
} catch (Swift_SwiftException $e) { | |||||
} | |||||
$this->mailer->send($message); | |||||
} | } | ||||
public function testCreateMessage() { | public function testCreateMessage() { | ||||
public function testSendInvalidMailException() { | public function testSendInvalidMailException() { | ||||
$this->config | |||||
->method('getSystemValue') | |||||
->willReturnMap([ | |||||
['mail_smtphost', '127.0.0.1', '127.0.0.1'], | |||||
['mail_smtpport', 25, 25], | |||||
['mail_smtptimeout', 10, 10], | |||||
]); | |||||
$this->expectException(\Exception::class); | $this->expectException(\Exception::class); | ||||
$message = $this->getMockBuilder('\OC\Mail\Message') | $message = $this->getMockBuilder('\OC\Mail\Message') | ||||
->disableOriginalConstructor()->getMock(); | ->disableOriginalConstructor()->getMock(); | ||||
$message->expects($this->once()) | $message->expects($this->once()) | ||||
->method('getSwiftMessage') | |||||
->willReturn(new \Swift_Message()); | |||||
->method('getSymfonyEmail') | |||||
->willReturn(new Email()); | |||||
$this->mailer->send($message); | $this->mailer->send($message); | ||||
} | } | ||||
$this->config->method('getSystemValue') | $this->config->method('getSystemValue') | ||||
->willReturnMap([ | ->willReturnMap([ | ||||
['mail_smtpmode', 'smtp', 'smtp'], | ['mail_smtpmode', 'smtp', 'smtp'], | ||||
['mail_smtpstreamoptions', [], ['foo' => 1]] | |||||
['mail_smtpstreamoptions', [], ['foo' => 1]], | |||||
['mail_smtphost', '127.0.0.1', '127.0.0.1'], | |||||
['mail_smtpport', 25, 25], | |||||
['mail_smtptimeout', 10, 10], | |||||
]); | ]); | ||||
$mailer = self::invokePrivate($this->mailer, 'getInstance'); | $mailer = self::invokePrivate($this->mailer, 'getInstance'); | ||||
$this->assertEquals(1, count($mailer->getTransport()->getStreamOptions())); | |||||
$this->assertTrue(isset($mailer->getTransport()->getStreamOptions()['foo'])); | |||||
/** @var EsmtpTransport $transport */ | |||||
$transport = self::invokePrivate($mailer, 'transport'); | |||||
$this->assertInstanceOf(EsmtpTransport::class, $transport); | |||||
$this->assertEquals(1, count($transport->getStream()->getStreamOptions())); | |||||
$this->assertTrue(isset($transport->getStream()->getStreamOptions()['foo'])); | |||||
} | } | ||||
public function testStreamingOptionsWrongType() { | public function testStreamingOptionsWrongType() { | ||||
$this->config->method('getSystemValue') | $this->config->method('getSystemValue') | ||||
->willReturnMap([ | ->willReturnMap([ | ||||
['mail_smtpmode', 'smtp', 'smtp'], | ['mail_smtpmode', 'smtp', 'smtp'], | ||||
['mail_smtpstreamoptions', [], 'bar'] | |||||
['mail_smtpstreamoptions', [], 'bar'], | |||||
['mail_smtphost', '127.0.0.1', '127.0.0.1'], | |||||
['mail_smtpport', 25, 25], | |||||
['mail_smtptimeout', 10, 10], | |||||
]); | ]); | ||||
$mailer = self::invokePrivate($this->mailer, 'getInstance'); | $mailer = self::invokePrivate($this->mailer, 'getInstance'); | ||||
$this->assertEquals(0, count($mailer->getTransport()->getStreamOptions())); | |||||
/** @var EsmtpTransport $transport */ | |||||
$transport = self::invokePrivate($mailer, 'transport'); | |||||
$this->assertInstanceOf(EsmtpTransport::class, $transport); | |||||
$this->assertEquals(0, count($transport->getStream()->getStreamOptions())); | |||||
} | } | ||||
public function testLocalDomain(): void { | public function testLocalDomain(): void { | ||||
$this->config->method('getSystemValue') | $this->config->method('getSystemValue') | ||||
->willReturnMap([ | ->willReturnMap([ | ||||
['mail_smtpmode', 'smtp', 'smtp'] | |||||
['mail_smtpmode', 'smtp', 'smtp'], | |||||
['mail_smtphost', '127.0.0.1', '127.0.0.1'], | |||||
['mail_smtpport', 25, 25], | |||||
['mail_smtptimeout', 10, 10], | |||||
]); | ]); | ||||
$this->config->method('getSystemValueString') | $this->config->method('getSystemValueString') | ||||
->with('overwrite.cli.url', '') | ->with('overwrite.cli.url', '') | ||||
->willReturn('https://some.valid.url.com:8080'); | ->willReturn('https://some.valid.url.com:8080'); | ||||
/** @var \Swift_Mailer $mailer */ | |||||
/** @var SymfonyMailer $mailer */ | |||||
$mailer = self::invokePrivate($this->mailer, 'getInstance'); | $mailer = self::invokePrivate($this->mailer, 'getInstance'); | ||||
self::assertInstanceOf(\Swift_Mailer::class, $mailer); | |||||
self::assertInstanceOf(SymfonyMailer::class, $mailer); | |||||
/** @var \Swift_Transport_EsmtpTransport $transport */ | |||||
$transport = $mailer->getTransport(); | |||||
self::assertInstanceOf(\Swift_Transport_EsmtpTransport::class, $transport); | |||||
/** @var EsmtpTransport $transport */ | |||||
$transport = self::invokePrivate($mailer, 'transport'); | |||||
self::assertInstanceOf(EsmtpTransport::class, $transport); | |||||
self::assertEquals('some.valid.url.com', $transport->getLocalDomain()); | self::assertEquals('some.valid.url.com', $transport->getLocalDomain()); | ||||
} | } | ||||
public function testLocalDomainInvalidUrl(): void { | public function testLocalDomainInvalidUrl(): void { | ||||
$this->config->method('getSystemValue') | $this->config->method('getSystemValue') | ||||
->willReturnMap([ | ->willReturnMap([ | ||||
['mail_smtpmode', 'smtp', 'smtp'] | |||||
['mail_smtpmode', 'smtp', 'smtp'], | |||||
['mail_smtphost', '127.0.0.1', '127.0.0.1'], | |||||
['mail_smtpport', 25, 25], | |||||
['mail_smtptimeout', 10, 10], | |||||
]); | ]); | ||||
$this->config->method('getSystemValueString') | $this->config->method('getSystemValueString') | ||||
->with('overwrite.cli.url', '') | ->with('overwrite.cli.url', '') | ||||
->willReturn('https:only.slash.does.not.work:8080'); | ->willReturn('https:only.slash.does.not.work:8080'); | ||||
/** @var \Swift_Mailer $mailer */ | |||||
/** @var SymfonyMailer $mailer */ | |||||
$mailer = self::invokePrivate($this->mailer, 'getInstance'); | $mailer = self::invokePrivate($this->mailer, 'getInstance'); | ||||
self::assertInstanceOf(\Swift_Mailer::class, $mailer); | |||||
self::assertInstanceOf(SymfonyMailer::class, $mailer); | |||||
/** @var \Swift_Transport_EsmtpTransport $transport */ | |||||
$transport = $mailer->getTransport(); | |||||
self::assertInstanceOf(\Swift_Transport_EsmtpTransport::class, $transport); | |||||
/** @var EsmtpTransport $transport */ | |||||
$transport = self::invokePrivate($mailer, 'transport'); | |||||
self::assertInstanceOf(EsmtpTransport::class, $transport); | |||||
self::assertEquals('[127.0.0.1]', $transport->getLocalDomain()); | self::assertEquals('[127.0.0.1]', $transport->getLocalDomain()); | ||||
} | } | ||||
} | } |
use OC\Mail\Message; | use OC\Mail\Message; | ||||
use OCP\Mail\Headers\AutoSubmitted; | use OCP\Mail\Headers\AutoSubmitted; | ||||
use OCP\Mail\IEMailTemplate; | use OCP\Mail\IEMailTemplate; | ||||
use Swift_Message; | |||||
use Symfony\Component\Mime\Address; | |||||
use Symfony\Component\Mime\Email; | |||||
use Symfony\Component\Mime\Exception\RfcComplianceException; | |||||
use Symfony\Component\Mime\Header\HeaderInterface; | |||||
use Symfony\Component\Mime\Header\Headers; | |||||
use Test\TestCase; | use Test\TestCase; | ||||
use PHPUnit\Framework\MockObject\MockObject; | |||||
class MessageTest extends TestCase { | class MessageTest extends TestCase { | ||||
/** @var Swift_Message */ | |||||
private $swiftMessage; | |||||
/** @var Email */ | |||||
private $symfonyEmail; | |||||
/** @var Message */ | /** @var Message */ | ||||
private $message; | private $message; | ||||
*/ | */ | ||||
public function mailAddressProvider() { | public function mailAddressProvider() { | ||||
return [ | return [ | ||||
[['lukas@owncloud.com' => 'Lukas Reschke'], ['lukas@owncloud.com' => 'Lukas Reschke']], | |||||
[['lukas@owncloud.com' => 'Lukas Reschke', 'lukas@öwnclöüd.com', 'lukäs@owncloud.örg' => 'Lükäs Réschke'], | |||||
['lukas@owncloud.com' => 'Lukas Reschke', 'lukas@xn--wncld-iuae2c.com', 'lukäs@owncloud.xn--rg-eka' => 'Lükäs Réschke']], | |||||
[['lukas@öwnclöüd.com'], ['lukas@xn--wncld-iuae2c.com']], | |||||
[ | |||||
['lukas@owncloud.com' => 'Lukas Reschke'], | |||||
[new Address('lukas@owncloud.com', 'Lukas Reschke')] | |||||
], | |||||
[ | |||||
[ | |||||
'lukas@owncloud.com' => 'Lukas Reschke', | |||||
'lukas@öwnclöüd.com', | |||||
'lukäs@owncloud.örg' => 'Lükäs Réschke' | |||||
], | |||||
[ | |||||
new Address('lukas@owncloud.com', 'Lukas Reschke'), | |||||
new Address('lukas@öwnclöüd.com'), | |||||
new Address('lukäs@owncloud.örg', 'Lükäs Réschke') | |||||
] | |||||
], | |||||
[ | |||||
['lukas@öwnclöüd.com'], | |||||
[new Address('lukas@öwnclöüd.com')] | |||||
], | |||||
]; | ]; | ||||
} | } | ||||
*/ | */ | ||||
public function getMailAddressProvider() { | public function getMailAddressProvider() { | ||||
return [ | return [ | ||||
[null, []], | |||||
[[], []], | |||||
[['lukas@owncloud.com' => 'Lukas Reschke'], ['lukas@owncloud.com' => 'Lukas Reschke']], | [['lukas@owncloud.com' => 'Lukas Reschke'], ['lukas@owncloud.com' => 'Lukas Reschke']], | ||||
]; | ]; | ||||
} | } | ||||
protected function setUp(): void { | protected function setUp(): void { | ||||
parent::setUp(); | parent::setUp(); | ||||
$this->swiftMessage = $this->getMockBuilder('\Swift_Message') | |||||
$this->symfonyEmail = $this->getMockBuilder(Email::class) | |||||
->disableOriginalConstructor()->getMock(); | ->disableOriginalConstructor()->getMock(); | ||||
$this->message = new Message($this->swiftMessage, false); | |||||
$this->message = new Message($this->symfonyEmail, false); | |||||
} | } | ||||
/** | /** | ||||
* @requires function idn_to_ascii | |||||
* @dataProvider mailAddressProvider | * @dataProvider mailAddressProvider | ||||
* | * | ||||
* @param string $unconverted | * @param string $unconverted | ||||
* @param string $expected | * @param string $expected | ||||
*/ | */ | ||||
public function testConvertAddresses($unconverted, $expected) { | public function testConvertAddresses($unconverted, $expected) { | ||||
$this->assertSame($expected, self::invokePrivate($this->message, 'convertAddresses', [$unconverted])); | |||||
} | |||||
public function testSetFrom() { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('setFrom') | |||||
->with(['lukas@owncloud.com']); | |||||
$this->message->setFrom(['lukas@owncloud.com']); | |||||
$this->assertEquals($expected, self::invokePrivate($this->message, 'convertAddresses', [$unconverted])); | |||||
} | } | ||||
public function testSetRecipients(): void { | |||||
$this->message = $this->message->setFrom(['pierres-general-store@stardewvalley.com' => 'Pierres General Store']); | |||||
$this->message = $this->message->setTo(['lewis-tent@stardewvalley.com' => "Lewis' Tent Life"]); | |||||
$this->message = $this->message->setReplyTo(['penny@stardewvalley-library.co.edu' => 'Penny']); | |||||
$this->message = $this->message->setCc(['gunther@stardewvalley-library.co.edu' => 'Gunther']); | |||||
$this->message = $this->message->setBcc(['pam@stardewvalley-bus.com' => 'Pam']); | |||||
/** | |||||
* @dataProvider getMailAddressProvider | |||||
* | |||||
* @param $swiftresult | |||||
* @param $return | |||||
*/ | |||||
public function testGetFrom($swiftresult, $return) { | |||||
$this->swiftMessage | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | |||||
->method('from') | |||||
->willReturn(new Address('pierres-general-store@stardewvalley.com', 'Pierres General Store')); | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | |||||
->method('to') | |||||
->willReturn(new Address('lewis-tent@stardewvalley.com', "Lewis' Tent Life")); | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | |||||
->method('replyTo') | |||||
->willReturn(new Address('penny@stardewvalley-library.co.edu', 'Penny')); | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | |||||
->method('cc') | |||||
->willReturn(new Address('gunther@stardewvalley-library.co.edu', 'Gunther')); | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | ->expects($this->once()) | ||||
->method('getFrom') | |||||
->willReturn($swiftresult); | |||||
->method('bcc') | |||||
->willReturn(new Address('pam@stardewvalley-bus.com', 'Pam')); | |||||
$this->assertSame($return, $this->message->getFrom()); | |||||
$this->message->setRecipients(); | |||||
} | } | ||||
public function testSetReplyTo() { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('setReplyTo') | |||||
->with(['lukas@owncloud.com']); | |||||
$this->message->setReplyTo(['lukas@owncloud.com']); | |||||
} | |||||
public function testSetTo() { | |||||
$expected = ['pierres-general-store@stardewvalley.com' => 'Pierres General Store']; | |||||
public function testGetReplyTo() { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('getReplyTo') | |||||
->willReturn('lukas@owncloud.com'); | |||||
$message = $this->message->setTo(['pierres-general-store@stardewvalley.com' => 'Pierres General Store']); | |||||
$this->assertSame('lukas@owncloud.com', $this->message->getReplyTo()); | |||||
$this->assertEquals($expected, $message->getTo()); | |||||
} | } | ||||
public function testSetRecipientsException(): void { | |||||
$message = $this->message->setTo(['lewis-tent@~~~~.com' => "Lewis' Tent Life"]); | |||||
/** @dataProvider dataSetTo */ | |||||
public function testSetTo(array $to, array $expected) { | |||||
$this->swiftMessage | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | ->expects($this->once()) | ||||
->method('setTo') | |||||
->with($expected); | |||||
$this->message->setTo($to); | |||||
} | |||||
->method('to') | |||||
->willThrowException(new RfcComplianceException()); | |||||
public function dataSetTo(): array { | |||||
return [ | |||||
[['robot@example.com'], ['robot@example.com']], | |||||
[['robot'], ['robot' => 'robot']], | |||||
[['robot' => 'robot display name'], ['robot' => 'robot display name']], | |||||
[['example@🤖.com'], ['example@xn--yp9h.com']], | |||||
[['example@🤖.com' => 'A robot'], ['example@xn--yp9h.com' => 'A robot']], | |||||
]; | |||||
$this->expectException(RfcComplianceException::class); | |||||
$message->setRecipients(); | |||||
} | } | ||||
/** | |||||
* @dataProvider getMailAddressProvider | |||||
*/ | |||||
public function testGetTo($swiftresult, $return) { | |||||
$this->swiftMessage | |||||
public function testSetRecipientsEmptyValues(): void { | |||||
$message = $this->message->setTo([]); | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | ->expects($this->once()) | ||||
->method('getTo') | |||||
->willReturn($swiftresult); | |||||
->method('to'); | |||||
$this->assertSame($return, $this->message->getTo()); | |||||
$message->setRecipients(); | |||||
} | } | ||||
public function testSetCc() { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('setCc') | |||||
->with(['lukas@owncloud.com']); | |||||
$this->message->setCc(['lukas@owncloud.com']); | |||||
} | |||||
public function testSetGetFrom() { | |||||
$expected = ['pierres-general-store@stardewvalley.com' => 'Pierres General Store']; | |||||
/** | |||||
* @dataProvider getMailAddressProvider | |||||
*/ | |||||
public function testGetCc($swiftresult, $return) { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('getCc') | |||||
->willReturn($swiftresult); | |||||
$message = $this->message->setFrom(['pierres-general-store@stardewvalley.com' => 'Pierres General Store']); | |||||
$this->assertSame($return, $this->message->getCc()); | |||||
$this->assertEquals($expected, $message->getFrom()); | |||||
} | } | ||||
public function testSetBcc() { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('setBcc') | |||||
->with(['lukas@owncloud.com']); | |||||
$this->message->setBcc(['lukas@owncloud.com']); | |||||
public function testSetGetTo() { | |||||
$expected = ['lewis-tent@stardewvalley.com' => "Lewis' Tent Life"]; | |||||
$message = $this->message->setTo(['lewis-tent@stardewvalley.com' => "Lewis' Tent Life"]); | |||||
$this->assertEquals($expected, $message->getTo()); | |||||
} | } | ||||
/** | |||||
* @dataProvider getMailAddressProvider | |||||
*/ | |||||
public function testGetBcc($swiftresult, $return) { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('getBcc') | |||||
->willReturn($swiftresult); | |||||
public function testSetGetReplyTo() { | |||||
$expected = ['penny@stardewvalley-library.co.edu' => 'Penny']; | |||||
$this->assertSame($return, $this->message->getBcc()); | |||||
$message = $this->message->setReplyTo(['penny@stardewvalley-library.co.edu' => 'Penny']); | |||||
$this->assertEquals($expected, $message->getReplyTo()); | |||||
} | } | ||||
public function testSetSubject() { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('setSubject') | |||||
->with('Fancy Subject'); | |||||
public function testSetGetCC() { | |||||
$expected = ['gunther@stardewvalley-library.co.edu' => 'Gunther']; | |||||
$this->message->setSubject('Fancy Subject'); | |||||
$message = $this->message->setCc(['gunther@stardewvalley-library.co.edu' => 'Gunther']); | |||||
$this->assertEquals($expected, $message->getCc()); | |||||
} | } | ||||
public function testGetSubject() { | |||||
$this->swiftMessage | |||||
->expects($this->once()) | |||||
->method('getSubject') | |||||
->willReturn('Fancy Subject'); | |||||
public function testSetGetBCC() { | |||||
$expected = ['pam@stardewvalley-bus.com' => 'Pam']; | |||||
$message = $this->message->setBcc(['pam@stardewvalley-bus.com' => 'Pam']); | |||||
$this->assertSame('Fancy Subject', $this->message->getSubject()); | |||||
$this->assertEquals($expected, $message->getBcc()); | |||||
} | } | ||||
public function testSetPlainBody() { | public function testSetPlainBody() { | ||||
$this->swiftMessage | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | ->expects($this->once()) | ||||
->method('setBody') | |||||
->method('text') | |||||
->with('Fancy Body'); | ->with('Fancy Body'); | ||||
$this->message->setPlainBody('Fancy Body'); | $this->message->setPlainBody('Fancy Body'); | ||||
} | } | ||||
public function testGetPlainBody() { | public function testGetPlainBody() { | ||||
$this->swiftMessage | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | ->expects($this->once()) | ||||
->method('getBody') | |||||
->method('getTextBody') | |||||
->willReturn('Fancy Body'); | ->willReturn('Fancy Body'); | ||||
$this->assertSame('Fancy Body', $this->message->getPlainBody()); | $this->assertSame('Fancy Body', $this->message->getPlainBody()); | ||||
} | } | ||||
public function testSetHtmlBody() { | public function testSetHtmlBody() { | ||||
$this->swiftMessage | |||||
$this->symfonyEmail | |||||
->expects($this->once()) | ->expects($this->once()) | ||||
->method('addPart') | |||||
->with('<blink>Fancy Body</blink>', 'text/html'); | |||||
->method('html') | |||||
->with('<blink>Fancy Body</blink>', 'utf-8'); | |||||
$this->message->setHtmlBody('<blink>Fancy Body</blink>'); | $this->message->setHtmlBody('<blink>Fancy Body</blink>'); | ||||
} | } | ||||
public function testPlainTextRenderOption() { | public function testPlainTextRenderOption() { | ||||
/** @var \PHPUnit\Framework\MockObject\MockObject|Swift_Message $swiftMessage */ | |||||
$swiftMessage = $this->getMockBuilder('\Swift_Message') | |||||
/** @var MockObject|Email $symfonyEmail */ | |||||
$symfonyEmail = $this->getMockBuilder(Email::class) | |||||
->disableOriginalConstructor()->getMock(); | ->disableOriginalConstructor()->getMock(); | ||||
/** @var \PHPUnit\Framework\MockObject\MockObject|IEMailTemplate $template */ | |||||
$template = $this->getMockBuilder('\OCP\Mail\IEMailTemplate') | |||||
/** @var MockObject|IEMailTemplate $template */ | |||||
$template = $this->getMockBuilder(IEMailTemplate::class) | |||||
->disableOriginalConstructor()->getMock(); | ->disableOriginalConstructor()->getMock(); | ||||
$message = new Message($swiftMessage, true); | |||||
$message = new Message($symfonyEmail, true); | |||||
$template | $template | ||||
->expects($this->never()) | ->expects($this->never()) | ||||
} | } | ||||
public function testBothRenderingOptions() { | public function testBothRenderingOptions() { | ||||
/** @var \PHPUnit\Framework\MockObject\MockObject|Swift_Message $swiftMessage */ | |||||
$swiftMessage = $this->getMockBuilder('\Swift_Message') | |||||
/** @var MockObject|Email $symfonyEmail */ | |||||
$symfonyEmail = $this->getMockBuilder(Email::class) | |||||
->disableOriginalConstructor()->getMock(); | ->disableOriginalConstructor()->getMock(); | ||||
/** @var \PHPUnit\Framework\MockObject\MockObject|IEMailTemplate $template */ | |||||
$template = $this->getMockBuilder('\OCP\Mail\IEMailTemplate') | |||||
/** @var MockObject|IEMailTemplate $template */ | |||||
$template = $this->getMockBuilder(IEMailTemplate::class) | |||||
->disableOriginalConstructor()->getMock(); | ->disableOriginalConstructor()->getMock(); | ||||
$message = new Message($swiftMessage, false); | |||||
$message = new Message($symfonyEmail, false); | |||||
$template | $template | ||||
->expects($this->once()) | ->expects($this->once()) | ||||
} | } | ||||
public function testSetAutoSubmitted1() { | public function testSetAutoSubmitted1() { | ||||
$swiftMimeSimpleHeaderSet = $this->getMockBuilder('\Swift_Mime_SimpleHeaderSet') | |||||
->disableOriginalConstructor() | |||||
->getMock(); | |||||
$swiftMessage = $this->getMockBuilder('\Swift_Message') | |||||
->disableOriginalConstructor() | |||||
->disableOriginalClone() | |||||
->disableArgumentCloning() | |||||
->disallowMockingUnknownTypes() | |||||
->getMock(); | |||||
$swiftMessage->method('getHeaders')->willReturn($swiftMimeSimpleHeaderSet); | |||||
$swiftMimeSimpleHeaderSet->expects($this->once()) | |||||
->method('has') | |||||
->with('Auto-Submitted'); | |||||
$swiftMimeSimpleHeaderSet->expects($this->never()) | |||||
->method('remove'); | |||||
$swiftMimeSimpleHeaderSet->expects($this->once()) | |||||
->method('addTextHeader') | |||||
->with('Auto-Submitted', AutoSubmitted::VALUE_AUTO_GENERATED); | |||||
$message = new Message($swiftMessage, false); | |||||
$headers = new Headers($this->createMock(HeaderInterface::class)); | |||||
$headers->addTextHeader(AutoSubmitted::HEADER, "yes"); | |||||
$symfonyEmail = $this->createMock(Email::class); | |||||
$symfonyEmail->method('getHeaders') | |||||
->willReturn($headers); | |||||
$message = new Message($symfonyEmail, false); | |||||
$message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED); | $message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED); | ||||
$this->assertNotSame('no', $message->getAutoSubmitted()); | |||||
} | } | ||||
public function testSetAutoSubmitted2() { | public function testSetAutoSubmitted2() { | ||||
$swiftMimeSimpleHeaderSet = $this->getMockBuilder('\Swift_Mime_SimpleHeaderSet') | |||||
->disableOriginalConstructor() | |||||
->getMock(); | |||||
$swiftMessage = $this->getMockBuilder('\Swift_Message') | |||||
->disableOriginalConstructor() | |||||
->disableOriginalClone() | |||||
->disableArgumentCloning() | |||||
->disallowMockingUnknownTypes() | |||||
->getMock(); | |||||
$swiftMessage->method('getHeaders')->willReturn($swiftMimeSimpleHeaderSet); | |||||
$swiftMimeSimpleHeaderSet->expects($this->once()) | |||||
->method('has') | |||||
->with('Auto-Submitted') | |||||
->willReturn(true); | |||||
$swiftMimeSimpleHeaderSet->expects($this->once()) | |||||
->method('remove') | |||||
->with('Auto-Submitted'); | |||||
$swiftMimeSimpleHeaderSet->expects($this->once()) | |||||
->method('addTextHeader') | |||||
->with('Auto-Submitted', AutoSubmitted::VALUE_AUTO_GENERATED); | |||||
$message = new Message($swiftMessage, false); | |||||
$headers = new Headers($this->createMock(HeaderInterface::class)); | |||||
$headers->addTextHeader(AutoSubmitted::HEADER, 'no'); | |||||
$symfonyEmail = $this->createMock(Email::class); | |||||
$symfonyEmail->method('getHeaders') | |||||
->willReturn($headers); | |||||
$message = new Message($symfonyEmail, false); | |||||
$message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED); | $message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED); | ||||
$this->assertSame('auto-generated', $message->getAutoSubmitted()); | |||||
} | } | ||||
public function testGetAutoSubmitted1() { | |||||
$swiftMimeSimpleHeaderSet = $this->getMockBuilder('\Swift_Mime_SimpleHeaderSet') | |||||
->disableOriginalConstructor() | |||||
->getMock(); | |||||
$swiftMessage = $this->getMockBuilder('\Swift_Message') | |||||
->disableOriginalConstructor() | |||||
->disableOriginalClone() | |||||
->disableArgumentCloning() | |||||
->disallowMockingUnknownTypes() | |||||
->getMock(); | |||||
$swiftMessage->method('getHeaders')->willReturn($swiftMimeSimpleHeaderSet); | |||||
$swiftMimeSimpleHeaderSet->expects($this->once()) | |||||
->method('has') | |||||
->with('Auto-Submitted'); | |||||
$swiftMimeSimpleHeaderSet->expects($this->never()) | |||||
->method('get'); | |||||
$message = new Message($swiftMessage, false); | |||||
public function testGetAutoSubmitted() { | |||||
$headers = new Headers($this->createMock(HeaderInterface::class)); | |||||
$headers->addTextHeader(AutoSubmitted::HEADER, 'no'); | |||||
$symfonyEmail = $this->createMock(Email::class); | |||||
$symfonyEmail->method('getHeaders') | |||||
->willReturn($headers); | |||||
$message = new Message($symfonyEmail, false); | |||||
$this->assertSame("no", $message->getAutoSubmitted()); | $this->assertSame("no", $message->getAutoSubmitted()); | ||||
} | } | ||||
public function testGetAutoSubmitted2() { | |||||
$swiftMimeHeader = $this->getMockBuilder('\Swift_Mime_Header') | |||||
->disableOriginalConstructor() | |||||
->getMockForAbstractClass(); | |||||
$swiftMimeSimpleHeaderSet = $this->getMockBuilder('\Swift_Mime_SimpleHeaderSet') | |||||
->disableOriginalConstructor() | |||||
->getMock(); | |||||
$swiftMessage = $this->getMockBuilder('\Swift_Message') | |||||
->disableOriginalConstructor() | |||||
->disableOriginalClone() | |||||
->disableArgumentCloning() | |||||
->disallowMockingUnknownTypes() | |||||
->getMock(); | |||||
$swiftMessage->method('getHeaders')->willReturn($swiftMimeSimpleHeaderSet); | |||||
$swiftMimeHeader->method('toString')->willReturn(AutoSubmitted::VALUE_AUTO_GENERATED); | |||||
$swiftMimeSimpleHeaderSet->expects($this->once()) | |||||
->method('has') | |||||
->with('Auto-Submitted') | |||||
->willReturn(true); | |||||
$swiftMimeSimpleHeaderSet->expects($this->once()) | |||||
->method('get') | |||||
->willReturn($swiftMimeHeader); | |||||
$message = new Message($swiftMessage, false); | |||||
$this->assertSame(AutoSubmitted::VALUE_AUTO_GENERATED, $message->getAutoSubmitted()); | |||||
} | |||||
} | } |