postoffice-1.0.x-dev/extensions/postoffice_compat/tests/src/Kernel/ContactMailPluginTest.php
extensions/postoffice_compat/tests/src/Kernel/ContactMailPluginTest.php
<?php
namespace Drupal\Tests\postoffice_compat\Kernel;
use Drupal\Component\Utility\Html;
use Drupal\Tests\user\Traits\UserCreationTrait;
use Drupal\contact\Entity\ContactForm;
use Drupal\contact\Entity\Message;
/**
* Tests for contact mail plugin.
*
* @group postoffice_compat
*/
class ContactMailPluginTest extends CompatTestBase {
use UserCreationTrait;
/**
* {@inheritdoc}
*/
protected static $modules = ['contact', 'user'];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installConfig(['contact', 'user']);
$this->installSchema('user', ['users_data']);
$this->installEntitySchema('contact_message');
$this->installEntitySchema('user');
$this->config('system.mail')
->set('interface.contact', 'postoffice_contact_mail')
->save();
}
/**
* Verify that a personal contact message is delivered using the plugin.
*/
public function testCompatContactPersonalMail() {
/** @var \Drupal\contact\MailHandlerInterface $mailHandler */
$mailHandler = $this->container->get('contact.mail_handler');
$sender = $this->createUser([], NULL, FALSE, [
'mail' => $this->randomMachineName() . '@example.com',
]);
$recipient = $this->createUser([], NULL, FALSE, [
'mail' => $this->randomMachineName() . '@example.com',
]);
$messageLines = [
$this->randomString(32),
$this->randomString(28),
$this->randomString(8),
];
$message = Message::create([
'contact_form' => 'personal',
'subject' => $this->randomMachineName(),
'message' => implode("\n\n", $messageLines),
'mail' => $sender->getEmail(),
'name' => $sender->getDisplayName(),
'recipient' => $recipient,
'copy' => TRUE,
]);
$message->save();
/** @var \Drupal\postoffice_compat\Email\ContactPersonalEmail[] $recordedEmails*/
$recordedEmails = $this->callAndRecordEmails(function () use ($mailHandler, $message, $sender) {
$mailHandler->sendMailMessages($message, $sender);
});
$recipientName = Html::escape($recipient->getDisplayName());
$recipientUrl = $recipient->toUrl('edit-form', ['absolute' => TRUE])->toString();
$senderName = Html::escape($sender->getDisplayName());
$senderUrl = $sender->toUrl('canonical', ['absolute' => TRUE])->toString();
$siteName = Html::escape($this->config('system.site')->get('name'));
$introLines = [
"<p>Hello {$recipientName},</p>",
"<p><a href=\"{$senderUrl}\">{$senderName}</a> has sent you a message via your contact form at {$siteName}.</p>",
"<p>If you don't want to receive such emails, you can change your settings <a href=\"{$recipientUrl}\">on your profile</a>.</p>",
];
// Expect two mails: One orig, one copy.
$this->assertCount(2, $recordedEmails);
[$orig, $copy] = $recordedEmails;
$this->assertEquals($recipient->getEmail(), $orig->getTo()[0]->toString());
$this->assertEquals($sender->getEmail(), $orig->getReplyTo()[0]->toString());
$this->assertEquals($sender->getEmail(), $copy->getTo()[0]->toString());
// Note: Core contact module sets the reply-to header to the senders email
// in both messages, i.e. the original and the copy. One would expect that
// in the copy message, the reply-to header should be set to the recipient
// email address. However, doing that would leak email addresses to the
// sender. Thus, we explicitly test that the reply-to header is correct in
// order to prevent people from trying to fix this slightly exotic behavior.
$this->assertEquals($sender->getEmail(), $copy->getReplyTo()[0]->toString());
foreach ($recordedEmails as $email) {
$actual = trim($email->getHtmlBody());
// Rendered markup is hard to predict. Thus, just assert that all the
// lines are in the message.
foreach ($introLines as $line) {
$this->assertStringContainsString($line, $actual);
}
foreach ($messageLines as $line) {
$this->assertStringContainsString(Html::escape($line), $actual);
}
}
}
/**
* Verify that a site contact message is delivered using the plugin.
*/
public function testCompatContactPageMail() {
/** @var \Drupal\contact\MailHandlerInterface $mailHandler */
$mailHandler = $this->container->get('contact.mail_handler');
$sender = $this->createUser([], NULL, FALSE, [
'mail' => $this->randomMachineName() . '@example.com',
]);
$contactForm = ContactForm::create([
'id' => $this->randomMachineName(),
'label' => $this->randomMachineName(),
'recipients' => [
$this->randomMachineName() . '@example.com',
],
]);
$contactForm->save();
$messageLines = [
$this->randomString(32),
$this->randomString(28),
$this->randomString(8),
];
$message = Message::create([
'contact_form' => $contactForm->id(),
'subject' => $this->randomMachineName(),
'message' => implode("\n\n", $messageLines),
'mail' => $sender->getEmail(),
'name' => $sender->getDisplayName(),
'copy' => TRUE,
]);
$message->save();
/** @var \Drupal\postoffice_compat\Email\ContactPageEmail[] $recordedEmails*/
$recordedEmails = $this->callAndRecordEmails(function () use ($mailHandler, $message, $sender) {
$mailHandler->sendMailMessages($message, $sender);
});
$senderName = Html::escape($sender->getDisplayName());
$senderUrl = $sender->toUrl('canonical', ['absolute' => TRUE])->toString();
$formUrl = $contactForm->toUrl('canonical', ['absolute' => TRUE])->toString();
$introLines = [
"<p><a href=\"{$senderUrl}\">{$senderName}</a> sent a message using the <a href=\"{$formUrl}\">contact form</a>.</p>",
];
[$orig, $copy] = $recordedEmails;
$this->assertEquals($contactForm->getRecipients()[0], $orig->getTo()[0]->toString());
$this->assertEquals($sender->getEmail(), $orig->getReplyTo()[0]->toString());
$this->assertEquals($sender->getEmail(), $copy->getTo()[0]->toString());
// Note: Core contact module sets the reply-to header to the senders email
// in both messages, i.e. the original and the copy. One would expect that
// in the copy message, the reply-to header should be set to the recipient
// email address. However, doing that would leak email addresses to the
// sender. Thus, we explicitly test that the reply-to header is correct in
// order to prevent people from trying to fix this slightly exotic behavior.
$this->assertEquals($sender->getEmail(), $copy->getReplyTo()[0]->toString());
// Expect two mails: One orig, one copy.
$this->assertCount(2, $recordedEmails);
foreach ($recordedEmails as $recordedEmail) {
$actual = trim($recordedEmail->getHtmlBody());
// Rendered markup is hard to predict. Thus, just assert that all the
// lines are in the message.
foreach ($introLines as $line) {
$this->assertStringContainsString($line, $actual);
}
foreach ($messageLines as $line) {
$this->assertStringContainsString(Html::escape($line), $actual);
}
}
}
}
