Files
portal/app/tests/Feature/Admin/AdminLeadsTest.php
T

90 lines
4.3 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
uses(DatabaseTransactions::class);
function seedLeadTenant(): int
{
return DB::table('tenants')->insertGetId([
'subdomain' => 'acme'.uniqid(), 'organization_name' => 'Acme', 'contact_email' => 'a@acme.ru',
'status' => 'active', 'is_trial' => false, 'balance_rub' => 0, 'balance_leads' => 0,
'chargeback_unrecovered_rub' => 0, 'created_at' => now(), 'updated_at' => now(),
]);
}
function seedSupplierProject(string $signal, string $key): int
{
return DB::table('supplier_projects')->insertGetId([
'platform' => 'B1', 'signal_type' => $signal, 'unique_key' => $key,
'current_limit' => 10, 'sync_status' => 'ok', 'created_at' => now(), 'updated_at' => now(),
]);
}
it('GET /api/admin/leads — пагинированный список с фильтром по каналу', function () {
$sp = seedSupplierProject('site', 'okna.ru');
DB::table('supplier_leads')->insert([
['supplier_project_id' => $sp, 'platform' => 'B1', 'raw_payload' => json_encode(['x' => 1]),
'phone' => '+79135397707', 'vid' => 1001, 'received_at' => now()->subHour(),
'processed_at' => now()->subHour(), 'deals_created_count' => 2],
['supplier_project_id' => null, 'platform' => 'B2', 'raw_payload' => json_encode(['x' => 2]),
'phone' => '+79990001122', 'vid' => 1002, 'received_at' => now()->subDays(2),
'processed_at' => null, 'deals_created_count' => 0],
]);
$res = $this->getJson('/api/admin/leads?per_page=10');
$res->assertOk();
$res->assertJsonStructure([
'data' => [['id', 'received_at', 'platform', 'channel', 'source', 'region_code', 'phone_masked', 'deals_created_count', 'status']],
'total', 'page', 'per_page',
]);
expect($res->json('total'))->toBeGreaterThanOrEqual(2);
// фильтр по каналу site → только лид с supplier_project site
$res2 = $this->getJson('/api/admin/leads?channel=site');
expect(collect($res2->json('data'))->pluck('channel')->unique()->all())->toBe(['site']);
});
it('телефон в списке маскируется', function () {
$sp = seedSupplierProject('call', '+74950000000');
DB::table('supplier_leads')->insert([
'supplier_project_id' => $sp, 'platform' => 'B1', 'raw_payload' => json_encode([]),
'phone' => '+79135397707', 'vid' => 2001, 'received_at' => now(), 'deals_created_count' => 0,
]);
$res = $this->getJson('/api/admin/leads?channel=call');
$masked = collect($res->json('data'))->firstWhere('id', '!=', null)['phone_masked'] ?? '';
expect($masked)->not->toContain('9135397'); // середина скрыта
expect($masked)->toContain('**');
});
it('GET /api/admin/leads/{id} — карточка с цепочкой: источник + сделки клиентов', function () {
$sp = seedSupplierProject('site', 'okna.ru');
$leadId = DB::table('supplier_leads')->insertGetId([
'supplier_project_id' => $sp, 'platform' => 'B1', 'raw_payload' => json_encode(['tag' => 77]),
'phone' => '+79135397707', 'vid' => 5005, 'received_at' => now()->subHour(),
'processed_at' => now()->subHour(), 'deals_created_count' => 1, 'resolved_subject_code' => 77,
]);
$tenant = seedLeadTenant();
$project = DB::table('projects')->insertGetId([
'tenant_id' => $tenant, 'name' => 'Проект', 'is_active' => true,
'created_at' => now(), 'updated_at' => now(),
]);
DB::table('deals')->insert([
'tenant_id' => $tenant, 'project_id' => $project, 'source_crm_id' => 5005, 'phone' => '+79135397707',
'status' => 'new', 'is_test' => false, 'received_at' => now()->subHour(), 'created_at' => now(), 'updated_at' => now(),
]);
$res = $this->getJson("/api/admin/leads/{$leadId}");
$res->assertOk();
$res->assertJsonStructure([
'lead' => ['id', 'platform', 'phone_masked', 'received_at', 'region_code', 'status'],
'source' => ['platform', 'channel', 'identifier'],
'deals' => [['tenant_id', 'tenant_name', 'status']],
]);
expect($res->json('source.identifier'))->toBe('okna.ru');
expect($res->json('deals.0.tenant_name'))->toBe('Acme');
});