Initial commit

This commit is contained in:
Ronald Huynen
2026-03-23 21:37:59 +01:00
commit 2547717edb
2193 changed files with 972171 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
<?php
namespace App\Console\Commands;
use App\Models\MailingBounce;
use App\Models\User;
use App\Models\Organization;
use Illuminate\Console\Command;
class TestBounceSystem extends Command
{
/**
* The name and signature of the console command.
*/
protected $signature = 'test:bounce-system
{--email= : Email to test (default: creates test emails)}
{--scenario= : Test scenario: single, threshold-verification, threshold-suppression, multiple}';
/**
* The console command description.
*/
protected $description = 'Test the bounce handling system with simulated bounces';
/**
* Execute the console command.
*/
public function handle()
{
$scenario = $this->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("");
}
}