Files
portal-api/tests/Feature/Api/Admin/MailCampaignBulkActionTest.php
T

127 lines
4.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Feature\Api\Admin;
use App\Jobs\Mail\SendMailCampaignRecipient;
use App\Models\Mail;
use App\Models\MailCampaign;
use App\Models\Setting;
use App\Models\User;
use App\Support\MailSettings;
use Illuminate\Support\Facades\Cache;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Mail as MailFacade;
use Illuminate\Support\Facades\Queue;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
class MailCampaignBulkActionTest extends TestCase
{
use RefreshDatabase;
private User $admin;
protected function setUp(): void
{
parent::setUp();
Role::firstOrCreate(['name' => 'Full Administrator', 'guard_name' => 'admin']);
$this->admin = User::factory()->create();
$this->admin->assignRole('Full Administrator');
}
private function campaign(string $status, int $sent = 0, int $failed = 0): MailCampaign
{
return MailCampaign::create([
'name' => 'C', 'subject' => 'S', 'message' => '<p>x</p>', 'recipient_type' => 'selected',
'total_recipients' => 2, 'sent_count' => $sent, 'failed_count' => $failed, 'status' => $status,
]);
}
public function test_index_filters_by_search_status_and_date(): void
{
$match = $this->campaign('completed');
$match->update(['name' => 'Khuyến mãi Tết']);
$this->campaign('failed')->update(['name' => 'Khuyến mãi hè']);
$this->campaign('completed')->update(['name' => 'Bảo trì']);
$old = $this->campaign('completed');
$old->update(['name' => 'Khuyến mãi cũ']);
$old->forceFill(['created_at' => now()->subMonth()])->saveQuietly();
$this->actingAs($this->admin, 'admin')
->getJson('/api/v1/administrator/mail-campaigns?' . http_build_query([
'search' => 'khuyến mãi', 'status' => ['completed'], 'date_from' => now()->subDay()->toDateString(),
]))
->assertOk()
->assertJsonPath('data.total', 1)
->assertJsonPath('data.items.0.uuid', $match->uuid);
}
public function test_sender_reports_smtp_from_address(): void
{
Setting::updateOrCreate(['key' => 'smtp'], ['value' => json_encode([
'host' => 'smtp.example.com', 'user' => 'u@example.com', 'from_address' => 'noreply@tgs.test', 'from_name' => 'TGS',
])]);
Cache::forget(MailSettings::cacheKey());
MailSettings::apply();
$this->actingAs($this->admin, 'admin')
->getJson('/api/v1/administrator/mail-campaigns/sender')
->assertOk()
->assertJsonPath('data.from_address', 'noreply@tgs.test')
->assertJsonPath('data.from_name', 'TGS')
->assertJsonPath('data.smtp_configured', true);
}
public function test_cancel_stops_pending_jobs_and_keeps_finished_campaigns(): void
{
MailFacade::fake();
$sending = $this->campaign('sending');
$done = $this->campaign('completed', 2);
$this->actingAs($this->admin, 'admin')
->postJson('/api/v1/administrator/mail-campaigns/bulk-action', ['action' => 'cancel', 'uuids' => [$sending->uuid, $done->uuid]])
->assertOk();
$this->assertSame('cancelled', $sending->fresh()->status);
$this->assertSame('completed', $done->fresh()->status);
(new SendMailCampaignRecipient($sending->id, null, 'a@example.com'))->handle(app(\App\Services\Email\MailCampaignRenderer::class));
MailFacade::assertNothingSent();
$this->assertSame(0, $sending->fresh()->sent_count);
}
public function test_retry_requeues_only_failed_recipients(): void
{
Queue::fake();
$campaign = $this->campaign('completed', 1, 1);
foreach (['ok@example.com' => 'sent', 'bad@example.com' => 'failed'] as $to => $status) {
Mail::create(['campaign_id' => $campaign->id, 'template_id' => 0, 'subject' => 'S', 'to' => $to, 'message' => 'x', 'status' => $status]);
}
$this->actingAs($this->admin, 'admin')
->postJson('/api/v1/administrator/mail-campaigns/bulk-action', ['action' => 'retry-failed', 'uuids' => [$campaign->uuid]])
->assertOk();
$campaign->refresh();
$this->assertSame('sending', $campaign->status);
$this->assertSame(0, $campaign->failed_count);
$this->assertDatabaseMissing('mail', ['to' => 'bad@example.com']);
Queue::assertPushed(SendMailCampaignRecipient::class, 1);
}
public function test_delete_skips_campaigns_still_sending(): void
{
$sending = $this->campaign('queued');
$done = $this->campaign('failed', 0, 2);
$this->actingAs($this->admin, 'admin')
->postJson('/api/v1/administrator/mail-campaigns/bulk-delete', ['uuids' => [$sending->uuid, $done->uuid]])
->assertOk();
$this->assertNotNull($sending->fresh());
$this->assertNull($done->fresh());
}
}