1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2022 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Services; 21 22use Fisharebest\Webtrees\Site; 23use Fisharebest\Webtrees\TestCase; 24use Fisharebest\Webtrees\Contracts\UserInterface; 25 26use function function_exists; 27 28/** 29 * Test harness for the class EmailService 30 * 31 * @covers \Fisharebest\Webtrees\Services\EmailService 32 */ 33class EmailServiceTest extends TestCase 34{ 35 protected static bool $uses_database = true; 36 37 /** 38 * @covers \Fisharebest\Webtrees\Services\EmailService::send 39 * @covers \Fisharebest\Webtrees\Services\EmailService::message 40 * @covers \Fisharebest\Webtrees\Services\EmailService::transport 41 */ 42 public function testSend(): void 43 { 44 $email_service = new EmailService(); 45 46 $user_from = $this->createMock(UserInterface::class); 47 $user_from->method('email')->willReturn('user.from@example.com'); 48 49 $user_from = $this->createMock(UserInterface::class); 50 $user_from->method('email')->willReturn('user.from@example.com'); 51 52 $user_to = $this->createMock(UserInterface::class); 53 $user_to->method('email')->willReturn('user.to@example.com'); 54 55 $user_reply_to = $this->createMock(UserInterface::class); 56 $user_reply_to->method('email')->willReturn('user.replyto@example.com'); 57 58 Site::setPreference('SMTP_ACTIVE', 'internal'); 59 60 self::assertTrue($email_service->send($user_from, $user_to, $user_reply_to, 'Test No DKIM', 'Test Plain Message', '<p>Test Html Message</p>')); 61 62 Site::setPreference('DKIM_DOMAIN', 'example.com'); 63 Site::setPreference('DKIM_SELECTOR', 'sel'); 64 Site::setPreference('DKIM_KEY', '-----BEGIN RSA PRIVATE KEY----- 65MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp 66wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5 671s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh 683tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2 69pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX 70GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il 71AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF 72L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k 73X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl 74U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ 7537sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0= 76-----END RSA PRIVATE KEY-----'); 77 78 self::assertTrue($email_service->send($user_from, $user_to, $user_reply_to, 'Test DKIM', 'Test Plain Message', '<p>Test Html Message</p>')); 79 } 80 81 /** 82 * Data provider for testing email validity 83 * 84 * @return array<array<bool|string>> 85 */ 86 public function emailProvider(): array 87 { 88 return [ 89 // Valid emails 90 ['Abc@webtrees.com', true], 91 ['ABC@webtrees.com', true], 92 ['Abc.123@webtrees.com', true], 93 ['user+mailbox/tree=family@webtrees.com', true], 94 ['!#$%&\'*+-/=?^_`.{|}~@webtrees.com', true], 95 ['"Abc@def"@webtrees.com', true], 96 ['"John\ Doe"@webtrees.com', true], 97 ['"Joe.\\Smith"@webtrees.com', true], 98 ['généalogie@webtrees.com', true], 99 // Invalid 100 ['example@invalid.example.com', false], 101 ['example', false], 102 ['example@with space', false], 103 ['example@webtrees.', false], 104 ['example@webtr\ees.com', false], 105 ['example(comment)@example.com', false], 106 ["\x80\x81\x82@\x83\x84\x85.\x86\x87\x88", false], 107 ['user name@example.com', false], 108 ['example.@example.com', false], 109 ['example(example]example@example.co.uk', false], 110 ['a@b.c+&%$.d', false], 111 ['a.b+&%$.c@d', false], 112 ['example@généalogie', false] 113 ]; 114 } 115 116 /** 117 * @dataProvider emailProvider 118 * 119 * @covers \Fisharebest\Webtrees\Services\EmailService::isValidEmail 120 * 121 * @param string $email 122 * @param bool $is_valid 123 */ 124 public function testIsValidEmail(string $email, bool $is_valid): void 125 { 126 self::assertSame($is_valid, (new EmailService())->isValidEmail($email)); 127 } 128 129 /** 130 * @covers \Fisharebest\Webtrees\Services\EmailService::mailSslOptions 131 */ 132 public function testMailSslOptions(): void 133 { 134 $options = (new EmailService())->mailSslOptions(); 135 self::assertCount(3, $options); 136 self::assertArrayHasKey('ssl', $options); 137 } 138 139 /** 140 * @covers \Fisharebest\Webtrees\Services\EmailService::mailTransportOptions 141 */ 142 public function testMailTransportOptions(): void 143 { 144 $options = (new EmailService())->mailTransportOptions(); 145 self::assertCount(function_exists('proc_open') ? 2 : 1, $options); 146 self::assertArrayHasKey('external', $options); 147 } 148} 149