Files
Investidor-V2/tests/Unit/TerritorialCsvAuditTest.php
T
2026-09-29 08:41:57 +02:00

76 lines
2.9 KiB
PHP

<?php
namespace Tests\Unit;
use App\Services\TerritorialCsvAudit;
use PHPUnit\Framework\TestCase;
use RuntimeException;
class TerritorialCsvAuditTest extends TestCase
{
private string $path;
protected function setUp(): void
{
$this->path = tempnam(sys_get_temp_dir(), 'geo-csv-');
}
protected function tearDown(): void
{
unlink($this->path);
}
private function inspect(string $rows): array
{
file_put_contents($this->path, implode(';', TerritorialCsvAudit::HEADERS)."\n".$rows);
return (new TerritorialCsvAudit)->inspect($this->path, ['01']);
}
public function test_preserves_leading_zero_codes_and_counts_identical_duplicates(): void
{
$row = '01;Synthetic;0101;District;010101;Post;01010101;Locality;village;-12.5;35.1';
$report = $this->inspect($row."\n".$row);
$this->assertSame('structurally_valid_requires_review', $report['status']);
$this->assertSame(1, $report['duplicate_records']);
$this->assertSame(1, $report['candidate_counts_by_province']['01']['locality']);
$this->assertSame(hash_file('sha256', $this->path), $report['sha256']);
}
public function test_conflicting_names_and_coordinates_cancel_whole_dataset(): void
{
$report = $this->inspect("01;Synthetic;0101;First;010101;Post;01010101;Locality;village;0;0\n01;Synthetic;0101;Other;010101;Post;01010101;Locality;village;1;0");
$this->assertSame('rejected', $report['status']);
$this->assertContains('conflicting_code:district', $report['errors'][0]['issues']);
$this->assertContains('conflicting_code:locality', $report['errors'][0]['issues']);
}
public function test_no_inferred_parent_or_coordinates_and_unknown_province_are_rejected(): void
{
$report = $this->inspect('02;Synthetic;0201;District;;;02010101;Locality;village;91;');
$this->assertSame('rejected', $report['status']);
foreach (['unknown_province', 'locality_requires_reviewed_parent_exception', 'incomplete_coordinates', 'invalid_coordinate:latitude'] as $issue) {
$this->assertContains($issue, $report['errors'][0]['issues']);
}
}
public function test_district_only_rows_do_not_create_localities(): void
{
$report = $this->inspect('01;Synthetic;0101;District;;;;;;;');
$this->assertSame('structurally_valid_requires_review', $report['status']);
$this->assertArrayNotHasKey('locality', $report['candidate_counts_by_province']['01']);
}
public function test_empty_csv_is_rejected(): void
{
$this->assertSame('rejected', $this->inspect('')['status']);
}
public function test_wrong_delimiter_is_not_silently_interpreted(): void
{
file_put_contents($this->path, implode(',', TerritorialCsvAudit::HEADERS));
$this->expectException(RuntimeException::class);
(new TerritorialCsvAudit)->inspect($this->path, ['01']);
}
}