Files
portal/app/tests/Feature/Import/ImportLeadsJobTest.php
T

106 lines
3.5 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Jobs\ImportLeadsJob;
use App\Mail\ImportCompletedNotification;
use App\Models\Deal;
use App\Models\ImportLog;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Import\CsvLeadsParser;
use App\Services\Import\HistoricalImportService;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Tests\Concerns\SharesSupplierPdo;
uses(DatabaseTransactions::class, SharesSupplierPdo::class);
// ImportLeadsJob запускает HistoricalImportService → MonthlyPartitionManager →
// CREATE через pgsql_supplier. Нужен shared PDO.
beforeEach(function (): void {
$this->tenant = Tenant::factory()->create();
$this->user = User::factory()->for($this->tenant)->create();
DB::statement('SET app.current_tenant_id = '.$this->tenant->id);
Mail::fake();
Storage::fake('local');
});
function storedCsv(int $tenantId, string $body): string
{
$header = "\xEF\xBB\xBF".'id,Проект,Тег проекта,Телефон,Создано,Напоминание,Комментарий,Состояние,Имя';
$path = "imports/{$tenantId}/test.csv";
Storage::disk('local')->put($path, $header."\n".$body);
return $path;
}
function runImportJob(int $logId, int $tenantId): void
{
(new ImportLeadsJob($logId, $tenantId))->handle(
app(HistoricalImportService::class),
app(CsvLeadsParser::class),
);
}
test('job импортирует лиды и переводит import_log в done', function (): void {
$path = storedCsv($this->tenant->id,
'7001,Окна,окна,79161112233,2023/05/10 10:00:00,,,Новые,Иван'
);
$log = ImportLog::create([
'tenant_id' => $this->tenant->id,
'user_id' => $this->user->id,
'filename' => 'leads.csv',
'file_path' => $path,
'status' => 'pending',
]);
runImportJob($log->id, $this->tenant->id);
$log->refresh();
expect($log->status)->toBe('done')
->and($log->rows_added)->toBe(1)
->and($log->finished_at)->not->toBeNull()
->and(Deal::query()->where('source_crm_id', 7001)->exists())->toBeTrue();
Mail::assertSent(ImportCompletedNotification::class);
});
test('job переводит import_log в failed при отсутствии файла', function (): void {
$log = ImportLog::create([
'tenant_id' => $this->tenant->id,
'user_id' => $this->user->id,
'filename' => 'leads.csv',
'file_path' => 'imports/missing.csv',
'status' => 'pending',
]);
runImportJob($log->id, $this->tenant->id);
expect($log->refresh()->status)->toBe('failed')
->and($log->error_message)->not->toBeNull();
});
test('job пишет unknown_statuses_count и rows_skipped', function (): void {
$path = storedCsv($this->tenant->id,
"7002,Окна,окна,79161112234,2023/05/11 10:00:00,,,Архив,\n".
'7003,Окна,окна,BADPHONE,2023/05/12 10:00:00,,,Новые,'
);
$log = ImportLog::create([
'tenant_id' => $this->tenant->id,
'user_id' => $this->user->id,
'filename' => 'leads.csv',
'file_path' => $path,
'status' => 'pending',
]);
runImportJob($log->id, $this->tenant->id);
$log->refresh();
expect($log->status)->toBe('done')
->and($log->unknown_statuses_count)->toBe(1) // «Архив»
->and($log->rows_skipped)->toBe(1); // битый телефон
});