76 lines
2.9 KiB
PHP
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']);
|
|
}
|
|
}
|