feat: admin editable email templates
addresses #869eg7ptr
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Email;
|
||||
|
||||
use App\Config\EmailTextCatalog;
|
||||
use App\Config\EmailTextKey;
|
||||
use App\Email\EmailTextRenderer;
|
||||
use App\Email\Mailer;
|
||||
use App\Repository\EmailTextRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
/**
|
||||
* Renders every editable mail through the real template stack.
|
||||
*
|
||||
* The unit tests cover what the renderer produces; this covers that the result actually
|
||||
* survives email/generic.html.twig and the layout around it - a mail that only breaks
|
||||
* when it is assembled would otherwise go unnoticed until a teamer fails to receive it.
|
||||
*/
|
||||
class EmailTextMailRenderingTest extends KernelTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideKeys
|
||||
*/
|
||||
public function testTheMailRenders(EmailTextKey $key): void
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$container = self::getContainer();
|
||||
$catalog = $container->get(EmailTextCatalog::class);
|
||||
$definition = $catalog->get($key);
|
||||
|
||||
$placeholders = [];
|
||||
|
||||
foreach ($definition->getPlaceholderNames() as $name) {
|
||||
$placeholders[$name] = '['.$name.']';
|
||||
}
|
||||
|
||||
// Renders the delivered wording: the test environment has no database, and the
|
||||
// defaults are what a mail falls back to anyway.
|
||||
$repository = $this->createMock(EmailTextRepository::class);
|
||||
$repository->method('findByKey')->willReturn(null);
|
||||
|
||||
$text = (new EmailTextRenderer($catalog, $repository))
|
||||
->render($key, $placeholders)
|
||||
;
|
||||
|
||||
$email = $container->get(Mailer::class)->create(['text' => $text], [
|
||||
'from' => '[email protected]',
|
||||
'to' => '[email protected]',
|
||||
'subject' => $text->subject,
|
||||
'template' => 'email/generic.html.twig',
|
||||
'subject_parameters' => [],
|
||||
'attachments' => [],
|
||||
'transport' => null,
|
||||
'bus_transport' => null,
|
||||
]);
|
||||
|
||||
$html = $email->getHtmlBody();
|
||||
|
||||
$this->assertNotEmpty($html);
|
||||
$this->assertStringContainsString($text->headline, $html);
|
||||
// The layout closes every mail with the same button, pointing at the site root
|
||||
// rather than a deep link so that a client's link preview cannot trip the
|
||||
// unauthorized-access logging.
|
||||
$this->assertStringContainsString('class="button">Zum Portal</a>', $html);
|
||||
$this->assertStringNotContainsString('/teamer/disposition/detail', $html);
|
||||
|
||||
// Every placeholder the mail declares has to reach the rendered body, or the
|
||||
// wording lost a detail somewhere between catalogue and template.
|
||||
foreach ($definition->getPlaceholderNames() as $name) {
|
||||
$this->assertStringContainsString(
|
||||
'['.$name.']',
|
||||
$html.$email->getSubject(),
|
||||
sprintf('Placeholder "%s" does not show up in the rendered mail', $name)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function provideKeys(): iterable
|
||||
{
|
||||
foreach (EmailTextKey::cases() as $key) {
|
||||
yield $key->value => [$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user