Add validation to importers to fix invalid/empty columns #222
This commit is contained in:
parent
bd30b1f900
commit
63544088cd
@ -53,7 +53,7 @@ class ExportService extends Service
|
||||
$writer = $this->openCsv($path);
|
||||
|
||||
// Write out the header first
|
||||
$writer->insertOne($exporter->getColumns());
|
||||
$writer->insertOne(array_keys($exporter->getColumns()));
|
||||
|
||||
// Write the rest of the rows
|
||||
foreach ($collection as $row) {
|
||||
|
@ -21,7 +21,7 @@ class AircraftExporter extends ImportExport
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$columns = AircraftImporter::$columns;
|
||||
self::$columns = array_keys(AircraftImporter::$columns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,11 +22,11 @@ class AircraftImporter extends ImportExport
|
||||
* Should match the database fields, for the most part
|
||||
*/
|
||||
public static $columns = [
|
||||
'subfleet',
|
||||
'name',
|
||||
'registration',
|
||||
'hex_code',
|
||||
'status',
|
||||
'subfleet' => 'required',
|
||||
'name' => 'required',
|
||||
'registration' => 'required',
|
||||
'hex_code' => 'nullable',
|
||||
'status' => 'nullable',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,7 @@ class AirportExporter extends ImportExport
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$columns = AirportImporter::$columns;
|
||||
self::$columns = array_keys(AirportImporter::$columns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,15 +18,15 @@ class AirportImporter extends ImportExport
|
||||
* Should match the database fields, for the most part
|
||||
*/
|
||||
public static $columns = [
|
||||
'icao',
|
||||
'iata',
|
||||
'name',
|
||||
'location',
|
||||
'country',
|
||||
'timezone',
|
||||
'hub',
|
||||
'lat',
|
||||
'lon',
|
||||
'icao' => 'required',
|
||||
'iata' => 'required',
|
||||
'name' => 'required',
|
||||
'location' => 'nullable',
|
||||
'country' => 'nullable',
|
||||
'timezone' => 'nullable',
|
||||
'hub' => 'nullable|boolean',
|
||||
'lat' => 'required|numeric',
|
||||
'lon' => 'required|numeric',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,7 @@ class ExpenseExporter extends ImportExport
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$columns = ExpenseImporter::$columns;
|
||||
self::$columns = array_keys(ExpenseImporter::$columns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,15 +23,15 @@ class ExpenseImporter extends ImportExport
|
||||
* Should match the database fields, for the most part
|
||||
*/
|
||||
public static $columns = [
|
||||
'airline',
|
||||
'name',
|
||||
'amount',
|
||||
'type',
|
||||
'charge_to_user',
|
||||
'multiplier',
|
||||
'active',
|
||||
'ref_class',
|
||||
'ref_class_id',
|
||||
'airline' => 'nullable',
|
||||
'name' => 'required',
|
||||
'amount' => 'required|numeric',
|
||||
'type' => 'required',
|
||||
'charge_to_user' => 'nullable|boolean',
|
||||
'multiplier' => 'nullable|numeric',
|
||||
'active' => 'nullable|boolean',
|
||||
'ref_class' => 'nullable',
|
||||
'ref_class_id' => 'nullable',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,7 @@ class FareExporter extends ImportExport
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$columns = FareImporter::$columns;
|
||||
self::$columns = array_keys(FareImporter::$columns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,13 +18,13 @@ class FareImporter extends ImportExport
|
||||
* Should match the database fields, for the most part
|
||||
*/
|
||||
public static $columns = [
|
||||
'code',
|
||||
'name',
|
||||
'price',
|
||||
'cost',
|
||||
'capacity',
|
||||
'notes',
|
||||
'active',
|
||||
'code' => 'required',
|
||||
'name' => 'required',
|
||||
'price' => 'nullable|numeric',
|
||||
'cost' => 'nullable|numeric',
|
||||
'capacity' => 'required|integer',
|
||||
'notes' => 'nullable',
|
||||
'active' => 'nullable|boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,7 @@ class FlightExporter extends ImportExport
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$columns = FlightImporter::$columns;
|
||||
self::$columns = array_keys(FlightImporter::$columns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,26 +27,26 @@ class FlightImporter extends ImportExport
|
||||
* Should match the database fields, for the most part
|
||||
*/
|
||||
public static $columns = [
|
||||
'airline',
|
||||
'flight_number',
|
||||
'route_code',
|
||||
'route_leg',
|
||||
'dpt_airport',
|
||||
'arr_airport',
|
||||
'alt_airport',
|
||||
'days',
|
||||
'dpt_time',
|
||||
'arr_time',
|
||||
'level',
|
||||
'distance',
|
||||
'flight_time',
|
||||
'flight_type',
|
||||
'route',
|
||||
'notes',
|
||||
'active',
|
||||
'subfleets',
|
||||
'fares',
|
||||
'fields',
|
||||
'airline' => 'required',
|
||||
'flight_number' => 'required',
|
||||
'route_code' => 'nullable',
|
||||
'route_leg' => 'nullable',
|
||||
'dpt_airport' => 'required',
|
||||
'arr_airport' => 'required',
|
||||
'alt_airport' => 'nullable',
|
||||
'days' => 'nullable',
|
||||
'dpt_time' => 'nullable',
|
||||
'arr_time' => 'nullable',
|
||||
'level' => 'nullable|integer',
|
||||
'distance' => 'required|numeric',
|
||||
'flight_time' => 'required|integer',
|
||||
'flight_type' => 'required|alpha',
|
||||
'route' => 'nullable',
|
||||
'notes' => 'nullable',
|
||||
'active' => 'nullable|boolean',
|
||||
'subfleets' => 'nullable',
|
||||
'fares' => 'nullable',
|
||||
'fields' => 'nullable',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,7 @@ class SubfleetExporter extends ImportExport
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$columns = SubfleetImporter::$columns;
|
||||
self::$columns = array_keys(SubfleetImporter::$columns);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,10 +20,10 @@ class SubfleetImporter extends ImportExport
|
||||
* Should match the database fields, for the most part
|
||||
*/
|
||||
public static $columns = [
|
||||
'airline',
|
||||
'type',
|
||||
'name',
|
||||
'fares',
|
||||
'airline' => 'required',
|
||||
'type' => 'required',
|
||||
'name' => 'required',
|
||||
'fares' => 'nullable',
|
||||
];
|
||||
|
||||
private $fareSvc;
|
||||
|
@ -83,7 +83,7 @@ class ImportService extends Service
|
||||
{
|
||||
$reader = $this->openCsv($file_path);
|
||||
|
||||
$cols = $importer->getColumns();
|
||||
$cols = array_keys($importer->getColumns());
|
||||
$first_header = $cols[0];
|
||||
|
||||
$first = true;
|
||||
@ -111,6 +111,14 @@ class ImportService extends Service
|
||||
return trim($val);
|
||||
})->toArray();
|
||||
|
||||
# Try to validate
|
||||
$validator = Validator::make($row, $importer->getColumns());
|
||||
if($validator->fails()) {
|
||||
$errors = 'Error in row '.$offset.','.implode(';', $validator->errors()->all());
|
||||
$importer->errorLog($errors);
|
||||
continue;
|
||||
}
|
||||
|
||||
$importer->import($row, $offset);
|
||||
}
|
||||
|
||||
|
@ -277,6 +277,18 @@ class ImporterTest extends TestCase
|
||||
$this->importSvc->importAirports($file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try importing the aicraft in the airports. Should fail because of
|
||||
* empty/invalid rows
|
||||
*/
|
||||
public function testEmptyCols(): void
|
||||
{
|
||||
$file_path = base_path('tests/data/expenses_empty_rows.csv');
|
||||
$status = $this->importSvc->importExpenses($file_path);
|
||||
$this->assertCount(8, $status['success']);
|
||||
$this->assertCount(0, $status['errors']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the importing of expenses
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
@ -291,7 +303,10 @@ class ImporterTest extends TestCase
|
||||
]);
|
||||
|
||||
$file_path = base_path('tests/data/expenses.csv');
|
||||
$this->importSvc->importExpenses($file_path);
|
||||
$status = $this->importSvc->importExpenses($file_path);
|
||||
|
||||
$this->assertCount(8, $status['success']);
|
||||
$this->assertCount(0, $status['errors']);
|
||||
|
||||
$expenses = \App\Models\Expense::all();
|
||||
|
||||
@ -320,7 +335,10 @@ class ImporterTest extends TestCase
|
||||
public function testFareImporter(): void
|
||||
{
|
||||
$file_path = base_path('tests/data/fares.csv');
|
||||
$this->importSvc->importFares($file_path);
|
||||
$status = $this->importSvc->importFares($file_path);
|
||||
|
||||
$this->assertCount(3, $status['success']);
|
||||
$this->assertCount(0, $status['errors']);
|
||||
|
||||
$fares = \App\Models\Fare::all();
|
||||
|
||||
@ -358,7 +376,10 @@ class ImporterTest extends TestCase
|
||||
[$airline, $subfleet] = $this->insertFlightsScaffoldData();
|
||||
|
||||
$file_path = base_path('tests/data/flights.csv');
|
||||
$this->importSvc->importFlights($file_path);
|
||||
$status = $this->importSvc->importFlights($file_path);
|
||||
|
||||
$this->assertCount(1, $status['success']);
|
||||
$this->assertCount(1, $status['errors']);
|
||||
|
||||
// See if it imported
|
||||
$flight = \App\Models\Flight::where([
|
||||
@ -425,7 +446,10 @@ class ImporterTest extends TestCase
|
||||
$subfleet = factory(App\Models\Subfleet::class)->create(['type' => 'A32X']);
|
||||
|
||||
$file_path = base_path('tests/data/aircraft.csv');
|
||||
$this->importSvc->importAircraft($file_path);
|
||||
$status = $this->importSvc->importAircraft($file_path);
|
||||
|
||||
$this->assertCount(1, $status['success']);
|
||||
$this->assertCount(1, $status['errors']);
|
||||
|
||||
// See if it imported
|
||||
$aircraft = \App\Models\Aircraft::where([
|
||||
@ -444,7 +468,10 @@ class ImporterTest extends TestCase
|
||||
public function testAirportImporter(): void
|
||||
{
|
||||
$file_path = base_path('tests/data/airports.csv');
|
||||
$this->importSvc->importAirports($file_path);
|
||||
$status = $this->importSvc->importAirports($file_path);
|
||||
|
||||
$this->assertCount(1, $status['success']);
|
||||
$this->assertCount(1, $status['errors']);
|
||||
|
||||
// See if it imported
|
||||
$airport = \App\Models\Airport::where([
|
||||
@ -468,7 +495,10 @@ class ImporterTest extends TestCase
|
||||
$airline = factory(App\Models\Airline::class)->create(['icao' => 'VMS']);
|
||||
|
||||
$file_path = base_path('tests/data/subfleets.csv');
|
||||
$this->importSvc->importSubfleets($file_path);
|
||||
$status = $this->importSvc->importSubfleets($file_path);
|
||||
|
||||
$this->assertCount(1, $status['success']);
|
||||
$this->assertCount(1, $status['errors']);
|
||||
|
||||
// See if it imported
|
||||
$subfleet = \App\Models\Subfleet::where([
|
||||
|
@ -1,2 +1,3 @@
|
||||
subfleet,name,registration,hex_code,status
|
||||
A32X,A320-211,N309US,,
|
||||
74X,747 400, ,,
|
||||
|
|
3
tests/data/aircraft_empty_cols.csv
Normal file
3
tests/data/aircraft_empty_cols.csv
Normal file
@ -0,0 +1,3 @@
|
||||
subfleet,name,registration,hex_code,status
|
||||
A32X,A320-211,N309US,,
|
||||
, B744-GE, N304,,
|
|
@ -1,2 +1,3 @@
|
||||
icao,iata,name,location,country,timezone,hub,lat,lon
|
||||
KAUS,AUS,Austin-Bergstrom,"Austin, Texas, USA", United States,America/Chicago,1,30.1945,-97.6699
|
||||
KJFK,JFK,Kennery,"Queens, New York, USA", United States,America/New_York,0,30.1945,abcd
|
||||
|
|
11
tests/data/expenses_empty_rows.csv
Normal file
11
tests/data/expenses_empty_rows.csv
Normal file
@ -0,0 +1,11 @@
|
||||
airline,name,amount,type,charge_to_user,multiplier,active,ref_class,ref_class_id
|
||||
,"Per-Flight (no muliplier)",100,F,0,0,1,,
|
||||
,"Per-Flight (multiplier)",100,F,0,1,1,,
|
||||
VMS,"Per-Flight (multiplier, on airline)",200,F,0,1,1,,
|
||||
,"A daily fee",800,D,0,0,1,,
|
||||
,"A monthly fee",5000,M,0,0,1,,
|
||||
,Catering,1000,F,0,0,1,Subfleet,744-3X-RB211
|
||||
,"Catering Staff",1000,D,0,0,1,Subfleet,744-3X-RB211
|
||||
,Maintenance,1000,D,0,0,1,App\Models\Aircraft,001Z
|
||||
|
||||
|
|
@ -1,2 +1,3 @@
|
||||
airline,flight_number,route_code,route_leg,dpt_airport,arr_airport,alt_airport,days,dpt_time,arr_time,level,distance,flight_time,flight_type,route,notes,active,subfleets,fares,fields
|
||||
VMS,1972,,,KAUS,KJFK,KLGA,15,0810 CST,1235 EST,350,1477,207,J,ILEXY2 ZENZI LFK ELD J29 MEM Q29 JHW J70 STENT J70 MAGIO J70 LVZ LENDY6,"Just a flight",1,A32X,Y?price=300&cost=100&capacity=130;F?price=600&cost=400;B?,Departure Gate=4;Arrival Gate=C41
|
||||
" ",1972,,,KAUS,KJFK,KLGA,15,0810 CST,1235 EST,350,1477,207,J,ILEXY2 ZENZI LFK ELD J29 MEM Q29 JHW J70 STENT J70 MAGIO J70 LVZ LENDY6,"Just a flight",1,A32X,Y?price=300&cost=100&capacity=130;F?price=600&cost=400;B?,Departure Gate=4;Arrival Gate=C41
|
||||
|
|
@ -1,2 +1,3 @@
|
||||
airline,type,name,fares
|
||||
VMS,A32X,Airbus A320,Y;B?capacity=100&price=500%
|
||||
VMS, ,Boeing 747-400,Y;B?capacity=100&price=500%
|
||||
|
|
Loading…
Reference in New Issue
Block a user