Add SMS bulk delay configuration and validate coupon phone function
This commit is contained in:
154
tests/Feature/SmsBroadcastServiceTest.php
Normal file
154
tests/Feature/SmsBroadcastServiceTest.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Enums\SmsSendStatus;
|
||||
use App\Jobs\SendSmsToCouponJob;
|
||||
use App\Models\Coupon;
|
||||
use App\Models\SmsCampaign;
|
||||
use App\Models\SmsSendLog;
|
||||
use App\Models\User;
|
||||
use App\Services\SmsBroadcastService;
|
||||
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Tests\TestCase;
|
||||
|
||||
class SmsBroadcastServiceTest extends TestCase
|
||||
{
|
||||
use LazilyRefreshDatabase;
|
||||
|
||||
private SmsBroadcastService $service;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Http::fake([
|
||||
config('services.sms.url') => Http::response('ok', 200),
|
||||
]);
|
||||
|
||||
$this->service = app(SmsBroadcastService::class);
|
||||
}
|
||||
|
||||
public function test_resolve_recipients_for_all_excluding_ids(): void
|
||||
{
|
||||
$included = Coupon::factory()->count(2)->create();
|
||||
$excluded = Coupon::factory()->create();
|
||||
|
||||
$recipients = $this->service->resolveRecipients(
|
||||
sendToAll: true,
|
||||
excludedIds: [$excluded->id],
|
||||
);
|
||||
|
||||
$this->assertCount(2, $recipients);
|
||||
$this->assertTrue($recipients->pluck('id')->contains($included->first()->id));
|
||||
$this->assertFalse($recipients->pluck('id')->contains($excluded->id));
|
||||
}
|
||||
|
||||
public function test_resolve_recipients_for_selected_only(): void
|
||||
{
|
||||
$selected = Coupon::factory()->create();
|
||||
Coupon::factory()->create();
|
||||
|
||||
$recipients = $this->service->resolveRecipients(
|
||||
sendToAll: false,
|
||||
selectedIds: [$selected->id],
|
||||
);
|
||||
|
||||
$this->assertCount(1, $recipients);
|
||||
$this->assertSame($selected->id, $recipients->first()->id);
|
||||
}
|
||||
|
||||
public function test_start_campaign_queues_chain_and_creates_logs(): void
|
||||
{
|
||||
Bus::fake();
|
||||
|
||||
$admin = User::factory()->create();
|
||||
$coupons = Coupon::factory()->count(2)->create();
|
||||
|
||||
$campaign = $this->service->startCampaign(
|
||||
admin: $admin,
|
||||
message: 'Test broadcast',
|
||||
sendToAll: false,
|
||||
selectedIds: $coupons->pluck('id')->all(),
|
||||
);
|
||||
|
||||
$this->assertSame(2, $campaign->recipient_count);
|
||||
$this->assertDatabaseCount(SmsSendLog::class, 2);
|
||||
$this->assertDatabaseHas(SmsSendLog::class, [
|
||||
'sms_campaign_id' => $campaign->id,
|
||||
'status' => SmsSendStatus::Pending->value,
|
||||
]);
|
||||
|
||||
Bus::assertChained([
|
||||
SendSmsToCouponJob::class,
|
||||
SendSmsToCouponJob::class,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_invalid_phone_is_skipped_without_queue_job(): void
|
||||
{
|
||||
Bus::fake();
|
||||
|
||||
$admin = User::factory()->create();
|
||||
$invalid = Coupon::factory()->create(['phone' => '81234567']);
|
||||
$valid = Coupon::factory()->create();
|
||||
|
||||
$campaign = $this->service->startCampaign(
|
||||
admin: $admin,
|
||||
message: 'Test',
|
||||
sendToAll: false,
|
||||
selectedIds: [$invalid->id, $valid->id],
|
||||
);
|
||||
|
||||
$this->assertSame(2, $campaign->recipient_count);
|
||||
$this->assertSame(1, $campaign->skipped_count);
|
||||
|
||||
$this->assertDatabaseHas(SmsSendLog::class, [
|
||||
'coupon_id' => $invalid->id,
|
||||
'status' => SmsSendStatus::SkippedInvalid->value,
|
||||
]);
|
||||
|
||||
Bus::assertChained([
|
||||
SendSmsToCouponJob::class,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_send_job_marks_success_and_completes_campaign(): void
|
||||
{
|
||||
Queue::fake();
|
||||
|
||||
$admin = User::factory()->create();
|
||||
$coupon = Coupon::factory()->create(['phone' => '61929248']);
|
||||
|
||||
$campaign = SmsCampaign::factory()->create([
|
||||
'message' => 'Queued hello',
|
||||
'recipient_count' => 1,
|
||||
'created_by' => $admin->id,
|
||||
]);
|
||||
|
||||
SmsSendLog::factory()->create([
|
||||
'sms_campaign_id' => $campaign->id,
|
||||
'coupon_id' => $coupon->id,
|
||||
'phone' => $coupon->phone,
|
||||
'message' => $campaign->message,
|
||||
'status' => SmsSendStatus::Pending,
|
||||
]);
|
||||
|
||||
$job = new SendSmsToCouponJob($campaign, $coupon);
|
||||
$job->handle();
|
||||
|
||||
Http::assertSentCount(1);
|
||||
|
||||
$campaign->refresh();
|
||||
|
||||
$this->assertSame(1, $campaign->sent_count);
|
||||
$this->assertNotNull($campaign->completed_at);
|
||||
$this->assertDatabaseHas(SmsSendLog::class, [
|
||||
'sms_campaign_id' => $campaign->id,
|
||||
'status' => SmsSendStatus::Sent->value,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user