Skip to content

Commit

Permalink
chore: migrate to symfony/mailer
Browse files Browse the repository at this point in the history
chore: remove email config `mail_smtpauthtype` - this is now auto detected

fix: Mailer::send will always thrown an exception in case of errors during delivery
  • Loading branch information
DeepDiver1975 committed Oct 9, 2023
1 parent 73c370c commit 9ea1926
Show file tree
Hide file tree
Showing 18 changed files with 545 additions and 800 deletions.
23 changes: 5 additions & 18 deletions apps/dav/lib/CalDAV/Schedule/IMipPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,12 @@
* @license http://sabre.io/license/ Modified BSD License
*/
class IMipPlugin extends SabreIMipPlugin {
/** @var IMailer */
private $mailer;

/** @var ILogger */
private $logger;

/** @var IRequest */
private $request;
private IMailer $mailer;
private ILogger $logger;
private IRequest $request;

/**
* Creates the email handler.
*
* @param IMailer $mailer
* @param ILogger $logger
* @param IRequest $request
*/
public function __construct(IMailer $mailer, ILogger $logger, IRequest $request) {
parent::__construct('');
Expand Down Expand Up @@ -123,14 +114,10 @@ public function schedule(ITip\Message $iTipMessage) {
->setFrom([$sender => $senderName])
->setTo([$recipient => $recipientName])
->setSubject($subject)
->setBody($iTipMessage->message->serialize(), $contentType);
->attach($iTipMessage->message->serialize(), "event.ics", $contentType);
try {
$failed = $this->mailer->send($message);
$this->mailer->send($message);
$iTipMessage->scheduleStatus = '1.1; Scheduling message is sent via iMip';
if ($failed) {
$this->logger->error('Unable to deliver message to {failed}', ['app' => 'dav', 'failed' => \implode(', ', $failed)]);
$iTipMessage->scheduleStatus = '5.0; EMail delivery failed';
}
} catch (\Exception $ex) {
$this->logger->logException($ex, ['app' => 'dav']);
$iTipMessage->scheduleStatus = '5.0; EMail delivery failed';
Expand Down
155 changes: 55 additions & 100 deletions apps/dav/tests/unit/CalDAV/Schedule/IMipPluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,124 +22,78 @@

namespace OCA\DAV\Tests\unit\CalDAV\Schedule;

use Exception;
use OC\Mail\Mailer;
use OCA\DAV\CalDAV\Schedule\IMipPlugin;
use OCP\ILogger;
use OCP\IRequest;
use PHPUnit\Framework\MockObject\MockObject;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\ITip\Message;
use Symfony\Component\Mime\Email;
use Test\TestCase;
use OC\Log;

class IMipPluginTest extends TestCase {
public function testDelivery() {
$mailMessage = new \OC\Mail\Message(new \Swift_Message());
/** @var Mailer | \PHPUnit\Framework\MockObject\MockObject $mailer */
$mailer = $this->createMock(Mailer::class);
$mailer->method('createMessage')->willReturn($mailMessage);
$mailer->expects($this->once())->method('send');
/** @var ILogger | \PHPUnit\Framework\MockObject\MockObject $logger */
$logger = $this->createMock(Log::class);
/** @var IRequest| \PHPUnit\Framework\MockObject\MockObject $request */
private \OC\Mail\Message $mailMessage;
/**
* @var Mailer|MockObject
*/
private $mailer;
private IMipPlugin $plugin;
/** @var ILogger|MockObject */
private $logger;

protected function setUp(): void {
parent::setUp();

$this->mailMessage = new \OC\Mail\Message(new Email());
$this->mailer = $this->createMock(Mailer::class);
$this->mailer->method('createMessage')->willReturn($this->mailMessage);

$this->logger = $this->createMock(Log::class);
/** @var IRequest| MockObject $request */
$request = $this->createMock(IRequest::class);

$plugin = new IMipPlugin($mailer, $logger, $request);
$message = new Message();
$message->method = 'REQUEST';
$message->message = new VCalendar();
$message->message->add('VEVENT', [
'UID' => $message->uid,
'SEQUENCE' => $message->sequence,
'SUMMARY' => 'Fellowship meeting',
]);
$message->sender = 'mailto:[email protected]';
$message->recipient = 'mailto:[email protected]';
$this->plugin = new IMipPlugin($this->mailer, $this->logger, $request);
}

public function testDelivery(): void {
$this->mailer->expects($this->once())->method('send');

$message = $this->buildIMIPMessage('REQUEST');

$plugin->schedule($message);
$this->plugin->schedule($message);
$this->assertEquals('1.1', $message->getScheduleStatus());
$this->assertEquals('Fellowship meeting', $mailMessage->getSubject());
$this->assertEquals(['[email protected]' => null], $mailMessage->getTo());
$this->assertEquals(['[email protected]' => null], $mailMessage->getReplyTo());
$this->assertEquals('text/calendar; charset=UTF-8; method=REQUEST', $mailMessage->getSwiftMessage()->getContentType());
$this->assertEquals('Fellowship meeting', $this->mailMessage->getSubject());
$this->assertEquals(['[email protected]' => null], $this->mailMessage->getTo());
$this->assertEquals(['[email protected]' => null], $this->mailMessage->getReplyTo());
$this->assertStringContainsString('text/calendar; charset=UTF-8; method=REQUEST', $this->mailMessage->getMessage()->getBody()->bodyToString());
}

public function testFailedDeliveryWithException() {
$mailMessage = new \OC\Mail\Message(new \Swift_Message());
/** @var Mailer | \PHPUnit\Framework\MockObject\MockObject $mailer */
$mailer = $this->createMock(Mailer::class);
$mailer->method('createMessage')->willReturn($mailMessage);
$mailer->method('send')->willThrowException(new \Exception());
/** @var ILogger | \PHPUnit\Framework\MockObject\MockObject $logger */
$logger = $this->createMock(Log::class);
/** @var IRequest| \PHPUnit\Framework\MockObject\MockObject $request */
$request = $this->createMock(IRequest::class);
public function testFailedDeliveryWithException(): void {
$ex = new Exception();
$this->mailer->method('send')->willThrowException($ex);
$this->logger->expects(self::once())->method('logException')->with($ex, ['app' => 'dav']);

$plugin = new IMipPlugin($mailer, $logger, $request);
$message = new Message();
$message->method = 'REQUEST';
$message->message = new VCalendar();
$message->message->add('VEVENT', [
'UID' => $message->uid,
'SEQUENCE' => $message->sequence,
'SUMMARY' => 'Fellowship meeting',
]);
$message->sender = 'mailto:[email protected]';
$message->recipient = 'mailto:[email protected]';
$message = $this->buildIMIPMessage('REQUEST');

$plugin->schedule($message);
$this->assertEquals('5.0', $message->getScheduleStatus());
$this->assertEquals('Fellowship meeting', $mailMessage->getSubject());
$this->assertEquals(['[email protected]' => null], $mailMessage->getTo());
$this->assertEquals(['[email protected]' => null], $mailMessage->getReplyTo());
$this->assertEquals('text/calendar; charset=UTF-8; method=REQUEST', $mailMessage->getSwiftMessage()->getContentType());
$this->plugin->schedule($message);
$this->assertIMipState($message, '5.0', 'REQUEST', 'Fellowship meeting');
}

public function testFailedDelivery() {
$mailMessage = new \OC\Mail\Message(new \Swift_Message());
/** @var Mailer | \PHPUnit\Framework\MockObject\MockObject $mailer */
$mailer = $this->createMock(Mailer::class);
$mailer->method('createMessage')->willReturn($mailMessage);
$mailer->method('send')->willReturn(['[email protected]']);
/** @var ILogger | \PHPUnit\Framework\MockObject\MockObject $logger */
$logger = $this->createMock(Log::class);
$logger->expects(self::once())->method('error')->with('Unable to deliver message to {failed}', ['app' => 'dav', 'failed' => '[email protected]']);
/** @var IRequest| \PHPUnit\Framework\MockObject\MockObject $request */
$request = $this->createMock(IRequest::class);
public function testDeliveryOfCancel(): void {
$this->mailer->expects($this->once())->method('send');

$plugin = new IMipPlugin($mailer, $logger, $request);
$message = new Message();
$message->method = 'REQUEST';
$message->message = new VCalendar();
$message->message->add('VEVENT', [
'UID' => $message->uid,
'SEQUENCE' => $message->sequence,
'SUMMARY' => 'Fellowship meeting',
]);
$message->sender = 'mailto:[email protected]';
$message->recipient = 'mailto:[email protected]';
$message = $this->buildIMIPMessage('CANCEL');

$plugin->schedule($message);
$this->assertEquals('5.0', $message->getScheduleStatus());
$this->assertEquals('Fellowship meeting', $mailMessage->getSubject());
$this->assertEquals(['[email protected]' => null], $mailMessage->getTo());
$this->assertEquals(['[email protected]' => null], $mailMessage->getReplyTo());
$this->assertEquals('text/calendar; charset=UTF-8; method=REQUEST', $mailMessage->getSwiftMessage()->getContentType());
$this->plugin->schedule($message);
$this->assertIMipState($message, '1.1', 'CANCEL', 'Cancelled: Fellowship meeting');
}

public function testDeliveryOfCancel() {
$mailMessage = new \OC\Mail\Message(new \Swift_Message());
/** @var Mailer | \PHPUnit\Framework\MockObject\MockObject $mailer */
$mailer = $this->createMock(Mailer::class);
$mailer->method('createMessage')->willReturn($mailMessage);
$mailer->expects($this->once())->method('send');
/** @var ILogger | \PHPUnit\Framework\MockObject\MockObject $logger */
$logger = $this->createMock(Log::class);
/** @var IRequest| \PHPUnit\Framework\MockObject\MockObject $request */
$request = $this->createMock(IRequest::class);

$plugin = new IMipPlugin($mailer, $logger, $request);
private function buildIMIPMessage(string $method): Message {
$message = new Message();
$message->method = 'CANCEL';
$message->method = $method;
$message->message = new VCalendar();
$message->message->add('VEVENT', [
'UID' => $message->uid,
Expand All @@ -148,13 +102,14 @@ public function testDeliveryOfCancel() {
]);
$message->sender = 'mailto:[email protected]';
$message->recipient = 'mailto:[email protected]';
return $message;
}

$plugin->schedule($message);
$this->assertEquals('1.1', $message->getScheduleStatus());
$this->assertEquals('Cancelled: Fellowship meeting', $mailMessage->getSubject());
$this->assertEquals(['[email protected]' => null], $mailMessage->getTo());
$this->assertEquals(['[email protected]' => null], $mailMessage->getReplyTo());
$this->assertEquals('text/calendar; charset=UTF-8; method=CANCEL', $mailMessage->getSwiftMessage()->getContentType());
$this->assertEquals('CANCELLED', $message->message->VEVENT->STATUS->getValue());
private function assertIMipState(Message $message, string $scheduleStatus, string $method, string $mailSubject): void {
$this->assertEquals($scheduleStatus, $message->getScheduleStatus());
$this->assertEquals($mailSubject, $this->mailMessage->getSubject());
$this->assertEquals(['[email protected]' => null], $this->mailMessage->getTo());
$this->assertEquals(['[email protected]' => null], $this->mailMessage->getReplyTo());
$this->assertStringContainsString("text/calendar; charset=UTF-8; method=$method", $this->mailMessage->getMessage()->getBody()->bodyToString());
}
}
74 changes: 37 additions & 37 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,50 +35,50 @@
},
"require": {
"php": ">=8.2",
"doctrine/dbal": "^2.13",
"phpseclib/phpseclib": "^3.0",
"ext-apcu": "*",
"ext-curl": "*",
"ext-exif": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-imagick": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-memcached": "*",
"ext-pdo": "*",
"ext-posix": "*",
"ext-simplexml": "*",
"ext-zip": "*",
"bantu/ini-get-wrapper": "v1.0.1",
"punic/punic": "^3.8",
"pear/archive_tar": "1.4.14",
"symfony/console": "^5.4",
"symfony/event-dispatcher": "^5.4",
"symfony/routing": "^5.4",
"symfony/process": "^5.4",
"pimple/pimple": "^3.5",
"nikic/php-parser": "^4.15",
"icewind/streams": "0.7.7",
"swiftmailer/swiftmailer": "^6.3",
"guzzlehttp/guzzle": "^7.7",
"league/flysystem": "^1.1",
"pear/pear-core-minimal": "^v1.10",
"interfasys/lognormalizer": "^v1.0",
"owncloud/tarstreamer": "v2.1.0",
"christophwurst/id3parser": "^0.1.4",
"sabre/dav": "^4.4",
"sabre/http": "^5.1",
"composer/semver": "^3.3",
"deepdiver/zipstreamer": "^2.0",
"symfony/translation": "^5.4",
"dg/composer-cleaner": "^2.2",
"doctrine/dbal": "^2.13",
"firebase/php-jwt": "^6.8",
"guzzlehttp/guzzle": "^7.7",
"icewind/streams": "0.7.7",
"interfasys/lognormalizer": "^v1.0",
"laminas/laminas-inputfilter": "^2.21",
"laminas/laminas-servicemanager": "^3.17",
"laminas/laminas-validator": "^2.25",
"composer/semver": "^3.3",
"ext-json": "*",
"sabre/vobject": "^4.5",
"dg/composer-cleaner": "^2.2",
"firebase/php-jwt": "^6.8",
"ext-curl": "*",
"ext-apcu": "*",
"laravel/serializable-closure": "^1.3",
"ext-zip": "*",
"ext-memcached": "*",
"ext-gd": "*",
"ext-pdo": "*",
"ext-libxml": "*",
"ext-simplexml": "*",
"ext-fileinfo": "*",
"ext-exif": "*",
"ext-imagick": "*",
"ext-posix": "*"
"league/flysystem": "^1.1",
"nikic/php-parser": "^4.15",
"owncloud/tarstreamer": "v2.1.0",
"pear/archive_tar": "1.4.14",
"pear/pear-core-minimal": "^v1.10",
"phpseclib/phpseclib": "^3.0",
"pimple/pimple": "^3.5",
"punic/punic": "^3.8",
"sabre/dav": "^4.4",
"sabre/http": "^5.1",
"sabre/vobject": "^4.5",
"symfony/console": "^5.4",
"symfony/event-dispatcher": "^5.4",
"symfony/mailer": "^5.4",
"symfony/process": "^5.4",
"symfony/routing": "^5.4",
"symfony/translation": "^5.4"
},
"extra": {
"bamarni-bin": {
Expand Down
Loading

0 comments on commit 9ea1926

Please sign in to comment.