]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add support for theming
authorLukas Reschke <lukas@statuscode.ch>
Fri, 7 Apr 2017 12:51:05 +0000 (14:51 +0200)
committerMorris Jobke <hey@morrisjobke.de>
Fri, 7 Apr 2017 17:03:47 +0000 (12:03 -0500)
Add support for theming in generated emails and simplify API

Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
17 files changed:
apps/provisioning_api/lib/AppInfo/Application.php
apps/provisioning_api/lib/Controller/UsersController.php
apps/provisioning_api/tests/Controller/UsersControllerTest.php
apps/theming/lib/ThemingDefaults.php
apps/theming/tests/ThemingDefaultsTest.php
lib/private/Mail/EMailTemplate.php
lib/private/Mail/IEMailTemplate.php
lib/private/Server.php
settings/Application.php
settings/Controller/UsersController.php
settings/Mailer/NewUserMailHelper.php [new file with mode: 0644]
tests/Settings/Controller/UsersControllerTest.php
tests/Settings/Mailer/NewUserMailHelperTest.php [new file with mode: 0644]
tests/data/emails/new-account-email-custom.html [new file with mode: 0644]
tests/data/emails/new-account-email-custom.txt [new file with mode: 0644]
tests/data/emails/new-account-email.html
tests/lib/Mail/EMailTemplateTest.php

index 2d6a82e2ff9bfbd3211abec50268dd51b27e4c33..fd03fd41e16c314d2d96670116d2d1236ba2afec 100644 (file)
@@ -3,8 +3,11 @@
 namespace OCA\Provisioning_API\AppInfo;
 
 use OC\AppFramework\Utility\SimpleContainer;
+use OC\AppFramework\Utility\TimeFactory;
+use OC\Settings\Mailer\NewUserMailHelper;
 use OCA\Provisioning_API\Middleware\ProvisioningApiMiddleware;
 use OCP\AppFramework\App;
