Files
Gnuboard7/tests/Unit/Services/MailSendLogServiceTest.php
T
2026-04-01 10:30:52 +09:00

368 lines
11 KiB
PHP

<?php
namespace Tests\Unit\Services;
use App\Enums\ExtensionOwnerType;
use App\Enums\MailSendStatus;
use App\Models\MailSendLog;
use App\Services\MailSendLogService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/**
* MailSendLogService 테스트
*
* 메일 발송 이력 서비스의 로깅, 조회, 통계 메서드를 검증합니다.
*/
class MailSendLogServiceTest extends TestCase
{
use RefreshDatabase;
private MailSendLogService $service;
protected function setUp(): void
{
parent::setUp();
$this->service = app(MailSendLogService::class);
}
// ========================================================================
// logSent
// ========================================================================
/**
* 발송 성공 이력을 기록합니다
*/
public function test_log_sent_creates_sent_record(): void
{
$log = $this->service->logSent(
recipientEmail: 'user@example.com',
recipientName: 'John Doe',
subject: 'Welcome',
templateType: 'welcome',
extensionType: ExtensionOwnerType::Core,
extensionIdentifier: 'core',
source: 'notification',
);
$this->assertInstanceOf(MailSendLog::class, $log);
$this->assertTrue($log->exists);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'user@example.com',
'recipient_name' => 'John Doe',
'subject' => 'Welcome',
'template_type' => 'welcome',
'extension_type' => ExtensionOwnerType::Core->value,
'extension_identifier' => 'core',
'source' => 'notification',
'status' => MailSendStatus::Sent->value,
]);
}
/**
* logSent는 기본값으로 extensionType=Core, extensionIdentifier='core', source=null을 사용
*/
public function test_log_sent_uses_default_values(): void
{
$log = $this->service->logSent(
recipientEmail: 'test@example.com',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'test@example.com',
'recipient_name' => null,
'subject' => null,
'template_type' => null,
'extension_type' => ExtensionOwnerType::Core->value,
'extension_identifier' => 'core',
'source' => null,
'status' => MailSendStatus::Sent->value,
]);
}
/**
* logSent는 sent_at을 자동 설정
*/
public function test_log_sent_sets_sent_at(): void
{
$log = $this->service->logSent(recipientEmail: 'test@example.com');
$this->assertNotNull($log->sent_at);
}
/**
* logSent는 body를 기록합니다
*/
public function test_log_sent_records_body(): void
{
$body = '<p>Welcome to G7!</p>';
$log = $this->service->logSent(
recipientEmail: 'user@example.com',
subject: 'Welcome',
body: $body,
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'user@example.com',
'body' => $body,
]);
}
/**
* logSent는 body가 null일 수 있음
*/
public function test_log_sent_allows_null_body(): void
{
$log = $this->service->logSent(
recipientEmail: 'test@example.com',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'test@example.com',
'body' => null,
]);
}
/**
* logSent는 발송자 정보를 기록합니다
*/
public function test_log_sent_records_sender(): void
{
$log = $this->service->logSent(
recipientEmail: 'user@example.com',
subject: 'Welcome',
senderEmail: 'admin@example.com',
senderName: 'G7 Admin',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'user@example.com',
'sender_email' => 'admin@example.com',
'sender_name' => 'G7 Admin',
]);
}
/**
* logSent는 발송자 정보가 null일 수 있음
*/
public function test_log_sent_allows_null_sender(): void
{
$log = $this->service->logSent(
recipientEmail: 'test@example.com',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'test@example.com',
'sender_email' => null,
'sender_name' => null,
]);
}
// ========================================================================
// logFailed
// ========================================================================
/**
* 발송 실패 이력을 기록합니다
*/
public function test_log_failed_creates_failed_record(): void
{
$log = $this->service->logFailed(
recipientEmail: 'user@example.com',
subject: 'Order Confirmation',
templateType: 'order_confirmed',
extensionType: ExtensionOwnerType::Module,
extensionIdentifier: 'sirsoft-ecommerce',
source: 'notification',
errorMessage: 'Connection timeout',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'user@example.com',
'subject' => 'Order Confirmation',
'template_type' => 'order_confirmed',
'extension_type' => ExtensionOwnerType::Module->value,
'extension_identifier' => 'sirsoft-ecommerce',
'source' => 'notification',
'status' => MailSendStatus::Failed->value,
'error_message' => 'Connection timeout',
]);
}
/**
* logFailed는 body를 기록합니다
*/
public function test_log_failed_records_body(): void
{
$body = '<p>Order Confirmation</p>';
$log = $this->service->logFailed(
recipientEmail: 'user@example.com',
subject: 'Order',
errorMessage: 'SMTP error',
body: $body,
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'user@example.com',
'body' => $body,
'status' => MailSendStatus::Failed->value,
]);
}
/**
* logFailed는 발송자 정보를 기록합니다
*/
public function test_log_failed_records_sender(): void
{
$log = $this->service->logFailed(
recipientEmail: 'user@example.com',
errorMessage: 'SMTP error',
senderEmail: 'noreply@example.com',
senderName: 'G7 System',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'user@example.com',
'sender_email' => 'noreply@example.com',
'sender_name' => 'G7 System',
'status' => MailSendStatus::Failed->value,
]);
}
/**
* logFailed는 error_message가 null일 수 있음
*/
public function test_log_failed_allows_null_error_message(): void
{
$log = $this->service->logFailed(
recipientEmail: 'test@example.com',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'test@example.com',
'status' => MailSendStatus::Failed->value,
'error_message' => null,
]);
}
// ========================================================================
// logSkipped
// ========================================================================
/**
* 발송 건너뛰기 이력을 기록합니다
*/
public function test_log_skipped_creates_skipped_record(): void
{
$log = $this->service->logSkipped(
recipientEmail: 'user@example.com',
recipientName: 'User',
templateType: 'welcome',
extensionType: ExtensionOwnerType::Core,
extensionIdentifier: 'core',
source: 'notification',
errorMessage: '비활성 템플릿',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'user@example.com',
'recipient_name' => 'User',
'subject' => null,
'template_type' => 'welcome',
'extension_type' => ExtensionOwnerType::Core->value,
'extension_identifier' => 'core',
'source' => 'notification',
'status' => MailSendStatus::Skipped->value,
'error_message' => '비활성 템플릿',
]);
}
/**
* logSkipped는 발송자 정보를 기록합니다
*/
public function test_log_skipped_records_sender(): void
{
$log = $this->service->logSkipped(
recipientEmail: 'user@example.com',
senderEmail: 'admin@example.com',
senderName: 'G7 Admin',
);
$this->assertDatabaseHas('mail_send_logs', [
'recipient_email' => 'user@example.com',
'sender_email' => 'admin@example.com',
'sender_name' => 'G7 Admin',
'status' => MailSendStatus::Skipped->value,
]);
}
/**
* logSkipped는 subject를 항상 null로 설정
*/
public function test_log_skipped_always_sets_null_subject(): void
{
$log = $this->service->logSkipped(
recipientEmail: 'test@example.com',
);
$this->assertNull($log->subject);
}
// ========================================================================
// getLogs
// ========================================================================
/**
* 발송 이력 목록 조회
*/
public function test_get_logs_returns_paginated_result(): void
{
MailSendLog::factory()->count(5)->create();
$result = $this->service->getLogs();
$this->assertCount(5, $result->items());
$this->assertEquals(5, $result->total());
}
/**
* 발송 이력 목록 필터 조회
*/
public function test_get_logs_applies_filters(): void
{
MailSendLog::factory()->forExtension(ExtensionOwnerType::Core, 'core')->count(3)->create();
MailSendLog::factory()->forExtension(ExtensionOwnerType::Module, 'sirsoft-ecommerce')->count(2)->create();
$result = $this->service->getLogs(['extension_type' => 'core']);
$this->assertCount(3, $result->items());
}
// ========================================================================
// getStatistics
// ========================================================================
/**
* 발송 통계 조회
*/
public function test_get_statistics_returns_correct_data(): void
{
MailSendLog::factory()->count(3)->create([
'status' => MailSendStatus::Sent->value,
'sent_at' => now(),
]);
MailSendLog::factory()->failed()->count(1)->create([
'sent_at' => now(),
]);
$stats = $this->service->getStatistics();
$this->assertEquals(4, $stats['total']);
$this->assertEquals(3, $stats['sent']);
$this->assertEquals(1, $stats['failed']);
$this->assertEquals(4, $stats['today']);
}
}