EmailProviderTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2019, Thomas Citharel
  5. * @copyright Copyright (c) 2019, Georg Ehrke
  6. *
  7. * @author Georg Ehrke <oc.list@georgehrke.com>
  8. * @author Roeland Jago Douma <roeland@famdouma.nl>
  9. * @author Thomas Citharel <tcit@tcit.fr>
  10. *
  11. * @license GNU AGPL version 3 or any later version
  12. *
  13. * This program is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License as
  15. * published by the Free Software Foundation, either version 3 of the
  16. * License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. *
  26. */
  27. namespace OCA\DAV\Tests\unit\CalDAV\Reminder\NotificationProvider;
  28. use OCA\DAV\CalDAV\Reminder\NotificationProvider\EmailProvider;
  29. use OCP\IConfig;
  30. use OCP\IL10N;
  31. use OCP\ILogger;
  32. use OCP\IURLGenerator;
  33. use OCP\IUser;
  34. use OCP\L10N\IFactory as L10NFactory;
  35. use OCP\Mail\IAttachment;
  36. use OCP\Mail\IEMailTemplate;
  37. use OCP\Mail\IMailer;
  38. use OCP\Mail\IMessage;
  39. use Sabre\VObject\Component\VCalendar;
  40. use Test\TestCase;
  41. class EmailProviderTest extends AbstractNotificationProviderTest {
  42. const USER_EMAIL = 'frodo@hobb.it';
  43. /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */
  44. protected $logger;
  45. /** @var L10NFactory|\PHPUnit\Framework\MockObject\MockObject */
  46. protected $l10nFactory;
  47. /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
  48. protected $l10n;
  49. /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */
  50. protected $urlGenerator;
  51. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  52. protected $config;
  53. /** @var IMailer|\PHPUnit\Framework\MockObject\MockObject */
  54. private $mailer;
  55. protected function setUp(): void {
  56. parent::setUp();
  57. $this->mailer = $this->createMock(IMailer::class);
  58. $this->provider = new EmailProvider(
  59. $this->config,
  60. $this->mailer,
  61. $this->logger,
  62. $this->l10nFactory,
  63. $this->urlGenerator
  64. );
  65. }
  66. public function testSendWithoutAttendees():void {
  67. $user1 = $this->createMock(IUser::class);
  68. $user1->method('getUID')
  69. ->willReturn('uid1');
  70. $user1->method('getEMailAddress')
  71. ->willReturn('uid1@example.com');
  72. $user2 = $this->createMock(IUser::class);
  73. $user2->method('getUID')
  74. ->willReturn('uid2');
  75. $user2->method('getEMailAddress')
  76. ->willReturn('uid2@example.com');
  77. $user3 = $this->createMock(IUser::class);
  78. $user3->method('getUID')
  79. ->willReturn('uid3');
  80. $user3->method('getEMailAddress')
  81. ->willReturn('uid3@example.com');
  82. $user4 = $this->createMock(IUser::class);
  83. $user4->method('getUID')
  84. ->willReturn('uid4');
  85. $user4->method('getEMailAddress')
  86. ->willReturn(null);
  87. $users = [$user1, $user2, $user3, $user4];
  88. $this->config->expects($this->at(0))
  89. ->method('getUserValue')
  90. ->with('uid1', 'core', 'lang', null)
  91. ->willReturn(null);
  92. $this->config->expects($this->at(1))
  93. ->method('getUserValue')
  94. ->with('uid2', 'core', 'lang', null)
  95. ->willReturn('de');
  96. $this->config->expects($this->at(2))
  97. ->method('getUserValue')
  98. ->with('uid3', 'core', 'lang', null)
  99. ->willReturn('de');
  100. $enL10N = $this->createMock(IL10N::class);
  101. $enL10N->method('t')
  102. ->willReturnArgument(0);
  103. $enL10N->method('l')
  104. ->willReturnArgument(0);
  105. $deL10N = $this->createMock(IL10N::class);
  106. $deL10N->method('t')
  107. ->willReturnArgument(0);
  108. $deL10N->method('l')
  109. ->willReturnArgument(0);
  110. $this->l10nFactory->expects($this->at(0))
  111. ->method('findLanguage')
  112. ->with()
  113. ->willReturn('en');
  114. $this->l10nFactory->expects($this->at(1))
  115. ->method('languageExists')
  116. ->with('dav', 'en')
  117. ->willReturn(true);
  118. $this->l10nFactory->expects($this->at(2))
  119. ->method('get')
  120. ->with('dav', 'en')
  121. ->willReturn($enL10N);
  122. $this->l10nFactory->expects($this->at(3))
  123. ->method('languageExists')
  124. ->with('dav', 'de')
  125. ->willReturn(true);
  126. $this->l10nFactory->expects($this->at(4))
  127. ->method('get')
  128. ->with('dav', 'de')
  129. ->willReturn($deL10N);
  130. $template1 = $this->getTemplateMock();
  131. $message11 = $this->getMessageMock('uid1@example.com', $template1);
  132. $template2 = $this->getTemplateMock();
  133. $message21 = $this->getMessageMock('uid2@example.com', $template2);
  134. $message22 = $this->getMessageMock('uid3@example.com', $template2);
  135. $this->mailer->expects($this->at(0))
  136. ->method('createEMailTemplate')
  137. ->with('dav.calendarReminder')
  138. ->willReturn($template1);
  139. $this->mailer->expects($this->at(1))
  140. ->method('createMessage')
  141. ->with()
  142. ->willReturn($message11);
  143. $this->mailer->expects($this->at(2))
  144. ->method('send')
  145. ->with($message11)
  146. ->willReturn([]);
  147. $this->mailer->expects($this->at(3))
  148. ->method('createEMailTemplate')
  149. ->with('dav.calendarReminder')
  150. ->willReturn($template2);
  151. $this->mailer->expects($this->at(4))
  152. ->method('createMessage')
  153. ->with()
  154. ->willReturn($message21);
  155. $this->mailer->expects($this->at(5))
  156. ->method('send')
  157. ->with($message21)
  158. ->willReturn([]);
  159. $this->mailer->expects($this->at(6))
  160. ->method('createMessage')
  161. ->with()
  162. ->willReturn($message22);
  163. $this->mailer->expects($this->at(7))
  164. ->method('send')
  165. ->with($message22)
  166. ->willReturn([]);
  167. $this->setupURLGeneratorMock(2);
  168. $vcalendar = $this->getNoAttendeeVCalendar();
  169. $this->provider->send($vcalendar->VEVENT, $this->calendarDisplayName, $users);
  170. }
  171. public function testSendWithAttendees(): void {
  172. $user1 = $this->createMock(IUser::class);
  173. $user1->method('getUID')
  174. ->willReturn('uid1');
  175. $user1->method('getEMailAddress')
  176. ->willReturn('uid1@example.com');
  177. $user2 = $this->createMock(IUser::class);
  178. $user2->method('getUID')
  179. ->willReturn('uid2');
  180. $user2->method('getEMailAddress')
  181. ->willReturn('uid2@example.com');
  182. $user3 = $this->createMock(IUser::class);
  183. $user3->method('getUID')
  184. ->willReturn('uid3');
  185. $user3->method('getEMailAddress')
  186. ->willReturn('uid3@example.com');
  187. $user4 = $this->createMock(IUser::class);
  188. $user4->method('getUID')
  189. ->willReturn('uid4');
  190. $user4->method('getEMailAddress')
  191. ->willReturn(null);
  192. $users = [$user1, $user2, $user3, $user4];
  193. $this->config->expects($this->at(0))
  194. ->method('getUserValue')
  195. ->with('uid1', 'core', 'lang', null)
  196. ->willReturn(null);
  197. $this->config->expects($this->at(1))
  198. ->method('getUserValue')
  199. ->with('uid2', 'core', 'lang', null)
  200. ->willReturn('de');
  201. $this->config->expects($this->at(2))
  202. ->method('getUserValue')
  203. ->with('uid3', 'core', 'lang', null)
  204. ->willReturn('de');
  205. $enL10N = $this->createMock(IL10N::class);
  206. $enL10N->method('t')
  207. ->willReturnArgument(0);
  208. $enL10N->method('l')
  209. ->willReturnArgument(0);
  210. $deL10N = $this->createMock(IL10N::class);
  211. $deL10N->method('t')
  212. ->willReturnArgument(0);
  213. $deL10N->method('l')
  214. ->willReturnArgument(0);
  215. $this->l10nFactory->expects($this->at(0))
  216. ->method('findLanguage')
  217. ->with()
  218. ->willReturn('en');
  219. $this->l10nFactory->expects($this->at(1))
  220. ->method('languageExists')
  221. ->with('dav', 'de')
  222. ->willReturn(true);
  223. $this->l10nFactory->expects($this->at(2))
  224. ->method('get')
  225. ->with('dav', 'de')
  226. ->willReturn($enL10N);
  227. $this->l10nFactory->expects($this->at(3))
  228. ->method('languageExists')
  229. ->with('dav', 'en')
  230. ->willReturn(true);
  231. $this->l10nFactory->expects($this->at(4))
  232. ->method('get')
  233. ->with('dav', 'en')
  234. ->willReturn($deL10N);
  235. $template1 = $this->getTemplateMock();
  236. $message11 = $this->getMessageMock('foo1@example.org', $template1);
  237. $message12 = $this->getMessageMock('uid2@example.com', $template1);
  238. $message13 = $this->getMessageMock('uid3@example.com', $template1);
  239. $template2 = $this->getTemplateMock();
  240. $message21 = $this->getMessageMock('foo3@example.org', $template2);
  241. $message22 = $this->getMessageMock('foo4@example.org', $template2);
  242. $message23 = $this->getMessageMock('uid1@example.com', $template2);
  243. $this->mailer->expects($this->at(0))
  244. ->method('createEMailTemplate')
  245. ->with('dav.calendarReminder')
  246. ->willReturn($template1);
  247. $this->mailer->expects($this->at(1))
  248. ->method('createMessage')
  249. ->with()
  250. ->willReturn($message11);
  251. $this->mailer->expects($this->at(2))
  252. ->method('send')
  253. ->with($message11)
  254. ->willReturn([]);
  255. $this->mailer->expects($this->at(3))
  256. ->method('createMessage')
  257. ->with()
  258. ->willReturn($message12);
  259. $this->mailer->expects($this->at(4))
  260. ->method('send')
  261. ->with($message12)
  262. ->willReturn([]);
  263. $this->mailer->expects($this->at(5))
  264. ->method('createMessage')
  265. ->with()
  266. ->willReturn($message13);
  267. $this->mailer->expects($this->at(6))
  268. ->method('send')
  269. ->with($message13)
  270. ->willReturn([]);
  271. $this->mailer->expects($this->at(7))
  272. ->method('createEMailTemplate')
  273. ->with('dav.calendarReminder')
  274. ->willReturn($template2);
  275. $this->mailer->expects($this->at(8))
  276. ->method('createMessage')
  277. ->with()
  278. ->willReturn($message21);
  279. $this->mailer->expects($this->at(9))
  280. ->method('send')
  281. ->with($message21)
  282. ->willReturn([]);
  283. $this->mailer->expects($this->at(10))
  284. ->method('createMessage')
  285. ->with()
  286. ->willReturn($message22);
  287. $this->mailer->expects($this->at(11))
  288. ->method('send')
  289. ->with($message22)
  290. ->willReturn([]);
  291. $this->mailer->expects($this->at(12))
  292. ->method('createMessage')
  293. ->with()
  294. ->willReturn($message23);
  295. $this->mailer->expects($this->at(13))
  296. ->method('send')
  297. ->with($message23)
  298. ->willReturn([]);
  299. $this->setupURLGeneratorMock(2);
  300. $vcalendar = $this->getAttendeeVCalendar();
  301. $this->provider->send($vcalendar->VEVENT, $this->calendarDisplayName, $users);
  302. }
  303. /**
  304. * @return IEMailTemplate
  305. */
  306. private function getTemplateMock():IEMailTemplate {
  307. $template = $this->createMock(IEMailTemplate::class);
  308. $template->expects($this->at(0))
  309. ->method('addHeader')
  310. ->with()
  311. ->willReturn($template);
  312. $template->expects($this->at(1))
  313. ->method('setSubject')
  314. ->with()
  315. ->willReturn($template);
  316. $template->expects($this->at(2))
  317. ->method('addHeading')
  318. ->with()
  319. ->willReturn($template);
  320. $template->expects($this->at(3))
  321. ->method('addBodyListItem')
  322. ->with()
  323. ->willReturn($template);
  324. $template->expects($this->at(4))
  325. ->method('addBodyListItem')
  326. ->with()
  327. ->willReturn($template);
  328. $template->expects($this->at(5))
  329. ->method('addBodyListItem')
  330. ->with()
  331. ->willReturn($template);
  332. $template->expects($this->at(6))
  333. ->method('addBodyListItem')
  334. ->with()
  335. ->willReturn($template);
  336. $template->expects($this->at(7))
  337. ->method('addFooter')
  338. ->with()
  339. ->willReturn($template);
  340. return $template;
  341. }
  342. /**
  343. * @param array $toMail
  344. * @param IEMailTemplate $templateMock
  345. * @param array $replyTo
  346. * @return IMessage
  347. */
  348. private function getMessageMock(string $toMail, IEMailTemplate $templateMock, array $replyTo=null):IMessage {
  349. $message = $this->createMock(IMessage::class);
  350. $i = 0;
  351. $message->expects($this->at($i++))
  352. ->method('setFrom')
  353. ->with([\OCP\Util::getDefaultEmailAddress('reminders-noreply')])
  354. ->willReturn($message);
  355. if ($replyTo) {
  356. $message->expects($this->at($i++))
  357. ->method('setReplyTo')
  358. ->with($replyTo)
  359. ->willReturn($message);
  360. }
  361. $message->expects($this->at($i++))
  362. ->method('setTo')
  363. ->with([$toMail])
  364. ->willReturn($message);
  365. $message->expects($this->at($i++))
  366. ->method('useTemplate')
  367. ->with($templateMock)
  368. ->willReturn($message);
  369. return $message;
  370. }
  371. private function getNoAttendeeVCalendar():VCalendar {
  372. $vcalendar = new VCalendar();
  373. $vcalendar->add('VEVENT', [
  374. 'SUMMARY' => 'Fellowship meeting',
  375. 'DTSTART' => new \DateTime('2017-01-01 00:00:00+00:00'), // 1483228800,
  376. 'UID' => 'uid1234',
  377. 'LOCATION' => 'Location 123',
  378. 'DESCRIPTION' => 'DESCRIPTION 456',
  379. ]);
  380. return $vcalendar;
  381. }
  382. private function getAttendeeVCalendar():VCalendar {
  383. $vcalendar = new VCalendar();
  384. $vcalendar->add('VEVENT', [
  385. 'SUMMARY' => 'Fellowship meeting',
  386. 'DTSTART' => new \DateTime('2017-01-01 00:00:00+00:00'), // 1483228800,
  387. 'UID' => 'uid1234',
  388. 'LOCATION' => 'Location 123',
  389. 'DESCRIPTION' => 'DESCRIPTION 456',
  390. ]);
  391. $vcalendar->VEVENT->add(
  392. 'ATTENDEE',
  393. 'mailto:foo1@example.org',
  394. [
  395. 'LANG' => 'de',
  396. 'PARTSTAT' => 'NEEDS-ACTION',
  397. ]
  398. );
  399. $vcalendar->VEVENT->add(
  400. 'ATTENDEE',
  401. 'mailto:foo2@example.org',
  402. [
  403. 'LANG' => 'de',
  404. 'PARTSTAT' => 'DECLINED',
  405. ]
  406. );
  407. $vcalendar->VEVENT->add(
  408. 'ATTENDEE',
  409. 'mailto:foo3@example.org',
  410. [
  411. 'LANG' => 'en',
  412. 'PARTSTAT' => 'CONFIRMED',
  413. ]
  414. );
  415. $vcalendar->VEVENT->add(
  416. 'ATTENDEE',
  417. 'mailto:foo4@example.org'
  418. );
  419. $vcalendar->VEVENT->add(
  420. 'ATTENDEE',
  421. 'tomail:foo5@example.org'
  422. );
  423. return $vcalendar;
  424. }
  425. private function setupURLGeneratorMock(int $times=1):void {
  426. for ($i = 0; $i < $times; $i++) {
  427. $this->urlGenerator
  428. ->expects($this->at(8 * $i))
  429. ->method('imagePath')
  430. ->with('core', 'actions/info.svg')
  431. ->willReturn('imagePath1');
  432. $this->urlGenerator
  433. ->expects($this->at(8 * $i + 1))
  434. ->method('getAbsoluteURL')
  435. ->with('imagePath1')
  436. ->willReturn('AbsURL1');
  437. $this->urlGenerator
  438. ->expects($this->at(8 * $i + 2))
  439. ->method('imagePath')
  440. ->with('core', 'places/calendar.svg')
  441. ->willReturn('imagePath2');
  442. $this->urlGenerator
  443. ->expects($this->at(8 * $i + 3))
  444. ->method('getAbsoluteURL')
  445. ->with('imagePath2')
  446. ->willReturn('AbsURL2');
  447. $this->urlGenerator
  448. ->expects($this->at(8 * $i + 4))
  449. ->method('imagePath')
  450. ->with('core', 'actions/address.svg')
  451. ->willReturn('imagePath3');
  452. $this->urlGenerator
  453. ->expects($this->at(8 * $i + 5))
  454. ->method('getAbsoluteURL')
  455. ->with('imagePath3')
  456. ->willReturn('AbsURL3');
  457. $this->urlGenerator
  458. ->expects($this->at(8 * $i + 6))
  459. ->method('imagePath')
  460. ->with('core', 'actions/more.svg')
  461. ->willReturn('imagePath4');
  462. $this->urlGenerator
  463. ->expects($this->at(8 * $i + 7))
  464. ->method('getAbsoluteURL')
  465. ->with('imagePath4')
  466. ->willReturn('AbsURL4');
  467. }
  468. }
  469. }