Files
agent-unit-testing/docs/components/10-notifications-and-mail.md
Pham-Tan-Thien 2045c856e9 feat: complete Smartgift AI Laravel unit testing toolkit
- Add 10 core testing guides (setup, AAA principles, PHPUnit/Pest, mocking, anti-patterns, PHP 8.4+, debugging, data factories, advanced edge cases)
- Add 13 component testing guides covering all Laravel layers
- Add standard templates for PHPUnit 10/11 and Pest v2/v3 including ArchitectureTest
- Add Docker smart test runner, dependency installer, and CI/CD templates (GitHub Actions, GitLab CI)
- Add 4 Claude Code skills (laravel-test-setup, laravel-unit-test with --all mode, laravel-test-review, laravel-mock-helper)
- Add single unified installer script (sg-install-unit-testing.sh) with global support, CLI runners, and 1-click updater (sg-test-update)
- Add comprehensive documentation (README.md, USAGE-GUIDE.md)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-07 16:41:37 +07:00

4.0 KiB

Component Guide: Mailables & Notifications

Kiểm thử gửi Mail và Notification trong Laravel gồm kiểm tra các kênh gửi (via), nội dung (toMail, toArray) và các biến dữ liệu gán vào view.


1. Bản Chất Kiểm Thử Mailable & Notification

  1. Mailable Unit Test:
    • Kiểm tra subject (tiêu đề email).
    • Kiểm tra người nhận (to), người gửi (from).
    • Kiểm tra file đính kèm (attachments).
    • Kiểm tra xem view template có render đúng nội dung với data truyền vào không.
  2. Notification Unit Test:
    • Kiểm tra method via($notifiable): Trả về đúng mảng các kênh ['mail', 'database'].
    • Kiểm tra method toMail($notifiable): Đối tượng MailMessage có chứa đúng tiêu đề, lời chào và URL nút bấm.
    • Kiểm tra method toArray($notifiable): Cấu trúc mảng lưu trữ vào bảng notifications.

2. Mã Mẫu Chuẩn: Notification Unit Test

Notification Nguồn: App\Notifications\InvoicePaidNotification

namespace App\Notifications;

use App\Models\Invoice;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class InvoicePaidNotification extends Notification
{
    use Queueable;

    public function __construct(
        public readonly Invoice $invoice
    ) {}

    public function via(object $notifiable): array
    {
        return ['mail', 'database'];
    }

    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
            ->subject("Hóa đơn #{$this->invoice->number} đã được thanh toán")
            ->greeting("Xin chào {$notifiable->name},")
            ->line("Cảm ơn bạn đã thanh toán số tiền: {$this->invoice->amount} VND.")
            ->action('Xem chi tiết hóa đơn', url("/invoices/{$this->invoice->id}"));
    }

    public function toArray(object $notifiable): array
    {
        return [
            'invoice_id' => $this->invoice->id,
            'amount'     => $this->invoice->amount,
            'paid_at'    => now()->toIso8601String(),
        ];
    }
}

Test Chuẩn: PHPUnit 10+

namespace Tests\Unit\Notifications;

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\Test;
use App\Notifications\InvoicePaidNotification;
use App\Models\Invoice;
use App\Models\User;

class InvoicePaidNotificationTest extends TestCase
{
    #[Test]
    public function it_defines_correct_notification_channels(): void
    {
        $invoice = new Invoice(['id' => 1, 'number' => 'INV-2026', 'amount' => 500000]);
        $notification = new InvoicePaidNotification($invoice);
        $user = new User(['id' => 10, 'name' => 'Thien']);

        $channels = $notification->via($user);

        $this->assertSame(['mail', 'database'], $channels);
    }

    #[Test]
    public function it_builds_correct_mail_message(): void
    {
        $invoice = new Invoice(['id' => 99, 'number' => 'INV-99', 'amount' => 100000]);
        $notification = new InvoicePaidNotification($invoice);
        $user = new User(['id' => 10, 'name' => 'Thien']);

        $mailMessage = $notification->toMail($user);

        $this->assertSame('Hóa đơn #INV-99 đã được thanh toán', $mailMessage->subject);
        $this->assertSame('Xin chào Thien,', $mailMessage->greeting);
        $this->assertSame('Xem chi tiết hóa đơn', $mailMessage->actionText);
        $this->assertStringContainsString('/invoices/99', $mailMessage->actionUrl);
    }

    #[Test]
    public function it_builds_correct_database_array_payload(): void
    {
        $invoice = new Invoice(['id' => 55, 'number' => 'INV-55', 'amount' => 250000]);
        $notification = new InvoicePaidNotification($invoice);
        $user = new User(['id' => 10, 'name' => 'Thien']);

        $data = $notification->toArray($user);

        $this->assertSame(55, $data['invoice_id']);
        $this->assertSame(250000, $data['amount']);
        $this->assertArrayHasKey('paid_at', $data);
    }
}