seedRolesAndPermissions(); } /** * Test welcome email has correct subject */ public function test_welcome_email_has_correct_subject(): void { $member = $this->createPendingMember(); $mail = new WelcomeMemberMail($member); $this->assertStringContainsString('歡迎', $mail->envelope()->subject); } /** * Test welcome email contains member name */ public function test_welcome_email_contains_member_name(): void { $member = $this->createPendingMember(['full_name' => 'Test Member Name']); $mail = new WelcomeMemberMail($member); $rendered = $mail->render(); $this->assertStringContainsString('Test Member Name', $rendered); } /** * Test welcome email contains dashboard link */ public function test_welcome_email_contains_dashboard_link(): void { $member = $this->createPendingMember(); $mail = new WelcomeMemberMail($member); $rendered = $mail->render(); $this->assertStringContainsString(route('member.dashboard'), $rendered); } /** * Test welcome email sent to correct recipient */ public function test_welcome_email_sent_to_correct_recipient(): void { Mail::fake(); $data = $this->getValidMemberRegistrationData(['email' => 'newmember@test.com']); $this->post(route('register.member.store'), $data); Mail::assertQueued(WelcomeMemberMail::class, function ($mail) { return $mail->hasTo('newmember@test.com'); }); } /** * Test payment submitted email to member */ public function test_payment_submitted_email_to_member(): void { $data = $this->createMemberWithPendingPayment(); $member = $data['member']; $payment = $data['payment']; $mail = new PaymentSubmittedMail($payment, $member->user, 'member'); $rendered = $mail->render(); $this->assertStringContainsString((string) $payment->amount, $rendered); } /** * Test payment submitted email to cashier */ public function test_payment_submitted_email_to_cashier(): void { $data = $this->createMemberWithPendingPayment(); $member = $data['member']; $payment = $data['payment']; $cashier = $this->createCashier(); $mail = new PaymentSubmittedMail($payment, $cashier, 'cashier'); $rendered = $mail->render(); $this->assertStringContainsString($member->full_name, $rendered); } /** * Test payment approved by cashier email */ public function test_payment_approved_by_cashier_email(): void { $data = $this->createMemberWithPaymentAtStage('cashier_approved'); $payment = $data['payment']; $mail = new PaymentApprovedByCashierMail($payment); $this->assertNotNull($mail->envelope()->subject); $rendered = $mail->render(); $this->assertNotEmpty($rendered); } /** * Test payment approved by accountant email */ public function test_payment_approved_by_accountant_email(): void { $data = $this->createMemberWithPaymentAtStage('accountant_approved'); $payment = $data['payment']; $mail = new PaymentApprovedByAccountantMail($payment); $this->assertNotNull($mail->envelope()->subject); } /** * Test payment fully approved email */ public function test_payment_fully_approved_email(): void { $data = $this->createMemberWithPaymentAtStage('fully_approved'); $payment = $data['payment']; $mail = new PaymentFullyApprovedMail($payment); $rendered = $mail->render(); $this->assertNotEmpty($rendered); } /** * Test payment rejected email contains reason */ public function test_payment_rejected_email_contains_reason(): void { $data = $this->createMemberWithPendingPayment(); $payment = $data['payment']; $payment->update([ 'status' => MembershipPayment::STATUS_REJECTED, 'rejection_reason' => 'Receipt is not clear', ]); $mail = new PaymentRejectedMail($payment); $rendered = $mail->render(); $this->assertStringContainsString('Receipt is not clear', $rendered); } /** * Test membership activated email */ public function test_membership_activated_email(): void { $member = $this->createActiveMember(); $mail = new MembershipActivatedMail($member); $rendered = $mail->render(); $this->assertStringContainsString($member->full_name, $rendered); $this->assertStringContainsString('啟用', $rendered); } /** * Test membership expiry reminder email * Note: This test is for if the system has expiry reminder functionality */ public function test_membership_expiry_reminder_email(): void { $member = $this->createActiveMember([ 'membership_expires_at' => now()->addDays(30), ]); // If MembershipExpiryReminderMail exists // $mail = new MembershipExpiryReminderMail($member); // $this->assertStringContainsString('到期', $mail->render()); // For now, just verify member expiry date is set $this->assertTrue($member->membership_expires_at->diffInDays(now()) <= 30); } }