Files
usher-manage-stack/tests/Feature/EmailTest.php
2025-11-20 23:21:05 +08:00

299 lines
9.5 KiB
PHP

<?php
namespace Tests\Feature;
use App\Mail\MemberRegistrationWelcomeMail;
use App\Mail\MembershipActivatedMail;
use App\Mail\PaymentApprovedByAccountantMail;
use App\Mail\PaymentApprovedByCashierMail;
use App\Mail\PaymentFullyApprovedMail;
use App\Mail\PaymentRejectedMail;
use App\Mail\PaymentSubmittedMail;
use App\Models\Member;
use App\Models\MembershipPayment;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;
class EmailTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
$this->artisan('db:seed', ['--class' => 'RoleSeeder']);
}
public function test_member_registration_welcome_mail_content(): void
{
$member = Member::factory()->create([
'full_name' => 'John Doe',
'email' => 'john@example.com',
]);
$mailable = new MemberRegistrationWelcomeMail($member);
$mailable->assertSeeInHtml('John Doe');
$mailable->assertSeeInHtml('Welcome');
}
public function test_payment_submitted_mail_member_variant(): void
{
$member = Member::factory()->create(['email' => 'member@example.com']);
$payment = MembershipPayment::factory()->create([
'member_id' => $member->id,
'amount' => 1000,
]);
$mailable = new PaymentSubmittedMail($payment, 'member');
$mailable->assertSeeInHtml('1,000');
$mailable->assertSeeInHtml('submitted');
}
public function test_payment_submitted_mail_cashier_variant(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create([
'member_id' => $member->id,
'amount' => 1000,
]);
$mailable = new PaymentSubmittedMail($payment, 'cashier');
$mailable->assertSeeInHtml('review');
$mailable->assertSeeInHtml('1,000');
}
public function test_payment_approved_by_cashier_mail(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create([
'member_id' => $member->id,
'status' => MembershipPayment::STATUS_APPROVED_CASHIER,
'amount' => 1000,
]);
$mailable = new PaymentApprovedByCashierMail($payment);
$mailable->assertSeeInHtml('Cashier');
$mailable->assertSeeInHtml('approved');
}
public function test_payment_approved_by_accountant_mail(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create([
'member_id' => $member->id,
'status' => MembershipPayment::STATUS_APPROVED_ACCOUNTANT,
'amount' => 1000,
]);
$mailable = new PaymentApprovedByAccountantMail($payment);
$mailable->assertSeeInHtml('Accountant');
$mailable->assertSeeInHtml('approved');
}
public function test_payment_fully_approved_mail(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create([
'member_id' => $member->id,
'status' => MembershipPayment::STATUS_APPROVED_CHAIR,
'amount' => 1000,
]);
$mailable = new PaymentFullyApprovedMail($payment);
$mailable->assertSeeInHtml('approved');
$mailable->assertSeeInHtml('1,000');
}
public function test_payment_rejected_mail(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create([
'member_id' => $member->id,
'status' => MembershipPayment::STATUS_REJECTED,
'rejection_reason' => 'Invalid receipt format',
'amount' => 1000,
]);
$mailable = new PaymentRejectedMail($payment);
$mailable->assertSeeInHtml('Invalid receipt format');
$mailable->assertSeeInHtml('rejected');
}
public function test_membership_activated_mail(): void
{
$member = Member::factory()->create([
'full_name' => 'John Doe',
'membership_status' => Member::STATUS_ACTIVE,
'membership_started_at' => now(),
'membership_expires_at' => now()->addYear(),
]);
$mailable = new MembershipActivatedMail($member);
$mailable->assertSeeInHtml('activated');
$mailable->assertSeeInHtml('John Doe');
}
public function test_all_emails_implement_should_queue(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create(['member_id' => $member->id]);
$mailables = [
new MemberRegistrationWelcomeMail($member),
new PaymentSubmittedMail($payment, 'member'),
new PaymentApprovedByCashierMail($payment),
new PaymentApprovedByAccountantMail($payment),
new PaymentFullyApprovedMail($payment),
new PaymentRejectedMail($payment),
new MembershipActivatedMail($member),
];
foreach ($mailables as $mailable) {
$this->assertInstanceOf(\Illuminate\Contracts\Queue\ShouldQueue::class, $mailable);
}
}
public function test_emails_queued_correctly(): void
{
Mail::fake();
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create(['member_id' => $member->id]);
Mail::to($member->email)->queue(new PaymentSubmittedMail($payment, 'member'));
Mail::assertQueued(PaymentSubmittedMail::class);
}
public function test_email_recipients_correct(): void
{
Mail::fake();
$member = Member::factory()->create(['email' => 'member@example.com']);
$payment = MembershipPayment::factory()->create(['member_id' => $member->id]);
Mail::to($member->email)->queue(new PaymentSubmittedMail($payment, 'member'));
Mail::assertQueued(PaymentSubmittedMail::class, function ($mail) {
return $mail->hasTo('member@example.com');
});
}
public function test_payment_submitted_mail_has_correct_subject(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create(['member_id' => $member->id]);
$mailable = new PaymentSubmittedMail($payment, 'member');
$this->assertStringContainsString('Payment', $mailable->subject ?? '');
}
public function test_rejection_mail_includes_next_steps(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create([
'member_id' => $member->id,
'status' => MembershipPayment::STATUS_REJECTED,
'rejection_reason' => 'Test reason',
]);
$mailable = new PaymentRejectedMail($payment);
$mailable->assertSeeInHtml('Submit New Payment');
}
public function test_activation_mail_includes_expiry_date(): void
{
$member = Member::factory()->create([
'membership_status' => Member::STATUS_ACTIVE,
'membership_expires_at' => now()->addYear(),
]);
$mailable = new MembershipActivatedMail($member);
$expiryDate = $member->membership_expires_at->format('Y-m-d');
$mailable->assertSeeInHtml($expiryDate);
}
public function test_welcome_mail_includes_dashboard_link(): void
{
$member = Member::factory()->create();
$mailable = new MemberRegistrationWelcomeMail($member);
$mailable->assertSeeInHtml(route('member.dashboard'));
}
public function test_payment_fully_approved_mail_mentions_activation(): void
{
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create([
'member_id' => $member->id,
'status' => MembershipPayment::STATUS_APPROVED_CHAIR,
]);
$mailable = new PaymentFullyApprovedMail($payment);
$mailable->assertSeeInHtml('activated');
}
public function test_mail_facades_work_correctly(): void
{
Mail::fake();
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create(['member_id' => $member->id]);
// Send various emails
Mail::to($member->email)->queue(new MemberRegistrationWelcomeMail($member));
Mail::to($member->email)->queue(new PaymentSubmittedMail($payment, 'member'));
Mail::to($member->email)->queue(new MembershipActivatedMail($member));
Mail::assertQueued(MemberRegistrationWelcomeMail::class);
Mail::assertQueued(PaymentSubmittedMail::class);
Mail::assertQueued(MembershipActivatedMail::class);
}
public function test_emails_not_sent_when_not_queued(): void
{
Mail::fake();
// Don't queue any emails
Mail::assertNothingQueued();
Mail::assertNothingSent();
}
public function test_multiple_recipients_can_receive_same_email(): void
{
Mail::fake();
$member = Member::factory()->create();
$payment = MembershipPayment::factory()->create(['member_id' => $member->id]);
// Send to multiple recipients
Mail::to(['admin1@example.com', 'admin2@example.com'])->queue(new PaymentSubmittedMail($payment, 'cashier'));
Mail::assertQueued(PaymentSubmittedMail::class, 1);
}
public function test_email_content_is_html_formatted(): void
{
$member = Member::factory()->create();
$mailable = new MemberRegistrationWelcomeMail($member);
$mailable->assertSeeInHtml('<');
$mailable->assertSeeInHtml('>');
}
}