Files
portal/app/tests/Unit/Supplier/SupplierCsvParserTest.php
T
Дмитрий 59d3dd06b6 @
test(supplier): SupplierCsvParserTest под 3-колоночный формат отчёта

Unit-тест ожидал устаревший 6-колоночный формат
vid;project;tag;phone;phones;time, тогда как SupplierCsvParser
переписан эпиком CSV-канала (T2, 18.05.2026) под 3-колоночный
Name;Tag;Phone — yields {project,tag,phone}, vid/time отсутствуют.

Тестовый долг вскрыт полной регрессией: 3 кейса падали
(«array has no key vid»). Тесты приведены к актуальному контракту
парапера. Pest SupplierCsvParserTest 5/5, full-suite 937/934/0/3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@
2026-05-19 07:42:34 +03:00

82 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
use App\Services\Supplier\SupplierCsvParser;
use Illuminate\Support\Facades\Log;
use Tests\TestCase;
uses(TestCase::class);
// Контракт парсера (эпик CSV-канал T2, 18.05.2026): отчёт «Запрос номеров»
// crm.bp-gr.ru — 3 колонки Name;Tag;Phone. vid и время в отчёте отсутствуют.
// SupplierCsvParser::parse() yields {project, tag, phone}. Spec §4.1.
beforeEach(function () {
$this->parser = new SupplierCsvParser;
});
it('parses empty CSV → yields nothing', function () {
$rows = iterator_to_array($this->parser->parse(''));
expect($rows)->toBeEmpty();
});
it('parses 1 row → yields 1 struct with project/tag/phone', function () {
$csv = "Name;Tag;Phone\n"
."B1_example.com;mytag;79991234567\n";
$rows = iterator_to_array($this->parser->parse($csv));
expect($rows)->toHaveCount(1);
expect($rows[0])->toMatchArray([
'project' => 'B1_example.com',
'tag' => 'mytag',
'phone' => '79991234567',
]);
});
it('parses 1000 rows without OOM (streaming generator)', function () {
$lines = ['Name;Tag;Phone'];
for ($i = 1; $i <= 1000; $i++) {
$lines[] = "B1_test.com;tag{$i};79991234567";
}
$csv = implode("\n", $lines)."\n";
$count = 0;
foreach ($this->parser->parse($csv) as $_) {
$count++;
}
expect($count)->toBe(1000);
});
it('skips malformed rows with missing columns + logs warning', function () {
Log::spy();
$csv = "Name;Tag;Phone\n"
."B1_example.com;mytag;79991234567\n"
."broken-row-only-one-column\n"
."B1_another.com;tag2;79991234500\n";
$rows = iterator_to_array($this->parser->parse($csv));
expect($rows)->toHaveCount(2);
expect($rows[0]['project'])->toBe('B1_example.com');
expect($rows[1]['project'])->toBe('B1_another.com');
Log::shouldHaveReceived('warning')
->with('supplier_csv_parser.malformed_row', Mockery::any())
->once();
});
it('handles BOM + CRLF line endings', function () {
$bom = "\xEF\xBB\xBF";
$csv = $bom."Name;Tag;Phone\r\n"
."B1_example.com;mytag;79991234567\r\n";
$rows = iterator_to_array($this->parser->parse($csv));
expect($rows)->toHaveCount(1);
expect($rows[0]['project'])->toBe('B1_example.com');
});