130 lines
4.8 KiB
PHP
130 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Exceptions\InvalidTemplateVariableException;
|
|
use App\Jobs\Mail\SendTemplateEmailJob;
|
|
use App\Mail\GenericTemplateMail;
|
|
use App\Models\Template;
|
|
use App\Services\Email\EmailTemplateService;
|
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|
use Illuminate\Support\Facades\Bus;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Tests\TestCase;
|
|
|
|
class EmailTemplateServiceTest extends TestCase
|
|
{
|
|
use DatabaseTransactions;
|
|
|
|
private function makeTemplate(array $overrides = []): Template
|
|
{
|
|
return Template::create(array_merge([
|
|
'type_id' => 0,
|
|
'scenario' => 'unit_test_scenario_' . uniqid(),
|
|
'format' => 'html',
|
|
'name' => 'Test scenario',
|
|
'subject' => 'Xin chào {{full_name}}',
|
|
'message' => '<p>Chào {{full_name}}, mời truy cập {{login_url}}</p>',
|
|
'metadata' => [
|
|
'variables' => [
|
|
['key' => 'full_name', 'label' => 'Họ tên', 'type' => 'string', 'example' => 'Quý khách'],
|
|
['key' => 'login_url', 'label' => 'Link đăng nhập', 'type' => 'url', 'example' => 'https://example.com'],
|
|
],
|
|
],
|
|
'status' => 1,
|
|
], $overrides));
|
|
}
|
|
|
|
public function test_send_dispatches_job_to_queue(): void
|
|
{
|
|
Bus::fake();
|
|
|
|
$template = $this->makeTemplate();
|
|
|
|
app(EmailTemplateService::class)->send($template->scenario, 'user@example.com', [
|
|
'full_name' => 'Nguyễn Văn A',
|
|
'login_url' => 'https://portal.tgs.com.vn/login',
|
|
]);
|
|
|
|
Bus::assertDispatched(SendTemplateEmailJob::class, fn (SendTemplateEmailJob $job) => $job->scenario === $template->scenario
|
|
&& $job->to === ['user@example.com']
|
|
&& $job->data['full_name'] === 'Nguyễn Văn A');
|
|
}
|
|
|
|
public function test_job_renders_and_sends_mail_with_template_sender_config(): void
|
|
{
|
|
Mail::fake();
|
|
|
|
$template = $this->makeTemplate([
|
|
'metadata' => [
|
|
'variables' => [
|
|
['key' => 'full_name', 'label' => 'Họ tên', 'type' => 'string'],
|
|
['key' => 'login_url', 'label' => 'Link', 'type' => 'url'],
|
|
],
|
|
'mail' => [
|
|
'from_email' => 'noreply@tgs.com.vn',
|
|
'from_name' => 'Thế Giới Số',
|
|
'reply_to' => 'support@tgs.com.vn',
|
|
'reply_to_name' => 'TGS Support',
|
|
],
|
|
],
|
|
]);
|
|
|
|
(new SendTemplateEmailJob($template->scenario, ['user@example.com'], [
|
|
'full_name' => 'Nguyễn Văn A',
|
|
'login_url' => 'https://portal.tgs.com.vn/login',
|
|
]))->handle(app(EmailTemplateService::class), app(\App\Services\Email\EmailTemplateRenderer::class));
|
|
|
|
Mail::assertSent(GenericTemplateMail::class, function (GenericTemplateMail $mail) {
|
|
$mail->assertTo('user@example.com');
|
|
$envelope = $mail->envelope();
|
|
|
|
return $envelope->subject === 'Xin chào Nguyễn Văn A'
|
|
&& $envelope->from->address === 'noreply@tgs.com.vn'
|
|
&& $envelope->replyTo[0]->address === 'support@tgs.com.vn'
|
|
&& str_contains($mail->renderedHtml, 'Nguyễn Văn A');
|
|
});
|
|
}
|
|
|
|
public function test_job_falls_back_to_system_default_sender_when_template_has_no_mail_config(): void
|
|
{
|
|
Mail::fake();
|
|
|
|
$template = $this->makeTemplate();
|
|
|
|
(new SendTemplateEmailJob($template->scenario, ['user@example.com'], [
|
|
'full_name' => 'A',
|
|
'login_url' => 'https://example.com',
|
|
]))->handle(app(EmailTemplateService::class), app(\App\Services\Email\EmailTemplateRenderer::class));
|
|
|
|
Mail::assertSent(GenericTemplateMail::class, function (GenericTemplateMail $mail) {
|
|
return $mail->envelope()->from === null;
|
|
});
|
|
}
|
|
|
|
public function test_preview_throws_for_undeclared_variable(): void
|
|
{
|
|
$template = $this->makeTemplate([
|
|
'message' => '<p>{{full_name}} {{not_declared}}</p>',
|
|
]);
|
|
|
|
$this->expectException(InvalidTemplateVariableException::class);
|
|
|
|
app(EmailTemplateService::class)->preview($template->scenario, ['full_name' => 'A']);
|
|
}
|
|
|
|
public function test_load_template_is_cached_by_scenario(): void
|
|
{
|
|
$template = $this->makeTemplate();
|
|
$service = app(EmailTemplateService::class);
|
|
|
|
$first = $service->loadTemplate($template->scenario);
|
|
$this->assertSame('Xin chào {{full_name}}', $first->subject);
|
|
|
|
$template->update(['subject' => 'Đã đổi']); // model event must bust the cache
|
|
$second = $service->loadTemplate($template->scenario);
|
|
|
|
$this->assertSame('Đã đổi', $second->subject);
|
|
}
|
|
}
|