CRM/backend/tests/Feature/FollowUpContractTest.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,
]);
}
}