+use OCP\Util;
 
 class Application extends App {
        public function __construct(array $urlParams = array()) {
@@ -13,6 +16,19 @@ class Application extends App {
                $container = $this->getContainer();
                $server = $container->getServer();
 
+               $container->registerService(NewUserMailHelper::class, function(SimpleContainer $c) use ($server) {
+                       return new NewUserMailHelper(
+                               $server->getThemingDefaults(),
+                               $server->getURLGenerator(),
+                               $server->getL10N('settings'),
+                               $server->getMailer(),
+                               $server->getSecureRandom(),
+                               new TimeFactory(),
+                               $server->getConfig(),
+                               $server->getCrypto(),
+                               Util::getDefaultEmailAddress('no-reply')
+                       );
+               });
                $container->registerService('ProvisioningApiMiddleware', function(SimpleContainer $c) use ($server) {
                        $user = $server->getUserManager()->get($c['UserId']);
                        $isAdmin = $user !== null ? $server->getGroupManager()->isAdmin($user->getUID()) : false;
index 9155d34276b75f3a4be74d8af728c8061879b092..0ccbc978a69c67df2568056f886bad2cd62c9ef4 100644 (file)
@@ -30,6 +30,7 @@
 namespace OCA\Provisioning_API\Controller;
 
 use OC\Accounts\AccountManager;
+use OC\Settings\Mailer\NewUserMailHelper;
 use \OC_Helper;
 use OCP\AppFramework\Http\DataResponse;
 use OCP\AppFramework\Http\TemplateResponse;
@@ -72,6 +73,8 @@ class UsersController extends OCSController {
        private $defaults;
        /** @var IFactory */
        private $l10nFactory;
+       /** @var NewUserMailHelper */
+       private $newUserMailHelper;
 
        /**
         * @param string $appName
@@ -87,6 +90,7 @@ class UsersController extends OCSController {
         * @param IMailer $mailer
         * @param \OC_Defaults $defaults
         * @param IFactory $l10nFactory
+        * @param NewUserMailHelper $newUserMailHelper
         */
        public function __construct($appName,
                                                                IRequest $request,
@@ -100,7 +104,8 @@ class UsersController extends OCSController {
                                                                IURLGenerator $urlGenerator,
                                                                IMailer $mailer,
                                                                \OC_Defaults $defaults,
-                                                               IFactory $l10nFactory) {
+                                                               IFactory $l10nFactory,
+                                                               NewUserMailHelper $newUserMailHelper) {
                parent::__construct($appName, $request);
 
                $this->userManager = $userManager;
@@ -114,6 +119,7 @@ class UsersController extends OCSController {
                $this->mailer = $mailer;
                $this->defaults = $defaults;
                $this->l10nFactory = $l10nFactory;
+               $this->newUserMailHelper = $newUserMailHelper;
        }
 
        /**
@@ -786,30 +792,10 @@ class UsersController extends OCSController {
 
                $l10n = $this->l10nFactory->get('settings', $lang);
 
-               // data for the mail template
-               $mailData = [
-                       'username' => $username,
-                       'url' => $this->urlGenerator->getAbsoluteURL('/')
-               ];
-
-               // FIXME: set users language in email
-               $mail = new TemplateResponse('settings', 'email.new_user', $mailData, 'blank');
-               $mailContent = $mail->render();
-
-               // FIXME: set users language in email
-               $mail = new TemplateResponse('settings', 'email.new_user_plain_text', $mailData, 'blank');
-               $plainTextMailContent = $mail->render();
-
-               $subject = $l10n->t('Your %s account was created', [$this->defaults->getName()]);
-
                try {
-                       $message = $this->mailer->createMessage();
-                       $message->setTo([$email => $username]);
-                       $message->setSubject($subject);
-                       $message->setHtmlBody($mailContent);
-                       $message->setPlainBody($plainTextMailContent);
-                       $message->setFrom([$this->fromMailAddress => $this->defaults->getName()]);
-                       $this->mailer->send($message);
+                       $this->newUserMailHelper->setL10N($l10n);
+                       $emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
+                       $this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
                } catch(\Exception $e) {
                        $this->logger->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
                        throw new OCSException('Sending email failed', 102);
index b5b63319d3534cba34486c18a940bb1cf6fb0f7b..0cbcccebf6ffd361a1f54f4abbfe9ee9c83d0c5e 100644 (file)
@@ -32,6 +32,8 @@ namespace OCA\Provisioning_API\Tests\Controller;
 use Exception;
 use OC\Accounts\AccountManager;
 use OC\Group\Manager;
+use OC\Mail\IEMailTemplate;
+use OC\Settings\Mailer\NewUserMailHelper;
 use OC\SubAdmin;
 use OCA\Provisioning_API\Controller\UsersController;
 use OCP\AppFramework\Http\DataResponse;
@@ -54,39 +56,30 @@ class UsersControllerTest extends TestCase {
 
        /** @var IUserManager|PHPUnit_Framework_MockObject_MockObject */
        protected $userManager;
-
        /** @var IConfig|PHPUnit_Framework_MockObject_MockObject */
        protected $config;
-
        /** @var Manager|PHPUnit_Framework_MockObject_MockObject */
        protected $groupManager;
-
        /** @var IUserSession|PHPUnit_Framework_MockObject_MockObject */
        protected $userSession;
-
        /** @var ILogger|PHPUnit_Framework_MockObject_MockObject */
        protected $logger;
-
        /** @var UsersController|PHPUnit_Framework_MockObject_MockObject */
        protected $api;
-
        /** @var  AccountManager|PHPUnit_Framework_MockObject_MockObject */
        protected $accountManager;
-
        /** @var  IRequest|PHPUnit_Framework_MockObject_MockObject */
        protected $request;
-
-       /** @var IURLGenerator | PHPUnit_Framework_MockObject_MockObject */
+       /** @var IURLGenerator|PHPUnit_Framework_MockObject_MockObject */
        private $urlGenerator;
-
-       /** @var IMailer | PHPUnit_Framework_MockObject_MockObject */
+       /** @var IMailer|PHPUnit_Framework_MockObject_MockObject */
        private $mailer;
-
-       /** @var \OC_Defaults | PHPUnit_Framework_MockObject_MockObject */
+       /** @var \OC_Defaults|PHPUnit_Framework_MockObject_MockObject */
        private $defaults;
-
-       /** @var IFactory | PHPUnit_Framework_MockObject_MockObject */
+       /** @var IFactory|PHPUnit_Framework_MockObject_MockObject */
        private $l10nFactory;
+       /** @var NewUserMailHelper|PHPUnit_Framework_MockObject_MockObject */
+       private $newUserMailHelper;
 
        protected function setUp() {
                parent::setUp();
@@ -102,6 +95,7 @@ class UsersControllerTest extends TestCase {
                $this->mailer = $this->createMock(IMailer::class);
                $this->defaults = $this->createMock(\OC_Defaults::class);
                $this->l10nFactory = $this->createMock(IFactory::class);
+               $this->newUserMailHelper = $this->createMock(NewUserMailHelper::class);
 
                $this->api = $this->getMockBuilder(UsersController::class)
                        ->setConstructorArgs([
@@ -117,7 +111,8 @@ class UsersControllerTest extends TestCase {
                                $this->urlGenerator,
                                $this->mailer,
                                $this->defaults,
-                               $this->l10nFactory
+                               $this->l10nFactory,
+                               $this->newUserMailHelper
                        ])
                        ->setMethods(['fillStorageInfo'])
                        ->getMock();
@@ -2621,7 +2616,8 @@ class UsersControllerTest extends TestCase {
                                $this->urlGenerator,
                                $this->mailer,
                                $this->defaults,
-                               $this->l10nFactory
+                               $this->l10nFactory,
+                               $this->newUserMailHelper
                        ])
                        ->setMethods(['getUserData'])
                        ->getMock();
@@ -2684,7 +2680,8 @@ class UsersControllerTest extends TestCase {
                                $this->urlGenerator,
                                $this->mailer,
                                $this->defaults,
-                               $this->l10nFactory
+                               $this->l10nFactory,
+                               $this->newUserMailHelper
                        ])
                        ->setMethods(['getUserData'])
                        ->getMock();
@@ -2884,56 +2881,6 @@ class UsersControllerTest extends TestCase {
                        ->expects($this->once())
                        ->method('getEmailAddress')
                        ->will($this->returnValue('abc@example.org'));
-               $message = $this->getMockBuilder('\OC\Mail\Message')
-                       ->disableOriginalConstructor()->getMock();
-               $message
-                       ->expects($this->at(0))
-                       ->method('setTo')
-                       ->with(['abc@example.org' => 'user-id']);
-               $message
-                       ->expects($this->at(1))
-                       ->method('setSubject')
-                       ->with('Your  account was created');
-               $htmlBody = new TemplateResponse(
-                       'settings',
-                       'email.new_user',
-                       [
-                               'username' => 'user-id',
-                               'url' => null,
-                       ],
-                       'blank'
-               );
-               $message
-                       ->expects($this->at(2))
-                       ->method('setHtmlBody')
-                       ->with($htmlBody->render());
-               $plainBody = new TemplateResponse(
-                       'settings',
-                       'email.new_user_plain_text',
-                       [
-                               'username' => 'user-id',
-                               'url' => null,
-                       ],
-                       'blank'
-               );
-               $message
-                       ->expects($this->at(3))
-                       ->method('setPlainBody')
-                       ->with($plainBody->render());
-               $message
-                       ->expects($this->at(4))
-                       ->method('setFrom')
-                       ->with(['test@example.org' => null]);
-
-               $this->mailer
-                       ->expects($this->at(0))
-                       ->method('createMessage')
-                       ->will($this->returnValue($message));
-               $this->mailer
-                       ->expects($this->at(1))
-                       ->method('send')
-                       ->with($message);
-
                $this->config
                        ->expects($this->at(0))
                        ->method('getUserValue')
@@ -2942,11 +2889,6 @@ class UsersControllerTest extends TestCase {
                $l10n = $this->getMockBuilder(IL10N::class)
                        ->disableOriginalConstructor()
                        ->getMock();
-               $l10n
-                       ->expects($this->at(0))
-                       ->method('t')
-                       ->with('Your %s account was created', [null])
-                       ->willReturn('Your  account was created');
                $this->l10nFactory
                        ->expects($this->at(0))
                        ->method('languageExists')
@@ -2957,6 +2899,19 @@ class UsersControllerTest extends TestCase {
                        ->method('get')
                        ->with('settings', 'es')
                        ->willReturn($l10n);
+               $emailTemplate = $this->createMock(IEMailTemplate::class);
+               $this->newUserMailHelper
+                       ->expects($this->at(0))
+                       ->method('setL10N')
+                       ->willReturn($l10n);
+               $this->newUserMailHelper
+                       ->expects($this->at(1))
+                       ->method('generateTemplate')
+                       ->willReturn($emailTemplate);
+               $this->newUserMailHelper
+                       ->expects($this->at(2))
+                       ->method('sendMail')
+                       ->with($targetUser, $emailTemplate);
 
                $this->api->resendWelcomeMessage('UserToGet');
        }
@@ -2996,56 +2951,6 @@ class UsersControllerTest extends TestCase {
                        ->expects($this->once())
                        ->method('getEmailAddress')
                        ->will($this->returnValue('abc@example.org'));
-               $message = $this->getMockBuilder('\OC\Mail\Message')
-                       ->disableOriginalConstructor()->getMock();
-               $message
-                       ->expects($this->at(0))
-                       ->method('setTo')
-                       ->with(['abc@example.org' => 'user-id']);
-               $message
-                       ->expects($this->at(1))
-                       ->method('setSubject')
-                       ->with('Your  account was created');
-               $htmlBody = new TemplateResponse(
-                       'settings',
-                       'email.new_user',
-                       [
-                               'username' => 'user-id',
-                               'url' => null,
-                       ],
-                       'blank'
-               );
-               $message
-                       ->expects($this->at(2))
-                       ->method('setHtmlBody')
-                       ->with($htmlBody->render());
-               $plainBody = new TemplateResponse(
-                       'settings',
-                       'email.new_user_plain_text',
-                       [
-                               'username' => 'user-id',
-                               'url' => null,
-                       ],
-                       'blank'
-               );
-               $message
-                       ->expects($this->at(3))
-                       ->method('setPlainBody')
-                       ->with($plainBody->render());
-               $message
-                       ->expects($this->at(4))
-                       ->method('setFrom')
-                       ->with(['test@example.org' => null]);
-
-               $this->mailer
-                       ->expects($this->at(0))
-                       ->method('createMessage')
-                       ->will($this->returnValue($message));
-               $this->mailer
-                       ->expects($this->at(1))
-                       ->method('send')
-                       ->with($message);
-
                $this->config
                        ->expects($this->at(0))
                        ->method('getUserValue')
@@ -3054,11 +2959,6 @@ class UsersControllerTest extends TestCase {
                $l10n = $this->getMockBuilder(IL10N::class)
                        ->disableOriginalConstructor()
                        ->getMock();
-               $l10n
-                       ->expects($this->at(0))
-                       ->method('t')
-                       ->with('Your %s account was created', [null])
-                       ->willReturn('Your  account was created');
                $this->l10nFactory
                        ->expects($this->at(0))
                        ->method('languageExists')
@@ -3069,6 +2969,19 @@ class UsersControllerTest extends TestCase {
                        ->method('get')
                        ->with('settings', 'en')
                        ->willReturn($l10n);
+               $emailTemplate = $this->createMock(IEMailTemplate::class);
+               $this->newUserMailHelper
+                       ->expects($this->at(0))
+                       ->method('setL10N')
+                       ->willReturn($l10n);
+               $this->newUserMailHelper
+                       ->expects($this->at(1))
+                       ->method('generateTemplate')
+                       ->willReturn($emailTemplate);
+               $this->newUserMailHelper
+                       ->expects($this->at(2))
+                       ->method('sendMail')
+                       ->with($targetUser, $emailTemplate);
 
                $this->api->resendWelcomeMessage('UserToGet');
        }
@@ -3113,56 +3026,6 @@ class UsersControllerTest extends TestCase {
                        ->expects($this->once())
                        ->method('getEmailAddress')
                        ->will($this->returnValue('abc@example.org'));
-               $message = $this->getMockBuilder('\OC\Mail\Message')
-                       ->disableOriginalConstructor()->getMock();
-               $message
-                       ->expects($this->at(0))
-                       ->method('setTo')
-                       ->with(['abc@example.org' => 'user-id']);
-               $message
-                       ->expects($this->at(1))
-                       ->method('setSubject')
-                       ->with('Your  account was created');
-               $htmlBody = new TemplateResponse(
-                       'settings',
-                       'email.new_user',
-                       [
-                               'username' => 'user-id',
-                               'url' => null,
-                       ],
-                       'blank'
-               );
-               $message
-                       ->expects($this->at(2))
-                       ->method('setHtmlBody')
-                       ->with($htmlBody->render());
-               $plainBody = new TemplateResponse(
-                       'settings',
-                       'email.new_user_plain_text',
-                       [
-                               'username' => 'user-id',
-                               'url' => null,
-                       ],
-                       'blank'
-               );
-               $message
-                       ->expects($this->at(3))
-                       ->method('setPlainBody')
-                       ->with($plainBody->render());
-               $message
-                       ->expects($this->at(4))
-                       ->method('setFrom')
-                       ->with(['test@example.org' => null]);
-
-               $this->mailer
-                       ->expects($this->at(0))
-                       ->method('createMessage')
-                       ->will($this->returnValue($message));
-               $this->mailer
-                       ->expects($this->at(1))
-                       ->method('send')
-                       ->will($this->throwException(new \Exception()));
-
                $this->config
                        ->expects($this->at(0))
                        ->method('getUserValue')
@@ -3171,11 +3034,6 @@ class UsersControllerTest extends TestCase {
                $l10n = $this->getMockBuilder(IL10N::class)
                        ->disableOriginalConstructor()
                        ->getMock();
-               $l10n
-                       ->expects($this->at(0))
-                       ->method('t')
-                       ->with('Your %s account was created', [null])
-                       ->willReturn('Your  account was created');
                $this->l10nFactory
                        ->expects($this->at(0))
                        ->method('languageExists')
@@ -3186,6 +3044,20 @@ class UsersControllerTest extends TestCase {
                        ->method('get')
                        ->with('settings', 'es')
                        ->willReturn($l10n);
+               $emailTemplate = $this->createMock(IEMailTemplate::class);
+               $this->newUserMailHelper
+                       ->expects($this->at(0))
+                       ->method('setL10N')
+                       ->willReturn($l10n);
+               $this->newUserMailHelper
+                       ->expects($this->at(1))
+                       ->method('generateTemplate')
+                       ->willReturn($emailTemplate);
+               $this->newUserMailHelper
+                       ->expects($this->at(2))
+                       ->method('sendMail')
+                       ->with($targetUser, $emailTemplate)
+                       ->willThrowException(new \Exception());
 
                $this->api->resendWelcomeMessage('UserToGet');
        }
index 5a863b1eb22dda8fc0b81cccb2fb3d098ef10f61..d4dc56d3ba9000ae00071a286f6d7676a727ffee 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 /**
  * @copyright Copyright (c) 2016 Bjoern Schiessle <bjoern@schiessle.org>
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
  *
  * @license GNU AGPL version 3 or any later version
  *
  *
  */
 
-
 namespace OCA\Theming;
 
 
+use OCP\Files\IAppData;
 use OCP\ICacheFactory;
 use OCP\IConfig;
 use OCP\IL10N;
 use OCP\IURLGenerator;
-use OCP\Files\IRootFolder;
 use OCP\Util;
 
 class ThemingDefaults extends \OC_Defaults {
@@ -38,8 +38,8 @@ class ThemingDefaults extends \OC_Defaults {
        private $l;
        /** @var IURLGenerator */
        private $urlGenerator;
-       /** @var IRootFolder */
-       private $rootFolder;
+       /** @var IAppData */
+       private $appData;
        /** @var ICacheFactory */
        private $cacheFactory;
        /** @var string */
@@ -58,21 +58,21 @@ class ThemingDefaults extends \OC_Defaults {
         * @param IL10N $l
         * @param IURLGenerator $urlGenerator
         * @param \OC_Defaults $defaults
-        * @param IRootFolder $rootFolder
+        * @param IAppData $appData
         * @param ICacheFactory $cacheFactory
         */
        public function __construct(IConfig $config,
                                                                IL10N $l,
                                                                IURLGenerator $urlGenerator,
                                                                \OC_Defaults $defaults,
-                                                               IRootFolder $rootFolder,
+                                                               IAppData $appData,
                                                                ICacheFactory $cacheFactory
        ) {
                parent::__construct();
                $this->config = $config;
                $this->l = $l;
                $this->urlGenerator = $urlGenerator;
-               $this->rootFolder = $rootFolder;
+               $this->appData = $appData;
                $this->cacheFactory = $cacheFactory;
 
                $this->name = $defaults->getName();
@@ -130,11 +130,19 @@ class ThemingDefaults extends \OC_Defaults {
         */
        public function getLogo() {
                $logo = $this->config->getAppValue('theming', 'logoMime');
-               if(!$logo || !$this->rootFolder->nodeExists('/themedinstancelogo')) {
+
+               $logoExists = true;
+               try {
+                       $this->appData->getFolder('images')->getFile('logo');
+               } catch (\Exception $e) {
+                       $logoExists = false;
+               }
+
+               if(!$logo || !$logoExists) {
                        return $this->urlGenerator->imagePath('core','logo.svg');
-               } else {
-                       return $this->urlGenerator->linkToRoute('theming.Theming.getLogo');
                }
+
+               return $this->urlGenerator->linkToRoute('theming.Theming.getLogo');
        }
 
        /**
@@ -144,11 +152,19 @@ class ThemingDefaults extends \OC_Defaults {
         */
        public function getBackground() {
                $backgroundLogo = $this->config->getAppValue('theming', 'backgroundMime');
-               if(!$backgroundLogo || !$this->rootFolder->nodeExists('/themedbackgroundlogo')) {
+
+               $backgroundExists = true;
+               try {
+                       $this->appData->getFolder('images')->getFile('background');
+               } catch (\Exception $e) {
+                       $backgroundExists = false;
+               }
+
+               if(!$backgroundLogo || !$backgroundExists) {
                        return $this->urlGenerator->imagePath('core','background.jpg');
-               } else {
-                       return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground');
                }
+
+               return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground');
        }
 
        /**
@@ -174,6 +190,15 @@ class ThemingDefaults extends \OC_Defaults {
                return $value;
        }
 
+       /**
+        * Gets the current cache buster count
+        *
+        * @return string
+        */
+       public function getCacheBusterCounter() {
+               return $this->config->getAppValue('theming', 'cachebuster', '0');
+       }
+
        /**
         * Increases the cache buster key
         */
index 72ccaa57d7707d97f4a01a0787bb3ac41b7ea285..986b2f342674e2e3765c36e01e788fbf59f0516f 100644 (file)
 namespace OCA\Theming\Tests;
 
 use OCA\Theming\ThemingDefaults;
+use OCP\Files\IAppData;
+use OCP\Files\SimpleFS\ISimpleFolder;
 use OCP\ICacheFactory;
 use OCP\IConfig;
 use OCP\IL10N;
 use OCP\IURLGenerator;
-use OCP\Files\IRootFolder;
 use Test\TestCase;
 
 class ThemingDefaultsTest extends TestCase {
-       /** @var IConfig */
+       /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
        private $config;
-       /** @var IL10N */
+       /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
        private $l10n;
-       /** @var IURLGenerator */
+       /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
        private $urlGenerator;
-       /** @var \OC_Defaults */
+       /** @var \OC_Defaults|\PHPUnit_Framework_MockObject_MockObject */
        private $defaults;
+       /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */
+       private $appData;
+       /** @var ICacheFactory|\PHPUnit_Framework_MockObject_MockObject */
+       private $cacheFactory;
        /** @var ThemingDefaults */
        private $template;
-       /** @var IRootFolder */
-       private $rootFolder;
-       /** @var ICacheFactory */
-       private $cacheFactory;
 
        public function setUp() {
                parent::setUp();
                $this->config = $this->getMockBuilder(IConfig::class)->getMock();
                $this->l10n = $this->getMockBuilder(IL10N::class)->getMock();
                $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock();
-               $this->rootFolder = $this->getMockBuilder(IRootFolder::class)
-                       ->disableOriginalConstructor()
-                       ->getMock();
+               $this->appData = $this->createMock(IAppData::class);
                $this->cacheFactory = $this->getMockBuilder(ICacheFactory::class)->getMock();
                $this->defaults = $this->getMockBuilder(\OC_Defaults::class)
                        ->disableOriginalConstructor()
@@ -80,7 +79,7 @@ class ThemingDefaultsTest extends TestCase {
                        $this->l10n,
                        $this->urlGenerator,
                        $this->defaults,
-                       $this->rootFolder,
+                       $this->appData,
                        $this->cacheFactory
                );
        }
@@ -386,6 +385,11 @@ class ThemingDefaultsTest extends TestCase {
                        ->method('getAppValue')
                        ->with('theming', 'backgroundMime')
                        ->willReturn('');
+               $this->appData
+                       ->expects($this->once())
+                       ->method('getFolder')
+                       ->with('images')
+                       ->willThrowException(new \Exception());
                $expected = $this->urlGenerator->imagePath('core','background.jpg');
                $this->assertEquals($expected, $this->template->getBackground());
        }
@@ -396,6 +400,17 @@ class ThemingDefaultsTest extends TestCase {
                        ->method('getAppValue')
                        ->with('theming', 'backgroundMime')
                        ->willReturn('image/svg+xml');
+               $simpleFolder = $this->createMock(ISimpleFolder::class);
+               $this->appData
+                       ->expects($this->once())
+                       ->method('getFolder')
+                       ->with('images')
+                       ->willReturn($simpleFolder);
+               $simpleFolder
+                       ->expects($this->once())
+                       ->method('getFile')
+                       ->with('background')
+                       ->willReturn('');
                $expected = $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground');
                $this->assertEquals($expected, $this->template->getBackground());
        }
@@ -406,6 +421,11 @@ class ThemingDefaultsTest extends TestCase {
                        ->method('getAppValue')
                        ->with('theming', 'logoMime')
                        ->willReturn('');
+               $this->appData
+                       ->expects($this->once())
+                       ->method('getFolder')
+                       ->with('images')
+                       ->willThrowException(new \Exception());
                $expected = $this->urlGenerator->imagePath('core','logo.svg');
                $this->assertEquals($expected, $this->template->getLogo());
        }
@@ -416,6 +436,17 @@ class ThemingDefaultsTest extends TestCase {
                        ->method('getAppValue')
                        ->with('theming', 'logoMime')
                        ->willReturn('image/svg+xml');
+               $simpleFolder = $this->createMock(ISimpleFolder::class);
+               $this->appData
+                       ->expects($this->once())
+                       ->method('getFolder')
+                       ->with('images')
+                       ->willReturn($simpleFolder);
+               $simpleFolder
+                       ->expects($this->once())
+                       ->method('getFile')
+                       ->with('logo')
+                       ->willReturn('');
                $expected = $this->urlGenerator->linkToRoute('theming.Theming.getLogo');
                $this->assertEquals($expected, $this->template->getLogo());
        }
index 7a884dd928c84f111317634d8344edac40d90216..7d3ca51c50e6904425373a513c7ed58b6263f04d 100644 (file)
@@ -1,8 +1,10 @@
 <?php
 /**
  * @copyright 2017, Morris Jobke <hey@morrisjobke.de>
+ * @copyright 2017, Lukas Reschke <lukas@statuscode.ch>
  *
  * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Lukas Reschke <lukas@statuscode.ch>
  *
  * @license GNU AGPL version 3 or any later version
  *
@@ -23,6 +25,9 @@
 
 namespace OC\Mail;
 
+use OCA\Theming\ThemingDefaults;
+use OCP\IL10N;
+use OCP\IURLGenerator;
 
 /**
  * Class EMailTemplate
@@ -33,9 +38,12 @@ namespace OC\Mail;
  * @package OC\Mail
  */
 class EMailTemplate implements IEMailTemplate {
-
-       /** @var \OC_Defaults */
-       protected $defaults;
+       /** @var ThemingDefaults */
+       protected $themingDefaults;
+       /** @var IURLGenerator */
+       protected $urlGenerator;
+       /** @var IL10N */
+       protected $l10n;
 
        /** @var string */
        protected $htmlBody = '';
@@ -88,7 +96,7 @@ EOF;
                                                <table class="row collapse" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
                                                        <tbody>
                                                        <tr style="padding:0;text-align:left;vertical-align:top">
-                                                               <center data-parsed="" style="min-width:580px;width:100%%"><!-- TODO -->
+                                                               <center data-parsed="" style="min-width:580px;width:100%%">
                                                                        <img class="logo float-center" src="%s" alt="logo" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;max-height:100%%;max-width:100px;outline:0;text-align:center;text-decoration:none;width:auto">
                                                                </center>
                                                        </tr>
@@ -240,8 +248,7 @@ EOF;
 <table align="center" class="wrapper footer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
        <tr style="padding:0;text-align:left;vertical-align:top">
                <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
-                       <center data-parsed="" style="min-width:580px;width:100%%"><!-- TODO -->
-                               <img class="logo float-center" src="%s" alt="logo" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;max-height:100%%;max-width:75px;outline:0;text-align:center;text-decoration:none;width:auto">
+                       <center data-parsed="" style="min-width:580px;width:100%%">
                                <table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
                                        <tbody>
                                        <tr style="padding:0;text-align:left;vertical-align:top">
@@ -249,32 +256,38 @@ EOF;
                                        </tr>
                                        </tbody>
                                </table>
-                               <p class="text-center float-center" align="center" style="Margin:0;Margin-bottom:10px;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:12px;font-weight:400;line-height:16px;margin:0;margin-bottom:10px;padding:0;text-align:center">%s</p>
+                               <p class="text-center float-center" align="center" style="Margin:0;Margin-bottom:10px;color:#C8C8C8;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:12px;font-weight:400;line-height:16px;margin:0;margin-bottom:10px;padding:0;text-align:center">%s</p>
                        </center>
                </td>
        </tr>
 </table>
 EOF;
 
-
-       public function __construct(\OC_Defaults $defaults) {
-               $this->defaults = $defaults;
-
+       /**
+        * @param ThemingDefaults $themingDefaults
+        * @param IURLGenerator $urlGenerator
+        * @param IL10N $l10n
+        */
+       public function __construct(ThemingDefaults $themingDefaults,
+                                                               IURLGenerator $urlGenerator,
+                                                               IL10N $l10n) {
+               $this->themingDefaults = $themingDefaults;
+               $this->urlGenerator = $urlGenerator;
+               $this->l10n = $l10n;
                $this->htmlBody .= $this->head;
        }
 
        /**
         * Adds a header to the email
-        *
-        * @param string $logoUrl
         */
-       public function addHeader($logoUrl) {
+       public function addHeader() {
                if ($this->headerAdded) {
                        return;
                }
                $this->headerAdded = true;
 
-               $this->htmlBody .= vsprintf($this->header, [$this->defaults->getColorPrimary(), $logoUrl]);
+               $logoUrl = $this->urlGenerator->getAbsoluteURL($this->themingDefaults->getLogo()) . '?v='. $this->themingDefaults->getCacheBusterCounter();
+               $this->htmlBody .= vsprintf($this->header, [$this->themingDefaults->getColorPrimary(), $logoUrl]);
        }
 
        /**
@@ -328,7 +341,7 @@ EOF;
                        $this->bodyOpened = true;
                }
 
-               $color = $this->defaults->getColorPrimary();
+               $color = $this->themingDefaults->getColorPrimary();
                $this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, $textLeft, $urlRight, $textRight]);
                $this->plainBody .= $textLeft . ': ' . $urlLeft . PHP_EOL;
                $this->plainBody .= $textRight . ': ' . $urlRight . PHP_EOL . PHP_EOL;
@@ -338,10 +351,13 @@ EOF;
        /**
         * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
         *
-        * @param string $logoUrl
         * @param string $text
         */
-       public function addFooter($logoUrl, $text) {
+       public function addFooter($text = '') {
+               if($text === '') {
+                       $text = $this->themingDefaults->getName() . ' - ' . $this->themingDefaults->getSlogan() . '<br>' . $this->l10n->t('This is an automatically generated email, please do not reply.');
+               }
+
                if ($this->footerAdded) {
                        return;
                }
@@ -351,7 +367,8 @@ EOF;
                        $this->htmlBody .= $this->bodyEnd;
                        $this->bodyOpened = false;
                }
-               $this->htmlBody .= vsprintf($this->footer, [$logoUrl, $text]);
+
+               $this->htmlBody .= vsprintf($this->footer, [$text]);
                $this->htmlBody .= $this->tail;
                $this->plainBody .= '--' . PHP_EOL;
                $this->plainBody .= str_replace('<br>', PHP_EOL, $text);
@@ -389,4 +406,3 @@ EOF;
                return $this->plainBody;
        }
 }
-
index 5bf2b8e43943201b89b929126081ddf350402e2e..0d660a355167164461c98b2fbaccc6e81df180e3 100644 (file)
@@ -34,7 +34,7 @@ namespace OC\Mail;
  *
  * $emailTemplate = new EMailTemplate($this->defaults);
  *
- * $emailTemplate->addHeader('https://example.org/img/logo-mail-header.png');
+ * $emailTemplate->addHeader();
  * $emailTemplate->addHeading('Welcome aboard');
  * $emailTemplate->addBodyText('You have now an Nextcloud account, you can add, protect, and share your data.');
  *
@@ -43,21 +43,25 @@ namespace OC\Mail;
  *     'Install Client', 'https://nextcloud.com/install/#install-clients'
  * );
  *
- * $emailTemplate->addFooter(
- *     'https://example.org/img/logo-mail-footer.png',
- *     'Nextcloud - a safe home for your data <br>This is an automatically generated email, please do not reply.'
- * );
+ * $emailTemplate->addFooter('Optional footer text');
  *
  * $htmlContent = $emailTemplate->renderHTML();
  * $plainContent = $emailTemplate->renderText();
  */
 interface IEMailTemplate {
+       /**
+        * @param \OCA\Theming\ThemingDefaults $themingDefaults
+        * @param \OCP\IURLGenerator $urlGenerator
+        * @param \OCP\IL10N $l10n
+        */
+       public function __construct(\OCA\Theming\ThemingDefaults $themingDefaults,
+                                                               \OCP\IURLGenerator $urlGenerator,
+                                                               \OCP\IL10N $l10n);
+
        /**
         * Adds a header to the email
-        *
-        * @param string $logoUrl
         */
-       public function addHeader($logoUrl);
+       public function addHeader();
 
        /**
         * Adds a heading to the email
@@ -86,10 +90,9 @@ interface IEMailTemplate {
        /**
         * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
         *
-        * @param string $logoUrl
         * @param string $text
         */
-       public function addFooter($logoUrl, $text);
+       public function addFooter($text = '');
 
        /**
         * Returns the rendered HTML email as string
@@ -104,4 +107,4 @@ interface IEMailTemplate {
         * @return string
         */
        public function renderText();
-}
\ No newline at end of file
+}
index 98910b097b7191a66995fb462a40d1fb9b4672fa..0d05bfe0dc8b0f3b927d86f1a2f42fe3a34cc06f 100644 (file)
@@ -823,7 +823,7 @@ class Server extends ServerContainer implements IServerContainer {
                                        $c->getL10N('theming'),
                                        $c->getURLGenerator(),
                                        new \OC_Defaults(),
-                                       $c->getLazyRootFolder(),
+                                       $c->getAppDataDir('theming'),
                                        $c->getMemCacheFactory()
                                );
                        }
@@ -1572,7 +1572,7 @@ class Server extends ServerContainer implements IServerContainer {
        }
 
        /**
-        * @return \OC_Defaults
+        * @return \OCA\Theming\ThemingDefaults
         */
        public function getThemingDefaults() {
                return $this->query('ThemingDefaults');
index 44747c2f6817ed9903288a6d5c7dac1b0905456a..bf149def94d9550607d31c9aa6d219c3b9c08487 100644 (file)
@@ -35,7 +35,10 @@ use OC\App\AppStore\Fetcher\CategoryFetcher;
 use OC\AppFramework\Utility\TimeFactory;
 use OC\Authentication\Token\IProvider;
 use OC\Server;
+use OC\ServerContainer;
+use OC\Settings\Mailer\NewUserMailHelper;
 use OC\Settings\Middleware\SubadminMiddleware;
+use OCA\Theming\ThemingDefaults;
 use OCP\AppFramework\App;
 use OCP\IContainer;
 use OCP\Settings\IManager;
@@ -75,9 +78,6 @@ class Application extends App {
                        }
                        return $isSubAdmin;
                });
-               $container->registerService('fromMailAddress', function() {
-                       return Util::getDefaultEmailAddress('no-reply');
-               });
                $container->registerService('userCertificateManager', function(IContainer $c) {
                        return $c->query('ServerContainer')->getCertificateManager();
                }, false);
@@ -90,6 +90,23 @@ class Application extends App {
                $container->registerService(IManager::class, function (IContainer $c) {
                        return $c->query('ServerContainer')->getSettingsManager();
                });
+
+               $container->registerService(NewUserMailHelper::class, function (IContainer $c) {
+                       /** @var Server $server */
+                       $server = $c->query('ServerContainer');
+
+                       return new NewUserMailHelper(
+                               $server->getThemingDefaults(),
+                               $server->getURLGenerator(),
+                               $server->getL10N('settings'),
+                               $server->getMailer(),
+                               $server->getSecureRandom(),
+                               new TimeFactory(),
+                               $server->getConfig(),
+                               $server->getCrypto(),
+                               Util::getDefaultEmailAddress('no-reply')
+                       );
+               });
                $container->registerService(AppFetcher::class, function (IContainer $c) {
                        /** @var Server $server */
                        $server = $c->query('ServerContainer');
index c7b2c2537dace169f7d767bd0ff57108a3473899..b42d4faa56993f709c8ad5c0ed6cef8dfedfa570 100644 (file)
@@ -33,12 +33,10 @@ namespace OC\Settings\Controller;
 use OC\Accounts\AccountManager;
 use OC\AppFramework\Http;
 use OC\ForbiddenException;
-use OC\Mail\EMailTemplate;
-use OC\User\User;
+use OC\Settings\Mailer\NewUserMailHelper;
 use OCP\App\IAppManager;
 use OCP\AppFramework\Controller;
 use OCP\AppFramework\Http\DataResponse;
-use OCP\AppFramework\Http\TemplateResponse;
 use OCP\IConfig;
 use OCP\IGroupManager;
 use OCP\IL10N;
@@ -50,9 +48,7 @@ use OCP\IUserManager;
 use OCP\IUserSession;
 use OCP\Mail\IMailer;
 use OCP\IAvatarManager;
-use OCP\Security\ICrypto;
 use OCP\Security\ISecureRandom;
-use OCP\AppFramework\Utility\ITimeFactory;
 
 /**
  * @package OC\Settings\Controller
@@ -72,14 +68,8 @@ class UsersController extends Controller {
        private $config;
        /** @var ILogger */
        private $log;
-       /** @var \OC_Defaults */
-       private $defaults;
        /** @var IMailer */
        private $mailer;
-       /** @var string */
-       private $fromMailAddress;
-       /** @var IURLGenerator */
-       private $urlGenerator;
        /** @var bool contains the state of the encryption app */
        private $isEncryptionAppEnabled;
        /** @var bool contains the state of the admin recovery setting */
@@ -90,11 +80,8 @@ class UsersController extends Controller {
        private $accountManager;
        /** @var ISecureRandom */
        private $secureRandom;
-       /** @var ITimeFactory */
-       private $timeFactory;
-       /** @var ICrypto */
-       private $crypto;
-
+       /** @var NewUserMailHelper */
+       private $newUserMailHelper;
 
        /**
         * @param string $appName
@@ -106,16 +93,13 @@ class UsersController extends Controller {
         * @param bool $isAdmin
         * @param IL10N $l10n
         * @param ILogger $log
-        * @param \OC_Defaults $defaults
         * @param IMailer $mailer
-        * @param string $fromMailAddress
         * @param IURLGenerator $urlGenerator
         * @param IAppManager $appManager
         * @param IAvatarManager $avatarManager
         * @param AccountManager $accountManager
         * @param ISecureRandom $secureRandom
-        * @param ITimeFactory $timeFactory
-        * @param ICrypto $crypto
+        * @param NewUserMailHelper $newUserMailHelper
         */
        public function __construct($appName,
                                                                IRequest $request,
@@ -126,16 +110,13 @@ class UsersController extends Controller {
                                                                $isAdmin,
                                                                IL10N $l10n,
                                                                ILogger $log,
-                                                               \OC_Defaults $defaults,
                                                                IMailer $mailer,
-                                                               $fromMailAddress,
                                                                IURLGenerator $urlGenerator,
                                                                IAppManager $appManager,
                                                                IAvatarManager $avatarManager,
                                                                AccountManager $accountManager,
                                                                ISecureRandom $secureRandom,
-                                                               ITimeFactory $timeFactory,
-                                                               ICrypto $crypto) {
+                                                               NewUserMailHelper $newUserMailHelper) {
                parent::__construct($appName, $request);
                $this->userManager = $userManager;
                $this->groupManager = $groupManager;
@@ -144,15 +125,11 @@ class UsersController extends Controller {
                $this->isAdmin = $isAdmin;
                $this->l10n = $l10n;
                $this->log = $log;
-               $this->defaults = $defaults;
                $this->mailer = $mailer;
-               $this->fromMailAddress = $fromMailAddress;
-               $this->urlGenerator = $urlGenerator;
                $this->avatarManager = $avatarManager;
                $this->accountManager = $accountManager;
                $this->secureRandom = $secureRandom;
-               $this->timeFactory = $timeFactory;
-               $this->crypto = $crypto;
+               $this->newUserMailHelper = $newUserMailHelper;
 
                // check for encryption state - TODO see formatUserForIndex
                $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
@@ -380,7 +357,7 @@ class UsersController extends Controller {
                        );
                }
 
-               $generatedPassword = false;
+               $generatePasswordResetToken = false;
                if ($password === '') {
                        if ($email === '') {
                                return new DataResponse(
@@ -392,7 +369,7 @@ class UsersController extends Controller {
                        }
 
                        $password = $this->secureRandom->generate(32);
-                       $generatedPassword = true;
+                       $generatePasswordResetToken = true;
                }
 
                try {
@@ -426,68 +403,9 @@ class UsersController extends Controller {
                         */
                        if($email !== '') {
                                $user->setEMailAddress($email);
-
-                               if ($generatedPassword) {
-                                       $token = $this->secureRandom->generate(
-                                               21,
-                                               ISecureRandom::CHAR_DIGITS .
-                                               ISecureRandom::CHAR_LOWER .
-                                               ISecureRandom::CHAR_UPPER
-                                       );
-                                       $tokenValue = $this->timeFactory->getTime() . ':' . $token;
-                                       $mailAddress = !is_null($user->getEMailAddress()) ? $user->getEMailAddress() : '';
-                                       $encryptedValue = $this->crypto->encrypt($tokenValue, $mailAddress . $this->config->getSystemValue('secret'));
-                                       $this->config->setUserValue($username, 'core', 'lostpassword', $encryptedValue);
-
-                                       $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $username, 'token' => $token]);
-                               } else {
-                                       $link = $this->urlGenerator->getAbsoluteURL('/');
-                               }
-
-                               $emailTemplate = new EMailTemplate($this->defaults);
-
-                               $emailTemplate->addHeader($this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('', 'logo-mail-header.png')));
-
-                               $displayName = $user->getDisplayName();
-                               if ($displayName === $username) {
-                                       $emailTemplate->addHeading($this->l10n->t('Welcome aboard'));
-                               } else {
-                                       $emailTemplate->addHeading($this->l10n->t('Welcome aboard %s', [$displayName]));
-                               }
-                               $emailTemplate->addBodyText($this->l10n->t('You have now an %s account, you can add, protect, and share your data.', [$this->defaults->getName()]));
-                               $emailTemplate->addBodyText($this->l10n->t('Your username is: %s', [$username]));
-
-                               if ($generatedPassword) {
-                                       $leftButtonText = $this->l10n->t('Set your password');
-                               } else {
-                                       $leftButtonText = $this->l10n->t('Go to %s', [$this->defaults->getName()]);
-                               }
-
-                               $emailTemplate->addBodyButtonGroup(
-                                       $leftButtonText,
-                                       $link,
-                                       $this->l10n->t('Install Client'),
-                                       'https://nextcloud.com/install/#install-clients'
-                               );
-
-                               $emailTemplate->addFooter(
-                                       $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('', 'logo-mail-footer.png')),
-                                       $this->defaults->getName() . ' - ' . $this->defaults->getSlogan() . '<br>' . $this->l10n->t('This is an automatically generated email, please do not reply.')
-                               );
-
-                               $mailContent = $emailTemplate->renderHTML();
-                               $plainTextMailContent = $emailTemplate->renderText();
-
-                               $subject = $this->l10n->t('Your %s account was created', [$this->defaults->getName()]);
-
                                try {
-                                       $message = $this->mailer->createMessage();
-                                       $message->setTo([$email => $username]);
-                                       $message->setSubject($subject);
-                                       $message->setHtmlBody($mailContent);
-                                       $message->setPlainBody($plainTextMailContent);
-                                       $message->setFrom([$this->fromMailAddress => $this->defaults->getName()]);
-                                       $this->mailer->send($message);
+                                       $emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
+                                       $this->newUserMailHelper->sendMail($user, $emailTemplate);
                                } catch(\Exception $e) {
                                        $this->log->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
                                }
diff --git a/settings/Mailer/NewUserMailHelper.php b/settings/Mailer/NewUserMailHelper.php
new file mode 100644 (file)
index 0000000..15b912f
--- /dev/null
@@ -0,0 +1,166 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Settings\Mailer;
+
+use OC\Mail\EMailTemplate;
+use OC\Mail\IEMailTemplate;
+use OCA\Theming\ThemingDefaults;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\IConfig;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\Mail\IMailer;
+use OCP\Security\ICrypto;
+use OCP\Security\ISecureRandom;
+
+class NewUserMailHelper {
+       /** @var ThemingDefaults */
+       private $themingDefaults;
+       /** @var IURLGenerator */
+       private $urlGenerator;
+       /** @var IL10N */
+       private $l10n;
+       /** @var IMailer */
+       private $mailer;
+       /** @var ISecureRandom */
+       private $secureRandom;
+       /** @var ITimeFactory */
+       private $timeFactory;
+       /** @var IConfig */
+       private $config;
+       /** @var ICrypto */
+       private $crypto;
+       /** @var string */
+       private $fromAddress;
+
+       /**
+        * @param ThemingDefaults $themingDefaults
+        * @param IURLGenerator $urlGenerator
+        * @param IL10N $l10n
+        * @param IMailer $mailer
+        * @param ISecureRandom $secureRandom
+        * @param ITimeFactory $timeFactory
+        * @param IConfig $config
+        * @param ICrypto $crypto
+        * @param string $fromAddress
+        */
+       public function __construct(ThemingDefaults $themingDefaults,
+                                                               IURLGenerator $urlGenerator,
+                                                               IL10N $l10n,
+                                                               IMailer $mailer,
+                                                               ISecureRandom $secureRandom,
+                                                               ITimeFactory $timeFactory,
+                                                               IConfig $config,
+                                                               ICrypto $crypto,
+                                                               $fromAddress) {
+               $this->themingDefaults = $themingDefaults;
+               $this->urlGenerator = $urlGenerator;
+               $this->l10n = $l10n;
+               $this->mailer = $mailer;
+               $this->secureRandom = $secureRandom;
+               $this->timeFactory = $timeFactory;
+               $this->config = $config;
+               $this->crypto = $crypto;
+               $this->fromAddress = $fromAddress;
+       }
+
+       /**
+        * Set the IL10N object
+        *
+        * @param IL10N $l10n
+        */
+       public function setL10N(IL10N $l10n) {
+               $this->l10n = $l10n;
+       }
+
+       /**
+        * @param IUser $user
+        * @param bool $generatePasswordResetToken
+        * @return EMailTemplate
+        */
+       public function generateTemplate(IUser $user, $generatePasswordResetToken = false) {
+               if ($generatePasswordResetToken) {
+                       $token = $this->secureRandom->generate(
+                               21,
+                               ISecureRandom::CHAR_DIGITS .
+                               ISecureRandom::CHAR_LOWER .
+                               ISecureRandom::CHAR_UPPER
+                       );
+                       $tokenValue = $this->timeFactory->getTime() . ':' . $token;
+                       $mailAddress = (null !== $user->getEMailAddress()) ? $user->getEMailAddress() : '';
+                       $encryptedValue = $this->crypto->encrypt($tokenValue, $mailAddress . $this->config->getSystemValue('secret'));
+                       $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
+                       $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', ['userId' => $user->getUID(), 'token' => $token]);
+               } else {
+                       $link = $this->urlGenerator->getAbsoluteURL('/');
+               }
+
+               $emailTemplate = new EMailTemplate(
+                       $this->themingDefaults,
+                       $this->urlGenerator,
+                       $this->l10n
+               );
+               $emailTemplate->addHeader();
+               $displayName = $user->getDisplayName();
+               $userName = $user->getUID();
+               if ($displayName === $userName) {
+                       $emailTemplate->addHeading($this->l10n->t('Welcome aboard'));
+               } else {
+                       $emailTemplate->addHeading($this->l10n->t('Welcome aboard %s', [$displayName]));
+               }
+               $emailTemplate->addBodyText($this->l10n->t('You have now an %s account, you can add, protect, and share your data.', [$this->themingDefaults->getName()]));
+               $emailTemplate->addBodyText($this->l10n->t('Your username is: %s', [$userName]));
+               if ($generatePasswordResetToken) {
+                       $leftButtonText = $this->l10n->t('Set your password');
+               } else {
+                       $leftButtonText = $this->l10n->t('Go to %s', [$this->themingDefaults->getName()]);
+               }
+               $emailTemplate->addBodyButtonGroup(
+                       $leftButtonText,
+                       $link,
+                       $this->l10n->t('Install Client'),
+                       'https://nextcloud.com/install/#install-clients'
+               );
+               $emailTemplate->addFooter();
+
+               return $emailTemplate;
+       }
+
+       /**
+        * Sends a welcome mail to $user
+        *
+        * @param IUser $user
+        * @param IEmailTemplate $emailTemplate
+        * @throws \Exception If mail could not be sent
+        */
+       public function sendMail(IUser $user,
+                                                        IEMailTemplate $emailTemplate) {
+               $message = $this->mailer->createMessage();
+               $message->setTo([$user->getEMailAddress() => $user->getDisplayName()]);
+               $message->setSubject($this->l10n->t('Your %s account was created', [$this->themingDefaults->getName()]));
+               $message->setHtmlBody($emailTemplate->renderHTML());
+               $message->setPlainBody($emailTemplate->renderText());
+               $message->setFrom([$this->fromAddress => $this->themingDefaults->getName()]);
+               $this->mailer->send($message);
+       }
+}
index 52a9a1cc8449c0485397a56253366859f3f7a027..d7961e2332b89c5ae1c588a11b0ff9050f86383c 100644 (file)
@@ -12,8 +12,9 @@ namespace Tests\Settings\Controller;
 
 use OC\Accounts\AccountManager;
 use OC\Group\Manager;
-use OC\Mail\EMailTemplate;
+use OC\Mail\IEMailTemplate;
 use OC\Settings\Controller\UsersController;
+use OC\Settings\Mailer\NewUserMailHelper;
 use OCP\App\IAppManager;
 use OCP\AppFramework\Http;
 use OCP\AppFramework\Http\DataResponse;
@@ -69,6 +70,8 @@ class UsersControllerTest extends \Test\TestCase {
        private $secureRandom;
        /** @var ITimeFactory | \PHPUnit_Framework_MockObject_MockObject */
        private $timeFactory;
+       /** @var NewUserMailHelper|\PHPUnit_Framework_MockObject_MockObject */
+       private $newUserMailHelper;
        /** @var ICrypto | \PHPUnit_Framework_MockObject_MockObject */
        private $crypto;
 
@@ -80,7 +83,6 @@ class UsersControllerTest extends \Test\TestCase {
                $this->userSession = $this->createMock(IUserSession::class);
                $this->config = $this->createMock(IConfig::class);
                $this->logger = $this->createMock(ILogger::class);
-               $this->defaults = $this->createMock(\OC_Defaults::class);
                $this->mailer = $this->createMock(IMailer::class);
                $this->urlGenerator = $this->createMock(IURLGenerator::class);
                $this->appManager = $this->createMock(IAppManager::class);
@@ -89,6 +91,7 @@ class UsersControllerTest extends \Test\TestCase {
                $this->secureRandom = $this->createMock(ISecureRandom::class);
                $this->timeFactory = $this->createMock(ITimeFactory::class);
                $this->crypto = $this->createMock(ICrypto::class);
+               $this->newUserMailHelper = $this->createMock(NewUserMailHelper::class);
                $this->l = $this->createMock(IL10N::class);
                $this->l->method('t')
                        ->will($this->returnCallback(function ($text, $parameters = []) {
@@ -127,16 +130,13 @@ class UsersControllerTest extends \Test\TestCase {
                                $isAdmin,
                                $this->l,
                                $this->logger,
-                               $this->defaults,
                                $this->mailer,
-                               'no-reply@nextcloud.com',
                                $this->urlGenerator,
                                $this->appManager,
                                $this->avatarManager,
                                $this->accountManager,
                                $this->secureRandom,
-                               $this->timeFactory,
-                               $this->crypto
+                               $this->newUserMailHelper
                        );
                } else {
                        return $this->getMockBuilder(UsersController::class)
@@ -151,16 +151,13 @@ class UsersControllerTest extends \Test\TestCase {
                                                $isAdmin,
                                                $this->l,
                                                $this->logger,
-                                               $this->defaults,
                                                $this->mailer,
-                                               'no-reply@nextcloud.com',
                                                $this->urlGenerator,
                                                $this->appManager,
                                                $this->avatarManager,
                                                $this->accountManager,
                                                $this->secureRandom,
-                                               $this->timeFactory,
-                                               $this->crypto
+                                               $this->newUserMailHelper
                                        ]
                                )->setMethods($mockedMethods)->getMock();
                }
@@ -1418,91 +1415,11 @@ class UsersControllerTest extends \Test\TestCase {
         */
        public function testCreateSuccessfulWithValidEmailAdmin() {
                $controller = $this->getController(true);
-               $message = $this->getMockBuilder('\OC\Mail\Message')
-                       ->disableOriginalConstructor()->getMock();
-               $message
-                       ->expects($this->at(0))
-                       ->method('setTo')
-                       ->with(['validMail@Adre.ss' => 'foo']);
-               $message
-                       ->expects($this->at(1))
-                       ->method('setSubject')
-                       ->with('Your Nextcloud account was created');
-
-               $this->urlGenerator
-                       ->expects($this->at(0))
-                       ->method('getAbsoluteURL')
-                       ->with('/')
-                       ->willReturn('https://example.org/');
-               $this->urlGenerator
-                       ->expects($this->at(1))
-                       ->method('imagePath')
-                       ->with('', 'logo-mail-header.png')
-                       ->willReturn('/img/logo-mail-header.png');
-               $this->urlGenerator
-                       ->expects($this->at(2))
-                       ->method('getAbsoluteURL')
-                       ->with('/img/logo-mail-header.png')
-                       ->willReturn('https://example.org/img/logo-mail-header.png');
-               $this->urlGenerator
-                       ->expects($this->at(3))
-                       ->method('imagePath')
-                       ->with('', 'logo-mail-footer.png')
-                       ->willReturn('/img/logo-mail-footer.png');
-               $this->urlGenerator
-                       ->expects($this->at(4))
-                       ->method('getAbsoluteURL')
-                       ->with('/img/logo-mail-footer.png')
-                       ->willReturn('https://example.org/img/logo-mail-footer.png');
-               $this->defaults
-                       ->expects($this->any())
-                       ->method('getName')
-                       ->willReturn('Nextcloud');
-               $this->defaults
-                       ->expects($this->any())
-                       ->method('getSlogan')
-                       ->willReturn('A safe home for your data');
-
-               $emailTemplate = new EMailTemplate($this->defaults);
-               $emailTemplate->addHeader('https://example.org/img/logo-mail-header.png');
-               $emailTemplate->addHeading('Welcome aboard');
-               $emailTemplate->addBodyText('You have now an Nextcloud account, you can add, protect, and share your data.');
-               $emailTemplate->addBodyText('Your username is: foo');
-               $emailTemplate->addBodyButtonGroup(
-                       'Go to Nextcloud', 'https://example.org/',
-                       'Install Client', 'https://nextcloud.com/install/#install-clients'
-               );
-               $emailTemplate->addFooter(
-                       'https://example.org/img/logo-mail-footer.png',
-                       'Nextcloud - A safe home for your data<br>This is an automatically generated email, please do not reply.'
-               );
-
-               $message
-                       ->expects($this->at(2))
-                       ->method('setHtmlBody')
-                       ->with($emailTemplate->renderHTML());
-               $message
-                       ->expects($this->at(3))
-                       ->method('setPlainBody')
-                       ->with($emailTemplate->renderText());
-               $message
-                       ->expects($this->at(4))
-                       ->method('setFrom')
-                       ->with(['no-reply@nextcloud.com' => 'Nextcloud']);
-
                $this->mailer
                        ->expects($this->at(0))
                        ->method('validateMailAddress')
                        ->with('validMail@Adre.ss')
                        ->will($this->returnValue(true));
-               $this->mailer
-                       ->expects($this->at(1))
-                       ->method('createMessage')
-                       ->will($this->returnValue($message));
-               $this->mailer
-                       ->expects($this->at(2))
-                       ->method('send')
-                       ->with($message);
 
                $user = $this->getMockBuilder('\OC\User\User')
                        ->disableOriginalConstructor()->getMock();
@@ -1523,6 +1440,17 @@ class UsersControllerTest extends \Test\TestCase {
                        ->method('getBackendClassName')
                        ->will($this->returnValue('bar'));
 
+               $emailTemplate = $this->createMock(IEMailTemplate::class);
+               $this->newUserMailHelper
+                       ->expects($this->at(0))
+                       ->method('generateTemplate')
+                       ->with($user, false)
+                       ->willReturn($emailTemplate);
+               $this->newUserMailHelper
+                       ->expects($this->at(1))
+                       ->method('sendMail')
+                       ->with($user, $emailTemplate);
+
                $this->userManager
                        ->expects($this->once())
                        ->method('createUser')
@@ -2334,106 +2262,22 @@ class UsersControllerTest extends \Test\TestCase {
                        ->method('getSubAdmin')
                        ->will($this->returnValue($subadmin));
 
-               $this->secureRandom
-                       ->expects($this->at(0))
-                       ->method('generate')
-                       ->with(32)
-                       ->will($this->returnValue('abc123'));
-               $this->secureRandom
-                       ->expects($this->at(1))
-                       ->method('generate')
-                       ->with(21,
-                               ISecureRandom::CHAR_DIGITS .
-                               ISecureRandom::CHAR_LOWER .
-                               ISecureRandom::CHAR_UPPER)
-                       ->will($this->returnValue('mytoken'));
-
                $controller = $this->getController(true);
-               $message = $this->getMockBuilder('\OC\Mail\Message')
-                       ->disableOriginalConstructor()->getMock();
-               $message
-                       ->expects($this->at(0))
-                       ->method('setTo')
-                       ->with(['abc@example.org' => 'foo']);
-               $message
-                       ->expects($this->at(1))
-                       ->method('setSubject')
-                       ->with('Your Nextcloud account was created');
-
-               $this->urlGenerator
-                       ->expects($this->at(0))
-                       ->method('linkToRouteAbsolute')
-                       ->with('core.lost.resetform', ['userId' => 'foo', 'token' => 'mytoken'])
-                       ->will($this->returnValue('https://example.org/resetPassword/123'));
-               $this->urlGenerator
-                       ->expects($this->at(1))
-                       ->method('imagePath')
-                       ->with('', 'logo-mail-header.png')
-                       ->willReturn('/img/logo-mail-header.png');
-               $this->urlGenerator
-                       ->expects($this->at(2))
-                       ->method('getAbsoluteURL')
-                       ->with('/img/logo-mail-header.png')
-                       ->willReturn('https://example.org/img/logo-mail-header.png');
-               $this->urlGenerator
-                       ->expects($this->at(3))
-                       ->method('imagePath')
-                       ->with('', 'logo-mail-footer.png')
-                       ->willReturn('/img/logo-mail-footer.png');
-               $this->urlGenerator
-                       ->expects($this->at(4))
-                       ->method('getAbsoluteURL')
-                       ->with('/img/logo-mail-footer.png')
-                       ->willReturn('https://example.org/img/logo-mail-footer.png');
-               $this->defaults
-                       ->expects($this->any())
-                       ->method('getName')
-                       ->willReturn('Nextcloud');
-               $this->defaults
-                       ->expects($this->any())
-                       ->method('getSlogan')
-                       ->willReturn('A safe home for your data');
-
-               $emailTemplate = new EMailTemplate($this->defaults);
-               $emailTemplate->addHeader('https://example.org/img/logo-mail-header.png');
-               $emailTemplate->addHeading('Welcome aboard John Doe');
-               $emailTemplate->addBodyText('You have now an Nextcloud account, you can add, protect, and share your data.');
-               $emailTemplate->addBodyText('Your username is: foo');
-               $emailTemplate->addBodyButtonGroup(
-                       'Set your password', 'https://example.org/resetPassword/123',
-                       'Install Client', 'https://nextcloud.com/install/#install-clients'
-               );
-               $emailTemplate->addFooter(
-                       'https://example.org/img/logo-mail-footer.png',
-                       'Nextcloud - A safe home for your data<br>This is an automatically generated email, please do not reply.'
-               );
-
-               $message
-                       ->expects($this->at(2))
-                       ->method('setHtmlBody')
-                       ->with($emailTemplate->renderHTML());
-               $message
-                       ->expects($this->at(3))
-                       ->method('setPlainBody')
-                       ->with($emailTemplate->renderText());
-               $message
-                       ->expects($this->at(4))
-                       ->method('setFrom')
-                       ->with(['no-reply@nextcloud.com' => 'Nextcloud']);
-
                $this->mailer
                        ->expects($this->at(0))
                        ->method('validateMailAddress')
                        ->with('abc@example.org')
                        ->will($this->returnValue(true));
-               $this->mailer
+               $emailTemplate = $this->createMock(IEMailTemplate::class);
+               $this->newUserMailHelper
+                       ->expects($this->at(0))
+                       ->method('generateTemplate')
+                       ->with($user, true)
+                       ->willReturn($emailTemplate);
+               $this->newUserMailHelper
                        ->expects($this->at(1))
-                       ->method('createMessage')
-                       ->will($this->returnValue($message));
-               $this->mailer
-                       ->expects($this->at(2))
-                       ->method('send')
-                       ->with($message);
+                       ->method('sendMail')
+                       ->with($user, $emailTemplate);
 
                $expectedResponse = new DataResponse(
                        [
diff --git a/tests/Settings/Mailer/NewUserMailHelperTest.php b/tests/Settings/Mailer/NewUserMailHelperTest.php
new file mode 100644 (file)
index 0000000..e77e8e1
--- /dev/null
@@ -0,0 +1,639 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Tests\Settings\Mailer;
+
+use OC\Mail\EMailTemplate;
+use OC\Mail\IEMailTemplate;
+use OC\Mail\Message;
+use OC\Settings\Mailer\NewUserMailHelper;
+use OCA\Theming\ThemingDefaults;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\IConfig;
+use OCP\IL10N;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\Mail\IMailer;
+use OCP\Security\ICrypto;
+use OCP\Security\ISecureRandom;
+use Test\TestCase;
+
+class NewUserMailHelperTest extends TestCase {
+       /** @var ThemingDefaults|\PHPUnit_Framework_MockObject_MockObject */
+       private $themingDefaults;
+       /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
+       private $urlGenerator;
+       /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
+       private $l10n;
+       /** @var IMailer|\PHPUnit_Framework_MockObject_MockObject */
+       private $mailer;
+       /** @var ISecureRandom|\PHPUnit_Framework_MockObject_MockObject */
+       private $secureRandom;
+       /** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
+       private $timeFactory;
+       /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
+       private $config;
+       /** @var ICrypto|\PHPUnit_Framework_MockObject_MockObject */
+       private $crypto;
+       /** @var NewUserMailHelper */
+       private $newUserMailHelper;
+
+       public function setUp() {
+               parent::setUp();
+
+               $this->themingDefaults = $this->createMock(ThemingDefaults::class);
+               $this->urlGenerator = $this->createMock(IURLGenerator::class);
+               $this->l10n = $this->createMock(IL10N::class);
+               $this->mailer = $this->createMock(IMailer::class);
+               $this->secureRandom = $this->createMock(ISecureRandom::class);
+               $this->timeFactory = $this->createMock(ITimeFactory::class);
+               $this->config = $this->createMock(IConfig::class);
+               $this->crypto = $this->createMock(ICrypto::class);
+               $this->l10n->method('t')
+                       ->will($this->returnCallback(function ($text, $parameters = []) {
+                               return vsprintf($text, $parameters);
+                       }));
+
+               $this->newUserMailHelper = new NewUserMailHelper(
+                       $this->themingDefaults,
+                       $this->urlGenerator,
+                       $this->l10n,
+                       $this->mailer,
+                       $this->secureRandom,
+                       $this->timeFactory,
+                       $this->config,
+                       $this->crypto,
+                       'no-reply@nextcloud.com'
+               );
+       }
+
+       public function testGenerateTemplateWithPasswordResetToken() {
+               $this->secureRandom
+                       ->expects($this->once())
+                       ->method('generate')
+                       ->with(21,
+                               ISecureRandom::CHAR_DIGITS .
+                               ISecureRandom::CHAR_LOWER .
+                               ISecureRandom::CHAR_UPPER
+                       )
+                       ->willReturn('MySuperLongSecureRandomToken');
+               $this->timeFactory
+                       ->expects($this->once())
+                       ->method('getTime')
+                       ->willReturn('12345');
+               /** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
+               $user = $this->createMock(IUser::class);
+               $user
+                       ->expects($this->at(0))
+                       ->method('getEmailAddress')
+                       ->willReturn('recipient@example.com');
+               $user
+                       ->expects($this->at(1))
+                       ->method('getEmailAddress')
+                       ->willReturn('recipient@example.com');
+               $this->config
+                       ->expects($this->at(0))
+                       ->method('getSystemValue')
+                       ->with('secret')
+                       ->willReturn('MyInstanceWideSecret');
+               $this->crypto
+                       ->expects($this->once())
+                       ->method('encrypt')
+                       ->with('12345:MySuperLongSecureRandomToken', 'recipient@example.comMyInstanceWideSecret')
+                       ->willReturn('TokenCiphertext');
+               $user
+                       ->expects($this->at(2))
+                       ->method('getUID')
+                       ->willReturn('john');
+               $this->config
+                       ->expects($this->at(1))
+                       ->method('setUserValue')
+                       ->with('john', 'core', 'lostpassword', 'TokenCiphertext');
+               $user
+                       ->expects($this->at(3))
+                       ->method('getUID')
+                       ->willReturn('john');
+               $this->urlGenerator
+                       ->expects($this->at(0))
+                       ->method('linkToRouteAbsolute')
+                       ->with('core.lost.resetform', ['userId' => 'john', 'token' => 'MySuperLongSecureRandomToken'])
+                       ->willReturn('https://example.com/resetPassword/MySuperLongSecureRandomToken');
+               $user
+                       ->expects($this->at(4))
+                       ->method('getDisplayName')
+                       ->willReturn('john');
+               $user
+                       ->expects($this->at(5))
+                       ->method('getUID')
+                       ->willReturn('john');
+               $this->themingDefaults
+                       ->expects($this->at(0))
+                       ->method('getName')
+                       ->willReturn('TestCloud');
+
+               $expectedHtmlBody = <<<EOF
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="-webkit-font-smoothing:antialiased;background:#f3f3f3!important">
+<head>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+       <meta name="viewport" content="width=device-width">
+       <title></title>
+       <style type="text/css">@media only screen{html{min-height:100%;background:#F5F5F5}}@media only screen and (max-width:610px){table.body img{width:auto;height:auto}table.body center{min-width:0!important}table.body .container{width:95%!important}table.body .columns{height:auto!important;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:30px!important;padding-right:30px!important}th.small-12{display:inline-block!important;width:100%!important}table.menu{width:100%!important}table.menu td,table.menu th{width:auto!important;display:inline-block!important}table.menu.vertical td,table.menu.vertical th{display:block!important}table.menu[align=center]{width:auto!important}}</style>
+</head>
+<body style="-moz-box-sizing:border-box;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;Margin:0;background:#f3f3f3!important;box-sizing:border-box;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;min-width:100%;padding:0;text-align:left;width:100%!important">
+       <span class="preheader" style="color:#F5F5F5;display:none!important;font-size:1px;line-height:1px;max-height:0;max-width:0;mso-hide:all!important;opacity:0;overflow:hidden;visibility:hidden">
+       </span>
+       <table class="body" style="-webkit-font-smoothing:antialiased;Margin:0;background:#f3f3f3!important;border-collapse:collapse;border-spacing:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;height:100%;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;width:100%">
+               <tr style="padding:0;text-align:left;vertical-align:top">
+                       <td class="center" align="center" valign="top" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                               <center data-parsed="" style="min-width:580px;width:100%"><table align="center" class="wrapper header float-center" style="Margin:0 auto;background:#8a8a8a;background-color:;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:20px;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <table align="center" class="container" style="Margin:0 auto;background:0 0;border-collapse:collapse;border-spacing:0;margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px">
+                               <tbody>
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                               <table class="row collapse" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+                                                       <tbody>
+                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                               <center data-parsed="" style="min-width:580px;width:100%">
+                                                                       <img class="logo float-center" src="?v=" alt="logo" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;max-height:100%;max-width:100px;outline:0;text-align:center;text-decoration:none;width:auto">
+                                                               </center>
+                                                       </tr>
+                                                       </tbody>
+                                               </table>
+                                       </td>
+                               </tr>
+                               </tbody>
+                       </table>
+               </td>
+       </tr>
+</table>
+<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="80px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:80px;font-weight:400;hyphens:auto;line-height:80px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table><table align="center" class="container main-heading float-center" style="Margin:0 auto;background:0 0!important;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:580px">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <h1 class="text-center" style="Margin:0;Margin-bottom:10px;color:inherit;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:24px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:center;word-wrap:normal">Welcome aboard</h1>
+               </td>
+       </tr>
+       </tbody>
+</table>
+<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="40px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:40px;font-weight:400;hyphens:auto;line-height:40px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table><table align="center" class="wrapper content float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <table align="center" class="container has-shadow" style="Margin:0 auto;background:#fefefe;border-collapse:collapse;border-spacing:0;box-shadow:0 1px 2px 0 rgba(0,0,0,.2),0 1px 3px 0 rgba(0,0,0,.1);margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px">
+                               <tbody>
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                               <table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                       <tbody>
+                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                               <td height="60px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:60px;font-weight:400;hyphens:auto;line-height:60px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+                                                       </tr>
+                                                       </tbody>
+                                               </table><table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:left">You have now an  account, you can add, protect, and share your data.</p>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table><table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:left">Your username is: john</p>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table><table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="50px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:50px;font-weight:400;hyphens:auto;line-height:50px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table>
+<table align="center" class="row btn-group" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <center data-parsed="" style="min-width:490px;width:100%">
+                                                       <table class="button btn default primary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;margin-right:15px;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
+                                                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                               <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                                               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:;border:0 solid ;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                                                       <a href="https://example.com/resetPassword/MySuperLongSecureRandomToken" style="Margin:0;border:0 solid ;border-radius:2px;color:#fefefe;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">Set your password</a>
+                                                                                               </td>
+                                                                                       </tr>
+                                                                               </table>
+                                                                       </td>
+                                                               </tr>
+                                                       </table>
+                                                       <table class="button btn default secondary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
+                                                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                               <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                                               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:#777;border:0 solid #777;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                                                       <a href="https://nextcloud.com/install/#install-clients" style="Margin:0;background-color:#fff;border:0 solid #777;border-radius:2px;color:#6C6C6C!important;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;outline:1px solid #CBCBCB;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">Install Client</a>
+                                                                                               </td>
+                                                                                       </tr>
+                                                                               </table>
+                                                                       </td>
+                                                               </tr>
+                                                       </table>
+                                               </center>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table>
+                                       </td>
+                               </tr>
+                               </tbody>
+                       </table>
+               </td>
+       </tr>
+</table><table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="60px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:60px;font-weight:400;hyphens:auto;line-height:60px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table>
+<table align="center" class="wrapper footer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <center data-parsed="" style="min-width:580px;width:100%">
+                               <table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+                                       <tbody>
+                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                               <td height="15px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:15px;font-weight:400;hyphens:auto;line-height:15px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+                                       </tr>
+                                       </tbody>
+                               </table>
+                               <p class="text-center float-center" align="center" style="Margin:0;Margin-bottom:10px;color:#C8C8C8;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:12px;font-weight:400;line-height:16px;margin:0;margin-bottom:10px;padding:0;text-align:center"> - <br>This is an automatically generated email, please do not reply.</p>
+                       </center>
+               </td>
+       </tr>
+</table>                                       </center>
+                               </td>
+                       </tr>
+               </table>
+               <!-- prevent Gmail on iOS font size manipulation -->
+               <div style="display:none;white-space:nowrap;font:15px courier;line-height:0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
+       </body>
+</html>
+EOF;
+               $expectedTextBody = <<<EOF
+Welcome aboard
+
+You have now an  account, you can add, protect, and share your data.
+
+Your username is: john
+
+Set your password: https://example.com/resetPassword/MySuperLongSecureRandomToken
+Install Client: https://nextcloud.com/install/#install-clients
+
+--
+ - 
+This is an automatically generated email, please do not reply.
+EOF;
+
+               $result = $this->newUserMailHelper->generateTemplate($user, true);
+               $this->assertEquals($expectedHtmlBody, $result->renderHTML());
+               $this->assertEquals($expectedTextBody, $result->renderText());
+               $this->assertSame('OC\Mail\EMailTemplate', get_class($result));
+       }
+
+       public function testGenerateTemplateWithoutPasswordResetToken() {
+               $this->urlGenerator
+                       ->expects($this->at(0))
+                       ->method('getAbsoluteURL')
+                       ->with('/')
+                       ->willReturn('https://example.com/');
+
+               /** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
+               $user = $this->createMock(IUser::class);
+               $user
+                       ->expects($this->at(0))
+                       ->method('getDisplayName')
+                       ->willReturn('John Doe');
+               $user
+                       ->expects($this->at(1))
+                       ->method('getUID')
+                       ->willReturn('john');
+               $this->themingDefaults
+                       ->expects($this->any())
+                       ->method('getName')
+                       ->willReturn('TestCloud');
+
+               $expectedHtmlBody = <<<EOF
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="-webkit-font-smoothing:antialiased;background:#f3f3f3!important">
+<head>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+       <meta name="viewport" content="width=device-width">
+       <title></title>
+       <style type="text/css">@media only screen{html{min-height:100%;background:#F5F5F5}}@media only screen and (max-width:610px){table.body img{width:auto;height:auto}table.body center{min-width:0!important}table.body .container{width:95%!important}table.body .columns{height:auto!important;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:30px!important;padding-right:30px!important}th.small-12{display:inline-block!important;width:100%!important}table.menu{width:100%!important}table.menu td,table.menu th{width:auto!important;display:inline-block!important}table.menu.vertical td,table.menu.vertical th{display:block!important}table.menu[align=center]{width:auto!important}}</style>
+</head>
+<body style="-moz-box-sizing:border-box;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;Margin:0;background:#f3f3f3!important;box-sizing:border-box;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;min-width:100%;padding:0;text-align:left;width:100%!important">
+       <span class="preheader" style="color:#F5F5F5;display:none!important;font-size:1px;line-height:1px;max-height:0;max-width:0;mso-hide:all!important;opacity:0;overflow:hidden;visibility:hidden">
+       </span>
+       <table class="body" style="-webkit-font-smoothing:antialiased;Margin:0;background:#f3f3f3!important;border-collapse:collapse;border-spacing:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;height:100%;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;width:100%">
+               <tr style="padding:0;text-align:left;vertical-align:top">
+                       <td class="center" align="center" valign="top" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                               <center data-parsed="" style="min-width:580px;width:100%"><table align="center" class="wrapper header float-center" style="Margin:0 auto;background:#8a8a8a;background-color:;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:20px;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <table align="center" class="container" style="Margin:0 auto;background:0 0;border-collapse:collapse;border-spacing:0;margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px">
+                               <tbody>
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                               <table class="row collapse" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+                                                       <tbody>
+                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                               <center data-parsed="" style="min-width:580px;width:100%">
+                                                                       <img class="logo float-center" src="?v=" alt="logo" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;max-height:100%;max-width:100px;outline:0;text-align:center;text-decoration:none;width:auto">
+                                                               </center>
+                                                       </tr>
+                                                       </tbody>
+                                               </table>
+                                       </td>
+                               </tr>
+                               </tbody>
+                       </table>
+               </td>
+       </tr>
+</table>
+<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="80px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:80px;font-weight:400;hyphens:auto;line-height:80px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table><table align="center" class="container main-heading float-center" style="Margin:0 auto;background:0 0!important;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:580px">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <h1 class="text-center" style="Margin:0;Margin-bottom:10px;color:inherit;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:24px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:center;word-wrap:normal">Welcome aboard John Doe</h1>
+               </td>
+       </tr>
+       </tbody>
+</table>
+<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="40px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:40px;font-weight:400;hyphens:auto;line-height:40px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table><table align="center" class="wrapper content float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <table align="center" class="container has-shadow" style="Margin:0 auto;background:#fefefe;border-collapse:collapse;border-spacing:0;box-shadow:0 1px 2px 0 rgba(0,0,0,.2),0 1px 3px 0 rgba(0,0,0,.1);margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px">
+                               <tbody>
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                               <table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                       <tbody>
+                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                               <td height="60px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:60px;font-weight:400;hyphens:auto;line-height:60px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+                                                       </tr>
+                                                       </tbody>
+                                               </table><table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:left">You have now an TestCloud account, you can add, protect, and share your data.</p>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table><table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:left">Your username is: john</p>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table><table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="50px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:50px;font-weight:400;hyphens:auto;line-height:50px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table>
+<table align="center" class="row btn-group" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <center data-parsed="" style="min-width:490px;width:100%">
+                                                       <table class="button btn default primary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;margin-right:15px;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
+                                                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                               <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                                               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:;border:0 solid ;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                                                       <a href="https://example.com/" style="Margin:0;border:0 solid ;border-radius:2px;color:#fefefe;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">Go to TestCloud</a>
+                                                                                               </td>
+                                                                                       </tr>
+                                                                               </table>
+                                                                       </td>
+                                                               </tr>
+                                                       </table>
+                                                       <table class="button btn default secondary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
+                                                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                               <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                                               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:#777;border:0 solid #777;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                                                       <a href="https://nextcloud.com/install/#install-clients" style="Margin:0;background-color:#fff;border:0 solid #777;border-radius:2px;color:#6C6C6C!important;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;outline:1px solid #CBCBCB;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">Install Client</a>
+                                                                                               </td>
+                                                                                       </tr>
+                                                                               </table>
+                                                                       </td>
+                                                               </tr>
+                                                       </table>
+                                               </center>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table>
+                                       </td>
+                               </tr>
+                               </tbody>
+                       </table>
+               </td>
+       </tr>
+</table><table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="60px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:60px;font-weight:400;hyphens:auto;line-height:60px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table>
+<table align="center" class="wrapper footer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <center data-parsed="" style="min-width:580px;width:100%">
+                               <table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+                                       <tbody>
+                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                               <td height="15px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:15px;font-weight:400;hyphens:auto;line-height:15px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+                                       </tr>
+                                       </tbody>
+                               </table>
+                               <p class="text-center float-center" align="center" style="Margin:0;Margin-bottom:10px;color:#C8C8C8;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:12px;font-weight:400;line-height:16px;margin:0;margin-bottom:10px;padding:0;text-align:center">TestCloud - <br>This is an automatically generated email, please do not reply.</p>
+                       </center>
+               </td>
+       </tr>
+</table>                                       </center>
+                               </td>
+                       </tr>
+               </table>
+               <!-- prevent Gmail on iOS font size manipulation -->
+               <div style="display:none;white-space:nowrap;font:15px courier;line-height:0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
+       </body>
+</html>
+EOF;
+               $expectedTextBody = <<<EOF
+Welcome aboard John Doe
+
+You have now an TestCloud account, you can add, protect, and share your data.
+
+Your username is: john
+
+Go to TestCloud: https://example.com/
+Install Client: https://nextcloud.com/install/#install-clients
+
+--
+TestCloud - 
+This is an automatically generated email, please do not reply.
+EOF;
+
+               $result = $this->newUserMailHelper->generateTemplate($user, false);
+               $this->assertEquals($expectedHtmlBody, $result->renderHTML());
+               $this->assertEquals($expectedTextBody, $result->renderText());
+               $this->assertSame('OC\Mail\EMailTemplate', get_class($result));
+       }
+
+       public function testSendMail() {
+               /** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
+               $user = $this->createMock(IUser::class);
+               $user
+                       ->expects($this->at(0))
+                       ->method('getEMailAddress')
+                       ->willReturn('recipient@example.com');
+               $user
+                       ->expects($this->at(1))
+                       ->method('getDisplayName')
+                       ->willReturn('John Doe');
+               /** @var IEMailTemplate|\PHPUnit_Framework_MockObject_MockObject $emailTemplate */
+               $emailTemplate = $this->createMock(IEMailTemplate::class);
+               $message = $this->createMock(Message::class);
+               $message
+                       ->expects($this->at(0))
+                       ->method('setTo')
+                       ->with(['recipient@example.com' => 'John Doe']);
+               $this->themingDefaults
+                       ->expects($this->exactly(2))
+                       ->method('getName')
+                       ->willReturn('TestCloud');
+               $message
+                       ->expects($this->at(1))
+                       ->method('setSubject')
+                       ->with('Your TestCloud account was created');
+               $message
+                       ->expects($this->at(2))
+                       ->method('setHtmlBody')
+                       ->with($emailTemplate->renderHTML());
+               $message
+                       ->expects($this->at(3))
+                       ->method('setPlainBody')
+                       ->with($emailTemplate->renderText());
+               $message
+                       ->expects($this->at(4))
+                       ->method('setFrom')
+                       ->with(['no-reply@nextcloud.com' => 'TestCloud']);
+               $this->mailer
+                       ->expects($this->once())
+                       ->method('createMessage')
+                       ->willReturn($message);
+
+               $this->newUserMailHelper->sendMail($user, $emailTemplate);
+       }
+}
diff --git a/tests/data/emails/new-account-email-custom.html b/tests/data/emails/new-account-email-custom.html
new file mode 100644 (file)
index 0000000..10d3330
--- /dev/null
@@ -0,0 +1,187 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="-webkit-font-smoothing:antialiased;background:#f3f3f3!important">
+<head>
+       <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+       <meta name="viewport" content="width=device-width">
+       <title></title>
+       <style type="text/css">@media only screen{html{min-height:100%;background:#F5F5F5}}@media only screen and (max-width:610px){table.body img{width:auto;height:auto}table.body center{min-width:0!important}table.body .container{width:95%!important}table.body .columns{height:auto!important;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:30px!important;padding-right:30px!important}th.small-12{display:inline-block!important;width:100%!important}table.menu{width:100%!important}table.menu td,table.menu th{width:auto!important;display:inline-block!important}table.menu.vertical td,table.menu.vertical th{display:block!important}table.menu[align=center]{width:auto!important}}</style>
+</head>
+<body style="-moz-box-sizing:border-box;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;Margin:0;background:#f3f3f3!important;box-sizing:border-box;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;min-width:100%;padding:0;text-align:left;width:100%!important">
+       <span class="preheader" style="color:#F5F5F5;display:none!important;font-size:1px;line-height:1px;max-height:0;max-width:0;mso-hide:all!important;opacity:0;overflow:hidden;visibility:hidden">
+       </span>
+       <table class="body" style="-webkit-font-smoothing:antialiased;Margin:0;background:#f3f3f3!important;border-collapse:collapse;border-spacing:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;height:100%;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;width:100%">
+               <tr style="padding:0;text-align:left;vertical-align:top">
+                       <td class="center" align="center" valign="top" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                               <center data-parsed="" style="min-width:580px;width:100%"><table align="center" class="wrapper header float-center" style="Margin:0 auto;background:#8a8a8a;background-color:#0082c9;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:20px;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <table align="center" class="container" style="Margin:0 auto;background:0 0;border-collapse:collapse;border-spacing:0;margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px">
+                               <tbody>
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                               <table class="row collapse" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+                                                       <tbody>
+                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                               <center data-parsed="" style="min-width:580px;width:100%">
+                                                                       <img class="logo float-center" src="https://example.org/img/logo-mail-header.png?v=48" alt="logo" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;max-height:100%;max-width:100px;outline:0;text-align:center;text-decoration:none;width:auto">
+                                                               </center>
+                                                       </tr>
+                                                       </tbody>
+                                               </table>
+                                       </td>
+                               </tr>
+                               </tbody>
+                       </table>
+               </td>
+       </tr>
+</table>
+<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="80px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:80px;font-weight:400;hyphens:auto;line-height:80px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table><table align="center" class="container main-heading float-center" style="Margin:0 auto;background:0 0!important;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:580px">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <h1 class="text-center" style="Margin:0;Margin-bottom:10px;color:inherit;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:24px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:center;word-wrap:normal">Welcome aboard</h1>
+               </td>
+       </tr>
+       </tbody>
+</table>
+<table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="40px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:40px;font-weight:400;hyphens:auto;line-height:40px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table><table align="center" class="wrapper content float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <table align="center" class="container has-shadow" style="Margin:0 auto;background:#fefefe;border-collapse:collapse;border-spacing:0;box-shadow:0 1px 2px 0 rgba(0,0,0,.2),0 1px 3px 0 rgba(0,0,0,.1);margin:0 auto;padding:0;text-align:inherit;vertical-align:top;width:580px">
+                               <tbody>
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                               <table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                       <tbody>
+                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                               <td height="60px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:60px;font-weight:400;hyphens:auto;line-height:60px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+                                                       </tr>
+                                                       </tbody>
+                                               </table><table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:left">You have now an Nextcloud account, you can add, protect, and share your data.</p>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table><table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;text-align:left">Your username is: abc</p>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table><table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="50px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:50px;font-weight:400;hyphens:auto;line-height:50px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table>
+<table align="center" class="row btn-group" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <th class="small-12 large-12 columns first last" style="Margin:0 auto;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0 auto;padding:0;padding-bottom:30px;padding-left:30px;padding-right:30px;text-align:left;width:550px">
+                       <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                       <th style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left">
+                                               <center data-parsed="" style="min-width:490px;width:100%">
+                                                       <table class="button btn default primary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;margin-right:15px;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
+                                                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                               <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                                               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:#0082c9;border:0 solid #0082c9;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                                                       <a href="https://example.org/resetPassword/123" style="Margin:0;border:0 solid #0082c9;border-radius:2px;color:#fefefe;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">Set your password</a>
+                                                                                               </td>
+                                                                                       </tr>
+                                                                               </table>
+                                                                       </td>
+                                                               </tr>
+                                                       </table>
+                                                       <table class="button btn default secondary float-center" style="Margin:0 0 30px 0;border-collapse:collapse;border-spacing:0;display:inline-block;float:none;margin:0 0 30px 0;max-height:40px;max-width:200px;padding:0;text-align:center;vertical-align:top;width:auto">
+                                                               <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                       <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                               <table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%">
+                                                                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                                                                               <td style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;background:#777;border:0 solid #777;border-collapse:collapse!important;color:#fefefe;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                                                                                                       <a href="https://nextcloud.com/install/#install-clients" style="Margin:0;background-color:#fff;border:0 solid #777;border-radius:2px;color:#6C6C6C!important;display:inline-block;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:regular;line-height:1.3;margin:0;outline:1px solid #CBCBCB;padding:10px 25px 10px 25px;text-align:left;text-decoration:none">Install Client</a>
+                                                                                               </td>
+                                                                                       </tr>
+                                                                               </table>
+                                                                       </td>
+                                                               </tr>
+                                                       </table>
+                                               </center>
+                                       </th>
+                                       <th class="expander" style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0!important;text-align:left;visibility:hidden;width:0"></th>
+                               </tr>
+                       </table>
+               </th>
+       </tr>
+       </tbody>
+</table>
+                                       </td>
+                               </tr>
+                               </tbody>
+                       </table>
+               </td>
+       </tr>
+</table><table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tbody>
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td height="60px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:60px;font-weight:400;hyphens:auto;line-height:60px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+       </tr>
+       </tbody>
+</table>
+<table align="center" class="wrapper footer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+       <tr style="padding:0;text-align:left;vertical-align:top">
+               <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
+                       <center data-parsed="" style="min-width:580px;width:100%">
+                               <table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
+                                       <tbody>
+                                       <tr style="padding:0;text-align:left;vertical-align:top">
+                                               <td height="15px" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:15px;font-weight:400;hyphens:auto;line-height:15px;margin:0;mso-line-height-rule:exactly;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">&#xA0;</td>
+                                       </tr>
+                                       </tbody>
+                               </table>
+                               <p class="text-center float-center" align="center" style="Margin:0;Margin-bottom:10px;color:#C8C8C8;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:12px;font-weight:400;line-height:16px;margin:0;margin-bottom:10px;padding:0;text-align:center">TestCloud - A safe home for your data<br></p>
+                       </center>
+               </td>
+       </tr>
+</table>                                       </center>
+                               </td>
+                       </tr>
+               </table>
+               <!-- prevent Gmail on iOS font size manipulation -->
+               <div style="display:none;white-space:nowrap;font:15px courier;line-height:0">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>
+       </body>
+</html>
\ No newline at end of file
diff --git a/tests/data/emails/new-account-email-custom.txt b/tests/data/emails/new-account-email-custom.txt
new file mode 100644 (file)
index 0000000..9621289
--- /dev/null
@@ -0,0 +1,11 @@
+Welcome aboard
+
+You have now an Nextcloud account, you can add, protect, and share your data.
+
+Your username is: abc
+
+Set your password: https://example.org/resetPassword/123
+Install Client: https://nextcloud.com/install/#install-clients
+
+--
+TestCloud - A safe home for your data
index 9b9155fa1d93957f94b42dd73bdc552451c86b89..a32ad61c49c777e6c1dfe964c6f800a2abbb0704 100644 (file)
@@ -22,8 +22,8 @@
                                                <table class="row collapse" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%">
                                                        <tbody>
                                                        <tr style="padding:0;text-align:left;vertical-align:top">
-                                                               <center data-parsed="" style="min-width:580px;width:100%"><!-- TODO -->
-                                                                       <img class="logo float-center" src="https://example.org/img/logo-mail-header.png" alt="logo" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;max-height:100%;max-width:100px;outline:0;text-align:center;text-decoration:none;width:auto">
+                                                               <center data-parsed="" style="min-width:580px;width:100%">
+                                                                       <img class="logo float-center" src="https://example.org/img/logo-mail-header.png?v=48" alt="logo" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;max-height:100%;max-width:100px;outline:0;text-align:center;text-decoration:none;width:auto">
                                                                </center>
                                                        </tr>
                                                        </tbody>
 <table align="center" class="wrapper footer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
        <tr style="padding:0;text-align:left;vertical-align:top">
                <td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
-                       <center data-parsed="" style="min-width:580px;width:100%"><!-- TODO -->
-                               <img class="logo float-center" src="https://example.org/img/logo-mail-footer.png" alt="logo" align="center" style="-ms-interpolation-mode:bicubic;Margin:0 auto;clear:both;display:block;float:none;margin:0 auto;max-height:100%;max-width:75px;outline:0;text-align:center;text-decoration:none;width:auto">
+                       <center data-parsed="" style="min-width:580px;width:100%">
                                <table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
                                        <tbody>
                                        <tr style="padding:0;text-align:left;vertical-align:top">
                                        </tr>
                                        </tbody>
                                </table>
-                               <p class="text-center float-center" align="center" style="Margin:0;Margin-bottom:10px;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:12px;font-weight:400;line-height:16px;margin:0;margin-bottom:10px;padding:0;text-align:center">TestCloud - A safe home for your data<br>This is an automatically generated email, please do not reply.</p>
+                               <p class="text-center float-center" align="center" style="Margin:0;Margin-bottom:10px;color:#C8C8C8;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:12px;font-weight:400;line-height:16px;margin:0;margin-bottom:10px;padding:0;text-align:center">TestCloud - A safe home for your data<br>This is an automatically generated email, please do not reply.</p>
                        </center>
                </td>
        </tr>
index 3acb742aeca797a9ca646abc62b82cdc0a11efb0..47fe09aabbb625f83a066ecd646ac69e5b55524b 100644 (file)
 namespace Test\Mail;
 
 use OC\Mail\EMailTemplate;
-use OC_Defaults;
+use OCA\Theming\ThemingDefaults;
+use OCP\IL10N;
+use OCP\IURLGenerator;
 use Test\TestCase;
 
 class EMailTemplateTest extends TestCase {
-       /** @var OC_Defaults */
+       /** @var ThemingDefaults|\PHPUnit_Framework_MockObject_MockObject */
        private $defaults;
-
-       function setUp() {
+       /** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
+       private $urlGenerator;
+       /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
+       private $l10n;
+       /** @var EMailTemplate */
+       private $emailTemplate;
+
+       public function setUp() {
                parent::setUp();
 
-               $this->defaults = $this->getMockBuilder('\OC_Defaults')
-                       ->disableOriginalConstructor()->getMock();
+               $this->defaults = $this->createMock(ThemingDefaults::class);
+               $this->urlGenerator = $this->createMock(IURLGenerator::class);
+               $this->l10n = $this->createMock(IL10N::class);
 
+               $this->emailTemplate = new EMailTemplate(
+                       $this->defaults,
+                       $this->urlGenerator,
+                       $this->l10n
+               );
+       }
+
+       public function testEMailTemplateCustomFooter() {
                $this->defaults
                        ->expects($this->any())
                        ->method('getColorPrimary')
                        ->willReturn('#0082c9');
-       }
-
-       public function testEMailTemplate() {
-               $emailTemplate = new EMailTemplate($this->defaults);
-
-               $emailTemplate->addHeader('https://example.org/img/logo-mail-header.png');
-
-               $emailTemplate->addHeading('Welcome aboard');
-               $emailTemplate->addBodyText('You have now an Nextcloud account, you can add, protect, and share your data.');
-               $emailTemplate->addBodyText('Your username is: abc');
-
-
-               $emailTemplate->addBodyButtonGroup(
+               $this->defaults
+                       ->expects($this->any())
+                       ->method('getLogo')
+                       ->willReturn('/img/logo-mail-header.png');
+               $this->defaults
+                       ->expects($this->any())
+                       ->method('getCacheBusterCounter')
+                       ->willReturn('48');
+               $this->urlGenerator
+                       ->expects($this->once())
+                       ->method('getAbsoluteURL')
+                       ->with('/img/logo-mail-header.png')
+                       ->willReturn('https://example.org/img/logo-mail-header.png');
+
+               $this->emailTemplate->addHeader();
+               $this->emailTemplate->addHeading('Welcome aboard');
+               $this->emailTemplate->addBodyText('You have now an Nextcloud account, you can add, protect, and share your data.');
+               $this->emailTemplate->addBodyText('Your username is: abc');
+               $this->emailTemplate->addBodyButtonGroup(
                        'Set your password', 'https://example.org/resetPassword/123',
                        'Install Client', 'https://nextcloud.com/install/#install-clients'
                );
-
-               $emailTemplate->addFooter(
-                       'https://example.org/img/logo-mail-footer.png',
+               $this->emailTemplate->addFooter(
                        'TestCloud - A safe home for your data<br>This is an automatically generated email, please do not reply.'
                );
 
                $expectedHTML = file_get_contents(\OC::$SERVERROOT . '/tests/data/emails/new-account-email.html');
-               $this->assertSame($expectedHTML, $emailTemplate->renderHTML());
+               $this->assertSame($expectedHTML, $this->emailTemplate->renderHTML());
+               $expectedTXT = file_get_contents(\OC::$SERVERROOT . '/tests/data/emails/new-account-email.txt');
+               $this->assertSame($expectedTXT, $this->emailTemplate->renderText());
+       }
 
+       public function testEMailTemplateDefaultFooter() {
+               $this->defaults
+                       ->expects($this->any())
+                       ->method('getColorPrimary')
+                       ->willReturn('#0082c9');
+               $this->defaults
+                       ->expects($this->any())
+                       ->method('getName')
+                       ->willReturn('TestCloud');
+               $this->defaults
+                       ->expects($this->any())
+                       ->method('getSlogan')
+                       ->willReturn('A safe home for your data');
+               $this->defaults
+                       ->expects($this->any())
+                       ->method('getLogo')
+                       ->willReturn('/img/logo-mail-header.png');
+               $this->defaults
+                       ->expects($this->any())
+                       ->method('getCacheBusterCounter')
+                       ->willReturn('48');
+               $this->urlGenerator
+                       ->expects($this->once())
+                       ->method('getAbsoluteURL')
+                       ->with('/img/logo-mail-header.png')
+                       ->willReturn('https://example.org/img/logo-mail-header.png');
+
+               $this->emailTemplate->addHeader();
+               $this->emailTemplate->addHeading('Welcome aboard');
+               $this->emailTemplate->addBodyText('You have now an Nextcloud account, you can add, protect, and share your data.');
+               $this->emailTemplate->addBodyText('Your username is: abc');
+               $this->emailTemplate->addBodyButtonGroup(
+                       'Set your password', 'https://example.org/resetPassword/123',
+                       'Install Client', 'https://nextcloud.com/install/#install-clients'
+               );
+               $this->emailTemplate->addFooter();
 
-               $expectedTXT = file_get_contents(\OC::$SERVERROOT . '/tests/data/emails/new-account-email.txt');
-               $this->assertSame($expectedTXT, $emailTemplate->renderText());
+               $expectedHTML = file_get_contents(\OC::$SERVERROOT . '/tests/data/emails/new-account-email-custom.html');
+               $this->assertSame($expectedHTML, $this->emailTemplate->renderHTML());
+               $expectedTXT = file_get_contents(\OC::$SERVERROOT . '/tests/data/emails/new-account-email-custom.txt');
+               $this->assertSame($expectedTXT, $this->emailTemplate->renderText());
        }