127 lines
4.9 KiB
PHP
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());
|
|
}
|
|
}
|