option('scenario') ?: 'single'; $email = $this->option('email'); switch ($scenario) { case 'single': $this->testSingleBounce($email); break; case 'threshold-verification': $this->testVerificationThreshold($email); break; case 'threshold-suppression': $this->testSuppressionThreshold($email); break; case 'multiple': $this->testMultipleEmails(); break; default: $this->error("Unknown scenario: {$scenario}"); $this->info("Available scenarios: single, threshold-verification, threshold-suppression, multiple"); return 1; } return 0; } /** * Test a single bounce (should not trigger any thresholds) */ protected function testSingleBounce(?string $email): void { $testEmail = $email ?: 'test-single@example.com'; $this->info("๐Ÿงช Testing Single Bounce for: {$testEmail}"); // Create a test user with verified email $this->createTestUser($testEmail); // Record a single hard bounce with definitive pattern $bounce = MailingBounce::recordBounce( $testEmail, 'hard', 'user unknown - mailbox does not exist' ); $this->line("โœ… Created bounce record ID: {$bounce->id}"); // Check the results $stats = MailingBounce::getBounceStats($testEmail); $this->displayResults($testEmail, $stats); } /** * Test verification threshold (2 bounces) */ protected function testVerificationThreshold(?string $email): void { $testEmail = $email ?: 'test-verification@example.com'; $this->info("๐Ÿงช Testing Verification Reset Threshold for: {$testEmail}"); // Create test user with verified email $user = $this->createTestUser($testEmail); $this->line("๐Ÿ“ง Created test user with verified email: {$user->email_verified_at}"); // Record first bounce with exact pattern from config $this->line("1๏ธโƒฃ Recording first hard bounce..."); MailingBounce::recordBounce($testEmail, 'hard', 'user unknown - definitive bounce'); $user->refresh(); $this->line(" User email_verified_at: " . ($user->email_verified_at ?: 'NULL')); // Record second bounce (should trigger verification reset) $this->line("2๏ธโƒฃ Recording second hard bounce (should reset verification)..."); MailingBounce::recordBounce($testEmail, 'hard', 'mailbox unavailable - permanent failure'); $user->refresh(); $this->line(" User email_verified_at: " . ($user->email_verified_at ?: 'NULL')); // Check results $stats = MailingBounce::getBounceStats($testEmail); $this->displayResults($testEmail, $stats); if (!$user->email_verified_at) { $this->info("โœ… SUCCESS: Email verification was reset!"); } else { $this->error("โŒ FAILED: Email verification was NOT reset!"); } } /** * Test suppression threshold (3 bounces) */ protected function testSuppressionThreshold(?string $email): void { $testEmail = $email ?: 'test-suppression@example.com'; $this->info("๐Ÿงช Testing Suppression Threshold for: {$testEmail}"); // Create test user $user = $this->createTestUser($testEmail); // Record three bounces for ($i = 1; $i <= 3; $i++) { $this->line("{$i}๏ธโƒฃ Recording hard bounce #{$i}..."); MailingBounce::recordBounce($testEmail, 'hard', "user unknown - attempt {$i}"); $user->refresh(); $isSuppressed = MailingBounce::isSuppressed($testEmail); $this->line(" Suppressed: " . ($isSuppressed ? 'YES' : 'NO')); $this->line(" Email verified: " . ($user->email_verified_at ? 'YES' : 'NO')); } // Check final results $stats = MailingBounce::getBounceStats($testEmail); $this->displayResults($testEmail, $stats); if ($stats['is_suppressed']) { $this->info("โœ… SUCCESS: Email was suppressed after 3 bounces!"); } else { $this->error("โŒ FAILED: Email was NOT suppressed!"); } } /** * Test multiple emails with different scenarios */ protected function testMultipleEmails(): void { $this->info("๐Ÿงช Testing Multiple Email Scenarios"); $scenarios = [ 'no-bounce@example.com' => 0, 'one-bounce@example.com' => 1, 'verification-reset@example.com' => 2, 'suppressed@example.com' => 3, 'over-threshold@example.com' => 5 ]; foreach ($scenarios as $email => $bounceCount) { $this->line("Setting up {$email} with {$bounceCount} bounces..."); $this->createTestUser($email); for ($i = 1; $i <= $bounceCount; $i++) { MailingBounce::recordBounce($email, 'hard', "user unknown - bounce {$i}"); } } $this->info("\n๐Ÿ“Š Results Summary:"); foreach ($scenarios as $email => $expectedBounces) { $stats = MailingBounce::getBounceStats($email); $user = User::where('email', $email)->first(); $this->line("๐Ÿ“ง {$email}:"); $this->line(" Hard bounces: {$stats['recent_hard_bounces']}"); $this->line(" Suppressed: " . ($stats['is_suppressed'] ? 'YES' : 'NO')); $this->line(" Verified: " . ($user && $user->email_verified_at ? 'YES' : 'NO')); } } /** * Create a test user with verified email */ protected function createTestUser(string $email): User { // Remove existing test user if any User::where('email', $email)->delete(); $user = User::create([ 'name' => 'Test User ' . substr($email, 0, strpos($email, '@')), 'email' => $email, 'password' => bcrypt('password'), ]); // Use forceFill since email_verified_at isn't in fillable $user->forceFill(['email_verified_at' => now()])->save(); return $user; } /** * Display test results */ protected function displayResults(string $email, array $stats): void { $this->info("\n๐Ÿ“Š Test Results for {$email}:"); $this->line("Total bounces: {$stats['total_bounces']}"); $this->line("Recent hard bounces: {$stats['recent_hard_bounces']}"); $this->line("Is suppressed: " . ($stats['is_suppressed'] ? 'YES' : 'NO')); $user = User::where('email', $email)->first(); if ($user) { $this->line("Email verified: " . ($user->email_verified_at ? 'YES' : 'NO')); } $this->line(""); } }