fix: harden postcodes:import against duplicate headers and test collisions
This commit is contained in:
@@ -6,7 +6,6 @@ use Illuminate\Console\Attributes\Description;
|
|||||||
use Illuminate\Console\Attributes\Signature;
|
use Illuminate\Console\Attributes\Signature;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
#[Signature('postcodes:import {--file= : Path to ONSPD CSV file}')]
|
#[Signature('postcodes:import {--file= : Path to ONSPD CSV file}')]
|
||||||
#[Description('Import UK postcodes (ONSPD) into the local postcodes and outcodes tables')]
|
#[Description('Import UK postcodes (ONSPD) into the local postcodes and outcodes tables')]
|
||||||
@@ -27,7 +26,9 @@ final class ImportPostcodes extends Command
|
|||||||
$handle = fopen($file, 'r');
|
$handle = fopen($file, 'r');
|
||||||
|
|
||||||
if ($handle === false) {
|
if ($handle === false) {
|
||||||
throw new RuntimeException("Unable to open {$file}");
|
$this->error("Unable to open {$file}.");
|
||||||
|
|
||||||
|
return self::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$header = fgetcsv($handle);
|
$header = fgetcsv($handle);
|
||||||
@@ -39,6 +40,17 @@ final class ImportPostcodes extends Command
|
|||||||
return self::FAILURE;
|
return self::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$headerCounts = array_count_values(array_map('strtolower', $header));
|
||||||
|
|
||||||
|
foreach (['pcd', 'lat', 'long'] as $required) {
|
||||||
|
if (($headerCounts[$required] ?? 0) > 1) {
|
||||||
|
$this->error("Column '{$required}' appears more than once — refusing to import.");
|
||||||
|
fclose($handle);
|
||||||
|
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$columns = array_change_key_case(array_flip($header), CASE_LOWER);
|
$columns = array_change_key_case(array_flip($header), CASE_LOWER);
|
||||||
|
|
||||||
foreach (['pcd', 'lat', 'long'] as $required) {
|
foreach (['pcd', 'lat', 'long'] as $required) {
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
|||||||
|
|
||||||
uses(RefreshDatabase::class);
|
uses(RefreshDatabase::class);
|
||||||
|
|
||||||
function writeOnspdFixture(string $contents): string
|
if (! function_exists('writeOnspdFixture')) {
|
||||||
{
|
function writeOnspdFixture(string $contents): string
|
||||||
$path = tempnam(sys_get_temp_dir(), 'onspd_').'.csv';
|
{
|
||||||
file_put_contents($path, $contents);
|
$path = tempnam(sys_get_temp_dir(), 'onspd_').'.csv';
|
||||||
|
file_put_contents($path, $contents);
|
||||||
|
|
||||||
return $path;
|
return $path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it('imports active postcodes from an ONSPD CSV', function (): void {
|
it('imports active postcodes from an ONSPD CSV', function (): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user