Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from culturecode/more-validation
More detailed shapefile archive validation
- Loading branch information
Showing
11 changed files
with
132 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
module SpatialFeatures | ||
module Validation | ||
# SHP file must come first | ||
REQUIRED_SHAPEFILE_COMPONENT_EXTENSIONS = %w[shp shx dbf prj].freeze | ||
|
||
# Check if a shapefile archive includes the required component files, otherwise | ||
# raise an exception. | ||
# | ||
# @param [Zip::File] zip_file A Zip::File object | ||
# @param [String] default_proj4_projection Optional, if supplied we don't raise an exception when we're missing a .PRJ file | ||
# @param [Boolean] allow_generic_zip_files When true, we skip validation entirely if the archive does not contain a .SHP file | ||
def self.validate_shapefile_archive!(zip_file, default_proj4_projection: nil, allow_generic_zip_files: false) | ||
zip_file_entries = zip_file.entries.each_with_object({}) do |f, obj| | ||
obj[File.extname(f.name).downcase[1..-1]] = File.basename(f.name, '.*') | ||
end | ||
|
||
shapefile_basename = zip_file_entries["shp"] | ||
unless shapefile_basename | ||
# not a shapefile archive but we don't care | ||
return if allow_generic_zip_files | ||
|
||
raise ::SpatialFeatures::Importers::IncompleteShapefileArchive, "Shapefile archive is missing a SHP file" | ||
end | ||
|
||
REQUIRED_SHAPEFILE_COMPONENT_EXTENSIONS[1..-1].each do |ext| | ||
ext_basename = zip_file_entries[ext] | ||
next if ext_basename&.casecmp?(shapefile_basename) | ||
|
||
case ext | ||
when "prj" | ||
# special case for missing projection files to allow using default_proj4_projection | ||
next if default_proj4_projection | ||
|
||
raise ::SpatialFeatures::Importers::IndeterminateShapefileProjection, "Shapefile archive is missing a projection file: #{expected_component_path(shapefile_basename, ext)}" | ||
else | ||
# for all un-handled cases of missing files raise the more generic error | ||
raise ::SpatialFeatures::Importers::IncompleteShapefileArchive, "Shapefile archive is missing a required file: #{expected_component_path(shapefile_basename, ext)}" | ||
end | ||
end | ||
|
||
true | ||
end | ||
|
||
def self.expected_component_path(basename, ext) | ||
"#{basename}.#{ext}" | ||
end | ||
end | ||
end |
Binary file renamed
BIN
+124 KB
.../shapefile_with_missing_required_file.zip → ...shapefile_with_incorrect_shx_basename.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
require 'spec_helper' | ||
|
||
describe SpatialFeatures do | ||
describe '::validate_shapefile_archive!!' do | ||
let(:data) { shapefile_without_shape_format } | ||
|
||
it 'skips validation with allow_generic_zip_files option' do | ||
expect { SpatialFeatures::Validation.validate_shapefile_archive!(SpatialFeatures::Download.entries(data), allow_generic_zip_files: true) }.not_to raise_exception | ||
end | ||
|
||
it 'performs validation without allow_generic_zip_files option' do | ||
expect { SpatialFeatures::Validation.validate_shapefile_archive!(SpatialFeatures::Download.entries(data), allow_generic_zip_files: false) }.to \ | ||
raise_exception(SpatialFeatures::Importers::IncompleteShapefileArchive, /FirstNationReserves\.shp/) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,51 @@ | ||
def open_fixture_file(path) | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/#{path}") | ||
end | ||
|
||
def kml_file | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/test.kml") | ||
open_fixture_file("test.kml") | ||
end | ||
|
||
def kmz_file | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/test.kmz") | ||
open_fixture_file("test.kmz") | ||
end | ||
|
||
def kmz_file_features_without_placemarks | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/kmz_file_features_without_placemarks.kmz") | ||
open_fixture_file("kmz_file_features_without_placemarks.kmz") | ||
end | ||
|
||
def kml_file_with_invalid_placemark | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/kml_file_with_invalid_placemark.kml") | ||
open_fixture_file("kml_file_with_invalid_placemark.kml") | ||
end | ||
|
||
def shapefile | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/shapefile.zip") | ||
open_fixture_file("shapefile.zip") | ||
end | ||
|
||
def shapefile_without_projection | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/shapefile_without_projection.zip") | ||
open_fixture_file("shapefile_without_projection.zip") | ||
end | ||
|
||
def shapefile_with_upcase_shp | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/shapefile_with_upcase_shp.zip") | ||
open_fixture_file("shapefile_with_upcase_shp.zip") | ||
end | ||
|
||
def shapefile_without_shape_format | ||
open_fixture_file("shapefile_without_shape_format.zip") | ||
end | ||
|
||
def shapefile_without_shape_index | ||
open_fixture_file("shapefile_without_shape_index.zip") | ||
end | ||
|
||
def shapefile_with_missing_dbf_file | ||
open_fixture_file("shapefile_with_missing_dbf_file.zip") | ||
end | ||
|
||
def shapefile_with_missing_required_file | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/shapefile_with_missing_required_file.zip") | ||
def shapefile_with_incorrect_shx_basename | ||
open_fixture_file("shapefile_with_incorrect_shx_basename.zip") | ||
end | ||
|
||
def archive_without_any_known_file | ||
File.open("#{SpatialFeatures::Engine.root}/spec/fixtures/archive_without_any_known_file.zip") | ||
open_fixture_file("archive_without_any_known_file.zip") | ||
end |