90 خطوط
3.1 KiB
PHP
90 خطوط
3.1 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\FollowUp;
|
|
use App\Models\Lead;
|
|
use App\Models\User;
|
|
use App\Services\FollowUpReminderService;
|
|
use Database\Seeders\RolePermissionSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class FollowUpContractTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->seed(RolePermissionSeeder::class);
|
|
}
|
|
|
|
public function test_follow_up_endpoints_share_one_canonical_enveloped_contract(): void
|
|
{
|
|
$agent = $this->agent();
|
|
$lead = $this->lead($agent);
|
|
|
|
$created = $this->actingAs($agent)->postJson('/api/follow-ups', [
|
|
'lead_id' => $lead->id,
|
|
'scheduled_at' => now()->addHour()->toISOString(),
|
|
'notes' => 'Call customer after lunch',
|
|
])->assertCreated()
|
|
->assertJsonPath('data.lead_id', $lead->id)
|
|
->assertJsonPath('data.user_id', $agent->id)
|
|
->assertJsonPath('data.status', 'pending')
|
|
->assertJsonStructure(['data' => ['id', 'lead', 'assignee', 'scheduled_at', 'completed_at', 'notes', 'status', 'is_overdue'], 'meta', 'links', 'message']);
|
|
|
|
$id = $created->json('data.id');
|
|
$this->actingAs($agent)->getJson('/api/follow-ups')
|
|
->assertOk()
|
|
->assertJsonPath('data.0.id', $id)
|
|
->assertJsonStructure(['data', 'meta' => ['current_page', 'last_page', 'per_page', 'total', 'from', 'to'], 'links']);
|
|
|
|
$this->actingAs($agent)->patchJson("/api/follow-ups/{$id}/mark-done")
|
|
->assertOk()
|
|
->assertJsonPath('data.status', 'completed')
|
|
->assertJsonPath('data.is_overdue', false);
|
|
}
|
|
|
|
public function test_today_get_has_no_side_effect_and_scheduler_sends_due_notification_once(): void
|
|
{
|
|
$agent = $this->agent();
|
|
$lead = $this->lead($agent);
|
|
$followUp = FollowUp::create([
|
|
'lead_id' => $lead->id,
|
|
'user_id' => $agent->id,
|
|
'scheduled_at' => now()->subMinute(),
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
$this->actingAs($agent)->getJson('/api/follow-ups/today')->assertOk()->assertJsonPath('data.0.id', $followUp->id);
|
|
$this->assertDatabaseCount('internal_notifications', 0);
|
|
|
|
$service = app(FollowUpReminderService::class);
|
|
$this->assertSame(1, $service->sendDueReminders());
|
|
$this->assertSame(0, $service->sendDueReminders());
|
|
$this->assertDatabaseHas('internal_notifications', ['user_id' => $agent->id, 'type' => 'overdue_follow_up']);
|
|
}
|
|
|
|
private function agent(): User
|
|
{
|
|
$agent = User::factory()->create(['is_active' => true]);
|
|
$agent->assignRole('agent');
|
|
|
|
return $agent;
|
|
}
|
|
|
|
private function lead(User $agent): Lead
|
|
{
|
|
return Lead::create([
|
|
'company' => 'Follow-up Co',
|
|
'first_name' => 'Mina',
|
|
'last_name' => 'Rahimi',
|
|
'phone' => fake()->unique()->numerify('021########'),
|
|
'assigned_to' => $agent->id,
|
|
'is_unassigned' => false,
|
|
]);
|
|
}
|
|
}
|